Fixing indentation in applications/solvers/solidMechanics
This commit is contained in:
parent
b46695ce1e
commit
c1cd77a15f
138 changed files with 5164 additions and 5127 deletions
|
@ -6,26 +6,24 @@ aitkenDelta = (U - U.prevIter()) / aitkenInitialRes;
|
||||||
|
|
||||||
// update relaxation factor
|
// update relaxation factor
|
||||||
if(iCorr == 0)
|
if(iCorr == 0)
|
||||||
{
|
{
|
||||||
aitkenTheta = 0.1;
|
aitkenTheta = 0.1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vectorField b = aitkenDelta.internalField() - aitkenDelta.prevIter().internalField();
|
vectorField b = aitkenDelta.internalField() - aitkenDelta.prevIter().internalField();
|
||||||
//scalar sumMagB = gSum(mag(b));
|
//scalar sumMagB = gSum(mag(b));
|
||||||
scalar sumMagB = gSum(magSqr(b));
|
scalar sumMagB = gSum(magSqr(b));
|
||||||
if(sumMagB < SMALL)
|
if(sumMagB < SMALL)
|
||||||
{
|
{
|
||||||
//Warning << "Aitken under-relaxation: denominator less then SMALL"
|
//Warning << "Aitken under-relaxation: denominator less then SMALL"
|
||||||
// << endl;
|
// << endl;
|
||||||
sumMagB += SMALL;
|
sumMagB += SMALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
aitkenTheta = -aitkenTheta*
|
aitkenTheta = -aitkenTheta*
|
||||||
gSum(aitkenDelta.prevIter().internalField() & b)
|
gSum(aitkenDelta.prevIter().internalField() & b)/sumMagB;
|
||||||
/
|
}
|
||||||
sumMagB;
|
|
||||||
}
|
|
||||||
|
|
||||||
// correction to the latest U
|
// correction to the latest U
|
||||||
U += aitkenTheta*aitkenDelta*aitkenInitialRes;
|
U += aitkenTheta*aitkenDelta*aitkenInitialRes;
|
||||||
|
|
|
@ -1,49 +1,44 @@
|
||||||
if(divSigmaExpMethod == "standard")
|
if(divSigmaExpMethod == "standard")
|
||||||
{
|
{
|
||||||
divSigmaExp = fvc::div
|
divSigmaExp = fvc::div
|
||||||
(
|
(
|
||||||
mu*gradU.T() + lambda*(I*tr(gradU)) - (mu + lambda)*gradU,
|
mu*gradU.T() + lambda*(I*tr(gradU)) - (mu + lambda)*gradU,
|
||||||
"div(sigma)"
|
"div(sigma)"
|
||||||
);
|
|
||||||
}
|
|
||||||
else if(divSigmaExpMethod == "surface")
|
|
||||||
{
|
|
||||||
divSigmaExp = fvc::div
|
|
||||||
(
|
|
||||||
muf*(mesh.Sf() & fvc::interpolate(gradU.T()))
|
|
||||||
+ lambdaf*(mesh.Sf() & I*fvc::interpolate(tr(gradU)))
|
|
||||||
- (muf + lambdaf)*(mesh.Sf() & fvc::interpolate(gradU))
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if(divSigmaExpMethod == "decompose")
|
else if(divSigmaExpMethod == "surface")
|
||||||
{
|
{
|
||||||
snGradU = fvc::snGrad(U);
|
divSigmaExp = fvc::div
|
||||||
|
(
|
||||||
|
muf*(mesh.Sf() & fvc::interpolate(gradU.T()))
|
||||||
|
+ lambdaf*(mesh.Sf() & I*fvc::interpolate(tr(gradU)))
|
||||||
|
- (muf + lambdaf)*(mesh.Sf() & fvc::interpolate(gradU))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if(divSigmaExpMethod == "decompose")
|
||||||
|
{
|
||||||
|
snGradU = fvc::snGrad(U);
|
||||||
|
|
||||||
surfaceTensorField shearGradU =
|
surfaceTensorField shearGradU = ((I - n*n) & fvc::interpolate(gradU));
|
||||||
((I - n*n)&fvc::interpolate(gradU));
|
|
||||||
|
|
||||||
divSigmaExp = fvc::div
|
divSigmaExp = fvc::div
|
||||||
(
|
(
|
||||||
mesh.magSf()
|
mesh.magSf()*
|
||||||
*(
|
(
|
||||||
- (muf + lambdaf)*(snGradU&(I - n*n))
|
- (muf + lambdaf)*(snGradU & (I - n*n))
|
||||||
+ lambdaf*tr(shearGradU&(I - n*n))*n
|
+ lambdaf*tr(shearGradU & (I - n*n))*n
|
||||||
+ muf*(shearGradU&n)
|
+ muf*(shearGradU&n)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if(divSigmaExpMethod == "expLaplacian")
|
else if(divSigmaExpMethod == "expLaplacian")
|
||||||
{
|
{
|
||||||
divSigmaExp =
|
divSigmaExp =
|
||||||
- fvc::laplacian(mu + lambda, U, "laplacian(DU,U)")
|
- fvc::laplacian(mu + lambda, U, "laplacian(DU,U)")
|
||||||
+ fvc::div
|
+ fvc::div(mu*gradU.T() + lambda*(I*tr(gradU)), "div(sigma)");
|
||||||
(
|
}
|
||||||
mu*gradU.T()
|
else
|
||||||
+ lambda*(I*tr(gradU)),
|
{
|
||||||
"div(sigma)"
|
FatalErrorIn(args.executable())
|
||||||
);
|
<< "divSigmaExp method " << divSigmaExpMethod << " not found!" << endl;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
FatalError << "divSigmaExp method " << divSigmaExpMethod << " not found!" << endl;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
{
|
{
|
||||||
// force residual is the net force on the model
|
// force residual is the net force on the model
|
||||||
// this should got to zero in a converged steady state model
|
// this should got to zero in a converged steady state model
|
||||||
// should be altered for parallel runs
|
// should be altered for parallel runs
|
||||||
vector netForce = vector::zero;
|
vector netForce = vector::zero;
|
||||||
forAll(mesh.boundary(), patchi)
|
forAll(mesh.boundary(), patchi)
|
||||||
{
|
{
|
||||||
netForce +=
|
netForce += sum
|
||||||
sum(
|
|
||||||
mesh.Sf().boundaryField()[patchi]
|
|
||||||
&
|
|
||||||
(
|
(
|
||||||
2*mu.boundaryField()[patchi]*symm(gradU.boundaryField()[patchi])
|
mesh.Sf().boundaryField()[patchi]
|
||||||
+ lambda*tr(gradU.boundaryField()[patchi])*I
|
&
|
||||||
)
|
(
|
||||||
|
2*mu.boundaryField()[patchi]*symm(gradU.boundaryField()[patchi])
|
||||||
|
+ lambda*tr(gradU.boundaryField()[patchi])*I
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
forceResidual = mag(netForce);
|
forceResidual = mag(netForce);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
{
|
{
|
||||||
surfaceVectorField n = mesh.Sf()/mesh.magSf();
|
surfaceVectorField n = mesh.Sf()/mesh.magSf();
|
||||||
|
|
||||||
// traction = (n&fvc::interpolate(sigma));
|
// traction = (n & fvc::interpolate(sigma));
|
||||||
|
|
||||||
// surfaceTensorField sGradU =
|
// surfaceTensorField sGradU =
|
||||||
// ((I - n*n)&fvc::interpolate(gradU));
|
// ((I - n*n) & fvc::interpolate(gradU));
|
||||||
|
|
||||||
// traction =
|
// traction =
|
||||||
// (2*mu + lambda)*snGradU
|
// (2*mu + lambda)*snGradU
|
||||||
// - (mu + lambda)*(snGradU&(I - n*n))
|
// - (mu + lambda)*(snGradU&(I - n*n))
|
||||||
// + mu*(sGradU&n)
|
// + mu*(sGradU & n)
|
||||||
// + lambda*tr(sGradU&(I - n*n))*n;
|
// + lambda*tr(sGradU&(I - n*n))*n;
|
||||||
|
|
||||||
// traction =
|
// traction =
|
||||||
// (2*mu + lambda)*fvc::snGrad(U)
|
// (2*mu + lambda)*fvc::snGrad(U)
|
||||||
// - (mu + lambda)*(n&sGradU)
|
// - (mu + lambda)*(n & sGradU)
|
||||||
// + mu*(sGradU&n)
|
// + mu*(sGradU & n)
|
||||||
// + lambda*tr(sGradU)*n;
|
// + lambda*tr(sGradU)*n;
|
||||||
|
|
||||||
// philipc
|
// philipc
|
||||||
// I am having trouble with back-calculation of interface tractions from solid interface
|
// I am having trouble with back-calculation of interface tractions from solid interface
|
||||||
|
@ -27,15 +27,15 @@
|
||||||
traction = (n&fvc::interpolate(sigma));
|
traction = (n&fvc::interpolate(sigma));
|
||||||
|
|
||||||
// forAll(traction.boundaryField(), patchi)
|
// forAll(traction.boundaryField(), patchi)
|
||||||
// {
|
// {
|
||||||
// if (mesh.boundary()[patchi].type() == "cohesive")
|
// if (mesh.boundary()[patchi].type() == "cohesive")
|
||||||
// {
|
// {
|
||||||
// forAll(traction.boundaryField()[patchi], facei)
|
// forAll(traction.boundaryField()[patchi], facei)
|
||||||
// {
|
// {
|
||||||
// Pout << "face " << facei << " with traction magnitude "
|
// Pout << "face " << facei << " with traction magnitude "
|
||||||
// << mag(traction.boundaryField()[patchi][facei])/1e6 << " MPa and traction "
|
// << mag(traction.boundaryField()[patchi][facei])/1e6 << " MPa and traction "
|
||||||
// << traction.boundaryField()[patchi][facei]/1e6 << " MPa" << endl;
|
// << traction.boundaryField()[patchi][facei]/1e6 << " MPa" << endl;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,54 +1,53 @@
|
||||||
label cohesivePatchID = -1;
|
label cohesivePatchID = -1;
|
||||||
|
|
||||||
solidCohesiveFvPatchVectorField* cohesivePatchUPtr = NULL;
|
solidCohesiveFvPatchVectorField* cohesivePatchUPtr = NULL;
|
||||||
solidCohesiveFixedModeMixFvPatchVectorField* cohesivePatchUFixedModePtr = NULL;
|
solidCohesiveFixedModeMixFvPatchVectorField* cohesivePatchUFixedModePtr = NULL;
|
||||||
|
|
||||||
forAll (U.boundaryField(), patchI)
|
forAll (U.boundaryField(), patchI)
|
||||||
{
|
{
|
||||||
if (isA<solidCohesiveFvPatchVectorField>(U.boundaryField()[patchI]))
|
if (isA<solidCohesiveFvPatchVectorField>(U.boundaryField()[patchI]))
|
||||||
{
|
{
|
||||||
cohesivePatchID = patchI;
|
cohesivePatchID = patchI;
|
||||||
cohesivePatchUPtr =
|
cohesivePatchUPtr =
|
||||||
&refCast<solidCohesiveFvPatchVectorField>
|
&refCast<solidCohesiveFvPatchVectorField>
|
||||||
(
|
(
|
||||||
U.boundaryField()[cohesivePatchID]
|
U.boundaryField()[cohesivePatchID]
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
else if (isA<solidCohesiveFixedModeMixFvPatchVectorField>(U.boundaryField()[patchI]))
|
||||||
|
{
|
||||||
|
cohesivePatchID = patchI;
|
||||||
|
cohesivePatchUFixedModePtr =
|
||||||
|
&refCast<solidCohesiveFixedModeMixFvPatchVectorField>
|
||||||
|
(
|
||||||
|
U.boundaryField()[cohesivePatchID]
|
||||||
|
);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (isA<solidCohesiveFixedModeMixFvPatchVectorField>(U.boundaryField()[patchI]))
|
|
||||||
{
|
|
||||||
cohesivePatchID = patchI;
|
|
||||||
cohesivePatchUFixedModePtr =
|
|
||||||
&refCast<solidCohesiveFixedModeMixFvPatchVectorField>
|
|
||||||
(
|
|
||||||
U.boundaryField()[cohesivePatchID]
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cohesivePatchID == -1)
|
if(cohesivePatchID == -1)
|
||||||
{
|
{
|
||||||
FatalErrorIn(args.executable())
|
FatalErrorIn(args.executable())
|
||||||
<< "Can't find cohesiveLawFvPatch" << nl
|
<< "Can't find cohesiveLawFvPatch" << nl
|
||||||
<< "One of the boundary patches in " << U.name() << ".boundaryField() "
|
<< "One of the boundary patches in " << U.name() << ".boundaryField() "
|
||||||
<< "should be of type " << solidCohesiveFvPatchVectorField::typeName
|
<< "should be of type " << solidCohesiveFvPatchVectorField::typeName
|
||||||
<< "or " << solidCohesiveFixedModeMixFvPatchVectorField::typeName
|
<< "or " << solidCohesiveFixedModeMixFvPatchVectorField::typeName
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// solidCohesiveFvPatchVectorField& cohesivePatchU =
|
// solidCohesiveFvPatchVectorField& cohesivePatchU =
|
||||||
// refCast<solidCohesiveFvPatchVectorField>
|
// refCast<solidCohesiveFvPatchVectorField>
|
||||||
// (
|
// (
|
||||||
// U.boundaryField()[cohesivePatchID]
|
// U.boundaryField()[cohesivePatchID]
|
||||||
// );
|
// );
|
||||||
|
|
||||||
// philipc: I have moved cohesive stuff to constitutiveModel
|
// philipc: I have moved cohesive stuff to constitutiveModel
|
||||||
|
// cohesiveZone is an index field
|
||||||
// cohesiveZone is an index field
|
// which allows the user to limit the crack to certain areas at runtime
|
||||||
// which allows the user to limit the crack to certain areas at runtime
|
// 1 for faces within cohesiveZone
|
||||||
// 1 for faces within cohesiveZone
|
// 0 for faces outside cohesiveZone
|
||||||
// 0 for faces outside cohesiveZone
|
|
||||||
surfaceScalarField cohesiveZone
|
surfaceScalarField cohesiveZone
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
|
@ -65,85 +64,87 @@
|
||||||
|
|
||||||
// limit crack to specified boxes
|
// limit crack to specified boxes
|
||||||
{
|
{
|
||||||
const dictionary& stressControl =
|
const dictionary& stressControl =
|
||||||
mesh.solutionDict().subDict("solidMechanics");
|
mesh.solutionDict().subDict("solidMechanics");
|
||||||
|
|
||||||
List<boundBox> userBoxes(stressControl.lookup("crackLimitingBoxes"));
|
List<boundBox> userBoxes(stressControl.lookup("crackLimitingBoxes"));
|
||||||
const surfaceVectorField& Cf = mesh.Cf();
|
const surfaceVectorField& Cf = mesh.Cf();
|
||||||
forAll(cohesiveZone.internalField(), faceI)
|
forAll(cohesiveZone.internalField(), faceI)
|
||||||
{
|
|
||||||
bool faceInsideBox = false;
|
|
||||||
|
|
||||||
forAll(userBoxes, boxi)
|
|
||||||
{
|
{
|
||||||
if(userBoxes[boxi].contains(Cf.internalField()[faceI])) faceInsideBox = true;
|
bool faceInsideBox = false;
|
||||||
}
|
|
||||||
|
|
||||||
if(faceInsideBox)
|
forAll(userBoxes, boxi)
|
||||||
{
|
|
||||||
cohesiveZone.internalField()[faceI] = 1.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
forAll(cohesiveZone.boundaryField(), patchI)
|
|
||||||
{
|
|
||||||
// cracks may go along proc boundaries
|
|
||||||
if(mesh.boundaryMesh()[patchI].type() == processorPolyPatch::typeName)
|
|
||||||
{
|
|
||||||
forAll(cohesiveZone.boundaryField()[patchI], faceI)
|
|
||||||
{
|
|
||||||
bool faceInsideBox = false;
|
|
||||||
|
|
||||||
forAll(userBoxes, boxi)
|
|
||||||
{
|
{
|
||||||
if(userBoxes[boxi].contains(Cf.boundaryField()[patchI][faceI])) faceInsideBox = true;
|
if(userBoxes[boxi].contains(Cf.internalField()[faceI])) faceInsideBox = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(faceInsideBox)
|
if(faceInsideBox)
|
||||||
{
|
{
|
||||||
cohesiveZone.boundaryField()[patchI][faceI] = 1.0;
|
cohesiveZone.internalField()[faceI] = 1.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Info << "\nThere are " << gSum(cohesiveZone.internalField()) << " potential internal crack faces" << nl << endl;
|
forAll(cohesiveZone.boundaryField(), patchI)
|
||||||
Info << "\nThere are " << gSum(cohesiveZone.boundaryField())/2 << " potential coupled boundary crack faces" << nl << endl;
|
{
|
||||||
|
// cracks may go along proc boundaries
|
||||||
|
if(mesh.boundaryMesh()[patchI].type() == processorPolyPatch::typeName)
|
||||||
|
{
|
||||||
|
forAll(cohesiveZone.boundaryField()[patchI], faceI)
|
||||||
|
{
|
||||||
|
bool faceInsideBox = false;
|
||||||
|
|
||||||
// write field for visualisation
|
forAll(userBoxes, boxi)
|
||||||
volScalarField cohesiveZoneVol
|
{
|
||||||
(
|
if(userBoxes[boxi].contains(Cf.boundaryField()[patchI][faceI])) faceInsideBox = true;
|
||||||
IOobject
|
}
|
||||||
(
|
|
||||||
"cohesiveZoneVol",
|
if(faceInsideBox)
|
||||||
runTime.timeName(),
|
{
|
||||||
mesh,
|
cohesiveZone.boundaryField()[patchI][faceI] = 1.0;
|
||||||
IOobject::NO_READ,
|
}
|
||||||
IOobject::AUTO_WRITE
|
}
|
||||||
),
|
}
|
||||||
mesh,
|
|
||||||
dimensionedScalar("zero", dimless, 0.0)
|
|
||||||
);
|
|
||||||
forAll(cohesiveZone.internalField(), facei)
|
|
||||||
{
|
|
||||||
if(cohesiveZone.internalField()[facei])
|
|
||||||
{
|
|
||||||
cohesiveZoneVol.internalField()[mesh.owner()[facei]] = 1.0;
|
|
||||||
cohesiveZoneVol.internalField()[mesh.neighbour()[facei]] = 1.0;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
forAll(cohesiveZone.boundaryField(), patchi)
|
Info << "\nThere are " << gSum(cohesiveZone.internalField()) << " potential internal crack faces" << nl << endl;
|
||||||
{
|
Info << "\nThere are " << gSum(cohesiveZone.boundaryField())/2 << " potential coupled boundary crack faces" << nl << endl;
|
||||||
forAll(cohesiveZone.boundaryField()[patchi], facei)
|
|
||||||
|
// write field for visualisation
|
||||||
|
volScalarField cohesiveZoneVol
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"cohesiveZoneVol",
|
||||||
|
runTime.timeName(),
|
||||||
|
mesh,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
),
|
||||||
|
mesh,
|
||||||
|
dimensionedScalar("zero", dimless, 0.0)
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(cohesiveZone.internalField(), facei)
|
||||||
{
|
{
|
||||||
if(cohesiveZone.boundaryField()[patchi][facei] > 0.0)
|
if(cohesiveZone.internalField()[facei])
|
||||||
|
{
|
||||||
|
cohesiveZoneVol.internalField()[mesh.owner()[facei]] = 1.0;
|
||||||
|
cohesiveZoneVol.internalField()[mesh.neighbour()[facei]] = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(cohesiveZone.boundaryField(), patchi)
|
||||||
{
|
{
|
||||||
cohesiveZoneVol.boundaryField()[patchi][facei] = 1.0;
|
forAll(cohesiveZone.boundaryField()[patchi], facei)
|
||||||
|
{
|
||||||
|
if(cohesiveZone.boundaryField()[patchi][facei] > 0.0)
|
||||||
|
{
|
||||||
|
cohesiveZoneVol.boundaryField()[patchi][facei] = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
Info << "Writing cohesiveZone field" << endl;
|
||||||
}
|
cohesiveZoneVol.write();
|
||||||
Info << "Writing cohesiveZone field" << endl;
|
|
||||||
cohesiveZoneVol.write();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,8 @@
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedVector("zero", dimless, vector::zero)
|
dimensionedVector("zero", dimless, vector::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
volVectorField V
|
volVectorField V
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedVector("zero", dimLength, vector::zero)
|
dimensionedVector("zero", dimLength, vector::zero)
|
||||||
);
|
);
|
||||||
// aitken relaxation factor
|
// aitken relaxation factor
|
||||||
scalar aitkenInitialRes = 1.0;
|
scalar aitkenInitialRes = 1.0;
|
||||||
|
@ -140,5 +140,5 @@ scalar aitkenTheta = 0.1;
|
||||||
// IOobject::AUTO_WRITE
|
// IOobject::AUTO_WRITE
|
||||||
// ),
|
// ),
|
||||||
// mesh,
|
// mesh,
|
||||||
// dimensionedVector("zero", dimless, vector::zero)
|
// dimensionedVector("zero", dimless, vector::zero)
|
||||||
// );
|
// );
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
OFstream * filePtr(NULL);
|
OFstream* filePtr(NULL);
|
||||||
word historyPatchName(mesh.solutionDict().subDict("solidMechanics").lookup("historyPatch"));
|
word historyPatchName(mesh.solutionDict().subDict("solidMechanics").lookup("historyPatch"));
|
||||||
label historyPatchID = mesh.boundaryMesh().findPatchID(historyPatchName);
|
label historyPatchID = mesh.boundaryMesh().findPatchID(historyPatchName);
|
||||||
if(historyPatchID == -1)
|
if(historyPatchID == -1)
|
||||||
{
|
{
|
||||||
Warning << "history patch " << historyPatchName
|
Warning << "history patch " << historyPatchName
|
||||||
<< " not found. Force-displacement will not be written"
|
<< " not found. Force-displacement will not be written"
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
else if(Pstream::master())
|
else if(Pstream::master())
|
||||||
{
|
{
|
||||||
Info << "Force-displacement for patch " << historyPatchName
|
Info << "Force-displacement for patch " << historyPatchName
|
||||||
<< " will be written to forceDisp.dat"
|
<< " will be written to forceDisp.dat"
|
||||||
<< endl;
|
<< endl;
|
||||||
|
@ -17,4 +17,4 @@ if(historyPatchID == -1)
|
||||||
filePtr = new OFstream(hisDirName/historyPatchName+"forceDisp.dat");
|
filePtr = new OFstream(hisDirName/historyPatchName+"forceDisp.dat");
|
||||||
OFstream& forceDispFile = *filePtr;
|
OFstream& forceDispFile = *filePtr;
|
||||||
forceDispFile << "#Disp(mm)\tForce(N)" << endl;
|
forceDispFile << "#Disp(mm)\tForce(N)" << endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,64 +54,64 @@ Author
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
# include "setRootCase.H"
|
# include "setRootCase.H"
|
||||||
# include "createTime.H"
|
# include "createTime.H"
|
||||||
# include "createCrackerMesh.H"
|
# include "createCrackerMesh.H"
|
||||||
# include "createFields.H"
|
# include "createFields.H"
|
||||||
# include "createCrack.H"
|
# include "createCrack.H"
|
||||||
//# include "createReference.H"
|
//# include "createReference.H"
|
||||||
# include "createHistory.H"
|
# include "createHistory.H"
|
||||||
# include "readDivSigmaExpMethod.H"
|
# include "readDivSigmaExpMethod.H"
|
||||||
# include "createSolidInterfaceNoModify.H"
|
# include "createSolidInterfaceNoModify.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Info<< "\nStarting time loop\n" << endl;
|
Info<< "\nStarting time loop\n" << endl;
|
||||||
|
|
||||||
lduMatrix::debug = 0;
|
lduMatrix::debug = 0;
|
||||||
|
|
||||||
scalar maxEffTractionFraction = 0;
|
scalar maxEffTractionFraction = 0;
|
||||||
|
|
||||||
// time rates for predictor
|
// time rates for predictor
|
||||||
volTensorField gradV = fvc::ddt(gradU);
|
volTensorField gradV = fvc::ddt(gradU);
|
||||||
surfaceVectorField snGradV =
|
surfaceVectorField snGradV =
|
||||||
(snGradU - snGradU.oldTime())/runTime.deltaT();
|
(snGradU - snGradU.oldTime())/runTime.deltaT();
|
||||||
|
|
||||||
//# include "initialiseSolution.H"
|
//# include "initialiseSolution.H"
|
||||||
|
|
||||||
while (runTime.run())
|
while (runTime.run())
|
||||||
{
|
{
|
||||||
# include "readSolidMechanicsControls.H"
|
# include "readSolidMechanicsControls.H"
|
||||||
# include "setDeltaT.H"
|
# include "setDeltaT.H"
|
||||||
|
|
||||||
runTime++;
|
runTime++;
|
||||||
|
|
||||||
Info<< "\nTime: " << runTime.timeName() << " s\n" << endl;
|
Info << "Time = " << runTime.timeName() << nl << endl;
|
||||||
|
|
||||||
volScalarField rho = rheology.rho();
|
volScalarField rho = rheology.rho();
|
||||||
volScalarField mu = rheology.mu();
|
volScalarField mu = rheology.mu();
|
||||||
volScalarField lambda = rheology.lambda();
|
volScalarField lambda = rheology.lambda();
|
||||||
surfaceScalarField muf = fvc::interpolate(mu);
|
surfaceScalarField muf = fvc::interpolate(mu);
|
||||||
surfaceScalarField lambdaf = fvc::interpolate(lambda);
|
surfaceScalarField lambdaf = fvc::interpolate(lambda);
|
||||||
|
|
||||||
if (solidInterfaceCorr)
|
if (solidInterfaceCorr)
|
||||||
{
|
{
|
||||||
solidInterfacePtr->modifyProperties(muf, lambdaf);
|
solidInterfacePtr->modifyProperties(muf, lambdaf);
|
||||||
}
|
}
|
||||||
|
|
||||||
//# include "waveCourantNo.H"
|
//# include "waveCourantNo.H"
|
||||||
|
|
||||||
int iCorr = 0;
|
int iCorr = 0;
|
||||||
lduMatrix::solverPerformance solverPerf;
|
lduMatrix::solverPerformance solverPerf;
|
||||||
scalar initialResidual = 0;
|
scalar initialResidual = 0;
|
||||||
scalar relativeResidual = 1;
|
scalar relativeResidual = 1;
|
||||||
//scalar forceResidual = 1;
|
//scalar forceResidual = 1;
|
||||||
label nFacesToBreak = 0;
|
label nFacesToBreak = 0;
|
||||||
label nCoupledFacesToBreak = 0;
|
label nCoupledFacesToBreak = 0;
|
||||||
bool topoChange = false;
|
bool topoChange = false;
|
||||||
|
|
||||||
// Predictor step using time rates
|
// Predictor step using time rates
|
||||||
if (predictor)
|
if (predictor)
|
||||||
{
|
{
|
||||||
Info<< "Predicting U, gradU and snGradU using velocity"
|
Info<< "Predicting U, gradU and snGradU using velocity"
|
||||||
<< endl;
|
<< endl;
|
||||||
|
@ -120,149 +120,148 @@ int main(int argc, char *argv[])
|
||||||
snGradU += snGradV*runTime.deltaT();
|
snGradU += snGradV*runTime.deltaT();
|
||||||
}
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
surfaceVectorField n = mesh.Sf()/mesh.magSf();
|
surfaceVectorField n = mesh.Sf()/mesh.magSf();
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
U.storePrevIter();
|
U.storePrevIter();
|
||||||
|
|
||||||
# include "calculateDivSigmaExp.H"
|
# include "calculateDivSigmaExp.H"
|
||||||
|
|
||||||
fvVectorMatrix UEqn
|
fvVectorMatrix UEqn
|
||||||
(
|
(
|
||||||
rho*fvm::d2dt2(U)
|
rho*fvm::d2dt2(U)
|
||||||
==
|
==
|
||||||
fvm::laplacian(2*muf + lambdaf, U, "laplacian(DU,U)")
|
fvm::laplacian(2*muf + lambdaf, U, "laplacian(DU,U)")
|
||||||
+ divSigmaExp
|
+ divSigmaExp
|
||||||
);
|
);
|
||||||
|
|
||||||
//# include "setReference.H"
|
//# include "setReference.H"
|
||||||
|
|
||||||
if (solidInterfaceCorr)
|
if(solidInterfaceCorr)
|
||||||
{
|
{
|
||||||
solidInterfacePtr->correct(UEqn);
|
solidInterfacePtr->correct(UEqn);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (relaxEqn)
|
if (relaxEqn)
|
||||||
{
|
{
|
||||||
UEqn.relax();
|
UEqn.relax();
|
||||||
}
|
}
|
||||||
|
|
||||||
solverPerf = UEqn.solve();
|
solverPerf = UEqn.solve();
|
||||||
|
|
||||||
if (aitkenRelax)
|
if (aitkenRelax)
|
||||||
{
|
{
|
||||||
# include "aitkenRelaxation.H"
|
# include "aitkenRelaxation.H"
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
U.relax();
|
U.relax();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iCorr == 0)
|
if (iCorr == 0)
|
||||||
{
|
{
|
||||||
initialResidual = solverPerf.initialResidual();
|
initialResidual = solverPerf.initialResidual();
|
||||||
aitkenInitialRes = gMax(mag(U.internalField()));
|
aitkenInitialRes = gMax(mag(U.internalField()));
|
||||||
}
|
}
|
||||||
|
|
||||||
//gradU = solidInterfacePtr->grad(U);
|
//gradU = solidInterfacePtr->grad(U);
|
||||||
// use leastSquaresSolidInterface grad scheme
|
// use leastSquaresSolidInterface grad scheme
|
||||||
gradU = fvc::grad(U);
|
gradU = fvc::grad(U);
|
||||||
|
|
||||||
# include "calculateRelativeResidual.H"
|
# include "calculateRelativeResidual.H"
|
||||||
//# include "calculateForceResidual.H"
|
//# include "calculateForceResidual.H"
|
||||||
|
|
||||||
if (iCorr % infoFrequency == 0)
|
if (iCorr % infoFrequency == 0)
|
||||||
{
|
{
|
||||||
Info << "\tTime " << runTime.value()
|
Info<< "\tTime " << runTime.value()
|
||||||
<< ", Corr " << iCorr
|
<< ", Corr " << iCorr
|
||||||
<< ", Solving for " << U.name()
|
<< ", Solving for " << U.name()
|
||||||
<< " using " << solverPerf.solverName()
|
<< " using " << solverPerf.solverName()
|
||||||
<< ", res = " << solverPerf.initialResidual()
|
<< ", res = " << solverPerf.initialResidual()
|
||||||
<< ", rel res = " << relativeResidual;
|
<< ", rel res = " << relativeResidual;
|
||||||
if (aitkenRelax)
|
if (aitkenRelax)
|
||||||
{
|
{
|
||||||
Info << ", aitken = " << aitkenTheta;
|
Info << ", aitken = " << aitkenTheta;
|
||||||
}
|
}
|
||||||
Info << ", inner iters " << solverPerf.nIterations() << endl;
|
Info << ", inner iters " << solverPerf.nIterations() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while
|
while
|
||||||
(
|
(
|
||||||
//iCorr++ == 0
|
//iCorr++ == 0
|
||||||
iCorr++ < 2
|
iCorr++ < 2
|
||||||
||
|
||
|
||||||
(
|
(
|
||||||
solverPerf.initialResidual() > convergenceTolerance
|
solverPerf.initialResidual() > convergenceTolerance
|
||||||
//relativeResidual > convergenceTolerance
|
//relativeResidual > convergenceTolerance
|
||||||
&&
|
&& iCorr < nCorr
|
||||||
iCorr < nCorr
|
)
|
||||||
)
|
);
|
||||||
);
|
|
||||||
|
|
||||||
Info << "Solving for " << U.name() << " using "
|
Info<< "Solving for " << U.name() << " using "
|
||||||
<< solverPerf.solverName()
|
<< solverPerf.solverName()
|
||||||
<< ", Initial residual = " << initialResidual
|
<< ", Initial residual = " << initialResidual
|
||||||
<< ", Final residual = " << solverPerf.initialResidual()
|
<< ", Final residual = " << solverPerf.initialResidual()
|
||||||
<< ", No outer iterations " << iCorr
|
<< ", No outer iterations " << iCorr
|
||||||
<< ", Relative residual " << relativeResidual << endl;
|
<< ", Relative residual " << relativeResidual << endl;
|
||||||
|
|
||||||
# include "calculateTraction.H"
|
# include "calculateTraction.H"
|
||||||
# include "updateCrack.H"
|
# include "updateCrack.H"
|
||||||
|
|
||||||
Info<< "Max effective traction fraction: "
|
Info<< "Max effective traction fraction: "
|
||||||
<< maxEffTractionFraction << endl;
|
<< maxEffTractionFraction << endl;
|
||||||
|
|
||||||
// reset counter if faces want to crack
|
// reset counter if faces want to crack
|
||||||
if ((nFacesToBreak > 0) || (nCoupledFacesToBreak > 0)) iCorr = 0;
|
if ((nFacesToBreak > 0) || (nCoupledFacesToBreak > 0)) iCorr = 0;
|
||||||
}
|
}
|
||||||
while( (nFacesToBreak > 0) || (nCoupledFacesToBreak > 0));
|
while( (nFacesToBreak > 0) || (nCoupledFacesToBreak > 0));
|
||||||
|
|
||||||
if (cohesivePatchUPtr)
|
if (cohesivePatchUPtr)
|
||||||
{
|
{
|
||||||
if (returnReduce(cohesivePatchUPtr->size(), sumOp<label>()))
|
if (returnReduce(cohesivePatchUPtr->size(), sumOp<label>()))
|
||||||
{
|
{
|
||||||
cohesivePatchUPtr->cracking();
|
cohesivePatchUPtr->cracking();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
returnReduce
|
returnReduce
|
||||||
(
|
(
|
||||||
cohesivePatchUFixedModePtr->size(),
|
cohesivePatchUFixedModePtr->size(),
|
||||||
sumOp<label>()
|
sumOp<label>()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Pout << "Number of faces in crack: "
|
Pout << "Number of faces in crack: "
|
||||||
<< cohesivePatchUFixedModePtr->size() << endl;
|
<< cohesivePatchUFixedModePtr->size() << endl;
|
||||||
cohesivePatchUFixedModePtr->relativeSeparationDistance();
|
cohesivePatchUFixedModePtr->relativeSeparationDistance();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update time rates for predictor
|
// update time rates for predictor
|
||||||
if (predictor)
|
if (predictor)
|
||||||
{
|
{
|
||||||
V = fvc::ddt(U);
|
V = fvc::ddt(U);
|
||||||
gradV = fvc::ddt(gradU);
|
gradV = fvc::ddt(gradU);
|
||||||
snGradV = (snGradU - snGradU.oldTime())/runTime.deltaT();
|
snGradV = (snGradU - snGradU.oldTime())/runTime.deltaT();
|
||||||
}
|
}
|
||||||
|
|
||||||
# include "calculateEpsilonSigma.H"
|
# include "calculateEpsilonSigma.H"
|
||||||
# include "writeFields.H"
|
# include "writeFields.H"
|
||||||
# include "writeHistory.H"
|
# include "writeHistory.H"
|
||||||
|
|
||||||
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s\n\n"
|
<< " ClockTime = " << runTime.elapsedClockTime() << " s\n\n"
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "End\n" << endl;
|
Info<< "End\n" << endl;
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
word divSigmaExpMethod(mesh.solutionDict().subDict("solidMechanics").lookup("divSigmaExp"));
|
word divSigmaExpMethod(mesh.solutionDict().subDict("solidMechanics").lookup("divSigmaExp"));
|
||||||
Info << "Selecting divSigmaExp calculation method " << divSigmaExpMethod << endl;
|
Info << "Selecting divSigmaExp calculation method " << divSigmaExpMethod << endl;
|
||||||
if(divSigmaExpMethod != "standard" && divSigmaExpMethod != "surface" && divSigmaExpMethod != "decompose" && divSigmaExpMethod != "laplacian")
|
if(divSigmaExpMethod != "standard" && divSigmaExpMethod != "surface" && divSigmaExpMethod != "decompose" && divSigmaExpMethod != "laplacian")
|
||||||
{
|
{
|
||||||
FatalError << "divSigmaExp method " << divSigmaExpMethod << " not found!" << nl
|
FatalError << "divSigmaExp method " << divSigmaExpMethod << " not found!" << nl
|
||||||
<< "valid methods are:\nstandard\nsurface\ndecompose\nlaplacian"
|
<< "valid methods are:\nstandard\nsurface\ndecompose\nlaplacian"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +1,36 @@
|
||||||
if (dynamicTimeStep && runTime.value() > dynamicTimeStepActivation)
|
if (dynamicTimeStep && runTime.value() > dynamicTimeStepActivation)
|
||||||
{
|
{
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
//(maxEffTraction < 0.999*CzLaw.sigmaMax().value())
|
//(maxEffTraction < 0.999*CzLaw.sigmaMax().value())
|
||||||
(returnReduce(maxEffTractionFraction, maxOp<scalar>()) < 0.99)
|
(returnReduce(maxEffTractionFraction, maxOp<scalar>()) < 0.99)
|
||||||
//&& (cohesivePatchU.size() == 0)
|
//&& (cohesivePatchU.size() == 0)
|
||||||
&& (mag(runTime.deltaT().value() - deltaTmax) < SMALL)
|
&& (mag(runTime.deltaT().value() - deltaTmax) < SMALL)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
runTime.setDeltaT(deltaTmax);
|
runTime.setDeltaT(deltaTmax);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
scalar newDeltaT = deltaTmin;
|
scalar newDeltaT = deltaTmin;
|
||||||
|
|
||||||
if (newDeltaT/runTime.deltaT().value() < 0.5)
|
if (newDeltaT/runTime.deltaT().value() < 0.5)
|
||||||
{
|
{
|
||||||
newDeltaT = 0.5*runTime.deltaT().value();
|
newDeltaT = 0.5*runTime.deltaT().value();
|
||||||
Info << "Reducing time step" << nl;
|
Info << "Reducing time step" << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
runTime.setDeltaT(newDeltaT);
|
runTime.setDeltaT(newDeltaT);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pout << "Current time step size: "
|
Pout << "Current time step size: "
|
||||||
<< runTime.deltaT().value() << " s" << endl;
|
<< runTime.deltaT().value() << " s" << endl;
|
||||||
|
|
||||||
scalar maxDT = runTime.deltaT().value();
|
scalar maxDT = runTime.deltaT().value();
|
||||||
|
|
||||||
if(mag(returnReduce(maxDT, maxOp<scalar>()) - runTime.deltaT().value()) > SMALL)
|
if(mag(returnReduce(maxDT, maxOp<scalar>()) - runTime.deltaT().value()) > SMALL)
|
||||||
{
|
{
|
||||||
FatalError << "Processors have different time-steps!"
|
FatalError << "Processors have different time-steps!"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ nCoupledFacesToBreak = 0;
|
||||||
// only consider tensile tractions
|
// only consider tensile tractions
|
||||||
normalTraction = max(normalTraction, scalar(0));
|
normalTraction = max(normalTraction, scalar(0));
|
||||||
scalarField shearTraction =
|
scalarField shearTraction =
|
||||||
cohesiveZone.internalField() *
|
cohesiveZone.internalField()*
|
||||||
mag( (I - Foam::sqr(n.internalField())) & traction.internalField() );
|
mag( (I - Foam::sqr(n.internalField())) & traction.internalField() );
|
||||||
|
|
||||||
// the traction fraction is monitored to decide which faces to break:
|
// the traction fraction is monitored to decide which faces to break:
|
||||||
|
@ -41,6 +41,7 @@ nCoupledFacesToBreak = 0;
|
||||||
(normalTraction/sigmaMaxI)*(normalTraction/sigmaMaxI)
|
(normalTraction/sigmaMaxI)*(normalTraction/sigmaMaxI)
|
||||||
+ (shearTraction/sigmaMaxI)*(shearTraction/sigmaMaxI);
|
+ (shearTraction/sigmaMaxI)*(shearTraction/sigmaMaxI);
|
||||||
}
|
}
|
||||||
|
|
||||||
maxEffTractionFraction = gMax(effTractionFraction);
|
maxEffTractionFraction = gMax(effTractionFraction);
|
||||||
|
|
||||||
SLList<label> facesToBreakList;
|
SLList<label> facesToBreakList;
|
||||||
|
@ -77,9 +78,14 @@ nCoupledFacesToBreak = 0;
|
||||||
scalar faceToBreakEffTractionFraction = 0;
|
scalar faceToBreakEffTractionFraction = 0;
|
||||||
forAll(facesToBreakEffTractionFraction, faceI)
|
forAll(facesToBreakEffTractionFraction, faceI)
|
||||||
{
|
{
|
||||||
if (facesToBreakEffTractionFraction[faceI] > faceToBreakEffTractionFraction)
|
if
|
||||||
|
(
|
||||||
|
facesToBreakEffTractionFraction[faceI]
|
||||||
|
> faceToBreakEffTractionFraction
|
||||||
|
)
|
||||||
{
|
{
|
||||||
faceToBreakEffTractionFraction = facesToBreakEffTractionFraction[faceI];
|
faceToBreakEffTractionFraction =
|
||||||
|
facesToBreakEffTractionFraction[faceI];
|
||||||
faceToBreakIndex = facesToBreak[faceI];
|
faceToBreakIndex = facesToBreak[faceI];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,7 +98,11 @@ nCoupledFacesToBreak = 0;
|
||||||
bool procHasFaceToBreak = false;
|
bool procHasFaceToBreak = false;
|
||||||
if (nFacesToBreak > 0)
|
if (nFacesToBreak > 0)
|
||||||
{
|
{
|
||||||
if ( mag(gMaxEffTractionFraction - faceToBreakEffTractionFraction) < SMALL )
|
if
|
||||||
|
(
|
||||||
|
mag(gMaxEffTractionFraction - faceToBreakEffTractionFraction)
|
||||||
|
< SMALL
|
||||||
|
)
|
||||||
{
|
{
|
||||||
// philipc - Maximum traction fraction is on this processor
|
// philipc - Maximum traction fraction is on this processor
|
||||||
procHasFaceToBreak = true;
|
procHasFaceToBreak = true;
|
||||||
|
@ -100,7 +110,7 @@ nCoupledFacesToBreak = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if maximum is present on more then one processors
|
// Check if maximum is present on more then one processors
|
||||||
label procID = Pstream::nProcs();
|
label procID = Pstream::nProcs();
|
||||||
if (procHasFaceToBreak)
|
if (procHasFaceToBreak)
|
||||||
{
|
{
|
||||||
procID = Pstream::myProcNo();
|
procID = Pstream::myProcNo();
|
||||||
|
@ -125,46 +135,51 @@ nCoupledFacesToBreak = 0;
|
||||||
if (mesh.boundary()[patchI].coupled())
|
if (mesh.boundary()[patchI].coupled())
|
||||||
{
|
{
|
||||||
// scalarField pEffTraction =
|
// scalarField pEffTraction =
|
||||||
// cohesiveZone.boundaryField()[patchI] *
|
// cohesiveZone.boundaryField()[patchI]*
|
||||||
// mag(traction.boundaryField()[patchI]);
|
// mag(traction.boundaryField()[patchI]);
|
||||||
// scalarField pEffTractionFraction = pEffTraction/sigmaMax.boundaryField()[patchI];
|
// scalarField pEffTractionFraction = pEffTraction/sigmaMax.boundaryField()[patchI];
|
||||||
|
|
||||||
scalarField pNormalTraction =
|
scalarField pNormalTraction =
|
||||||
cohesiveZone.boundaryField()[patchI] *
|
cohesiveZone.boundaryField()[patchI]*
|
||||||
( n.boundaryField()[patchI] & traction.boundaryField()[patchI] );
|
( n.boundaryField()[patchI] & traction.boundaryField()[patchI] );
|
||||||
pNormalTraction = max(pNormalTraction, scalar(0)); // only consider tensile tractions
|
|
||||||
scalarField pShearTraction =
|
|
||||||
cohesiveZone.boundaryField()[patchI] *
|
|
||||||
mag( (I - Foam::sqr(n.boundaryField()[patchI])) & traction.boundaryField()[patchI] );
|
|
||||||
|
|
||||||
// the traction fraction is monitored to decide which faces to break:
|
// only consider tensile tractions
|
||||||
// ie (tN/tNC)^2 + (tS/tSC)^2 >1 to crack a face
|
pNormalTraction = max(pNormalTraction, scalar(0));
|
||||||
const scalarField& pSigmaMax = sigmaMax.boundaryField()[patchI];
|
|
||||||
const scalarField& pTauMax = tauMax.boundaryField()[patchI];
|
|
||||||
|
|
||||||
scalarField pEffTractionFraction(pNormalTraction.size(), 0.0);
|
scalarField pShearTraction =
|
||||||
if(cohesivePatchUPtr)
|
cohesiveZone.boundaryField()[patchI]*
|
||||||
{
|
mag( (I - Foam::sqr(n.boundaryField()[patchI])) & traction.boundaryField()[patchI] );
|
||||||
pEffTractionFraction =
|
|
||||||
(pNormalTraction/pSigmaMax)*(pNormalTraction/pSigmaMax) + (pShearTraction/pTauMax)*(pShearTraction/pTauMax);
|
// the traction fraction is monitored to decide which faces to break:
|
||||||
}
|
// ie (tN/tNC)^2 + (tS/tSC)^2 >1 to crack a face
|
||||||
else
|
const scalarField& pSigmaMax = sigmaMax.boundaryField()[patchI];
|
||||||
{
|
const scalarField& pTauMax = tauMax.boundaryField()[patchI];
|
||||||
// solidCohesiveFixedModeMix only uses sigmaMax
|
|
||||||
pEffTractionFraction =
|
scalarField pEffTractionFraction(pNormalTraction.size(), 0.0);
|
||||||
(pNormalTraction/pSigmaMax)*(pNormalTraction/pSigmaMax) + (pShearTraction/pSigmaMax)*(pShearTraction/pSigmaMax);
|
if(cohesivePatchUPtr)
|
||||||
}
|
{
|
||||||
|
pEffTractionFraction =
|
||||||
|
(pNormalTraction/pSigmaMax)*(pNormalTraction/pSigmaMax)
|
||||||
|
+ (pShearTraction/pTauMax)*(pShearTraction/pTauMax);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// solidCohesiveFixedModeMix only uses sigmaMax
|
||||||
|
pEffTractionFraction =
|
||||||
|
(pNormalTraction/pSigmaMax)*(pNormalTraction/pSigmaMax)
|
||||||
|
+ (pShearTraction/pSigmaMax)*(pShearTraction/pSigmaMax);
|
||||||
|
}
|
||||||
|
|
||||||
label start = mesh.boundaryMesh()[patchI].start();
|
label start = mesh.boundaryMesh()[patchI].start();
|
||||||
|
|
||||||
forAll(pEffTractionFraction, faceI)
|
forAll(pEffTractionFraction, faceI)
|
||||||
{
|
{
|
||||||
if (pEffTractionFraction[faceI] > maxEffTractionFraction)
|
if (pEffTractionFraction[faceI] > maxEffTractionFraction)
|
||||||
{
|
{
|
||||||
maxEffTractionFraction = pEffTractionFraction[faceI];
|
maxEffTractionFraction = pEffTractionFraction[faceI];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pEffTractionFraction[faceI] > 1.0)
|
if (pEffTractionFraction[faceI] > 1.0)
|
||||||
{
|
{
|
||||||
coupledFacesToBreakList.insert(start + faceI);
|
coupledFacesToBreakList.insert(start + faceI);
|
||||||
coupledFacesToBreakEffTractionFractionList.insert
|
coupledFacesToBreakEffTractionFractionList.insert
|
||||||
|
@ -259,8 +274,8 @@ nCoupledFacesToBreak = 0;
|
||||||
labelList index(Pstream::nProcs(), -1);
|
labelList index(Pstream::nProcs(), -1);
|
||||||
if (nCoupledFacesToBreak)
|
if (nCoupledFacesToBreak)
|
||||||
{
|
{
|
||||||
label patchID =
|
label patchID =
|
||||||
mesh.boundaryMesh().whichPatch(coupledFaceToBreakIndex);
|
mesh.boundaryMesh().whichPatch(coupledFaceToBreakIndex);
|
||||||
|
|
||||||
label start = mesh.boundaryMesh()[patchID].start();
|
label start = mesh.boundaryMesh()[patchID].start();
|
||||||
label localIndex = coupledFaceToBreakIndex - start;
|
label localIndex = coupledFaceToBreakIndex - start;
|
||||||
|
@ -318,6 +333,7 @@ nCoupledFacesToBreak = 0;
|
||||||
vector faceToBreakNormal = vector::zero;
|
vector faceToBreakNormal = vector::zero;
|
||||||
scalar faceToBreakSigmaMax = 0.0;
|
scalar faceToBreakSigmaMax = 0.0;
|
||||||
scalar faceToBreakTauMax = 0.0;
|
scalar faceToBreakTauMax = 0.0;
|
||||||
|
|
||||||
// Set faces to break
|
// Set faces to break
|
||||||
if (nFacesToBreak > 0)
|
if (nFacesToBreak > 0)
|
||||||
{
|
{
|
||||||
|
@ -325,31 +341,39 @@ nCoupledFacesToBreak = 0;
|
||||||
faceToBreakNormal = n.internalField()[faceToBreakIndex];
|
faceToBreakNormal = n.internalField()[faceToBreakIndex];
|
||||||
|
|
||||||
// Scale broken face traction
|
// Scale broken face traction
|
||||||
faceToBreakSigmaMax = sigmaMaxI[faceToBreakIndex];
|
faceToBreakSigmaMax = sigmaMaxI[faceToBreakIndex];
|
||||||
faceToBreakTauMax = tauMaxI[faceToBreakIndex];
|
faceToBreakTauMax = tauMaxI[faceToBreakIndex];
|
||||||
scalar normalTrac = faceToBreakNormal & faceToBreakTraction;
|
scalar normalTrac = faceToBreakNormal & faceToBreakTraction;
|
||||||
normalTrac = max(normalTrac, 0.0);
|
normalTrac = max(normalTrac, 0.0);
|
||||||
scalar shearTrac = mag( (I - sqr(faceToBreakNormal)) & faceToBreakTraction );
|
scalar shearTrac = mag( (I - sqr(faceToBreakNormal)) & faceToBreakTraction );
|
||||||
scalar scaleFactor = 1;
|
scalar scaleFactor = 1;
|
||||||
if(cohesivePatchUPtr)
|
if(cohesivePatchUPtr)
|
||||||
{
|
|
||||||
scaleFactor =
|
|
||||||
::sqrt(1 / (
|
|
||||||
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
|
|
||||||
+ (shearTrac/faceToBreakTauMax)*(shearTrac/faceToBreakTauMax)
|
|
||||||
) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// solidCohesiveFixedModeMix only uses sigmaMax
|
scaleFactor =
|
||||||
scaleFactor =
|
Foam::sqrt
|
||||||
::sqrt(1 / (
|
(
|
||||||
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
|
1 /
|
||||||
+ (shearTrac/faceToBreakSigmaMax)*(shearTrac/faceToBreakSigmaMax)
|
(
|
||||||
) );
|
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
|
||||||
|
+ (shearTrac/faceToBreakTauMax)*(shearTrac/faceToBreakTauMax)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// solidCohesiveFixedModeMix only uses sigmaMax
|
||||||
|
scaleFactor =
|
||||||
|
Foam::sqrt
|
||||||
|
(
|
||||||
|
1 /
|
||||||
|
(
|
||||||
|
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
|
||||||
|
+ (shearTrac/faceToBreakSigmaMax)*(shearTrac/faceToBreakSigmaMax)
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
faceToBreakTraction *= scaleFactor;
|
faceToBreakTraction *= scaleFactor;
|
||||||
|
|
||||||
topoChange = true;
|
topoChange = true;
|
||||||
}
|
}
|
||||||
|
@ -364,29 +388,37 @@ nCoupledFacesToBreak = 0;
|
||||||
faceToBreakNormal = n.boundaryField()[patchID][localIndex];
|
faceToBreakNormal = n.boundaryField()[patchID][localIndex];
|
||||||
|
|
||||||
// Scale broken face traction
|
// Scale broken face traction
|
||||||
faceToBreakSigmaMax = sigmaMax.boundaryField()[patchID][localIndex];
|
faceToBreakSigmaMax = sigmaMax.boundaryField()[patchID][localIndex];
|
||||||
faceToBreakTauMax = tauMax.boundaryField()[patchID][localIndex];
|
faceToBreakTauMax = tauMax.boundaryField()[patchID][localIndex];
|
||||||
scalar normalTrac = faceToBreakNormal & faceToBreakTraction;
|
scalar normalTrac = faceToBreakNormal & faceToBreakTraction;
|
||||||
normalTrac = max(normalTrac, 0.0);
|
normalTrac = max(normalTrac, 0.0);
|
||||||
scalar shearTrac = mag( (I - sqr(faceToBreakNormal)) & faceToBreakTraction );
|
scalar shearTrac = mag( (I - sqr(faceToBreakNormal)) & faceToBreakTraction );
|
||||||
scalar scaleFactor = 1;
|
scalar scaleFactor = 1;
|
||||||
if(cohesivePatchUPtr)
|
if(cohesivePatchUPtr)
|
||||||
{
|
{
|
||||||
scaleFactor =
|
scaleFactor =
|
||||||
::sqrt(1 / (
|
Foam::sqrt
|
||||||
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
|
(
|
||||||
+ (shearTrac/faceToBreakTauMax)*(shearTrac/faceToBreakTauMax)
|
1 /
|
||||||
) );
|
(
|
||||||
}
|
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
|
||||||
else
|
+ (shearTrac/faceToBreakTauMax)*(shearTrac/faceToBreakTauMax)
|
||||||
{
|
)
|
||||||
// solidCohesiveFixedModeMix only uses sigmaMax
|
);
|
||||||
scaleFactor =
|
}
|
||||||
::sqrt(1 / (
|
else
|
||||||
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
|
{
|
||||||
+ (shearTrac/faceToBreakSigmaMax)*(shearTrac/faceToBreakSigmaMax)
|
// solidCohesiveFixedModeMix only uses sigmaMax
|
||||||
) );
|
scaleFactor =
|
||||||
}
|
Foam::sqrt
|
||||||
|
(
|
||||||
|
1 /
|
||||||
|
(
|
||||||
|
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
|
||||||
|
+ (shearTrac/faceToBreakSigmaMax)*(shearTrac/faceToBreakSigmaMax)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
faceToBreakTraction *= scaleFactor;
|
faceToBreakTraction *= scaleFactor;
|
||||||
|
|
||||||
|
@ -422,20 +454,20 @@ nCoupledFacesToBreak = 0;
|
||||||
muf = fvc::interpolate(mu);
|
muf = fvc::interpolate(mu);
|
||||||
lambdaf = fvc::interpolate(lambda);
|
lambdaf = fvc::interpolate(lambda);
|
||||||
|
|
||||||
// we need to modify propertiess after cracking otherwise momentum equation is wrong
|
// we need to modify propertiess after cracking otherwise momentum equation is wrong
|
||||||
// but solidInterface seems to hold some information about old mesh
|
// but solidInterface seems to hold some information about old mesh
|
||||||
// so we will delete it and make another
|
// so we will delete it and make another
|
||||||
// we could probably add a public clearout function
|
// we could probably add a public clearout function
|
||||||
// create new solidInterface
|
// create new solidInterface
|
||||||
//Pout << "Creating new solidInterface" << endl;
|
//Pout << "Creating new solidInterface" << endl;
|
||||||
//delete solidInterfacePtr;
|
//delete solidInterfacePtr;
|
||||||
//solidInterfacePtr = new solidInterface(mesh, rheology);
|
//solidInterfacePtr = new solidInterface(mesh, rheology);
|
||||||
// delete demand driven data as the mesh has changed
|
// delete demand driven data as the mesh has changed
|
||||||
if(rheology.solidInterfaceActive())
|
if(rheology.solidInterfaceActive())
|
||||||
{
|
{
|
||||||
rheology.solInterface().clearOut();
|
rheology.solInterface().clearOut();
|
||||||
solidInterfacePtr->modifyProperties(muf, lambdaf);
|
solidInterfacePtr->modifyProperties(muf, lambdaf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Local crack displacement
|
// Local crack displacement
|
||||||
vectorField UpI =
|
vectorField UpI =
|
||||||
|
@ -447,21 +479,21 @@ nCoupledFacesToBreak = 0;
|
||||||
vectorField globalUpI = mesh.globalCrackField(UpI);
|
vectorField globalUpI = mesh.globalCrackField(UpI);
|
||||||
vectorField globalOldUpI = mesh.globalCrackField(oldUpI);
|
vectorField globalOldUpI = mesh.globalCrackField(oldUpI);
|
||||||
|
|
||||||
// mu and lambda field on new crack faces must be updated
|
// mu and lambda field on new crack faces must be updated
|
||||||
scalarField muPI = mu.boundaryField()[cohesivePatchID].patchInternalField();
|
scalarField muPI = mu.boundaryField()[cohesivePatchID].patchInternalField();
|
||||||
scalarField lambdaPI = lambda.boundaryField()[cohesivePatchID].patchInternalField();
|
scalarField lambdaPI = lambda.boundaryField()[cohesivePatchID].patchInternalField();
|
||||||
scalarField globalMuPI = mesh.globalCrackField(muPI);
|
scalarField globalMuPI = mesh.globalCrackField(muPI);
|
||||||
scalarField globalLambdaPI = mesh.globalCrackField(lambdaPI);
|
scalarField globalLambdaPI = mesh.globalCrackField(lambdaPI);
|
||||||
|
|
||||||
// cohesivePatchU.size()
|
// cohesivePatchU.size()
|
||||||
int cohesivePatchSize(cohesivePatchUPtr ? cohesivePatchUPtr->size() : cohesivePatchUFixedModePtr->size());
|
int cohesivePatchSize(cohesivePatchUPtr ? cohesivePatchUPtr->size() : cohesivePatchUFixedModePtr->size());
|
||||||
|
|
||||||
// Initialise U for new cohesive face
|
// Initialise U for new cohesive face
|
||||||
const labelList& gcfa = mesh.globalCrackFaceAddressing();
|
const labelList& gcfa = mesh.globalCrackFaceAddressing();
|
||||||
label globalIndex = mesh.localCrackStart();
|
label globalIndex = mesh.localCrackStart();
|
||||||
// for (label i=0; i<cohesivePatchU.size(); i++)
|
// for (label i=0; i<cohesivePatchU.size(); i++)
|
||||||
for (label i=0; i<cohesivePatchSize; i++)
|
for (label i=0; i<cohesivePatchSize; i++)
|
||||||
{
|
{
|
||||||
label oldFaceIndex = faceMap[start+i];
|
label oldFaceIndex = faceMap[start+i];
|
||||||
|
|
||||||
// If new face
|
// If new face
|
||||||
|
@ -480,10 +512,10 @@ nCoupledFacesToBreak = 0;
|
||||||
+ globalOldUpI[gcfa[globalIndex]]
|
+ globalOldUpI[gcfa[globalIndex]]
|
||||||
);
|
);
|
||||||
|
|
||||||
// initialise mu and lambda on new faces
|
// initialise mu and lambda on new faces
|
||||||
// set new face value to value of internal cell
|
// set new face value to value of internal cell
|
||||||
muf.boundaryField()[cohesivePatchID][i] = globalMuPI[globalIndex];
|
muf.boundaryField()[cohesivePatchID][i] = globalMuPI[globalIndex];
|
||||||
lambdaf.boundaryField()[cohesivePatchID][i] = globalLambdaPI[globalIndex];
|
lambdaf.boundaryField()[cohesivePatchID][i] = globalLambdaPI[globalIndex];
|
||||||
|
|
||||||
globalIndex++;
|
globalIndex++;
|
||||||
}
|
}
|
||||||
|
@ -494,24 +526,24 @@ nCoupledFacesToBreak = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we must calculate grad using interface
|
// we must calculate grad using interface
|
||||||
// U at the interface has not been calculated yet as interface.correct()
|
// U at the interface has not been calculated yet as interface.correct()
|
||||||
// has not been called yet
|
// has not been called yet
|
||||||
// not really a problem as gradU is correct in second outer iteration
|
// not really a problem as gradU is correct in second outer iteration
|
||||||
// as long as this does not cause convergence problems for the first iterations.
|
// as long as this does not cause convergence problems for the first iterations.
|
||||||
// we should be able to calculate the interface displacements without
|
// we should be able to calculate the interface displacements without
|
||||||
// having to call interface.correct()
|
// having to call interface.correct()
|
||||||
// todo: add calculateInterfaceU() function
|
// todo: add calculateInterfaceU() function
|
||||||
// interface grad uses Gauss, we need least squares
|
// interface grad uses Gauss, we need least squares
|
||||||
//gradU = solidInterfacePtr->grad(U);
|
//gradU = solidInterfacePtr->grad(U);
|
||||||
gradU = fvc::grad(U); // leastSquaresSolidInterface grad scheme
|
gradU = fvc::grad(U); // leastSquaresSolidInterface grad scheme
|
||||||
//snGradU = fvc::snGrad(U);
|
//snGradU = fvc::snGrad(U);
|
||||||
|
|
||||||
# include "calculateTraction.H"
|
# include "calculateTraction.H"
|
||||||
//if (nFacesToBreak || nCoupledFacesToBreak) mesh.write(); traction.write();
|
//if (nFacesToBreak || nCoupledFacesToBreak) mesh.write(); traction.write();
|
||||||
|
|
||||||
// Initialise initiation traction for new cohesive patch face
|
// Initialise initiation traction for new cohesive patch face
|
||||||
// for (label i=0; i<cohesivePatchU.size(); i++)
|
// for (label i=0; i<cohesivePatchU.size(); i++)
|
||||||
for (label i=0; i<cohesivePatchSize; i++)
|
for (label i=0; i<cohesivePatchSize; i++)
|
||||||
{
|
{
|
||||||
label oldFaceIndex = faceMap[start+i];
|
label oldFaceIndex = faceMap[start+i];
|
||||||
|
|
||||||
|
@ -527,48 +559,49 @@ nCoupledFacesToBreak = 0;
|
||||||
/mesh.magSf().boundaryField()[cohesivePatchID][i];
|
/mesh.magSf().boundaryField()[cohesivePatchID][i];
|
||||||
//vector n1 = -n0;
|
//vector n1 = -n0;
|
||||||
|
|
||||||
if ((n0&faceToBreakNormal) > SMALL)
|
if ((n0 & faceToBreakNormal) > SMALL)
|
||||||
{
|
{
|
||||||
traction.boundaryField()[cohesivePatchID][i] =
|
traction.boundaryField()[cohesivePatchID][i] =
|
||||||
faceToBreakTraction;
|
faceToBreakTraction;
|
||||||
|
|
||||||
traction.oldTime().boundaryField()[cohesivePatchID][i] =
|
traction.oldTime().boundaryField()[cohesivePatchID][i] =
|
||||||
faceToBreakTraction;
|
faceToBreakTraction;
|
||||||
|
|
||||||
if(cohesivePatchUPtr)
|
if(cohesivePatchUPtr)
|
||||||
{
|
{
|
||||||
cohesivePatchUPtr->traction()[i] = faceToBreakTraction;
|
cohesivePatchUPtr->traction()[i] = faceToBreakTraction;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cohesivePatchUFixedModePtr->traction()[i] = faceToBreakTraction;
|
cohesivePatchUFixedModePtr->traction()[i] = faceToBreakTraction;
|
||||||
cohesivePatchUFixedModePtr->initiationTraction()[i] = faceToBreakTraction;
|
cohesivePatchUFixedModePtr->initiationTraction()[i] = faceToBreakTraction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
traction.boundaryField()[cohesivePatchID][i] =
|
traction.boundaryField()[cohesivePatchID][i] =
|
||||||
-faceToBreakTraction;
|
-faceToBreakTraction;
|
||||||
|
traction.oldTime().boundaryField()[cohesivePatchID][i] =
|
||||||
|
-faceToBreakTraction;
|
||||||
|
|
||||||
traction.oldTime().boundaryField()[cohesivePatchID][i] =
|
//cohesivePatchU.traction()[i] = -faceToBreakTraction;
|
||||||
-faceToBreakTraction;
|
if(cohesivePatchUPtr)
|
||||||
|
{
|
||||||
//cohesivePatchU.traction()[i] = -faceToBreakTraction;
|
cohesivePatchUPtr->traction()[i] = -faceToBreakTraction;
|
||||||
if(cohesivePatchUPtr)
|
}
|
||||||
{
|
else
|
||||||
cohesivePatchUPtr->traction()[i] = -faceToBreakTraction;
|
{
|
||||||
}
|
cohesivePatchUFixedModePtr->traction()[i] =
|
||||||
else
|
-faceToBreakTraction;
|
||||||
{
|
cohesivePatchUFixedModePtr->initiationTraction()[i] =
|
||||||
cohesivePatchUFixedModePtr->traction()[i] = -faceToBreakTraction;
|
-faceToBreakTraction;
|
||||||
cohesivePatchUFixedModePtr->initiationTraction()[i] = -faceToBreakTraction;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// hmmnn we only need a reference for very small groups of cells
|
// hmmnn we only need a reference for very small groups of cells
|
||||||
// turn off for now
|
// turn off for now
|
||||||
//# include "updateReference.H"
|
//# include "updateReference.H"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,20 +4,21 @@
|
||||||
|
|
||||||
forAll(U.boundaryField(), patchI)
|
forAll(U.boundaryField(), patchI)
|
||||||
{
|
{
|
||||||
// philipc - this used to set a reference on
|
// philipc - this used to set a reference on
|
||||||
// processors which did not have a patch that fixesValue
|
// processors which did not have a patch that fixesValue
|
||||||
// so processor in the centre of the domain all had
|
// so processor in the centre of the domain all had
|
||||||
// a referece set causing stress peaks and resulting
|
// a referece set causing stress peaks and resulting
|
||||||
// in an incorrect solution
|
// in an incorrect solution
|
||||||
// so a quick fix is to not set a reference on regions
|
// so a quick fix is to not set a reference on regions
|
||||||
// with a processor boundary
|
// with a processor boundary
|
||||||
//if (U.boundaryField()[patchI].fixesValue())
|
//if (U.boundaryField()[patchI].fixesValue())
|
||||||
if (
|
if
|
||||||
U.boundaryField()[patchI].fixesValue()
|
(
|
||||||
||
|
U.boundaryField()[patchI].fixesValue()
|
||||||
mesh.boundaryMesh()[patchI].type()
|
||
|
||||||
== processorPolyPatch::typeName
|
mesh.boundaryMesh()[patchI].type()
|
||||||
)
|
== processorPolyPatch::typeName
|
||||||
|
)
|
||||||
{
|
{
|
||||||
const unallocLabelList& curFaceCells =
|
const unallocLabelList& curFaceCells =
|
||||||
mesh.boundary()[patchI].faceCells();
|
mesh.boundary()[patchI].faceCells();
|
||||||
|
|
|
@ -85,62 +85,65 @@ if (runTime.outputTime() || topoChange)
|
||||||
|
|
||||||
//- cohesive damage and cracking, and GII and GII
|
//- cohesive damage and cracking, and GII and GII
|
||||||
volScalarField damageAndCracks
|
volScalarField damageAndCracks
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"damageAndCracks",
|
"damageAndCracks",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedScalar("zero", dimless, 0.0),
|
dimensionedScalar("zero", dimless, 0.0),
|
||||||
calculatedFvPatchVectorField::typeName
|
calculatedFvPatchVectorField::typeName
|
||||||
);
|
);
|
||||||
volScalarField GI
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
"GI",
|
|
||||||
runTime.timeName(),
|
|
||||||
mesh,
|
|
||||||
IOobject::NO_READ,
|
|
||||||
IOobject::AUTO_WRITE
|
|
||||||
),
|
|
||||||
mesh,
|
|
||||||
dimensionedScalar("zero", dimless, 0.0),
|
|
||||||
calculatedFvPatchVectorField::typeName
|
|
||||||
);
|
|
||||||
volScalarField GII
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
"GII",
|
|
||||||
runTime.timeName(),
|
|
||||||
mesh,
|
|
||||||
IOobject::NO_READ,
|
|
||||||
IOobject::AUTO_WRITE
|
|
||||||
),
|
|
||||||
mesh,
|
|
||||||
dimensionedScalar("zero", dimless, 0.0),
|
|
||||||
calculatedFvPatchVectorField::typeName
|
|
||||||
);
|
|
||||||
forAll(U.boundaryField(), patchi)
|
|
||||||
{
|
|
||||||
// if(U.boundaryField()[patchi].type() == cohesiveLawMultiMatFvPatchVectorField::typeName)
|
|
||||||
if(U.boundaryField()[patchi].type() == solidCohesiveFvPatchVectorField::typeName)
|
|
||||||
{
|
|
||||||
// cohesiveLawMultiMatFvPatchVectorField& Upatch =
|
|
||||||
// refCast<cohesiveLawMultiMatFvPatchVectorField>(U.boundaryField()[patchi]);
|
|
||||||
solidCohesiveFvPatchVectorField& Upatch =
|
|
||||||
refCast<solidCohesiveFvPatchVectorField>(U.boundaryField()[patchi]);
|
|
||||||
|
|
||||||
GI.boundaryField()[patchi] = Upatch.GI();
|
volScalarField GI
|
||||||
GII.boundaryField()[patchi] = Upatch.GII();
|
(
|
||||||
damageAndCracks.boundaryField()[patchi] = Upatch.crackingAndDamage();
|
IOobject
|
||||||
}
|
(
|
||||||
}
|
"GI",
|
||||||
|
runTime.timeName(),
|
||||||
|
mesh,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
),
|
||||||
|
mesh,
|
||||||
|
dimensionedScalar("zero", dimless, 0.0),
|
||||||
|
calculatedFvPatchVectorField::typeName
|
||||||
|
);
|
||||||
|
|
||||||
|
volScalarField GII
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"GII",
|
||||||
|
runTime.timeName(),
|
||||||
|
mesh,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
),
|
||||||
|
mesh,
|
||||||
|
dimensionedScalar("zero", dimless, 0.0),
|
||||||
|
calculatedFvPatchVectorField::typeName
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(U.boundaryField(), patchi)
|
||||||
|
{
|
||||||
|
// if(U.boundaryField()[patchi].type() == cohesiveLawMultiMatFvPatchVectorField::typeName)
|
||||||
|
if(U.boundaryField()[patchi].type() == solidCohesiveFvPatchVectorField::typeName)
|
||||||
|
{
|
||||||
|
// cohesiveLawMultiMatFvPatchVectorField& Upatch =
|
||||||
|
// refCast<cohesiveLawMultiMatFvPatchVectorField>(U.boundaryField()[patchi]);
|
||||||
|
solidCohesiveFvPatchVectorField& Upatch =
|
||||||
|
refCast<solidCohesiveFvPatchVectorField>(U.boundaryField()[patchi]);
|
||||||
|
|
||||||
|
GI.boundaryField()[patchi] = Upatch.GI();
|
||||||
|
GII.boundaryField()[patchi] = Upatch.GII();
|
||||||
|
damageAndCracks.boundaryField()[patchi] = Upatch.crackingAndDamage();
|
||||||
|
}
|
||||||
|
}
|
||||||
volScalarField GTotal("GTotal", GI + GII);
|
volScalarField GTotal("GTotal", GI + GII);
|
||||||
GTotal.write();
|
GTotal.write();
|
||||||
|
|
||||||
|
|
|
@ -1,35 +1,35 @@
|
||||||
//- write force displacement to file
|
//- write force displacement to file
|
||||||
if(historyPatchID != -1)
|
if(historyPatchID != -1)
|
||||||
{
|
{
|
||||||
Info << "Writing disp and force of patch "<<historyPatchName<<" to file"
|
Info << "Writing disp and force of patch "<<historyPatchName<<" to file"
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
//- for small strain or moving mesh
|
//- for small strain or moving mesh
|
||||||
vector force = gSum(mesh.boundary()[historyPatchID].Sf() & sigma.boundaryField()[historyPatchID]);
|
vector force = gSum(mesh.boundary()[historyPatchID].Sf() & sigma.boundaryField()[historyPatchID]);
|
||||||
|
|
||||||
//- for large strain total lagrangian
|
//- for large strain total lagrangian
|
||||||
// tensorField F = I + gradU.boundaryField()[historyPatchID];
|
// tensorField F = I + gradU.boundaryField()[historyPatchID];
|
||||||
// vectorField totalForce = mesh.Sf().boundaryField()[historyPatchID] & (sigma.boundaryField()[historyPatchID] & F);
|
// vectorField totalForce = mesh.Sf().boundaryField()[historyPatchID] & (sigma.boundaryField()[historyPatchID] & F);
|
||||||
|
|
||||||
//vector force = sum( totalForce );
|
//vector force = sum( totalForce );
|
||||||
|
|
||||||
//scalar force = force[vector::Y];
|
//scalar force = force[vector::Y];
|
||||||
|
|
||||||
//- patchIntegrate utility integrates it this way but this is worng because the sigma tensor should
|
//- patchIntegrate utility integrates it this way but this is worng because the sigma tensor should
|
||||||
//- be dotted with the surface normal to give the actual traction/force
|
//- be dotted with the surface normal to give the actual traction/force
|
||||||
//- you cannot just take the component of the sigma tensor
|
//- you cannot just take the component of the sigma tensor
|
||||||
//scalar forcePatchIntegrateMethod = gSum(
|
//scalar forcePatchIntegrateMethod = gSum(
|
||||||
// mesh.magSf().boundaryField()[historyPatchID]
|
// mesh.magSf().boundaryField()[historyPatchID]*
|
||||||
// *sigma.boundaryField()[historyPatchID].component(symmTensor::XY)
|
// sigma.boundaryField()[historyPatchID].component(symmTensor::XY)
|
||||||
// );
|
//);
|
||||||
|
|
||||||
vector avDisp = gAverage(U.boundaryField()[historyPatchID]);
|
vector avDisp = gAverage(U.boundaryField()[historyPatchID]);
|
||||||
|
|
||||||
//- write to file
|
//- write to file
|
||||||
if(Pstream::master())
|
if(Pstream::master())
|
||||||
{
|
{
|
||||||
OFstream& forceDispFile = *filePtr;
|
OFstream& forceDispFile = *filePtr;
|
||||||
forceDispFile << avDisp.x() << " " << avDisp.y() << " " << avDisp.z() << " "
|
forceDispFile << avDisp.x() << " " << avDisp.y() << " " << avDisp.z() << " "
|
||||||
<< force.x() << " " << force.y() << " " << force.z() << endl;
|
<< force.x() << " " << force.y() << " " << force.z() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,26 +6,24 @@ aitkenDelta = (DU - DU.prevIter()) / aitkenInitialRes;
|
||||||
|
|
||||||
// update relaxation factor
|
// update relaxation factor
|
||||||
if(iCorr == 0)
|
if(iCorr == 0)
|
||||||
{
|
{
|
||||||
aitkenTheta = 0.01;
|
aitkenTheta = 0.01;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vectorField b = aitkenDelta.internalField() - aitkenDelta.prevIter().internalField();
|
vectorField b = aitkenDelta.internalField() - aitkenDelta.prevIter().internalField();
|
||||||
//scalar sumMagB = gSum(mag(b));
|
//scalar sumMagB = gSum(mag(b));
|
||||||
scalar sumMagB = gSum(magSqr(b));
|
scalar sumMagB = gSum(magSqr(b));
|
||||||
if(sumMagB < SMALL)
|
if(sumMagB < SMALL)
|
||||||
{
|
{
|
||||||
//Warning << "Aitken under-relaxation: denominator less then SMALL"
|
//Warning << "Aitken under-relaxation: denominator less then SMALL"
|
||||||
// << endl;
|
// << endl;
|
||||||
sumMagB += SMALL;
|
sumMagB += SMALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
aitkenTheta = -aitkenTheta*
|
aitkenTheta = -aitkenTheta*
|
||||||
gSum(aitkenDelta.prevIter().internalField() & b)
|
gSum(aitkenDelta.prevIter().internalField() & b)/sumMagB;
|
||||||
/
|
}
|
||||||
sumMagB;
|
|
||||||
}
|
|
||||||
|
|
||||||
// correction to the latest DU
|
// correction to the latest DU
|
||||||
DU += aitkenTheta*aitkenDelta*aitkenInitialRes;
|
DU += aitkenTheta*aitkenDelta*aitkenInitialRes;
|
||||||
|
|
|
@ -1,49 +1,45 @@
|
||||||
if(divDSigmaExpMethod == "standard")
|
if(divDSigmaExpMethod == "standard")
|
||||||
{
|
{
|
||||||
divDSigmaExp = fvc::div
|
divDSigmaExp = fvc::div
|
||||||
(
|
(
|
||||||
mu*gradDU.T() + lambda*(I*tr(gradDU)) - (mu + lambda)*gradDU,
|
mu*gradDU.T() + lambda*(I*tr(gradDU)) - (mu + lambda)*gradDU,
|
||||||
"div(sigma)"
|
"div(sigma)"
|
||||||
);
|
|
||||||
}
|
|
||||||
else if(divDSigmaExpMethod == "surface")
|
|
||||||
{
|
|
||||||
divDSigmaExp = fvc::div
|
|
||||||
(
|
|
||||||
muf*(mesh.Sf() & fvc::interpolate(gradDU.T()))
|
|
||||||
+ lambdaf*(mesh.Sf() & I*fvc::interpolate(tr(gradDU)))
|
|
||||||
- (muf + lambdaf)*(mesh.Sf() & fvc::interpolate(gradDU))
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if(divDSigmaExpMethod == "decompose")
|
else if(divDSigmaExpMethod == "surface")
|
||||||
{
|
{
|
||||||
snGradDU = fvc::snGrad(DU);
|
divDSigmaExp = fvc::div
|
||||||
|
(
|
||||||
|
muf*(mesh.Sf() & fvc::interpolate(gradDU.T()))
|
||||||
|
+ lambdaf*(mesh.Sf() & I*fvc::interpolate(tr(gradDU)))
|
||||||
|
- (muf + lambdaf)*(mesh.Sf() & fvc::interpolate(gradDU))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if(divDSigmaExpMethod == "decompose")
|
||||||
|
{
|
||||||
|
snGradDU = fvc::snGrad(DU);
|
||||||
|
|
||||||
surfaceTensorField shearGradDU =
|
surfaceTensorField shearGradDU = ((I - n*n) & fvc::interpolate(gradDU));
|
||||||
((I - n*n)&fvc::interpolate(gradDU));
|
|
||||||
|
|
||||||
divDSigmaExp = fvc::div
|
divDSigmaExp = fvc::div
|
||||||
(
|
(
|
||||||
mesh.magSf()
|
mesh.magSf()*
|
||||||
*(
|
(
|
||||||
- (muf + lambdaf)*(snGradDU&(I - n*n))
|
- (muf + lambdaf)*(snGradDU & (I - n*n))
|
||||||
+ lambdaf*tr(shearGradDU&(I - n*n))*n
|
+ lambdaf*tr(shearGradDU & (I - n*n))*n
|
||||||
+ muf*(shearGradDU&n)
|
+ muf*(shearGradDU & n)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if(divDSigmaExpMethod == "expLaplacian")
|
else if(divDSigmaExpMethod == "expLaplacian")
|
||||||
{
|
{
|
||||||
divDSigmaExp =
|
divDSigmaExp =
|
||||||
- fvc::laplacian(mu + lambda, DU, "laplacian(DDU,DU)")
|
- fvc::laplacian(mu + lambda, DU, "laplacian(DDU,DU)")
|
||||||
+ fvc::div
|
+ fvc::div(mu*gradDU.T() + lambda*(I*tr(gradDU)), "div(sigma)");
|
||||||
(
|
}
|
||||||
mu*gradDU.T()
|
else
|
||||||
+ lambda*(I*tr(gradDU)),
|
{
|
||||||
"div(sigma)"
|
FatalErrorIn(args.executable())
|
||||||
);
|
<< "divDSigmaExp method " << divDSigmaExpMethod << " not found!"
|
||||||
}
|
<< abort(FatalError);
|
||||||
else
|
}
|
||||||
{
|
|
||||||
FatalError << "divDSigmaExp method " << divDSigmaExpMethod << " not found!" << endl;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
{
|
{
|
||||||
// force residual is the net force on the model
|
// force residual is the net force on the model
|
||||||
// this should got to zero in a converged steady state model
|
// this should got to zero in a converged steady state model
|
||||||
// should be altered for parallel runs
|
// should be altered for parallel runs
|
||||||
vector netForce = vector::zero;
|
vector netForce = vector::zero;
|
||||||
forAll(mesh.boundary(), patchi)
|
forAll(mesh.boundary(), patchi)
|
||||||
{
|
{
|
||||||
netForce +=
|
netForce += sum
|
||||||
sum(
|
|
||||||
mesh.Sf().boundaryField()[patchi]
|
|
||||||
&
|
|
||||||
(
|
(
|
||||||
2*mu.boundaryField()[patchi]*symm(gradU.boundaryField()[patchi])
|
mesh.Sf().boundaryField()[patchi]
|
||||||
+ lambda*tr(gradU.boundaryField()[patchi])*I
|
&
|
||||||
)
|
(
|
||||||
|
2*mu.boundaryField()[patchi]*symm(gradU.boundaryField()[patchi])
|
||||||
|
+ lambda*tr(gradU.boundaryField()[patchi])*I
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
forceResidual = mag(netForce);
|
forceResidual = mag(netForce);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
{
|
{
|
||||||
surfaceVectorField n = mesh.Sf()/mesh.magSf();
|
surfaceVectorField n = mesh.Sf()/mesh.magSf();
|
||||||
|
|
||||||
// traction = (n&fvc::interpolate(sigma));
|
// traction = (n & fvc::interpolate(sigma));
|
||||||
|
|
||||||
// surfaceTensorField sGradU =
|
// surfaceTensorField sGradU =
|
||||||
// ((I - n*n)&fvc::interpolate(gradU));
|
// ((I - n*n) & fvc::interpolate(gradU));
|
||||||
|
|
||||||
// traction =
|
// traction =
|
||||||
// (2*mu + lambda)*snGradU
|
// (2*mu + lambda)*snGradU
|
||||||
// - (mu + lambda)*(snGradU&(I - n*n))
|
// - (mu + lambda)*(snGradU&(I - n*n))
|
||||||
// + mu*(sGradU&n)
|
// + mu*(sGradU & n)
|
||||||
// + lambda*tr(sGradU&(I - n*n))*n;
|
// + lambda*tr(sGradU&(I - n*n))*n;
|
||||||
|
|
||||||
// traction =
|
// traction =
|
||||||
// (2*mu + lambda)*fvc::snGrad(U)
|
// (2*mu + lambda)*fvc::snGrad(U)
|
||||||
// - (mu + lambda)*(n&sGradU)
|
// - (mu + lambda)*(n & sGradU)
|
||||||
// + mu*(sGradU&n)
|
// + mu*(sGradU & n)
|
||||||
// + lambda*tr(sGradU)*n;
|
// + lambda*tr(sGradU)*n;
|
||||||
|
|
||||||
// philipc
|
// philipc
|
||||||
// I am having trouble with back-calculation of interface tractions from solid interface
|
// I am having trouble with back-calculation of interface tractions from solid interface
|
||||||
|
@ -27,15 +27,15 @@
|
||||||
traction = (n&fvc::interpolate(sigma+DSigma));
|
traction = (n&fvc::interpolate(sigma+DSigma));
|
||||||
|
|
||||||
// forAll(traction.boundaryField(), patchi)
|
// forAll(traction.boundaryField(), patchi)
|
||||||
// {
|
// {
|
||||||
// if (mesh.boundary()[patchi].type() == "cohesive")
|
// if (mesh.boundary()[patchi].type() == "cohesive")
|
||||||
// {
|
// {
|
||||||
// forAll(traction.boundaryField()[patchi], facei)
|
// forAll(traction.boundaryField()[patchi], facei)
|
||||||
// {
|
// {
|
||||||
// Pout << "face " << facei << " with traction magnitude "
|
// Pout << "face " << facei << " with traction magnitude "
|
||||||
// << mag(traction.boundaryField()[patchi][facei])/1e6 << " MPa and traction "
|
// << mag(traction.boundaryField()[patchi][facei])/1e6 << " MPa and traction "
|
||||||
// << traction.boundaryField()[patchi][facei]/1e6 << " MPa" << endl;
|
// << traction.boundaryField()[patchi][facei]/1e6 << " MPa" << endl;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,53 +1,53 @@
|
||||||
label cohesivePatchID = -1;
|
label cohesivePatchID = -1;
|
||||||
|
|
||||||
solidCohesiveFvPatchVectorField* cohesivePatchDUPtr = NULL;
|
solidCohesiveFvPatchVectorField* cohesivePatchDUPtr = NULL;
|
||||||
solidCohesiveFixedModeMixFvPatchVectorField* cohesivePatchDUFixedModePtr = NULL;
|
solidCohesiveFixedModeMixFvPatchVectorField* cohesivePatchDUFixedModePtr = NULL;
|
||||||
|
|
||||||
forAll (DU.boundaryField(), patchI)
|
forAll (DU.boundaryField(), patchI)
|
||||||
{
|
{
|
||||||
if (isA<solidCohesiveFvPatchVectorField>(DU.boundaryField()[patchI]))
|
if (isA<solidCohesiveFvPatchVectorField>(DU.boundaryField()[patchI]))
|
||||||
{
|
{
|
||||||
cohesivePatchID = patchI;
|
cohesivePatchID = patchI;
|
||||||
cohesivePatchDUPtr =
|
cohesivePatchDUPtr =
|
||||||
&refCast<solidCohesiveFvPatchVectorField>
|
&refCast<solidCohesiveFvPatchVectorField>
|
||||||
(
|
(
|
||||||
DU.boundaryField()[cohesivePatchID]
|
DU.boundaryField()[cohesivePatchID]
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
else if (isA<solidCohesiveFixedModeMixFvPatchVectorField>(DU.boundaryField()[patchI]))
|
||||||
|
{
|
||||||
|
cohesivePatchID = patchI;
|
||||||
|
cohesivePatchDUFixedModePtr =
|
||||||
|
&refCast<solidCohesiveFixedModeMixFvPatchVectorField>
|
||||||
|
(
|
||||||
|
DU.boundaryField()[cohesivePatchID]
|
||||||
|
);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (isA<solidCohesiveFixedModeMixFvPatchVectorField>(DU.boundaryField()[patchI]))
|
|
||||||
{
|
|
||||||
cohesivePatchID = patchI;
|
|
||||||
cohesivePatchDUFixedModePtr =
|
|
||||||
&refCast<solidCohesiveFixedModeMixFvPatchVectorField>
|
|
||||||
(
|
|
||||||
DU.boundaryField()[cohesivePatchID]
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cohesivePatchID == -1)
|
if(cohesivePatchID == -1)
|
||||||
{
|
{
|
||||||
FatalErrorIn(args.executable())
|
FatalErrorIn(args.executable())
|
||||||
<< "Can't find cohesiveLawFvPatch" << nl
|
<< "Can't find cohesiveLawFvPatch" << nl
|
||||||
<< "One of the boundary patches in " << DU.name() << ".boundaryField() "
|
<< "One of the boundary patches in " << DU.name() << ".boundaryField() "
|
||||||
<< "should be of type " << solidCohesiveFvPatchVectorField::typeName
|
<< "should be of type " << solidCohesiveFvPatchVectorField::typeName
|
||||||
<< "or " << solidCohesiveFixedModeMixFvPatchVectorField::typeName
|
<< "or " << solidCohesiveFixedModeMixFvPatchVectorField::typeName
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// solidCohesiveFvPatchVectorField& cohesivePatchDU =
|
// solidCohesiveFvPatchVectorField& cohesivePatchDU =
|
||||||
// refCast<solidCohesiveFvPatchVectorField>
|
// refCast<solidCohesiveFvPatchVectorField>
|
||||||
// (
|
// (
|
||||||
// DU.boundaryField()[cohesivePatchID]
|
// DU.boundaryField()[cohesivePatchID]
|
||||||
// );
|
// );
|
||||||
|
|
||||||
// philipc: I have moved cohesive stuff to constitutiveModel
|
// philipc: I have moved cohesive stuff to constitutiveModel
|
||||||
// cohesiveZone is an index field
|
// cohesiveZone is an index field
|
||||||
// which allows the user to limit the crack to certain areas at runtime
|
// which allows the user to limit the crack to certain areas at runtime
|
||||||
// 1 for faces within cohesiveZone
|
// 1 for faces within cohesiveZone
|
||||||
// 0 for faces outside cohesiveZone
|
// 0 for faces outside cohesiveZone
|
||||||
surfaceScalarField cohesiveZone
|
surfaceScalarField cohesiveZone
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
|
@ -59,110 +59,111 @@
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
//dimensionedScalar("one", dimless, 1.0)
|
|
||||||
dimensionedScalar("zero", dimless, 0.0)
|
dimensionedScalar("zero", dimless, 0.0)
|
||||||
);
|
);
|
||||||
|
|
||||||
// limit crack to specified boxes
|
// limit crack to specified boxes
|
||||||
{
|
{
|
||||||
const dictionary& stressControl =
|
const dictionary& stressControl =
|
||||||
mesh.solutionDict().subDict("solidMechanics");
|
mesh.solutionDict().subDict("solidMechanics");
|
||||||
|
|
||||||
List<boundBox> userBoxes(stressControl.lookup("crackLimitingBoxes"));
|
List<boundBox> userBoxes(stressControl.lookup("crackLimitingBoxes"));
|
||||||
const surfaceVectorField& Cf = mesh.Cf();
|
const surfaceVectorField& Cf = mesh.Cf();
|
||||||
//int numPossibleCrackFaces = 0;
|
//int numPossibleCrackFaces = 0;
|
||||||
forAll(cohesiveZone.internalField(), faceI)
|
forAll(cohesiveZone.internalField(), faceI)
|
||||||
{
|
|
||||||
bool faceInsideBox = false;
|
|
||||||
|
|
||||||
forAll(userBoxes, boxi)
|
|
||||||
{
|
{
|
||||||
if(userBoxes[boxi].contains(Cf.internalField()[faceI])) faceInsideBox = true;
|
bool faceInsideBox = false;
|
||||||
}
|
|
||||||
|
|
||||||
if(faceInsideBox)
|
forAll(userBoxes, boxi)
|
||||||
{
|
|
||||||
cohesiveZone.internalField()[faceI] = 1.0;
|
|
||||||
//numPossibleCrackFaces++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//reduce(numPossibleCrackFaces, sumOp<int>());
|
|
||||||
|
|
||||||
forAll(cohesiveZone.boundaryField(), patchI)
|
|
||||||
{
|
|
||||||
// cracks may go along proc boundaries
|
|
||||||
if(mesh.boundaryMesh()[patchI].type() == processorPolyPatch::typeName)
|
|
||||||
{
|
|
||||||
forAll(cohesiveZone.boundaryField()[patchI], faceI)
|
|
||||||
{
|
|
||||||
bool faceInsideBox = false;
|
|
||||||
|
|
||||||
forAll(userBoxes, boxi)
|
|
||||||
{
|
{
|
||||||
if(userBoxes[boxi].contains(Cf.boundaryField()[patchI][faceI])) faceInsideBox = true;
|
if(userBoxes[boxi].contains(Cf.internalField()[faceI])) faceInsideBox = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(faceInsideBox)
|
if(faceInsideBox)
|
||||||
{
|
{
|
||||||
cohesiveZone.boundaryField()[patchI][faceI] = 1.0;
|
cohesiveZone.internalField()[faceI] = 1.0;
|
||||||
|
//numPossibleCrackFaces++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//reduce(numPossibleCrackFaces, sumOp<int>());
|
||||||
|
|
||||||
// numPossibleCrackFaces += int(sum(cohesiveZone.boundaryField()[patchI]));
|
forAll(cohesiveZone.boundaryField(), patchI)
|
||||||
// philipc multiMat cracks not working on proc boundaries yet... disable for now
|
{
|
||||||
// found the problem: solidInterface needs to know about mesh changes so
|
// cracks may go along proc boundaries
|
||||||
// I make a new one each time there is a crack
|
if(mesh.boundaryMesh()[patchI].type() == processorPolyPatch::typeName)
|
||||||
// int numProcFaces = int(sum(cohesiveZone.boundaryField()[patchI]));
|
{
|
||||||
|
forAll(cohesiveZone.boundaryField()[patchI], faceI)
|
||||||
|
{
|
||||||
|
bool faceInsideBox = false;
|
||||||
|
|
||||||
|
forAll(userBoxes, boxi)
|
||||||
|
{
|
||||||
|
if(userBoxes[boxi].contains(Cf.boundaryField()[patchI][faceI])) faceInsideBox = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(faceInsideBox)
|
||||||
|
{
|
||||||
|
cohesiveZone.boundaryField()[patchI][faceI] = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// numPossibleCrackFaces += int(sum(cohesiveZone.boundaryField()[patchI]));
|
||||||
|
// philipc multiMat cracks not working on proc boundaries yet... disable for now
|
||||||
|
// found the problem: solidInterface needs to know about mesh changes so
|
||||||
|
// I make a new one each time there is a crack
|
||||||
|
// int numProcFaces = int(sum(cohesiveZone.boundaryField()[patchI]));
|
||||||
// if(numProcFaces > 0)
|
// if(numProcFaces > 0)
|
||||||
// {
|
// {
|
||||||
// cohesiveZone.boundaryField()[patchI] = 0.0;
|
// cohesiveZone.boundaryField()[patchI] = 0.0;
|
||||||
// Warning << "Processor boundary cracking is "
|
// Warning << "Processor boundary cracking is "
|
||||||
// << "disabled because it is not working yet for multi-materials." << nl
|
// << "disabled because it is not working yet for multi-materials." << nl
|
||||||
// << "There are " << numProcFaces << " possible cracks "
|
// << "There are " << numProcFaces << " possible cracks "
|
||||||
// << "faces on processor boundary " << mesh.boundary()[patchI].name()
|
// << "faces on processor boundary " << mesh.boundary()[patchI].name()
|
||||||
// << ", which are not allowed to crack." << endl;
|
// << ", which are not allowed to crack." << endl;
|
||||||
// }
|
// }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Info << "\nNumber of possible cracking faces is " << numPossibleCrackFaces << endl;
|
// Info << "\nNumber of possible cracking faces is " << numPossibleCrackFaces << endl;
|
||||||
Info << "\nThere are " << gSum(cohesiveZone.internalField()) << " potential internal crack faces" << nl << endl;
|
Info << "\nThere are " << gSum(cohesiveZone.internalField()) << " potential internal crack faces" << nl << endl;
|
||||||
Info << "\nThere are " << gSum(cohesiveZone.boundaryField())/2 << " potential coupled boundary crack faces" << nl << endl;
|
Info << "\nThere are " << gSum(cohesiveZone.boundaryField())/2 << " potential coupled boundary crack faces" << nl << endl;
|
||||||
|
|
||||||
// write field for visualisation
|
// write field for visualisation
|
||||||
volScalarField cohesiveZoneVol
|
volScalarField cohesiveZoneVol
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"cohesiveZoneVol",
|
"cohesiveZoneVol",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedScalar("zero", dimless, 0.0)
|
dimensionedScalar("zero", dimless, 0.0)
|
||||||
);
|
);
|
||||||
forAll(cohesiveZone.internalField(), facei)
|
|
||||||
{
|
forAll(cohesiveZone.internalField(), facei)
|
||||||
if(cohesiveZone.internalField()[facei])
|
|
||||||
{
|
{
|
||||||
cohesiveZoneVol.internalField()[mesh.owner()[facei]] = 1.0;
|
if(cohesiveZone.internalField()[facei])
|
||||||
cohesiveZoneVol.internalField()[mesh.neighbour()[facei]] = 1.0;
|
{
|
||||||
|
cohesiveZoneVol.internalField()[mesh.owner()[facei]] = 1.0;
|
||||||
|
cohesiveZoneVol.internalField()[mesh.neighbour()[facei]] = 1.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
forAll(cohesiveZone.boundaryField(), patchi)
|
forAll(cohesiveZone.boundaryField(), patchi)
|
||||||
{
|
|
||||||
forAll(cohesiveZone.boundaryField()[patchi], facei)
|
|
||||||
{
|
{
|
||||||
if(cohesiveZone.boundaryField()[patchi][facei])
|
forAll(cohesiveZone.boundaryField()[patchi], facei)
|
||||||
{
|
{
|
||||||
cohesiveZoneVol.boundaryField()[patchi][facei] = 1.0;
|
if(cohesiveZone.boundaryField()[patchi][facei] > 0.0)
|
||||||
|
{
|
||||||
|
cohesiveZoneVol.boundaryField()[patchi][facei] = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
Info << "Writing cohesiveZone field" << endl;
|
||||||
}
|
cohesiveZoneVol.write();
|
||||||
Info << "Writing cohesiveZone field" << endl;
|
|
||||||
cohesiveZoneVol.write();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,8 @@
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedVector("zero", dimless, vector::zero)
|
dimensionedVector("zero", dimless, vector::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
Info<< "Creating field U\n" << endl;
|
Info<< "Creating field U\n" << endl;
|
||||||
|
@ -59,15 +59,15 @@
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"DEpsilon",
|
"DEpsilon",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::READ_IF_PRESENT,
|
IOobject::READ_IF_PRESENT,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedSymmTensor("zero", dimless, symmTensor::zero)
|
dimensionedSymmTensor("zero", dimless, symmTensor::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
volSymmTensorField DSigma
|
volSymmTensorField DSigma
|
||||||
(
|
(
|
||||||
|
@ -111,23 +111,23 @@
|
||||||
dimensionedSymmTensor("zero", dimForce/dimArea, symmTensor::zero)
|
dimensionedSymmTensor("zero", dimForce/dimArea, symmTensor::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
volVectorField divDSigmaExp
|
volVectorField divDSigmaExp
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"divDSigmaExp",
|
"divDSigmaExp",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedVector("zero", dimForce/dimVolume, vector::zero)
|
dimensionedVector("zero", dimForce/dimVolume, vector::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
constitutiveModel rheology(sigma, DU);
|
constitutiveModel rheology(sigma, DU);
|
||||||
//solidInterface interface(mesh, rheology);
|
//solidInterface interface(mesh, rheology);
|
||||||
// solidInterface* interfacePtr = new solidInterface(mesh, rheology);
|
//solidInterface* interfacePtr = new solidInterface(mesh, rheology);
|
||||||
|
|
||||||
surfaceVectorField traction
|
surfaceVectorField traction
|
||||||
(
|
(
|
||||||
|
@ -143,8 +143,8 @@ constitutiveModel rheology(sigma, DU);
|
||||||
dimensionedVector("zero", dimForce/dimArea, vector::zero)
|
dimensionedVector("zero", dimForce/dimArea, vector::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
// for aitken relaxation
|
// for aitken relaxation
|
||||||
volVectorField aitkenDelta
|
volVectorField aitkenDelta
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
|
@ -155,8 +155,9 @@ constitutiveModel rheology(sigma, DU);
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedVector("zero", dimLength, vector::zero)
|
dimensionedVector("zero", dimLength, vector::zero)
|
||||||
);
|
);
|
||||||
// aitken relaxation factor
|
|
||||||
scalar aitkenInitialRes = 1.0;
|
// aitken relaxation factor
|
||||||
scalar aitkenTheta = 0.1;
|
scalar aitkenInitialRes = 1.0;
|
||||||
|
scalar aitkenTheta = 0.1;
|
||||||
|
|
|
@ -2,17 +2,17 @@ OFstream * filePtr(NULL);
|
||||||
word historyPatchName(mesh.solutionDict().subDict("solidMechanics").lookup("historyPatch"));
|
word historyPatchName(mesh.solutionDict().subDict("solidMechanics").lookup("historyPatch"));
|
||||||
label historyPatchID = mesh.boundaryMesh().findPatchID(historyPatchName);
|
label historyPatchID = mesh.boundaryMesh().findPatchID(historyPatchName);
|
||||||
if(historyPatchID == -1)
|
if(historyPatchID == -1)
|
||||||
{
|
{
|
||||||
Warning << "history patch " << historyPatchName
|
Warning << "history patch " << historyPatchName
|
||||||
<< " not found. Force-displacement will not be written"
|
<< " not found. Force-displacement will not be written"
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
else if(Pstream::master())
|
else if(Pstream::master())
|
||||||
{
|
{
|
||||||
Info << "Force-displacement for patch " << historyPatchName
|
Info << "Force-displacement for patch " << historyPatchName
|
||||||
<< " will be written to forceDisp.dat"
|
<< " will be written to forceDisp.dat"
|
||||||
<< endl;
|
<< endl;
|
||||||
filePtr = new OFstream("forceDisp.dat");
|
filePtr = new OFstream("forceDisp.dat");
|
||||||
OFstream& forceDispFile = *filePtr;
|
OFstream& forceDispFile = *filePtr;
|
||||||
forceDispFile << "#Disp(mm)\tForce(N)" << endl;
|
forceDispFile << "#Disp(mm)\tForce(N)" << endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ Author
|
||||||
Philip Cardiff UCD
|
Philip Cardiff UCD
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "fvCFD.H"
|
#include "fvCFD.H"
|
||||||
#include "constitutiveModel.H"
|
#include "constitutiveModel.H"
|
||||||
//#include "componentReferenceList.H"
|
//#include "componentReferenceList.H"
|
||||||
|
@ -48,196 +49,197 @@ Author
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
# include "setRootCase.H"
|
# include "setRootCase.H"
|
||||||
# include "createTime.H"
|
# include "createTime.H"
|
||||||
# include "createCrackerMesh.H"
|
# include "createCrackerMesh.H"
|
||||||
# include "createFields.H"
|
# include "createFields.H"
|
||||||
# include "createCrack.H"
|
# include "createCrack.H"
|
||||||
//# include "createReference.H"
|
//# include "createReference.H"
|
||||||
# include "createHistory.H"
|
# include "createHistory.H"
|
||||||
# include "readDivDSigmaExpMethod.H"
|
# include "readDivDSigmaExpMethod.H"
|
||||||
# include "createSolidInterfaceIncrNoModify.H"
|
# include "createSolidInterfaceIncrNoModify.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Info<< "\nStarting time loop\n" << endl;
|
Info<< "\nStarting time loop\n" << endl;
|
||||||
|
|
||||||
lduMatrix::debug = 0;
|
lduMatrix::debug = 0;
|
||||||
|
|
||||||
scalar maxEffTractionFraction = 0;
|
scalar maxEffTractionFraction = 0;
|
||||||
|
|
||||||
while (runTime.run())
|
while (runTime.run())
|
||||||
{
|
{
|
||||||
# include "readSolidMechanicsControls.H"
|
# include "readSolidMechanicsControls.H"
|
||||||
# include "setDeltaT.H"
|
# include "setDeltaT.H"
|
||||||
|
|
||||||
runTime++;
|
runTime++;
|
||||||
|
|
||||||
Info<< "\nTime: " << runTime.timeName() << " s\n" << endl;
|
Info<< "\nTime = " << runTime.timeName() << " s\n" << endl;
|
||||||
|
|
||||||
volScalarField rho = rheology.rho();
|
volScalarField rho = rheology.rho();
|
||||||
volScalarField mu = rheology.mu();
|
volScalarField mu = rheology.mu();
|
||||||
volScalarField lambda = rheology.lambda();
|
volScalarField lambda = rheology.lambda();
|
||||||
surfaceScalarField muf = fvc::interpolate(mu);
|
surfaceScalarField muf = fvc::interpolate(mu);
|
||||||
surfaceScalarField lambdaf = fvc::interpolate(lambda);
|
surfaceScalarField lambdaf = fvc::interpolate(lambda);
|
||||||
|
|
||||||
solidInterfacePtr->modifyProperties(muf, lambdaf);
|
solidInterfacePtr->modifyProperties(muf, lambdaf);
|
||||||
//# include "waveCourantNo.H"
|
//# include "waveCourantNo.H"
|
||||||
|
|
||||||
int iCorr = 0;
|
int iCorr = 0;
|
||||||
lduMatrix::solverPerformance solverPerf;
|
lduMatrix::solverPerformance solverPerf;
|
||||||
scalar initialResidual = 0;
|
scalar initialResidual = 0;
|
||||||
scalar relativeResidual = 1;
|
scalar relativeResidual = 1;
|
||||||
//scalar forceResidual = 1;
|
//scalar forceResidual = 1;
|
||||||
label nFacesToBreak = 0;
|
label nFacesToBreak = 0;
|
||||||
label nCoupledFacesToBreak = 0;
|
label nCoupledFacesToBreak = 0;
|
||||||
bool topoChange = false;
|
bool topoChange = false;
|
||||||
|
|
||||||
// DU from the previous timestep is usually a good guess
|
// DU from the previous timestep is usually a good guess
|
||||||
// for the next timestep, but it can cause faces to prematurely
|
// for the next timestep, but it can cause faces to prematurely
|
||||||
// crack.
|
// crack.
|
||||||
// so I will reduce DU here to stop this happening
|
// so I will reduce DU here to stop this happening
|
||||||
if (!predictor)
|
if (!predictor)
|
||||||
{
|
{
|
||||||
DU *= 0.0;
|
DU *= 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
surfaceVectorField n = mesh.Sf()/mesh.magSf();
|
surfaceVectorField n = mesh.Sf()/mesh.magSf();
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
DU.storePrevIter();
|
DU.storePrevIter();
|
||||||
|
|
||||||
# include "calculateDivDSigmaExp.H"
|
# include "calculateDivDSigmaExp.H"
|
||||||
|
|
||||||
fvVectorMatrix DUEqn
|
fvVectorMatrix DUEqn
|
||||||
(
|
(
|
||||||
rho*fvm::d2dt2(DU)
|
rho*fvm::d2dt2(DU)
|
||||||
==
|
==
|
||||||
fvm::laplacian(2*muf + lambdaf, DU, "laplacian(DDU,DU)")
|
fvm::laplacian(2*muf + lambdaf, DU, "laplacian(DDU,DU)")
|
||||||
+ divDSigmaExp
|
+ divDSigmaExp
|
||||||
);
|
);
|
||||||
|
|
||||||
//# include "setReference.H"
|
//# include "setReference.H"
|
||||||
|
|
||||||
if(solidInterfacePtr)
|
if(solidInterfacePtr)
|
||||||
{
|
{
|
||||||
solidInterfacePtr->correct(DUEqn);
|
solidInterfacePtr->correct(DUEqn);
|
||||||
}
|
}
|
||||||
|
|
||||||
//DUEqn.relax();
|
//DUEqn.relax();
|
||||||
|
|
||||||
solverPerf = DUEqn.solve();
|
solverPerf = DUEqn.solve();
|
||||||
|
|
||||||
if (aitkenRelax)
|
if (aitkenRelax)
|
||||||
{
|
{
|
||||||
# include "aitkenRelaxation.H"
|
# include "aitkenRelaxation.H"
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DU.relax();
|
DU.relax();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iCorr == 0)
|
if (iCorr == 0)
|
||||||
{
|
{
|
||||||
initialResidual = solverPerf.initialResidual();
|
initialResidual = solverPerf.initialResidual();
|
||||||
aitkenInitialRes = gMax(mag(DU.internalField()));
|
aitkenInitialRes = gMax(mag(DU.internalField()));
|
||||||
}
|
}
|
||||||
|
|
||||||
//gradDU = solidInterfacePtr->grad(DU);
|
//gradDU = solidInterfacePtr->grad(DU);
|
||||||
// use leastSquaresSolidInterface grad scheme
|
// use leastSquaresSolidInterface grad scheme
|
||||||
gradDU = fvc::grad(DU);
|
gradDU = fvc::grad(DU);
|
||||||
|
|
||||||
# include "calculateRelativeResidual.H"
|
# include "calculateRelativeResidual.H"
|
||||||
|
|
||||||
if (iCorr % infoFrequency == 0)
|
if (iCorr % infoFrequency == 0)
|
||||||
{
|
{
|
||||||
Info << "\tTime " << runTime.value()
|
Info<< "\tTime " << runTime.value()
|
||||||
<< ", Corr " << iCorr
|
<< ", Corr " << iCorr
|
||||||
<< ", Solving for " << DU.name()
|
<< ", Solving for " << DU.name()
|
||||||
<< " using " << solverPerf.solverName()
|
<< " using " << solverPerf.solverName()
|
||||||
<< ", res = " << solverPerf.initialResidual()
|
<< ", res = " << solverPerf.initialResidual()
|
||||||
<< ", rel res = " << relativeResidual;
|
<< ", rel res = " << relativeResidual;
|
||||||
if (aitkenRelax)
|
if (aitkenRelax)
|
||||||
{
|
{
|
||||||
Info << ", aitken = " << aitkenTheta;
|
Info << ", aitken = " << aitkenTheta;
|
||||||
}
|
}
|
||||||
Info << ", inner iters " << solverPerf.nIterations() << endl;
|
Info << ", inner iters " << solverPerf.nIterations() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while
|
while
|
||||||
(
|
(
|
||||||
//iCorr++ == 0
|
//iCorr++ == 0
|
||||||
iCorr++ < 10
|
iCorr++ < 10
|
||||||
||
|
||
|
||||||
(
|
(
|
||||||
//solverPerf.initialResidual() > convergenceTolerance
|
//solverPerf.initialResidual() > convergenceTolerance
|
||||||
relativeResidual > convergenceTolerance
|
relativeResidual > convergenceTolerance
|
||||||
&&
|
&&
|
||||||
iCorr < nCorr
|
iCorr < nCorr
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
Info<< "Solving for " << DU.name() << " using "
|
Info<< "Solving for " << DU.name() << " using "
|
||||||
<< solverPerf.solverName()
|
<< solverPerf.solverName()
|
||||||
<< ", Initial residual = " << initialResidual
|
<< ", Initial residual = " << initialResidual
|
||||||
<< ", Final residual = " << solverPerf.initialResidual()
|
<< ", Final residual = " << solverPerf.initialResidual()
|
||||||
<< ", No outer iterations " << iCorr
|
<< ", No outer iterations " << iCorr
|
||||||
<< ", Relative residual " << relativeResidual << endl;
|
<< ", Relative residual " << relativeResidual << endl;
|
||||||
|
|
||||||
# include "calculateTraction.H"
|
# include "calculateTraction.H"
|
||||||
# include "updateCrack.H"
|
# include "updateCrack.H"
|
||||||
|
|
||||||
Info<< "Max effective traction fraction: "
|
Info<< "Max effective traction fraction: "
|
||||||
<< maxEffTractionFraction << endl;
|
<< maxEffTractionFraction << endl;
|
||||||
|
|
||||||
// reset counter if faces want to crack
|
// reset counter if faces want to crack
|
||||||
if ((nFacesToBreak > 0) || (nCoupledFacesToBreak > 0)) iCorr = 0;
|
if ((nFacesToBreak > 0) || (nCoupledFacesToBreak > 0)) iCorr = 0;
|
||||||
}
|
}
|
||||||
while( (nFacesToBreak > 0) || (nCoupledFacesToBreak > 0));
|
while( (nFacesToBreak > 0) || (nCoupledFacesToBreak > 0));
|
||||||
|
|
||||||
if (cohesivePatchDUPtr)
|
if (cohesivePatchDUPtr)
|
||||||
{
|
{
|
||||||
if (returnReduce(cohesivePatchDUPtr->size(), sumOp<label>()))
|
if (returnReduce(cohesivePatchDUPtr->size(), sumOp<label>()))
|
||||||
{
|
{
|
||||||
cohesivePatchDUPtr->cracking();
|
cohesivePatchDUPtr->cracking();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
returnReduce
|
returnReduce
|
||||||
(
|
(
|
||||||
cohesivePatchDUFixedModePtr->size(),
|
cohesivePatchDUFixedModePtr->size(),
|
||||||
sumOp<label>())
|
sumOp<label>()
|
||||||
)
|
)
|
||||||
{
|
)
|
||||||
Pout << "Number of faces in crack: "
|
{
|
||||||
<< cohesivePatchDUFixedModePtr->size() << endl;
|
Pout << "Number of faces in crack: "
|
||||||
cohesivePatchDUFixedModePtr->relativeSeparationDistance();
|
<< cohesivePatchDUFixedModePtr->size() << endl;
|
||||||
}
|
cohesivePatchDUFixedModePtr->relativeSeparationDistance();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# include "calculateDEpsilonDSigma.H"
|
# include "calculateDEpsilonDSigma.H"
|
||||||
|
|
||||||
// update total quantities
|
// update total quantities
|
||||||
U += DU;
|
U += DU;
|
||||||
epsilon += DEpsilon;
|
epsilon += DEpsilon;
|
||||||
sigma += DSigma;
|
sigma += DSigma;
|
||||||
|
|
||||||
# include "writeFields.H"
|
# include "writeFields.H"
|
||||||
# include "writeHistory.H"
|
# include "writeHistory.H"
|
||||||
|
|
||||||
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s\n\n"
|
<< " ClockTime = " << runTime.elapsedClockTime() << " s\n\n"
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "End\n" << endl;
|
Info<< "End\n" << endl;
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,6 @@ Info << "Selecting divDSigmaExp calculation method " << divDSigmaExpMethod << e
|
||||||
if(divDSigmaExpMethod != "standard" && divDSigmaExpMethod != "surface" && divDSigmaExpMethod != "decompose" && divDSigmaExpMethod != "laplacian")
|
if(divDSigmaExpMethod != "standard" && divDSigmaExpMethod != "surface" && divDSigmaExpMethod != "decompose" && divDSigmaExpMethod != "laplacian")
|
||||||
{
|
{
|
||||||
FatalError << "divDSigmaExp method " << divDSigmaExpMethod << " not found!" << nl
|
FatalError << "divDSigmaExp method " << divDSigmaExpMethod << " not found!" << nl
|
||||||
<< "valid methods are:\nstandard\nsurface\ndecompose\nlaplacian"
|
<< "valid methods are:\nstandard\nsurface\ndecompose\nlaplacian"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +1,36 @@
|
||||||
if (dynamicTimeStep)
|
if (dynamicTimeStep)
|
||||||
{
|
{
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
//(maxEffTraction < 0.999*CzLaw.sigmaMax().value())
|
//(maxEffTraction < 0.999*CzLaw.sigmaMax().value())
|
||||||
(returnReduce(maxEffTractionFraction, maxOp<scalar>()) < 0.99)
|
(returnReduce(maxEffTractionFraction, maxOp<scalar>()) < 0.99)
|
||||||
//&& (cohesivePatchU.size() == 0)
|
//&& (cohesivePatchU.size() == 0)
|
||||||
&& (mag(runTime.deltaT().value() - deltaTmax) < SMALL)
|
&& (mag(runTime.deltaT().value() - deltaTmax) < SMALL)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
runTime.setDeltaT(deltaTmax);
|
runTime.setDeltaT(deltaTmax);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
scalar newDeltaT = deltaTmin;
|
scalar newDeltaT = deltaTmin;
|
||||||
|
|
||||||
if (newDeltaT/runTime.deltaT().value() < 0.5)
|
if (newDeltaT/runTime.deltaT().value() < 0.5)
|
||||||
{
|
{
|
||||||
newDeltaT = 0.5*runTime.deltaT().value();
|
newDeltaT = 0.5*runTime.deltaT().value();
|
||||||
Info << "Reducing time step" << nl;
|
Info << "Reducing time step" << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
runTime.setDeltaT(newDeltaT);
|
runTime.setDeltaT(newDeltaT);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pout << "Current time step size: "
|
Pout << "Current time step size: "
|
||||||
<< runTime.deltaT().value() << " s" << endl;
|
<< runTime.deltaT().value() << " s" << endl;
|
||||||
|
|
||||||
scalar maxDT = runTime.deltaT().value();
|
scalar maxDT = runTime.deltaT().value();
|
||||||
|
|
||||||
if(mag(returnReduce(maxDT, maxOp<scalar>()) - runTime.deltaT().value()) > SMALL)
|
if(mag(returnReduce(maxDT, maxOp<scalar>()) - runTime.deltaT().value()) > SMALL)
|
||||||
{
|
{
|
||||||
FatalError << "Processors have different time-steps!"
|
FatalError << "Processors have different time-steps!"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,15 +10,15 @@ nCoupledFacesToBreak = 0;
|
||||||
cohesiveZone.internalField()*
|
cohesiveZone.internalField()*
|
||||||
( n.internalField() & traction.internalField() );
|
( n.internalField() & traction.internalField() );
|
||||||
|
|
||||||
// only consider tensile tractions
|
// only consider tensile tractions
|
||||||
normalTraction = max(normalTraction, scalar(0));
|
normalTraction = max(normalTraction, scalar(0));
|
||||||
|
|
||||||
scalarField shearTraction =
|
scalarField shearTraction =
|
||||||
cohesiveZone.internalField() *
|
cohesiveZone.internalField()*
|
||||||
mag( (I - Foam::sqr(n.internalField())) & traction.internalField() );
|
mag( (I - Foam::sqr(n.internalField())) & traction.internalField() );
|
||||||
|
|
||||||
// the traction fraction is monitored to decide which faces to break:
|
// the traction fraction is monitored to decide which faces to break:
|
||||||
// ie (tN/tNC)^2 + (tS/tSC)^2 >1 to crack a face
|
// ie (tN/tNC)^2 + (tS/tSC)^2 >1 to crack a face
|
||||||
|
|
||||||
const surfaceScalarField sigmaMax = rheology.cohLaw().sigmaMax();
|
const surfaceScalarField sigmaMax = rheology.cohLaw().sigmaMax();
|
||||||
const surfaceScalarField tauMax = rheology.cohLaw().tauMax();
|
const surfaceScalarField tauMax = rheology.cohLaw().tauMax();
|
||||||
|
|
||||||
|
@ -91,6 +91,7 @@ nCoupledFacesToBreak = 0;
|
||||||
faceToBreakIndex = facesToBreak[faceI];
|
faceToBreakIndex = facesToBreak[faceI];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scalar gMaxEffTractionFraction =
|
scalar gMaxEffTractionFraction =
|
||||||
returnReduce(faceToBreakEffTractionFraction, maxOp<scalar>());
|
returnReduce(faceToBreakEffTractionFraction, maxOp<scalar>());
|
||||||
|
|
||||||
|
@ -111,7 +112,6 @@ nCoupledFacesToBreak = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if maximum is present on more then one processors
|
// Check if maximum is present on more then one processors
|
||||||
|
|
||||||
label procID = Pstream::nProcs();
|
label procID = Pstream::nProcs();
|
||||||
if (procHasFaceToBreak)
|
if (procHasFaceToBreak)
|
||||||
{
|
{
|
||||||
|
@ -132,46 +132,47 @@ nCoupledFacesToBreak = 0;
|
||||||
|
|
||||||
SLList<label> coupledFacesToBreakList;
|
SLList<label> coupledFacesToBreakList;
|
||||||
SLList<scalar> coupledFacesToBreakEffTractionFractionList;
|
SLList<scalar> coupledFacesToBreakEffTractionFractionList;
|
||||||
|
|
||||||
forAll(mesh.boundary(), patchI)
|
forAll(mesh.boundary(), patchI)
|
||||||
{
|
{
|
||||||
if (mesh.boundary()[patchI].coupled())
|
if (mesh.boundary()[patchI].coupled())
|
||||||
{
|
{
|
||||||
// scalarField pEffTraction =
|
// scalarField pEffTraction =
|
||||||
// cohesiveZone.boundaryField()[patchI] *
|
// cohesiveZone.boundaryField()[patchI]*
|
||||||
// mag(traction.boundaryField()[patchI]);
|
// mag(traction.boundaryField()[patchI]);
|
||||||
// scalarField pEffTractionFraction = pEffTraction/sigmaMax.boundaryField()[patchI];
|
// scalarField pEffTractionFraction = pEffTraction/sigmaMax.boundaryField()[patchI];
|
||||||
|
|
||||||
scalarField pNormalTraction =
|
scalarField pNormalTraction =
|
||||||
cohesiveZone.boundaryField()[patchI]*
|
cohesiveZone.boundaryField()[patchI]*
|
||||||
( n.boundaryField()[patchI] & traction.boundaryField()[patchI] );
|
( n.boundaryField()[patchI] & traction.boundaryField()[patchI] );
|
||||||
|
|
||||||
// only consider tensile tractions
|
// only consider tensile tractions
|
||||||
pNormalTraction = max(pNormalTraction, scalar(0));
|
pNormalTraction = max(pNormalTraction, scalar(0));
|
||||||
|
|
||||||
scalarField pShearTraction =
|
scalarField pShearTraction =
|
||||||
cohesiveZone.boundaryField()[patchI] *
|
cohesiveZone.boundaryField()[patchI]*
|
||||||
mag( (I - Foam::sqr(n.boundaryField()[patchI])) & traction.boundaryField()[patchI] );
|
mag( (I - Foam::sqr(n.boundaryField()[patchI])) & traction.boundaryField()[patchI] );
|
||||||
|
|
||||||
// the traction fraction is monitored to decide which faces to break:
|
// the traction fraction is monitored to decide which faces to break:
|
||||||
// ie (tN/tNC)^2 + (tS/tSC)^2 >1 to crack a face
|
// ie (tN/tNC)^2 + (tS/tSC)^2 >1 to crack a face
|
||||||
const scalarField& pSigmaMax = sigmaMax.boundaryField()[patchI];
|
const scalarField& pSigmaMax = sigmaMax.boundaryField()[patchI];
|
||||||
const scalarField& pTauMax = tauMax.boundaryField()[patchI];
|
const scalarField& pTauMax = tauMax.boundaryField()[patchI];
|
||||||
|
|
||||||
// scalarField pEffTractionFraction =
|
// scalarField pEffTractionFraction =
|
||||||
// (pNormalTraction/pSigmaMax)*(pNormalTraction/pSigmaMax) + (pShearTraction/pTauMax)*(pShearTraction/pTauMax);
|
// (pNormalTraction/pSigmaMax)*(pNormalTraction/pSigmaMax) + (pShearTraction/pTauMax)*(pShearTraction/pTauMax);
|
||||||
scalarField pEffTractionFraction(pNormalTraction.size(), 0.0);
|
scalarField pEffTractionFraction(pNormalTraction.size(), 0.0);
|
||||||
if(cohesivePatchDUPtr)
|
if(cohesivePatchDUPtr)
|
||||||
{
|
{
|
||||||
pEffTractionFraction =
|
pEffTractionFraction =
|
||||||
(pNormalTraction/pSigmaMax)*(pNormalTraction/pSigmaMax) + (pShearTraction/pTauMax)*(pShearTraction/pTauMax);
|
(pNormalTraction/pSigmaMax)*(pNormalTraction/pSigmaMax)
|
||||||
}
|
+ (pShearTraction/pTauMax)*(pShearTraction/pTauMax);
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
// solidCohesiveFixedModeMix only uses sigmaMax
|
{
|
||||||
pEffTractionFraction =
|
// solidCohesiveFixedModeMix only uses sigmaMax
|
||||||
(pNormalTraction/pSigmaMax)*(pNormalTraction/pSigmaMax) + (pShearTraction/pSigmaMax)*(pShearTraction/pSigmaMax);
|
pEffTractionFraction =
|
||||||
}
|
(pNormalTraction/pSigmaMax)*(pNormalTraction/pSigmaMax)
|
||||||
|
+ (pShearTraction/pSigmaMax)*(pShearTraction/pSigmaMax);
|
||||||
|
}
|
||||||
|
|
||||||
label start = mesh.boundaryMesh()[patchI].start();
|
label start = mesh.boundaryMesh()[patchI].start();
|
||||||
|
|
||||||
|
@ -182,9 +183,9 @@ nCoupledFacesToBreak = 0;
|
||||||
maxEffTractionFraction = pEffTractionFraction[faceI];
|
maxEffTractionFraction = pEffTractionFraction[faceI];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pEffTractionFraction[faceI] > 1.0)
|
if (pEffTractionFraction[faceI] > 1.0)
|
||||||
{
|
{
|
||||||
//Pout << "coupled face to break " << faceI << endl;
|
//Pout << "coupled face to break " << faceI << endl;
|
||||||
coupledFacesToBreakList.insert(start + faceI);
|
coupledFacesToBreakList.insert(start + faceI);
|
||||||
coupledFacesToBreakEffTractionFractionList.insert
|
coupledFacesToBreakEffTractionFractionList.insert
|
||||||
(
|
(
|
||||||
|
@ -227,7 +228,6 @@ nCoupledFacesToBreak = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
scalar gMaxCoupledEffTractionFraction =
|
scalar gMaxCoupledEffTractionFraction =
|
||||||
returnReduce(coupledFaceToBreakEffTractionFraction, maxOp<scalar>());
|
returnReduce(coupledFaceToBreakEffTractionFraction, maxOp<scalar>());
|
||||||
|
|
||||||
|
@ -249,7 +249,6 @@ nCoupledFacesToBreak = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if maximum is present on more then one processors
|
// Check if maximum is present on more then one processors
|
||||||
|
|
||||||
label procID = Pstream::nProcs();
|
label procID = Pstream::nProcs();
|
||||||
if (procHasCoupledFaceToBreak)
|
if (procHasCoupledFaceToBreak)
|
||||||
{
|
{
|
||||||
|
@ -283,6 +282,7 @@ nCoupledFacesToBreak = 0;
|
||||||
{
|
{
|
||||||
label patchID =
|
label patchID =
|
||||||
mesh.boundaryMesh().whichPatch(coupledFaceToBreakIndex);
|
mesh.boundaryMesh().whichPatch(coupledFaceToBreakIndex);
|
||||||
|
|
||||||
label start = mesh.boundaryMesh()[patchID].start();
|
label start = mesh.boundaryMesh()[patchID].start();
|
||||||
label localIndex = coupledFaceToBreakIndex - start;
|
label localIndex = coupledFaceToBreakIndex - start;
|
||||||
|
|
||||||
|
@ -347,30 +347,38 @@ nCoupledFacesToBreak = 0;
|
||||||
faceToBreakNormal = n.internalField()[faceToBreakIndex];
|
faceToBreakNormal = n.internalField()[faceToBreakIndex];
|
||||||
|
|
||||||
// Scale broken face traction
|
// Scale broken face traction
|
||||||
// The scale factor is derived by solving the following eqn for alpha:
|
// The scale factor is derived by solving the following eqn for alpha:
|
||||||
// (alpha*tN/tNC)^2 + (alpha*tS/tSC)^2 = 1
|
// (alpha*tN/tNC)^2 + (alpha*tS/tSC)^2 = 1
|
||||||
faceToBreakSigmaMax = sigmaMaxI[faceToBreakIndex];
|
faceToBreakSigmaMax = sigmaMaxI[faceToBreakIndex];
|
||||||
faceToBreakTauMax = tauMaxI[faceToBreakIndex];
|
faceToBreakTauMax = tauMaxI[faceToBreakIndex];
|
||||||
scalar normalTrac = faceToBreakNormal & faceToBreakTraction;
|
scalar normalTrac = faceToBreakNormal & faceToBreakTraction;
|
||||||
normalTrac = max(normalTrac, 0.0);
|
normalTrac = max(normalTrac, 0.0);
|
||||||
scalar shearTrac = mag( (I - sqr(faceToBreakNormal)) & faceToBreakTraction );
|
scalar shearTrac = mag( (I - sqr(faceToBreakNormal)) & faceToBreakTraction );
|
||||||
scalar scaleFactor = 1;
|
scalar scaleFactor = 1;
|
||||||
if(cohesivePatchDUPtr)
|
if(cohesivePatchDUPtr)
|
||||||
{
|
|
||||||
scaleFactor =
|
|
||||||
::sqrt(1 / (
|
|
||||||
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
|
|
||||||
+ (shearTrac/faceToBreakTauMax)*(shearTrac/faceToBreakTauMax)
|
|
||||||
) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// solidCohesiveFixedModeMix only uses sigmaMax
|
scaleFactor =
|
||||||
scaleFactor =
|
Foam::sqrt
|
||||||
::sqrt(1 / (
|
(
|
||||||
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
|
1 /
|
||||||
+ (shearTrac/faceToBreakSigmaMax)*(shearTrac/faceToBreakSigmaMax)
|
(
|
||||||
) );
|
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
|
||||||
|
+ (shearTrac/faceToBreakTauMax)*(shearTrac/faceToBreakTauMax)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// solidCohesiveFixedModeMix only uses sigmaMax
|
||||||
|
scaleFactor =
|
||||||
|
Foam::sqrt
|
||||||
|
(
|
||||||
|
1 /
|
||||||
|
(
|
||||||
|
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
|
||||||
|
+ (shearTrac/faceToBreakSigmaMax)*(shearTrac/faceToBreakSigmaMax)
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
faceToBreakTraction *= scaleFactor;
|
faceToBreakTraction *= scaleFactor;
|
||||||
|
@ -388,44 +396,41 @@ nCoupledFacesToBreak = 0;
|
||||||
faceToBreakNormal = n.boundaryField()[patchID][localIndex];
|
faceToBreakNormal = n.boundaryField()[patchID][localIndex];
|
||||||
|
|
||||||
// Scale broken face traction
|
// Scale broken face traction
|
||||||
faceToBreakSigmaMax = sigmaMax.boundaryField()[patchID][localIndex];
|
faceToBreakSigmaMax = sigmaMax.boundaryField()[patchID][localIndex];
|
||||||
faceToBreakTauMax = tauMax.boundaryField()[patchID][localIndex];
|
faceToBreakTauMax = tauMax.boundaryField()[patchID][localIndex];
|
||||||
scalar normalTrac = faceToBreakNormal & faceToBreakTraction;
|
scalar normalTrac = faceToBreakNormal & faceToBreakTraction;
|
||||||
normalTrac = max(normalTrac, scalar(0));
|
normalTrac = max(normalTrac, 0.0);
|
||||||
scalar shearTrac = mag( (I - sqr(faceToBreakNormal)) & faceToBreakTraction );
|
scalar shearTrac = mag( (I - sqr(faceToBreakNormal)) & faceToBreakTraction );
|
||||||
scalar scaleFactor = 1;
|
scalar scaleFactor = 1;
|
||||||
if(cohesivePatchDUPtr)
|
if(cohesivePatchDUPtr)
|
||||||
{
|
{
|
||||||
scaleFactor =
|
scaleFactor =
|
||||||
Foam::sqrt
|
Foam::sqrt
|
||||||
(
|
|
||||||
1/
|
|
||||||
(
|
(
|
||||||
(normalTrac/faceToBreakSigmaMax)*
|
1 /
|
||||||
(normalTrac/faceToBreakSigmaMax)
|
(
|
||||||
+ (shearTrac/faceToBreakTauMax)*(shearTrac/faceToBreakTauMax)
|
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
|
||||||
)
|
+ (shearTrac/faceToBreakTauMax)*(shearTrac/faceToBreakTauMax)
|
||||||
);
|
)
|
||||||
}
|
);
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
// solidCohesiveFixedModeMix only uses sigmaMax
|
{
|
||||||
scaleFactor =
|
// solidCohesiveFixedModeMix only uses sigmaMax
|
||||||
Foam::sqrt
|
scaleFactor =
|
||||||
(
|
Foam::sqrt
|
||||||
1/
|
|
||||||
(
|
(
|
||||||
(normalTrac/faceToBreakSigmaMax)*
|
1 /
|
||||||
(normalTrac/faceToBreakSigmaMax)
|
(
|
||||||
+ (shearTrac/faceToBreakSigmaMax)*
|
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
|
||||||
(shearTrac/faceToBreakSigmaMax)
|
+ (shearTrac/faceToBreakSigmaMax)*(shearTrac/faceToBreakSigmaMax)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
faceToBreakTraction *= scaleFactor;
|
faceToBreakTraction *= scaleFactor;
|
||||||
|
|
||||||
topoChange = true;
|
topoChange = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
reduce(topoChange, orOp<bool>());
|
reduce(topoChange, orOp<bool>());
|
||||||
|
@ -447,7 +452,7 @@ nCoupledFacesToBreak = 0;
|
||||||
Pout << "Coupled face to break: " << coupledFaceToBreak << endl;
|
Pout << "Coupled face to break: " << coupledFaceToBreak << endl;
|
||||||
|
|
||||||
mesh.setBreak(faceToBreak, faceToBreakFlip, coupledFaceToBreak);
|
mesh.setBreak(faceToBreak, faceToBreakFlip, coupledFaceToBreak);
|
||||||
mesh.update();
|
mesh.update();
|
||||||
|
|
||||||
const labelList& faceMap = mesh.topoChangeMap().faceMap();
|
const labelList& faceMap = mesh.topoChangeMap().faceMap();
|
||||||
label start = mesh.boundaryMesh()[cohesivePatchID].start();
|
label start = mesh.boundaryMesh()[cohesivePatchID].start();
|
||||||
|
@ -457,19 +462,19 @@ nCoupledFacesToBreak = 0;
|
||||||
muf = fvc::interpolate(mu);
|
muf = fvc::interpolate(mu);
|
||||||
lambdaf = fvc::interpolate(lambda);
|
lambdaf = fvc::interpolate(lambda);
|
||||||
|
|
||||||
// we need to modify propertiess after cracking otherwise momentum equation is wrong
|
// we need to modify propertiess after cracking otherwise momentum equation is wrong
|
||||||
// but solidInterface seems to hold some information about old mesh
|
// but solidInterface seems to hold some information about old mesh
|
||||||
// so we will delete it and make another
|
// so we will delete it and make another
|
||||||
// we could probably add a public clearout function
|
// we could probably add a public clearout function
|
||||||
// create new solidInterface
|
// create new solidInterface
|
||||||
if(rheology.solidInterfaceActive())
|
if(rheology.solidInterfaceActive())
|
||||||
{
|
{
|
||||||
rheology.solInterface().clearOut();
|
rheology.solInterface().clearOut();
|
||||||
solidInterfacePtr->modifyProperties(muf, lambdaf);
|
solidInterfacePtr->modifyProperties(muf, lambdaf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// All values on the new crack faces get set to zero
|
// All values on the new crack faces get set to zero
|
||||||
// so we must manually correct them
|
// so we must manually correct them
|
||||||
const vectorField DUpI =
|
const vectorField DUpI =
|
||||||
DU.boundaryField()[cohesivePatchID].patchInternalField();
|
DU.boundaryField()[cohesivePatchID].patchInternalField();
|
||||||
const vectorField oldDUpI =
|
const vectorField oldDUpI =
|
||||||
|
@ -492,8 +497,8 @@ nCoupledFacesToBreak = 0;
|
||||||
const scalarField globalMuPI = mesh.globalCrackField(muPI);
|
const scalarField globalMuPI = mesh.globalCrackField(muPI);
|
||||||
const scalarField globalLambdaPI = mesh.globalCrackField(lambdaPI);
|
const scalarField globalLambdaPI = mesh.globalCrackField(lambdaPI);
|
||||||
|
|
||||||
// cohesivePatchU.size()
|
// cohesivePatchU.size()
|
||||||
int cohesivePatchSize(cohesivePatchDUPtr ? cohesivePatchDUPtr->size() : cohesivePatchDUFixedModePtr->size());
|
int cohesivePatchSize(cohesivePatchDUPtr ? cohesivePatchDUPtr->size() : cohesivePatchDUFixedModePtr->size());
|
||||||
|
|
||||||
// Initialise fields for new cohesive face
|
// Initialise fields for new cohesive face
|
||||||
const labelList& gcfa = mesh.globalCrackFaceAddressing();
|
const labelList& gcfa = mesh.globalCrackFaceAddressing();
|
||||||
|
@ -506,9 +511,9 @@ nCoupledFacesToBreak = 0;
|
||||||
// If new face
|
// If new face
|
||||||
if (oldFaceIndex == faceToBreakIndex)
|
if (oldFaceIndex == faceToBreakIndex)
|
||||||
{
|
{
|
||||||
// set to average of old cell centres
|
// set to average of old cell centres
|
||||||
// hmnnn it would be better to interpolate
|
// hmnnn it would be better to interpolate
|
||||||
// using weights... OK for now: future work
|
// using weights... OK for now: future work
|
||||||
DU.boundaryField()[cohesivePatchID][i] =
|
DU.boundaryField()[cohesivePatchID][i] =
|
||||||
0.5
|
0.5
|
||||||
*(
|
*(
|
||||||
|
@ -540,10 +545,10 @@ nCoupledFacesToBreak = 0;
|
||||||
+ globalsigmapI[gcfa[globalIndex]]
|
+ globalsigmapI[gcfa[globalIndex]]
|
||||||
);
|
);
|
||||||
|
|
||||||
// initialise mu and lambda on new faces
|
// initialise mu and lambda on new faces
|
||||||
// set new face value to value of internal cell
|
// set new face value to value of internal cell
|
||||||
muf.boundaryField()[cohesivePatchID][i] = globalMuPI[globalIndex];
|
muf.boundaryField()[cohesivePatchID][i] = globalMuPI[globalIndex];
|
||||||
lambdaf.boundaryField()[cohesivePatchID][i] = globalLambdaPI[globalIndex];
|
lambdaf.boundaryField()[cohesivePatchID][i] = globalLambdaPI[globalIndex];
|
||||||
|
|
||||||
globalIndex++;
|
globalIndex++;
|
||||||
}
|
}
|
||||||
|
@ -554,24 +559,24 @@ nCoupledFacesToBreak = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we must calculate grad using interface
|
// we must calculate grad using interface
|
||||||
// DU at the interface has not been calculated yet as interface.correct()
|
// DU at the interface has not been calculated yet as interface.correct()
|
||||||
// has not been called yet
|
// has not been called yet
|
||||||
// not really a problem as gradDU is correct in second outer iteration
|
// not really a problem as gradDU is correct in second outer iteration
|
||||||
// as long as this does not cause convergence problems for the first iterations.
|
// as long as this does not cause convergence problems for the first iterations.
|
||||||
// we should be able to calculate the interface displacements without
|
// we should be able to calculate the interface displacements without
|
||||||
// having to call interface.correct()
|
// having to call interface.correct()
|
||||||
// todo: add calculateInterfaceDU() function
|
// todo: add calculateInterfaceDU() function
|
||||||
// interface grad uses Gauss, we need least squares
|
// interface grad uses Gauss, we need least squares
|
||||||
gradDU = fvc::grad(DU); // leastSquaresSolidInterface grad scheme
|
gradDU = fvc::grad(DU); // leastSquaresSolidInterface grad scheme
|
||||||
//gradDU = solidInterfacePtr->grad(DU);
|
//gradDU = solidInterfacePtr->grad(DU);
|
||||||
//snGradDU = fvc::snGrad(DU);
|
//snGradDU = fvc::snGrad(DU);
|
||||||
|
|
||||||
# include "calculateTraction.H"
|
# include "calculateTraction.H"
|
||||||
//if (nFacesToBreak || nCoupledFacesToBreak) mesh.write(); traction.write();
|
//if (nFacesToBreak || nCoupledFacesToBreak) mesh.write(); traction.write();
|
||||||
|
|
||||||
// Initialise initiation traction for new cohesive patch face
|
// Initialise initiation traction for new cohesive patch face
|
||||||
// we also need to update the traction_ field in the crack boundary condition
|
// we also need to update the traction_ field in the crack boundary condition
|
||||||
// this is because it cannot set itself during mapping.
|
// this is because it cannot set itself during mapping.
|
||||||
//for (label i=0; i<cohesivePatchDU.size(); i++)
|
//for (label i=0; i<cohesivePatchDU.size(); i++)
|
||||||
for (label i=0; i<cohesivePatchSize; i++)
|
for (label i=0; i<cohesivePatchSize; i++)
|
||||||
{
|
{
|
||||||
|
@ -589,51 +594,52 @@ nCoupledFacesToBreak = 0;
|
||||||
/mesh.magSf().boundaryField()[cohesivePatchID][i];
|
/mesh.magSf().boundaryField()[cohesivePatchID][i];
|
||||||
//vector n1 = -n0;
|
//vector n1 = -n0;
|
||||||
|
|
||||||
if ((n0&faceToBreakNormal) > SMALL)
|
if ((n0 & faceToBreakNormal) > SMALL)
|
||||||
{
|
{
|
||||||
traction.boundaryField()[cohesivePatchID][i] =
|
traction.boundaryField()[cohesivePatchID][i] =
|
||||||
faceToBreakTraction;
|
faceToBreakTraction;
|
||||||
|
|
||||||
traction.oldTime().boundaryField()[cohesivePatchID][i] =
|
traction.oldTime().boundaryField()[cohesivePatchID][i] =
|
||||||
faceToBreakTraction;
|
faceToBreakTraction;
|
||||||
|
|
||||||
// this seems to slow convergence in some simple test cases...
|
// this seems to slow convergence in some simple test cases...
|
||||||
// but surely it should be better update it
|
// but surely it should be better update it
|
||||||
//cohesivePatchDU.traction()[i] = faceToBreakTraction;
|
//cohesivePatchDU.traction()[i] = faceToBreakTraction;
|
||||||
if(cohesivePatchDUPtr)
|
if(cohesivePatchDUPtr)
|
||||||
{
|
{
|
||||||
cohesivePatchDUPtr->traction()[i] = faceToBreakTraction;
|
cohesivePatchDUPtr->traction()[i] = faceToBreakTraction;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cohesivePatchDUFixedModePtr->traction()[i] = faceToBreakTraction;
|
cohesivePatchDUFixedModePtr->traction()[i] = faceToBreakTraction;
|
||||||
cohesivePatchDUFixedModePtr->initiationTraction()[i] = faceToBreakTraction;
|
cohesivePatchDUFixedModePtr->initiationTraction()[i] = faceToBreakTraction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
traction.boundaryField()[cohesivePatchID][i] =
|
traction.boundaryField()[cohesivePatchID][i] =
|
||||||
-faceToBreakTraction;
|
-faceToBreakTraction;
|
||||||
|
traction.oldTime().boundaryField()[cohesivePatchID][i] =
|
||||||
|
-faceToBreakTraction;
|
||||||
|
|
||||||
traction.oldTime().boundaryField()[cohesivePatchID][i] =
|
//cohesivePatchDU.traction()[i] = -faceToBreakTraction;
|
||||||
-faceToBreakTraction;
|
if(cohesivePatchDUPtr)
|
||||||
|
{
|
||||||
//cohesivePatchDU.traction()[i] = -faceToBreakTraction;
|
cohesivePatchDUPtr->traction()[i] = -faceToBreakTraction;
|
||||||
if(cohesivePatchDUPtr)
|
}
|
||||||
{
|
else
|
||||||
cohesivePatchDUPtr->traction()[i] = -faceToBreakTraction;
|
{
|
||||||
}
|
cohesivePatchDUFixedModePtr->traction()[i] =
|
||||||
else
|
-faceToBreakTraction;
|
||||||
{
|
cohesivePatchDUFixedModePtr->initiationTraction()[i] =
|
||||||
cohesivePatchDUFixedModePtr->traction()[i] = -faceToBreakTraction;
|
-faceToBreakTraction;
|
||||||
cohesivePatchDUFixedModePtr->initiationTraction()[i] = -faceToBreakTraction;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// hmmnn we only need a reference for very small groups of cells
|
// hmmnn we only need a reference for very small groups of cells
|
||||||
// turn off for now
|
// turn off for now
|
||||||
//# include "updateReference.H"
|
//# include "updateReference.H"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,20 +4,21 @@
|
||||||
|
|
||||||
forAll(U.boundaryField(), patchI)
|
forAll(U.boundaryField(), patchI)
|
||||||
{
|
{
|
||||||
// philipc - this used to set a reference on
|
// philipc - this used to set a reference on
|
||||||
// processors which did not have a patch that fixesValue
|
// processors which did not have a patch that fixesValue
|
||||||
// so processor in the centre of the domain all had
|
// so processor in the centre of the domain all had
|
||||||
// a referece set causing stress peaks and resulting
|
// a referece set causing stress peaks and resulting
|
||||||
// in an incorrect solution
|
// in an incorrect solution
|
||||||
// so a quick fix is to not set a reference on regions
|
// so a quick fix is to not set a reference on regions
|
||||||
// with a processor boundary
|
// with a processor boundary
|
||||||
//if (U.boundaryField()[patchI].fixesValue())
|
//if (U.boundaryField()[patchI].fixesValue())
|
||||||
if (
|
if
|
||||||
U.boundaryField()[patchI].fixesValue()
|
(
|
||||||
||
|
U.boundaryField()[patchI].fixesValue()
|
||||||
mesh.boundaryMesh()[patchI].type()
|
||
|
||||||
== processorPolyPatch::typeName
|
mesh.boundaryMesh()[patchI].type()
|
||||||
)
|
== processorPolyPatch::typeName
|
||||||
|
)
|
||||||
{
|
{
|
||||||
const unallocLabelList& curFaceCells =
|
const unallocLabelList& curFaceCells =
|
||||||
mesh.boundary()[patchI].faceCells();
|
mesh.boundary()[patchI].faceCells();
|
||||||
|
|
|
@ -85,87 +85,90 @@ if (runTime.outputTime() || topoChange)
|
||||||
|
|
||||||
// //- boundary traction
|
// //- boundary traction
|
||||||
// volVectorField tractionBoundary
|
// volVectorField tractionBoundary
|
||||||
// (
|
// (
|
||||||
// IOobject
|
// IOobject
|
||||||
// (
|
// (
|
||||||
// "tractionBoundary",
|
// "tractionBoundary",
|
||||||
// runTime.timeName(),
|
// runTime.timeName(),
|
||||||
// mesh,
|
// mesh,
|
||||||
// IOobject::NO_READ,
|
// IOobject::NO_READ,
|
||||||
// IOobject::AUTO_WRITE
|
// IOobject::AUTO_WRITE
|
||||||
// ),
|
// ),
|
||||||
// mesh,
|
// mesh,
|
||||||
// dimensionedVector("zero", dimForce/dimArea, vector::zero)
|
// dimensionedVector("zero", dimForce/dimArea, vector::zero)
|
||||||
// );
|
// );
|
||||||
// surfaceVectorField n = mesh.Sf()/mesh.magSf();
|
// surfaceVectorField n = mesh.Sf()/mesh.magSf();
|
||||||
// forAll(tractionBoundary.boundaryField(), patchi)
|
// forAll(tractionBoundary.boundaryField(), patchi)
|
||||||
// {
|
// {
|
||||||
// if(mesh.boundaryMesh()[patchi].type() != processorPolyPatch::typeName)
|
// if(mesh.boundaryMesh()[patchi].type() != processorPolyPatch::typeName)
|
||||||
// {
|
// {
|
||||||
// tractionBoundary.boundaryField()[patchi] =
|
// tractionBoundary.boundaryField()[patchi] =
|
||||||
// n.boundaryField()[patchi] & sigma.boundaryField()[patchi];
|
// n.boundaryField()[patchi] & sigma.boundaryField()[patchi];
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
//- cohesive damage and cracking, and GII and GII
|
//- cohesive damage and cracking, and GII and GII
|
||||||
volScalarField damageAndCracks
|
volScalarField damageAndCracks
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"damageAndCracks",
|
"damageAndCracks",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedScalar("zero", dimless, 0.0),
|
dimensionedScalar("zero", dimless, 0.0),
|
||||||
calculatedFvPatchVectorField::typeName
|
calculatedFvPatchVectorField::typeName
|
||||||
);
|
);
|
||||||
volScalarField GI
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
"GI",
|
|
||||||
runTime.timeName(),
|
|
||||||
mesh,
|
|
||||||
IOobject::NO_READ,
|
|
||||||
IOobject::AUTO_WRITE
|
|
||||||
),
|
|
||||||
mesh,
|
|
||||||
dimensionedScalar("zero", dimless, 0.0),
|
|
||||||
calculatedFvPatchVectorField::typeName
|
|
||||||
);
|
|
||||||
volScalarField GII
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
"GII",
|
|
||||||
runTime.timeName(),
|
|
||||||
mesh,
|
|
||||||
IOobject::NO_READ,
|
|
||||||
IOobject::AUTO_WRITE
|
|
||||||
),
|
|
||||||
mesh,
|
|
||||||
dimensionedScalar("zero", dimless, 0.0),
|
|
||||||
calculatedFvPatchVectorField::typeName
|
|
||||||
);
|
|
||||||
forAll(DU.boundaryField(), patchi)
|
|
||||||
{
|
|
||||||
// if(DU.boundaryField()[patchi].type() == cohesiveLawMultiMatFvPatchVectorField::typeName)
|
|
||||||
if(DU.boundaryField()[patchi].type() == solidCohesiveFvPatchVectorField::typeName)
|
|
||||||
{
|
|
||||||
// cohesiveLawMultiMatFvPatchVectorField& DUpatch =
|
|
||||||
// refCast<cohesiveLawMultiMatFvPatchVectorField>(DU.boundaryField()[patchi]);
|
|
||||||
solidCohesiveFvPatchVectorField& DUpatch =
|
|
||||||
refCast<solidCohesiveFvPatchVectorField>(DU.boundaryField()[patchi]);
|
|
||||||
|
|
||||||
GI.boundaryField()[patchi] = DUpatch.GI();
|
volScalarField GI
|
||||||
GII.boundaryField()[patchi] = DUpatch.GII();
|
(
|
||||||
damageAndCracks.boundaryField()[patchi] = DUpatch.crackingAndDamage();
|
IOobject
|
||||||
}
|
(
|
||||||
}
|
"GI",
|
||||||
|
runTime.timeName(),
|
||||||
|
mesh,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
),
|
||||||
|
mesh,
|
||||||
|
dimensionedScalar("zero", dimless, 0.0),
|
||||||
|
calculatedFvPatchVectorField::typeName
|
||||||
|
);
|
||||||
|
|
||||||
|
volScalarField GII
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"GII",
|
||||||
|
runTime.timeName(),
|
||||||
|
mesh,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
),
|
||||||
|
mesh,
|
||||||
|
dimensionedScalar("zero", dimless, 0.0),
|
||||||
|
calculatedFvPatchVectorField::typeName
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(DU.boundaryField(), patchi)
|
||||||
|
{
|
||||||
|
// if(DU.boundaryField()[patchi].type() == cohesiveLawMultiMatFvPatchVectorField::typeName)
|
||||||
|
if(DU.boundaryField()[patchi].type() == solidCohesiveFvPatchVectorField::typeName)
|
||||||
|
{
|
||||||
|
// cohesiveLawMultiMatFvPatchVectorField& DUpatch =
|
||||||
|
// refCast<cohesiveLawMultiMatFvPatchVectorField>(DU.boundaryField()[patchi]);
|
||||||
|
solidCohesiveFvPatchVectorField& DUpatch =
|
||||||
|
refCast<solidCohesiveFvPatchVectorField>(DU.boundaryField()[patchi]);
|
||||||
|
|
||||||
|
GI.boundaryField()[patchi] = DUpatch.GI();
|
||||||
|
GII.boundaryField()[patchi] = DUpatch.GII();
|
||||||
|
damageAndCracks.boundaryField()[patchi] = DUpatch.crackingAndDamage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Info << "done" << endl;
|
//Info << "done" << endl;
|
||||||
|
|
||||||
|
|
|
@ -1,40 +1,41 @@
|
||||||
//- write force displacement to file
|
//- write force displacement to file
|
||||||
if(historyPatchID != -1)
|
if(historyPatchID != -1)
|
||||||
{
|
{
|
||||||
Info << "Found patch "<<historyPatchName<<", writing y force and displacement to file"
|
Info << "Found patch "<<historyPatchName<<", writing y force and displacement to file"
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
//- calculate force in specified direction on topClamp patch
|
//- calculate force in specified direction on topClamp patch
|
||||||
vector direction(0, 1, 0);
|
vector direction(0, 1, 0);
|
||||||
|
|
||||||
//- for small strain or moving mesh
|
//- for small strain or moving mesh
|
||||||
scalar force = gSum(
|
scalar force = gSum
|
||||||
direction &
|
(
|
||||||
(mesh.boundary()[historyPatchID].Sf() & sigma.boundaryField()[historyPatchID])
|
direction &
|
||||||
);
|
(mesh.boundary()[historyPatchID].Sf() & sigma.boundaryField()[historyPatchID])
|
||||||
|
);
|
||||||
|
|
||||||
//- for large strain total lagrangian
|
//- for large strain total lagrangian
|
||||||
// tensorField F = I + gradU.boundaryField()[historyPatchID];
|
// tensorField F = I + gradU.boundaryField()[historyPatchID];
|
||||||
// vectorField totalForce = mesh.Sf().boundaryField()[historyPatchID] & (sigma.boundaryField()[historyPatchID] & F);
|
// vectorField totalForce = mesh.Sf().boundaryField()[historyPatchID] & (sigma.boundaryField()[historyPatchID] & F);
|
||||||
|
|
||||||
//vector force = sum( totalForce );
|
//vector force = sum( totalForce );
|
||||||
|
|
||||||
//scalar force = force[vector::Y];
|
//scalar force = force[vector::Y];
|
||||||
|
|
||||||
//- patchIntegrate utility integrates it this way but this is worng because the sigma tensor should
|
//- patchIntegrate utility integrates it this way but this is worng because the sigma tensor should
|
||||||
//- be dotted with the surface normal to give the actual traction/force
|
//- be dotted with the surface normal to give the actual traction/force
|
||||||
//- you cannot just take the component of the sigma tensor
|
//- you cannot just take the component of the sigma tensor
|
||||||
//scalar forcePatchIntegrateMethod = gSum(
|
//scalar forcePatchIntegrateMethod = gSum(
|
||||||
// mesh.magSf().boundaryField()[historyPatchID]
|
// mesh.magSf().boundaryField()[historyPatchID]
|
||||||
// *sigma.boundaryField()[historyPatchID].component(symmTensor::XY)
|
// *sigma.boundaryField()[historyPatchID].component(symmTensor::XY)
|
||||||
// );
|
// );
|
||||||
|
|
||||||
scalar disp = max(U.boundaryField()[historyPatchID].component(vector::Y));
|
scalar disp = max(U.boundaryField()[historyPatchID].component(vector::Y));
|
||||||
|
|
||||||
//- write to file
|
//- write to file
|
||||||
if(Pstream::master())
|
if(Pstream::master())
|
||||||
{
|
{
|
||||||
OFstream& forceDispFile = *filePtr;
|
OFstream& forceDispFile = *filePtr;
|
||||||
forceDispFile << disp << "\t" << force << endl;
|
forceDispFile << disp << "\t" << force << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,33 +10,34 @@ else if(divDSigmaExpMethod == "surface")
|
||||||
{
|
{
|
||||||
divDSigmaExp = fvc::div
|
divDSigmaExp = fvc::div
|
||||||
(
|
(
|
||||||
muf*(mesh.Sf() & fvc::interpolate(gradDU.T()))
|
muf*(mesh.Sf() & fvc::interpolate(gradDU.T()))
|
||||||
+ lambdaf*(mesh.Sf() & I*fvc::interpolate(tr(gradDU)))
|
+ lambdaf*(mesh.Sf() & I*fvc::interpolate(tr(gradDU)))
|
||||||
- (muf + lambdaf)*(mesh.Sf() & fvc::interpolate(gradDU))
|
- (muf + lambdaf)*(mesh.Sf() & fvc::interpolate(gradDU))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if(divDSigmaExpMethod == "decompose")
|
else if(divDSigmaExpMethod == "decompose")
|
||||||
{
|
{
|
||||||
surfaceTensorField shearGradDU =
|
surfaceTensorField shearGradDU = ((I - n*n) & fvc::interpolate(gradDU));
|
||||||
((I - n*n) & fvc::interpolate(gradDU));
|
|
||||||
|
|
||||||
divDSigmaExp = fvc::div
|
divDSigmaExp = fvc::div
|
||||||
(
|
(
|
||||||
mesh.magSf()*
|
mesh.magSf()*
|
||||||
(
|
(
|
||||||
- (muf + lambdaf)*(fvc::snGrad(DU) & (I - n*n))
|
- (muf + lambdaf)*(fvc::snGrad(DU) & (I - n*n))
|
||||||
+ lambdaf*tr(shearGradDU&(I - n*n))*n
|
+ lambdaf*tr(shearGradDU&(I - n*n))*n
|
||||||
+ muf*(shearGradDU&n)
|
+ muf*(shearGradDU&n)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if(divDSigmaExpMethod == "laplacian")
|
else if(divDSigmaExpMethod == "laplacian")
|
||||||
{
|
{
|
||||||
divDSigmaExp = - fvc::laplacian(mu + lambda, DU, "laplacian(DDU,DU)")
|
divDSigmaExp =
|
||||||
|
- fvc::laplacian(mu + lambda, DU, "laplacian(DDU,DU)")
|
||||||
+ fvc::div(mu*gradDU.T() + lambda*(I*tr(gradDU)), "div(sigma)");
|
+ fvc::div(mu*gradDU.T() + lambda*(I*tr(gradDU)), "div(sigma)");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FatalError << "divDSigmaExp method " << divDSigmaExpMethod
|
FatalErrorIn(args.executable())
|
||||||
<< " not found!" << endl;
|
<< "divDSigmaExp method " << divDSigmaExpMethod << " not found!"
|
||||||
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
while(runTime.loop())
|
while(runTime.loop())
|
||||||
{
|
{
|
||||||
Info<< "Time: " << runTime.timeName() << nl << endl;
|
Info<< "Time = " << runTime.timeName() << nl << endl;
|
||||||
|
|
||||||
# include "readSolidMechanicsControls.H"
|
# include "readSolidMechanicsControls.H"
|
||||||
|
|
||||||
|
|
|
@ -7,18 +7,20 @@ if(leftPatchID == -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
//- calculate force in x direction on leftClamp patch
|
//- calculate force in x direction on leftClamp patch
|
||||||
scalar leftForce = gSum(
|
scalar leftForce = gSum
|
||||||
vector(1, 0, 0) &
|
(
|
||||||
(mesh.boundary()[leftPatchID].Sf() & sigma.boundaryField()[leftPatchID])
|
vector(1, 0, 0) &
|
||||||
);
|
(mesh.boundary()[leftPatchID].Sf() & sigma.boundaryField()[leftPatchID])
|
||||||
|
);
|
||||||
|
|
||||||
//- patchIntegrate utility integrates it this way but this is worng because the sigma tensor should
|
//- patchIntegrate utility integrates it this way but this is worng because the sigma tensor should
|
||||||
//- be dotted with the surface normal to give the actual traction/force
|
//- be dotted with the surface normal to give the actual traction/force
|
||||||
//- you cannot just take the component of the sigma tensor
|
//- you cannot just take the component of the sigma tensor
|
||||||
//scalar leftForcePatchIntegrateMethod = gSum(
|
//scalar leftForcePatchIntegrateMethod = gSum
|
||||||
// mesh.magSf().boundaryField()[leftPatchID]
|
//(
|
||||||
// *sigma.boundaryField()[leftPatchID].component(symmTensor::XY)
|
// mesh.magSf().boundaryField()[leftPatchID]*
|
||||||
// );
|
// sigma.boundaryField()[leftPatchID].component(symmTensor::XY)
|
||||||
|
//);
|
||||||
|
|
||||||
vector gaugeU1 = vector::zero;
|
vector gaugeU1 = vector::zero;
|
||||||
vector gaugeU2 = vector::zero;
|
vector gaugeU2 = vector::zero;
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
IOobject::READ_IF_PRESENT,
|
IOobject::READ_IF_PRESENT,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedVector("zero", dimLength, vector::zero)
|
dimensionedVector("zero", dimLength, vector::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
volTensorField gradU
|
volTensorField gradU
|
||||||
|
@ -38,8 +38,8 @@
|
||||||
IOobject::READ_IF_PRESENT,
|
IOobject::READ_IF_PRESENT,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedTensor("zero", dimless, tensor::zero)
|
dimensionedTensor("zero", dimless, tensor::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
//- increment of Green finite strain tensor
|
//- increment of Green finite strain tensor
|
||||||
|
@ -53,8 +53,8 @@
|
||||||
IOobject::READ_IF_PRESENT,
|
IOobject::READ_IF_PRESENT,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedSymmTensor("zero", dimless, symmTensor::zero)
|
dimensionedSymmTensor("zero", dimless, symmTensor::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Green strain tensor
|
//- Green strain tensor
|
||||||
|
@ -68,8 +68,8 @@
|
||||||
IOobject::READ_IF_PRESENT,
|
IOobject::READ_IF_PRESENT,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedSymmTensor("zero", dimless, symmTensor::zero)
|
dimensionedSymmTensor("zero", dimless, symmTensor::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,8 +99,8 @@
|
||||||
IOobject::READ_IF_PRESENT,
|
IOobject::READ_IF_PRESENT,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedSymmTensor("zero", dimForce/dimArea, symmTensor::zero)
|
dimensionedSymmTensor("zero", dimForce/dimArea, symmTensor::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
constitutiveModel rheology(sigma, DU);
|
constitutiveModel rheology(sigma, DU);
|
||||||
|
|
|
@ -43,105 +43,108 @@ Author
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
# include "setRootCase.H"
|
# include "setRootCase.H"
|
||||||
# include "createTime.H"
|
# include "createTime.H"
|
||||||
# include "createMesh.H"
|
# include "createMesh.H"
|
||||||
# include "createFields.H"
|
# include "createFields.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Info<< "\nStarting time loop\n" << endl;
|
Info<< "\nStarting time loop\n" << endl;
|
||||||
|
|
||||||
while(runTime.loop())
|
while(runTime.loop())
|
||||||
{
|
{
|
||||||
Info<< "Time: " << runTime.timeName() << nl << endl;
|
Info<< "Time = " << runTime.timeName() << nl << endl;
|
||||||
|
|
||||||
# include "readSolidMechanicsControls.H"
|
# include "readSolidMechanicsControls.H"
|
||||||
|
|
||||||
int iCorr = 0;
|
int iCorr = 0;
|
||||||
scalar initialResidual = 0;
|
scalar initialResidual = 0;
|
||||||
lduMatrix::solverPerformance solverPerf;
|
lduMatrix::solverPerformance solverPerf;
|
||||||
scalar relativeResidual = 1.0;
|
scalar relativeResidual = 1.0;
|
||||||
lduMatrix::debug=0;
|
lduMatrix::debug=0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
DU.storePrevIter();
|
DU.storePrevIter();
|
||||||
|
|
||||||
fvVectorMatrix DUEqn
|
fvVectorMatrix DUEqn
|
||||||
(
|
(
|
||||||
fvm::d2dt2(rho, DU)
|
fvm::d2dt2(rho, DU)
|
||||||
==
|
==
|
||||||
fvm::laplacian(2*mu + lambda, DU, "laplacian(DDU,DU)")
|
fvm::laplacian(2*mu + lambda, DU, "laplacian(DDU,DU)")
|
||||||
+ fvc::div(
|
+ fvc::div
|
||||||
-( (mu + lambda) * gradDU )
|
(
|
||||||
+ ( mu * (
|
- ( (mu + lambda) * gradDU )
|
||||||
gradDU.T()
|
+ (
|
||||||
+ (gradDU & gradU.T())
|
mu *
|
||||||
+ (gradU & gradDU.T())
|
(
|
||||||
+ (gradDU & gradDU.T())
|
gradDU.T()
|
||||||
) )
|
+ (gradDU & gradU.T())
|
||||||
+ ( lambda * tr(DEpsilon) * I )
|
+ (gradU & gradDU.T())
|
||||||
+ ( DSigma & gradU )
|
+ (gradDU & gradDU.T())
|
||||||
+ ( (sigma + DSigma) & gradDU ),
|
)
|
||||||
"div(sigma)"
|
)
|
||||||
)
|
+ ( lambda * tr(DEpsilon) * I )
|
||||||
);
|
+ ( DSigma & gradU )
|
||||||
|
+ ( (sigma + DSigma) & gradDU ),
|
||||||
|
"div(sigma)"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
solverPerf = DUEqn.solve();
|
solverPerf = DUEqn.solve();
|
||||||
|
|
||||||
if (iCorr == 0)
|
if (iCorr == 0)
|
||||||
{
|
{
|
||||||
initialResidual = solverPerf.initialResidual();
|
initialResidual = solverPerf.initialResidual();
|
||||||
|
}
|
||||||
|
|
||||||
|
DU.relax();
|
||||||
|
|
||||||
|
gradDU = fvc::grad(DU);
|
||||||
|
|
||||||
|
# include "calculateDEpsilonDSigma.H"
|
||||||
|
# include "calculateRelativeResidual.H"
|
||||||
|
|
||||||
|
Info<< "\tTime " << runTime.value()
|
||||||
|
<< ", Corrector " << iCorr
|
||||||
|
<< ", Solving for " << DU.name()
|
||||||
|
<< " using " << solverPerf.solverName()
|
||||||
|
<< ", residual = " << solverPerf.initialResidual()
|
||||||
|
<< ", relative residual = " << relativeResidual
|
||||||
|
<< ", inner iterations = " << solverPerf.nIterations() << endl;
|
||||||
}
|
}
|
||||||
|
while
|
||||||
|
(
|
||||||
|
solverPerf.initialResidual() > convergenceTolerance
|
||||||
|
//relativeResidual > convergenceTolerance
|
||||||
|
&& ++iCorr < nCorr
|
||||||
|
);
|
||||||
|
|
||||||
DU.relax();
|
Info<< nl << "Time " << runTime.value() << ", Solving for " << DU.name()
|
||||||
|
<< ", Initial residual = " << initialResidual
|
||||||
|
<< ", Final residual = " << solverPerf.initialResidual()
|
||||||
|
<< ", Relative residual = " << relativeResidual
|
||||||
|
<< ", No outer iterations " << iCorr
|
||||||
|
<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||||
|
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||||
|
<< endl;
|
||||||
|
|
||||||
gradDU = fvc::grad(DU);
|
U += DU;
|
||||||
|
gradU += gradDU;
|
||||||
|
epsilon += DEpsilon;
|
||||||
|
sigma += DSigma;
|
||||||
|
|
||||||
# include "calculateDEpsilonDSigma.H"
|
# include "writeFields.H"
|
||||||
# include "calculateRelativeResidual.H"
|
|
||||||
|
|
||||||
Info << "\tTime " << runTime.value()
|
Info<< "ExecutionTime = "
|
||||||
<< ", Corrector " << iCorr
|
<< runTime.elapsedCpuTime()
|
||||||
<< ", Solving for " << DU.name()
|
<< " s\n\n" << endl;
|
||||||
<< " using " << solverPerf.solverName()
|
|
||||||
<< ", residual = " << solverPerf.initialResidual()
|
|
||||||
<< ", relative residual = " << relativeResidual
|
|
||||||
<< ", inner iterations = " << solverPerf.nIterations() << endl;
|
|
||||||
}
|
|
||||||
while
|
|
||||||
(
|
|
||||||
solverPerf.initialResidual() > convergenceTolerance
|
|
||||||
//relativeResidual > convergenceTolerance
|
|
||||||
&&
|
|
||||||
++iCorr < nCorr
|
|
||||||
);
|
|
||||||
|
|
||||||
Info << nl << "Time " << runTime.value() << ", Solving for " << DU.name()
|
|
||||||
<< ", Initial residual = " << initialResidual
|
|
||||||
<< ", Final residual = " << solverPerf.initialResidual()
|
|
||||||
<< ", Relative residual = " << relativeResidual
|
|
||||||
<< ", No outer iterations " << iCorr
|
|
||||||
<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
|
||||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
|
||||||
<< endl;
|
|
||||||
|
|
||||||
U += DU;
|
|
||||||
gradU += gradDU;
|
|
||||||
epsilon += DEpsilon;
|
|
||||||
sigma += DSigma;
|
|
||||||
|
|
||||||
# include "writeFields.H"
|
|
||||||
|
|
||||||
Info<< "ExecutionTime = "
|
|
||||||
<< runTime.elapsedCpuTime()
|
|
||||||
<< " s\n\n" << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "End\n" << endl;
|
Info<< "End\n" << endl;
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,36 +1,36 @@
|
||||||
if (runTime.outputTime())
|
if (runTime.outputTime())
|
||||||
{
|
{
|
||||||
volScalarField epsilonEq
|
volScalarField epsilonEq
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"epsilonEq",
|
"epsilonEq",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
sqrt((2.0/3.0)*magSqr(dev(epsilon)))
|
sqrt((2.0/3.0)*magSqr(dev(epsilon)))
|
||||||
);
|
);
|
||||||
|
|
||||||
Info<< "Max epsilonEq = " << max(epsilonEq).value()
|
Info<< "Max epsilonEq = " << max(epsilonEq).value()
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
volScalarField sigmaEq
|
volScalarField sigmaEq
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"sigmaEq",
|
"sigmaEq",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
sqrt((3.0/2.0)*magSqr(dev(sigma)))
|
sqrt((3.0/2.0)*magSqr(dev(sigma)))
|
||||||
);
|
);
|
||||||
|
|
||||||
Info<< "Max sigmaEq = " << max(sigmaEq).value()
|
Info<< "Max sigmaEq = " << max(sigmaEq).value()
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
//- Calculate Cauchy stress
|
//- Calculate Cauchy stress
|
||||||
volTensorField F = I + gradU;
|
volTensorField F = I + gradU;
|
||||||
|
@ -40,70 +40,70 @@ if (runTime.outputTime())
|
||||||
rho = rho/J;
|
rho = rho/J;
|
||||||
|
|
||||||
volSymmTensorField sigmaCauchy
|
volSymmTensorField sigmaCauchy
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"sigmaCauchy",
|
"sigmaCauchy",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
(1/J) * symm(F.T() & sigma & F)
|
(1/J) * symm(F.T() & sigma & F)
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Cauchy von Mises stress
|
//- Cauchy von Mises stress
|
||||||
volScalarField sigmaCauchyEq
|
volScalarField sigmaCauchyEq
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"sigmaCauchyEq",
|
"sigmaCauchyEq",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
sqrt((3.0/2.0)*magSqr(dev(sigmaCauchy)))
|
sqrt((3.0/2.0)*magSqr(dev(sigmaCauchy)))
|
||||||
);
|
);
|
||||||
|
|
||||||
Info<< "Max sigmaCauchyEq = " << max(sigmaCauchyEq).value()
|
Info<< "Max sigmaCauchyEq = " << max(sigmaCauchyEq).value()
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
volTensorField Finv = inv(F);
|
volTensorField Finv = inv(F);
|
||||||
volSymmTensorField epsilonAlmansi
|
volSymmTensorField epsilonAlmansi
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"epsilonAlmansi",
|
"epsilonAlmansi",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
symm(Finv & epsilon & Finv.T())
|
symm(Finv & epsilon & Finv.T())
|
||||||
);
|
);
|
||||||
|
|
||||||
//- boundary traction
|
//- boundary traction
|
||||||
volVectorField traction
|
volVectorField traction
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"tractionCauchy",
|
"tractionCauchy",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedVector("zero", dimForce/dimArea, vector::zero)
|
dimensionedVector("zero", dimForce/dimArea, vector::zero)
|
||||||
);
|
);
|
||||||
forAll(traction.boundaryField(), patchi)
|
forAll(traction.boundaryField(), patchi)
|
||||||
{
|
{
|
||||||
tensorField Fpatch = I + gradU.boundaryField()[patchi];
|
tensorField Fpatch = I + gradU.boundaryField()[patchi];
|
||||||
|
|
||||||
traction.boundaryField()[patchi] =
|
traction.boundaryField()[patchi] =
|
||||||
n.boundaryField()[patchi] & (sigma.boundaryField()[patchi] & Fpatch);
|
n.boundaryField()[patchi] & (sigma.boundaryField()[patchi] & Fpatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
runTime.write();
|
runTime.write();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +1,33 @@
|
||||||
{
|
{
|
||||||
forAll(mesh.boundary(), patchID)
|
forAll(mesh.boundary(), patchID)
|
||||||
{
|
{
|
||||||
if(U.boundaryField()[patchID].type()
|
if(U.boundaryField()[patchID].type()
|
||||||
== solidDirectionMixedFvPatchVectorField::typeName
|
== solidDirectionMixedFvPatchVectorField::typeName
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
solidDirectionMixedFvPatchVectorField& loadingPatch =
|
solidDirectionMixedFvPatchVectorField& loadingPatch =
|
||||||
refCast<solidDirectionMixedFvPatchVectorField>
|
refCast<solidDirectionMixedFvPatchVectorField>
|
||||||
(
|
(
|
||||||
U.boundaryField()[patchID]
|
U.boundaryField()[patchID]
|
||||||
);
|
);
|
||||||
|
|
||||||
tensorField Finv = inv(I + gradU);
|
tensorField Finv = inv(I + gradU);
|
||||||
vectorField newN = Finv & n.boundaryField()[patchID];
|
vectorField newN = Finv & n.boundaryField()[patchID];
|
||||||
newN /= mag(newN);
|
newN /= mag(newN);
|
||||||
loadingPatch.valueFraction() = sqr(newN);
|
loadingPatch.valueFraction() = sqr(newN);
|
||||||
|
|
||||||
//- set gradient
|
//- set gradient
|
||||||
loadingPatch.refGrad() =
|
loadingPatch.refGrad() =
|
||||||
(
|
(
|
||||||
//Traction
|
//Traction
|
||||||
( (mu.boundaryField()[patchID] + lambda.boundaryField()[patchID]) * (n.boundaryField()[patchID] & gradU.boundaryField()[patchID]) )
|
( (mu.boundaryField()[patchID] + lambda.boundaryField()[patchID]) * (n.boundaryField()[patchID] & gradU.boundaryField()[patchID]) )
|
||||||
- ( mu.boundaryField()[patchID] * (n.boundaryField()[patchID] & gradU.boundaryField()[patchID].T()) )
|
- ( mu.boundaryField()[patchID] * (n.boundaryField()[patchID] & gradU.boundaryField()[patchID].T()) )
|
||||||
- ( mu.boundaryField()[patchID] * ( n.boundaryField()[patchID] & (gradU.boundaryField()[patchID] & gradU.boundaryField()[patchID].T()) ) )
|
- ( mu.boundaryField()[patchID] * ( n.boundaryField()[patchID] & (gradU.boundaryField()[patchID] & gradU.boundaryField()[patchID].T()) ) )
|
||||||
- ( lambda.boundaryField()[patchID] * tr(gradU.boundaryField()[patchID]) * n.boundaryField()[patchID] )
|
- ( lambda.boundaryField()[patchID] * tr(gradU.boundaryField()[patchID]) * n.boundaryField()[patchID] )
|
||||||
- ( 0.5 * lambda.boundaryField()[patchID] * tr(gradU.boundaryField()[patchID] & gradU.boundaryField()[patchID].T()) * n.boundaryField()[patchID] )
|
- ( 0.5 * lambda.boundaryField()[patchID] * tr(gradU.boundaryField()[patchID] & gradU.boundaryField()[patchID].T()) * n.boundaryField()[patchID] )
|
||||||
)
|
)
|
||||||
/
|
/
|
||||||
(2.0*mu.boundaryField()[patchID] + lambda.boundaryField()[patchID]);
|
(2.0*mu.boundaryField()[patchID] + lambda.boundaryField()[patchID]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,19 +3,19 @@ bool solidInterfaceCorr = rheology.solidInterfaceActive();
|
||||||
solidInterface* solidInterfacePtr(NULL);
|
solidInterface* solidInterfacePtr(NULL);
|
||||||
|
|
||||||
if(solidInterfaceCorr)
|
if(solidInterfaceCorr)
|
||||||
{
|
{
|
||||||
solidInterfacePtr = &rheology.solInterface();
|
solidInterfacePtr = &rheology.solInterface();
|
||||||
solidInterfacePtr->modifyProperties(muf, lambdaf);
|
solidInterfacePtr->modifyProperties(muf, lambdaf);
|
||||||
|
|
||||||
//- solidInterface needs muf and lambdaf to be used for divDSigmaExp
|
//- solidInterface needs muf and lambdaf to be used for divDSigmaExp
|
||||||
// if(divDSigmaExpMethod != "surface" && divDSigmaExpMethod != "decompose")
|
// if(divDSigmaExpMethod != "surface" && divDSigmaExpMethod != "decompose")
|
||||||
// {
|
// {
|
||||||
// FatalError << "divDSigmaExp must be decompose or surface when solidInterface is on"
|
// FatalError << "divDSigmaExp must be decompose or surface when solidInterface is on"
|
||||||
// << exit(FatalError);
|
// << exit(FatalError);
|
||||||
// }
|
// }
|
||||||
// if(divDSigmaLargeStrainExpMethod != "surface")
|
// if(divDSigmaLargeStrainExpMethod != "surface")
|
||||||
// {
|
// {
|
||||||
// FatalError << "divDSigmaLargeStrainExp must be surface when solidInterface is on"
|
// FatalError << "divDSigmaLargeStrainExp must be surface when solidInterface is on"
|
||||||
// << exit(FatalError);
|
// << exit(FatalError);
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,105 +56,104 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
while(runTime.loop())
|
while(runTime.loop())
|
||||||
{
|
{
|
||||||
Info<< "Time: " << runTime.timeName() << nl << endl;
|
Info<< "Time = " << runTime.timeName() << nl << endl;
|
||||||
|
|
||||||
# include "readSolidMechanicsControls.H"
|
# include "readSolidMechanicsControls.H"
|
||||||
|
|
||||||
int iCorr = 0;
|
int iCorr = 0;
|
||||||
scalar initialResidual = 0;
|
scalar initialResidual = 0;
|
||||||
lduMatrix::solverPerformance solverPerf;
|
lduMatrix::solverPerformance solverPerf;
|
||||||
scalar relativeResidual = 1.0;
|
scalar relativeResidual = 1.0;
|
||||||
lduMatrix::debug = 0;
|
lduMatrix::debug = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
U.storePrevIter();
|
U.storePrevIter();
|
||||||
|
|
||||||
surfaceTensorField shearGradU
|
surfaceTensorField shearGradU
|
||||||
(
|
(
|
||||||
"shearGradU",
|
"shearGradU",
|
||||||
(I - sqr(n)) & fvc::interpolate(gradU)
|
(I - sqr(n)) & fvc::interpolate(gradU)
|
||||||
);
|
);
|
||||||
|
|
||||||
fvVectorMatrix UEqn
|
fvVectorMatrix UEqn
|
||||||
(
|
(
|
||||||
fvm::d2dt2(rho, U)
|
fvm::d2dt2(rho, U)
|
||||||
==
|
==
|
||||||
fvm::laplacian(2*muf + lambdaf, U, "laplacian(DU,U)")
|
fvm::laplacian(2*muf + lambdaf, U, "laplacian(DU,U)")
|
||||||
// + fvc::div
|
// + fvc::div
|
||||||
// (
|
// (
|
||||||
// -(mu + lambda)*gradU
|
// -(mu + lambda)*gradU
|
||||||
// + mu*gradU.T()
|
// + mu*gradU.T()
|
||||||
// + mu*(gradU & gradU.T())
|
// + mu*(gradU & gradU.T())
|
||||||
// + lambda*tr(gradU)*I
|
// + lambda*tr(gradU)*I
|
||||||
// + 0.5*lambda*tr(gradU & gradU.T())*I
|
// + 0.5*lambda*tr(gradU & gradU.T())*I
|
||||||
// + (sigma & gradU),
|
// + (sigma & gradU),
|
||||||
// "div(sigma)"
|
// "div(sigma)"
|
||||||
// )
|
// )
|
||||||
+ fvc::div
|
+ fvc::div
|
||||||
(
|
(
|
||||||
mesh.magSf()*
|
mesh.magSf()*
|
||||||
(
|
(
|
||||||
- (muf + lambdaf)*(fvc::snGrad(U) & (I - n*n))
|
- (muf + lambdaf)*(fvc::snGrad(U) & (I - n*n))
|
||||||
+ lambdaf*tr(shearGradU & (I - n*n))*n
|
+ lambdaf*tr(shearGradU & (I - n*n))*n
|
||||||
+ muf*(shearGradU & n)
|
+ muf*(shearGradU & n)
|
||||||
+ muf*(n & fvc::interpolate(gradU & gradU.T()))
|
+ muf*(n & fvc::interpolate(gradU & gradU.T()))
|
||||||
+ 0.5*lambdaf*(n*tr(fvc::interpolate(gradU & gradU.T())))
|
+ 0.5*lambdaf*(n*tr(fvc::interpolate(gradU & gradU.T())))
|
||||||
+ (n & fvc::interpolate(sigma & gradU))
|
+ (n & fvc::interpolate(sigma & gradU))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (solidInterfaceCorr)
|
if (solidInterfaceCorr)
|
||||||
{
|
{
|
||||||
solidInterfacePtr->correct(UEqn);
|
solidInterfacePtr->correct(UEqn);
|
||||||
}
|
}
|
||||||
|
|
||||||
solverPerf = UEqn.solve();
|
solverPerf = UEqn.solve();
|
||||||
|
|
||||||
if (iCorr == 0)
|
if (iCorr == 0)
|
||||||
{
|
{
|
||||||
initialResidual = solverPerf.initialResidual();
|
initialResidual = solverPerf.initialResidual();
|
||||||
}
|
}
|
||||||
|
|
||||||
U.relax();
|
U.relax();
|
||||||
|
|
||||||
//gradU = solidInterfacePtr->grad(U);
|
//gradU = solidInterfacePtr->grad(U);
|
||||||
gradU = fvc::grad(U);
|
gradU = fvc::grad(U);
|
||||||
|
|
||||||
# include "calculateEpsilonSigma.H"
|
# include "calculateEpsilonSigma.H"
|
||||||
# include "calculateRelativeResidual.H"
|
# include "calculateRelativeResidual.H"
|
||||||
|
|
||||||
Info<< "\tTime " << runTime.value()
|
Info<< "\tTime " << runTime.value()
|
||||||
<< ", Corrector " << iCorr
|
<< ", Corrector " << iCorr
|
||||||
<< ", Solving for " << U.name()
|
<< ", Solving for " << U.name()
|
||||||
<< " using " << solverPerf.solverName()
|
<< " using " << solverPerf.solverName()
|
||||||
<< ", residual = " << solverPerf.initialResidual()
|
<< ", residual = " << solverPerf.initialResidual()
|
||||||
<< ", relative residual = " << relativeResidual
|
<< ", relative residual = " << relativeResidual
|
||||||
<< ", inner iterations " << solverPerf.nIterations() << endl;
|
<< ", inner iterations " << solverPerf.nIterations() << endl;
|
||||||
}
|
}
|
||||||
while
|
while
|
||||||
(
|
(
|
||||||
solverPerf.initialResidual() > convergenceTolerance
|
solverPerf.initialResidual() > convergenceTolerance
|
||||||
//relativeResidual > convergenceTolerance
|
//relativeResidual > convergenceTolerance
|
||||||
&&
|
&& ++iCorr < nCorr
|
||||||
++iCorr < nCorr
|
);
|
||||||
);
|
|
||||||
|
|
||||||
Info<< nl << "Time " << runTime.value() << ", Solving for " << U.name()
|
Info<< nl << "Time " << runTime.value() << ", Solving for " << U.name()
|
||||||
<< ", Initial residual = " << initialResidual
|
<< ", Initial residual = " << initialResidual
|
||||||
<< ", Final residual = " << solverPerf.initialResidual()
|
<< ", Final residual = " << solverPerf.initialResidual()
|
||||||
<< ", Relative residual = " << relativeResidual
|
<< ", Relative residual = " << relativeResidual
|
||||||
<< ", No outer iterations " << iCorr
|
<< ", No outer iterations " << iCorr
|
||||||
<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
# include "writeFields.H"
|
# include "writeFields.H"
|
||||||
|
|
||||||
Info<< "ExecutionTime = "
|
Info<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||||
<< runTime.elapsedCpuTime()
|
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||||
<< " s\n\n" << endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "End\n" << endl;
|
Info<< "End\n" << endl;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//- move mesh
|
//- move mesh
|
||||||
//--------------------------------------------------//
|
//--------------------------------------------------//
|
||||||
if(min(J.internalField()) > 0)
|
if(min(J.internalField()) > 0)
|
||||||
{
|
{
|
||||||
Info << "Moving mesh using least squares interpolation" << endl;
|
Info << "Moving mesh using least squares interpolation" << endl;
|
||||||
|
|
||||||
leastSquaresVolPointInterpolation pointInterpolation(mesh);
|
leastSquaresVolPointInterpolation pointInterpolation(mesh);
|
||||||
|
@ -11,46 +11,45 @@ if(min(J.internalField()) > 0)
|
||||||
pointMesh pMesh(mesh);
|
pointMesh pMesh(mesh);
|
||||||
|
|
||||||
wordList types
|
wordList types
|
||||||
(
|
(
|
||||||
pMesh.boundary().size(),
|
pMesh.boundary().size(),
|
||||||
calculatedFvPatchVectorField::typeName
|
calculatedFvPatchVectorField::typeName
|
||||||
);
|
);
|
||||||
|
|
||||||
pointVectorField pointU
|
pointVectorField pointU
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"pointU",
|
"pointU",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh
|
mesh
|
||||||
),
|
),
|
||||||
pMesh,
|
pMesh,
|
||||||
dimensionedVector("zero", dimLength, vector::zero),
|
dimensionedVector("zero", dimLength, vector::zero),
|
||||||
types
|
types
|
||||||
);
|
);
|
||||||
|
|
||||||
pointInterpolation.interpolate(U, pointU);
|
pointInterpolation.interpolate(U, pointU);
|
||||||
|
|
||||||
const vectorField& pointUI =
|
const vectorField& pointUI = pointU.internalField();
|
||||||
pointU.internalField();
|
|
||||||
|
|
||||||
//- Move mesh
|
//- Move mesh
|
||||||
vectorField newPoints = mesh.allPoints();
|
vectorField newPoints = mesh.allPoints();
|
||||||
|
|
||||||
forAll (pointUI, pointI)
|
forAll (pointUI, pointI)
|
||||||
{
|
{
|
||||||
newPoints[pointI] += pointUI[pointI];
|
newPoints[pointI] += pointUI[pointI];
|
||||||
}
|
}
|
||||||
|
|
||||||
twoDPointCorrector twoDCorrector(mesh);
|
twoDPointCorrector twoDCorrector(mesh);
|
||||||
twoDCorrector.correctPoints(newPoints);
|
twoDCorrector.correctPoints(newPoints);
|
||||||
mesh.movePoints(newPoints);
|
mesh.movePoints(newPoints);
|
||||||
mesh.V00();
|
mesh.V00();
|
||||||
mesh.moving(false);
|
mesh.moving(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FatalErrorIn(args.executable())
|
FatalErrorIn(args.executable())
|
||||||
<< "Negative Jacobian"
|
<< "Negative Jacobian"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +1,36 @@
|
||||||
if (runTime.outputTime())
|
if (runTime.outputTime())
|
||||||
{
|
{
|
||||||
volScalarField epsilonEq
|
volScalarField epsilonEq
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"epsilonEq",
|
"epsilonEq",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
sqrt((2.0/3.0)*magSqr(dev(epsilon)))
|
sqrt((2.0/3.0)*magSqr(dev(epsilon)))
|
||||||
);
|
);
|
||||||
|
|
||||||
Info<< "Max epsilonEq = " << max(epsilonEq).value()
|
Info<< "Max epsilonEq = " << max(epsilonEq).value()
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
volScalarField sigmaEq
|
volScalarField sigmaEq
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"sigmaEq",
|
"sigmaEq",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
sqrt((3.0/2.0)*magSqr(dev(sigma)))
|
sqrt((3.0/2.0)*magSqr(dev(sigma)))
|
||||||
);
|
);
|
||||||
|
|
||||||
Info<< "Max sigmaEq = " << max(sigmaEq).value()
|
Info<< "Max sigmaEq = " << max(sigmaEq).value()
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
//- Calculate Cauchy stress
|
//- Calculate Cauchy stress
|
||||||
volTensorField F = I + gradU;
|
volTensorField F = I + gradU;
|
||||||
|
@ -40,49 +40,49 @@ if (runTime.outputTime())
|
||||||
rho = rho/J;
|
rho = rho/J;
|
||||||
|
|
||||||
volSymmTensorField sigmaCauchy
|
volSymmTensorField sigmaCauchy
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"sigmaCauchy",
|
"sigmaCauchy",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
(1/J) * symm(F.T() & sigma & F)
|
(1/J) * symm(F.T() & sigma & F)
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Cauchy von Mises stress
|
//- Cauchy von Mises stress
|
||||||
volScalarField sigmaCauchyEq
|
volScalarField sigmaCauchyEq
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"sigmaCauchyEq",
|
"sigmaCauchyEq",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
sqrt((3.0/2.0)*magSqr(dev(sigmaCauchy)))
|
sqrt((3.0/2.0)*magSqr(dev(sigmaCauchy)))
|
||||||
);
|
);
|
||||||
|
|
||||||
Info<< "Max sigmaCauchyEq = " << max(sigmaCauchyEq).value()
|
Info<< "Max sigmaCauchyEq = " << max(sigmaCauchyEq).value()
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
|
|
||||||
volTensorField Finv = inv(F);
|
volTensorField Finv = inv(F);
|
||||||
volSymmTensorField epsilonAlmansi
|
volSymmTensorField epsilonAlmansi
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"epsilonAlmansi",
|
"epsilonAlmansi",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
symm(Finv & epsilon & Finv.T())
|
symm(Finv & epsilon & Finv.T())
|
||||||
);
|
);
|
||||||
|
|
||||||
// volVectorField traction
|
// volVectorField traction
|
||||||
// (
|
// (
|
||||||
|
@ -163,4 +163,4 @@ if (runTime.outputTime())
|
||||||
// }
|
// }
|
||||||
|
|
||||||
runTime.write();
|
runTime.write();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,47 +1,43 @@
|
||||||
if(divDSigmaExpMethod == "standard")
|
if(divDSigmaExpMethod == "standard")
|
||||||
{
|
{
|
||||||
divDSigmaExp = fvc::div
|
divDSigmaExp = fvc::div
|
||||||
(
|
(
|
||||||
mu*gradDU.T() + lambda*(I*tr(gradDU)) - (mu + lambda)*gradDU,
|
mu*gradDU.T() + lambda*(I*tr(gradDU)) - (mu + lambda)*gradDU,
|
||||||
"div(sigma)"
|
"div(sigma)"
|
||||||
);
|
|
||||||
}
|
|
||||||
else if(divDSigmaExpMethod == "surface")
|
|
||||||
{
|
|
||||||
divDSigmaExp = fvc::div
|
|
||||||
(
|
|
||||||
muf*(mesh.Sf() & fvc::interpolate(gradDU.T()))
|
|
||||||
+ lambdaf*(mesh.Sf() & I*fvc::interpolate(tr(gradDU)))
|
|
||||||
- (muf + lambdaf)*(mesh.Sf() & fvc::interpolate(gradDU))
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if(divDSigmaExpMethod == "decompose")
|
else if(divDSigmaExpMethod == "surface")
|
||||||
{
|
{
|
||||||
surfaceTensorField shearGradDU =
|
divDSigmaExp = fvc::div
|
||||||
((I - n*n)&fvc::interpolate(gradDU));
|
(
|
||||||
|
muf*(mesh.Sf() & fvc::interpolate(gradDU.T()))
|
||||||
|
+ lambdaf*(mesh.Sf() & I*fvc::interpolate(tr(gradDU)))
|
||||||
|
- (muf + lambdaf)*(mesh.Sf() & fvc::interpolate(gradDU))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if(divDSigmaExpMethod == "decompose")
|
||||||
|
{
|
||||||
|
surfaceTensorField shearGradDU = ((I - n*n) & fvc::interpolate(gradDU));
|
||||||
|
|
||||||
divDSigmaExp = fvc::div
|
divDSigmaExp = fvc::div
|
||||||
(
|
(
|
||||||
mesh.magSf()
|
mesh.magSf()*
|
||||||
*(
|
(
|
||||||
- (muf + lambdaf)*(fvc::snGrad(DU)&(I - n*n))
|
- (muf + lambdaf)*(fvc::snGrad(DU) & (I - n*n))
|
||||||
+ lambdaf*tr(shearGradDU&(I - n*n))*n
|
+ lambdaf*tr(shearGradDU & (I - n*n))*n
|
||||||
+ muf*(shearGradDU&n)
|
+ muf*(shearGradDU & n)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if(divDSigmaExpMethod == "laplacian")
|
else if(divDSigmaExpMethod == "laplacian")
|
||||||
{
|
{
|
||||||
divDSigmaExp =
|
divDSigmaExp =
|
||||||
- fvc::laplacian(mu + lambda, DU, "laplacian(DDU,DU)")
|
- fvc::laplacian(mu + lambda, DU, "laplacian(DDU,DU)")
|
||||||
+ fvc::div
|
+ fvc::div(mu*gradDU.T() + lambda*(I*tr(gradDU)), "div(sigma)");
|
||||||
(
|
}
|
||||||
mu*gradDU.T()
|
else
|
||||||
+ lambda*(I*tr(gradDU)),
|
{
|
||||||
"div(sigma)"
|
FatalErrorIn(args.executable())
|
||||||
);
|
<< "divDSigmaExp method " << divDSigmaExpMethod << " not found!"
|
||||||
}
|
<< abort(FatalError);
|
||||||
else
|
}
|
||||||
{
|
|
||||||
FatalError << "divDSigmaExp method " << divDSigmaExpMethod << " not found!" << endl;
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,30 +2,28 @@
|
||||||
//- sigma explicit non linear explicit terms
|
//- sigma explicit non linear explicit terms
|
||||||
//----------------------------------------------------//
|
//----------------------------------------------------//
|
||||||
if(divDSigmaLargeStrainExpMethod == "standard")
|
if(divDSigmaLargeStrainExpMethod == "standard")
|
||||||
{
|
{
|
||||||
divDSigmaLargeStrainExp =
|
divDSigmaLargeStrainExp = fvc::div
|
||||||
fvc::div
|
(
|
||||||
(
|
mu*(gradDU & gradDU.T())
|
||||||
mu*(gradDU & gradDU.T())
|
//+ 0.5*lambda*(gradDU && gradDU)*I //- equivalent to 0.5*lambda*(I*tr(gradDU & gradDU.T()))
|
||||||
//+ 0.5*lambda*(gradDU && gradDU)*I //- equivalent to 0.5*lambda*(I*tr(gradDU & gradDU.T()))
|
+ 0.5*lambda*tr(gradDU & gradDU.T())*I
|
||||||
+ 0.5*lambda*tr(gradDU & gradDU.T())*I
|
+ ((sigma + DSigma) & gradDU),
|
||||||
+ ((sigma + DSigma) & gradDU),
|
"div(sigma)"
|
||||||
"div(sigma)"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if(divDSigmaLargeStrainExpMethod == "surface")
|
|
||||||
{
|
|
||||||
divDSigmaLargeStrainExp =
|
|
||||||
fvc::div
|
|
||||||
(
|
|
||||||
muf * (mesh.Sf() & fvc::interpolate(gradDU & gradDU.T()))
|
|
||||||
+ 0.5*lambdaf * (mesh.Sf() & (fvc::interpolate(gradDU && gradDU)*I))
|
|
||||||
+ (mesh.Sf() & fvc::interpolate( (sigma + DSigma) & gradDU ))
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else if(divDSigmaLargeStrainExpMethod == "surface")
|
||||||
{
|
{
|
||||||
FatalError
|
divDSigmaLargeStrainExp = fvc::div
|
||||||
<< "divDSigmaLargeStrainMethod not found!"
|
(
|
||||||
<< exit(FatalError);
|
muf * (mesh.Sf() & fvc::interpolate(gradDU & gradDU.T()))
|
||||||
}
|
+ 0.5*lambdaf * (mesh.Sf() & (fvc::interpolate(gradDU && gradDU)*I))
|
||||||
|
+ (mesh.Sf() & fvc::interpolate( (sigma + DSigma) & gradDU ))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FatalError
|
||||||
|
<< "divDSigmaLargeStrainMethod not found!"
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
|
@ -15,59 +15,57 @@
|
||||||
FieldField<Field, vector> extraVecs(ptc.size());
|
FieldField<Field, vector> extraVecs(ptc.size());
|
||||||
|
|
||||||
{
|
{
|
||||||
const labelListList& pfaces = mesh.pointFaces();
|
const labelListList& pfaces = mesh.pointFaces();
|
||||||
|
|
||||||
const volVectorField& centres = mesh.C();
|
const volVectorField& centres = mesh.C();
|
||||||
|
|
||||||
const fvBoundaryMesh& bm = mesh.boundary();
|
const fvBoundaryMesh& bm = mesh.boundary();
|
||||||
|
|
||||||
forAll (ptc, pointI)
|
forAll (ptc, pointI)
|
||||||
{
|
{
|
||||||
const label curPoint = ptc[pointI];
|
const label curPoint = ptc[pointI];
|
||||||
|
|
||||||
const labelList& curFaces = pfaces[curPoint];
|
const labelList& curFaces = pfaces[curPoint];
|
||||||
|
|
||||||
// extraVecs.hook(new vectorField(curFaces.size())); //- no hook function
|
// extraVecs.hook(new vectorField(curFaces.size())); //- no hook function
|
||||||
extraVecs.set
|
extraVecs.set
|
||||||
(
|
|
||||||
pointI,
|
|
||||||
new vectorField(curFaces.size())
|
|
||||||
);
|
|
||||||
|
|
||||||
vectorField& curExtraVectors = extraVecs[pointI];
|
|
||||||
|
|
||||||
label nFacesAroundPoint = 0;
|
|
||||||
|
|
||||||
const vector& pointLoc = mesh.points()[curPoint];
|
|
||||||
|
|
||||||
// Go through all the faces
|
|
||||||
forAll (curFaces, faceI)
|
|
||||||
{
|
|
||||||
if (!mesh.isInternalFace(curFaces[faceI]))
|
|
||||||
{
|
|
||||||
// This is a boundary face. If not in the empty patch
|
|
||||||
// or coupled calculate the extrapolation vector
|
|
||||||
label patchID =
|
|
||||||
mesh.boundaryMesh().whichPatch(curFaces[faceI]);
|
|
||||||
|
|
||||||
if
|
|
||||||
(
|
(
|
||||||
!isA<emptyFvPatch>(bm[patchID])
|
pointI,
|
||||||
&& !bm[patchID].coupled()
|
new vectorField(curFaces.size())
|
||||||
)
|
);
|
||||||
|
|
||||||
|
vectorField& curExtraVectors = extraVecs[pointI];
|
||||||
|
|
||||||
|
label nFacesAroundPoint = 0;
|
||||||
|
|
||||||
|
const vector& pointLoc = mesh.points()[curPoint];
|
||||||
|
|
||||||
|
// Go through all the faces
|
||||||
|
forAll (curFaces, faceI)
|
||||||
{
|
{
|
||||||
// Found a face for extrapolation
|
if (!mesh.isInternalFace(curFaces[faceI]))
|
||||||
curExtraVectors[nFacesAroundPoint] =
|
{
|
||||||
pointLoc
|
// This is a boundary face. If not in the empty patch
|
||||||
- centres.boundaryField()[patchID]
|
// or coupled calculate the extrapolation vector
|
||||||
[bm[patchID].patch().whichFace(curFaces[faceI])];
|
label patchID =
|
||||||
|
mesh.boundaryMesh().whichPatch(curFaces[faceI]);
|
||||||
|
|
||||||
nFacesAroundPoint++;
|
if
|
||||||
|
(
|
||||||
|
!isA<emptyFvPatch>(bm[patchID]) && !bm[patchID].coupled()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Found a face for extrapolation
|
||||||
|
curExtraVectors[nFacesAroundPoint] =
|
||||||
|
pointLoc
|
||||||
|
- centres.boundaryField()[patchID]
|
||||||
|
[bm[patchID].patch().whichFace(curFaces[faceI])];
|
||||||
|
|
||||||
|
nFacesAroundPoint++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
curExtraVectors.setSize(nFacesAroundPoint);
|
curExtraVectors.setSize(nFacesAroundPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,114 +8,114 @@
|
||||||
FieldField<Field, scalar> w(ptc.size());
|
FieldField<Field, scalar> w(ptc.size());
|
||||||
|
|
||||||
{
|
{
|
||||||
const labelListList& pf = mesh.pointFaces();
|
const labelListList& pf = mesh.pointFaces();
|
||||||
|
|
||||||
const volVectorField& centres = mesh.C();
|
const volVectorField& centres = mesh.C();
|
||||||
|
|
||||||
const fvBoundaryMesh& bm = mesh.boundary();
|
const fvBoundaryMesh& bm = mesh.boundary();
|
||||||
|
|
||||||
pointScalarField volPointSumWeights
|
pointScalarField volPointSumWeights
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
|
||||||
"volPointSumWeights",
|
|
||||||
mesh.polyMesh::instance(),
|
|
||||||
mesh
|
|
||||||
),
|
|
||||||
pMesh,
|
|
||||||
dimensionedScalar("zero", dimless, 0)
|
|
||||||
);
|
|
||||||
|
|
||||||
forAll (ptc, pointI)
|
|
||||||
{
|
|
||||||
const label curPoint = ptc[pointI];
|
|
||||||
|
|
||||||
const labelList& curFaces = pf[curPoint];
|
|
||||||
|
|
||||||
//w.hook(new scalarField(curFaces.size())); //philipc no hook function
|
|
||||||
w.set
|
|
||||||
(
|
|
||||||
pointI,
|
|
||||||
new scalarField(curFaces.size())
|
|
||||||
);
|
|
||||||
|
|
||||||
scalarField& curWeights = w[pointI];
|
|
||||||
|
|
||||||
label nFacesAroundPoint = 0;
|
|
||||||
|
|
||||||
const vector& pointLoc = mesh.points()[curPoint];
|
|
||||||
|
|
||||||
// Go through all the faces
|
|
||||||
forAll (curFaces, faceI)
|
|
||||||
{
|
|
||||||
if (!mesh.isInternalFace(curFaces[faceI]))
|
|
||||||
{
|
|
||||||
// This is a boundary face. If not in the empty patch
|
|
||||||
// or coupled calculate the extrapolation vector
|
|
||||||
label patchID =
|
|
||||||
mesh.boundaryMesh().whichPatch(curFaces[faceI]);
|
|
||||||
|
|
||||||
if
|
|
||||||
(
|
(
|
||||||
!isA<emptyFvPatch>(bm[patchID])
|
"volPointSumWeights",
|
||||||
&& !(
|
mesh.polyMesh::instance(),
|
||||||
bm[patchID].coupled()
|
mesh
|
||||||
//&& Pstream::parRun()
|
),
|
||||||
//&& !mesh.parallelData().cyclicParallel()
|
pMesh,
|
||||||
)
|
dimensionedScalar("zero", dimless, 0)
|
||||||
)
|
|
||||||
{
|
|
||||||
curWeights[nFacesAroundPoint] =
|
|
||||||
1.0/mag
|
|
||||||
(
|
|
||||||
pointLoc
|
|
||||||
- centres.boundaryField()[patchID]
|
|
||||||
[
|
|
||||||
bm[patchID].patch().whichFace(curFaces[faceI])
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
nFacesAroundPoint++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset the sizes of the local weights
|
|
||||||
curWeights.setSize(nFacesAroundPoint);
|
|
||||||
|
|
||||||
// Collect the sum of weights for parallel correction
|
|
||||||
volPointSumWeights[curPoint] += sum(curWeights);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do parallel correction of weights
|
|
||||||
|
|
||||||
// Update coupled boundaries
|
|
||||||
// Work-around for cyclic parallels.
|
|
||||||
/*if (Pstream::parRun() && !mesh.parallelData().cyclicParallel())
|
|
||||||
{
|
|
||||||
forAll (volPointSumWeights.boundaryField(), patchI)
|
|
||||||
{
|
|
||||||
if (volPointSumWeights.boundaryField()[patchI].coupled())
|
|
||||||
{
|
|
||||||
volPointSumWeights.boundaryField()[patchI].initAddField();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
forAll (volPointSumWeights.boundaryField(), patchI)
|
|
||||||
{
|
|
||||||
if (volPointSumWeights.boundaryField()[patchI].coupled())
|
|
||||||
{
|
|
||||||
volPointSumWeights.boundaryField()[patchI].addField
|
|
||||||
(
|
|
||||||
volPointSumWeights.internalField()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
forAll (ptc, pointI)
|
||||||
|
{
|
||||||
|
const label curPoint = ptc[pointI];
|
||||||
|
|
||||||
|
const labelList& curFaces = pf[curPoint];
|
||||||
|
|
||||||
|
//w.hook(new scalarField(curFaces.size())); //philipc no hook function
|
||||||
|
w.set
|
||||||
|
(
|
||||||
|
pointI,
|
||||||
|
new scalarField(curFaces.size())
|
||||||
|
);
|
||||||
|
|
||||||
|
scalarField& curWeights = w[pointI];
|
||||||
|
|
||||||
|
label nFacesAroundPoint = 0;
|
||||||
|
|
||||||
|
const vector& pointLoc = mesh.points()[curPoint];
|
||||||
|
|
||||||
|
// Go through all the faces
|
||||||
|
forAll (curFaces, faceI)
|
||||||
|
{
|
||||||
|
if (!mesh.isInternalFace(curFaces[faceI]))
|
||||||
|
{
|
||||||
|
// This is a boundary face. If not in the empty patch
|
||||||
|
// or coupled calculate the extrapolation vector
|
||||||
|
label patchID =
|
||||||
|
mesh.boundaryMesh().whichPatch(curFaces[faceI]);
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
!isA<emptyFvPatch>(bm[patchID])
|
||||||
|
&& !(
|
||||||
|
bm[patchID].coupled()
|
||||||
|
//&& Pstream::parRun()
|
||||||
|
//&& !mesh.parallelData().cyclicParallel()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
curWeights[nFacesAroundPoint] =
|
||||||
|
1.0/mag
|
||||||
|
(
|
||||||
|
pointLoc
|
||||||
|
- centres.boundaryField()[patchID]
|
||||||
|
[
|
||||||
|
bm[patchID].patch().whichFace(curFaces[faceI])
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
nFacesAroundPoint++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the sizes of the local weights
|
||||||
|
curWeights.setSize(nFacesAroundPoint);
|
||||||
|
|
||||||
|
// Collect the sum of weights for parallel correction
|
||||||
|
volPointSumWeights[curPoint] += sum(curWeights);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// Do parallel correction of weights
|
||||||
|
|
||||||
|
// Update coupled boundaries
|
||||||
|
// Work-around for cyclic parallels.
|
||||||
|
/*if (Pstream::parRun() && !mesh.parallelData().cyclicParallel())
|
||||||
|
{
|
||||||
|
forAll (volPointSumWeights.boundaryField(), patchI)
|
||||||
|
{
|
||||||
|
if (volPointSumWeights.boundaryField()[patchI].coupled())
|
||||||
|
{
|
||||||
|
volPointSumWeights.boundaryField()[patchI].initAddField();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll (volPointSumWeights.boundaryField(), patchI)
|
||||||
|
{
|
||||||
|
if (volPointSumWeights.boundaryField()[patchI].coupled())
|
||||||
|
{
|
||||||
|
volPointSumWeights.boundaryField()[patchI].addField
|
||||||
|
(
|
||||||
|
volPointSumWeights.internalField()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
// Re-scale the weights for the current point
|
// Re-scale the weights for the current point
|
||||||
forAll (ptc, pointI)
|
forAll (ptc, pointI)
|
||||||
{
|
{
|
||||||
w[pointI] /= volPointSumWeights[ptc[pointI]];
|
w[pointI] /= volPointSumWeights[ptc[pointI]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,31 +92,31 @@
|
||||||
//- explicit terms in the momentum equation
|
//- explicit terms in the momentum equation
|
||||||
volVectorField divDSigmaExp
|
volVectorField divDSigmaExp
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"divDSigmaExp",
|
"divDSigmaExp",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedVector("zero", dimensionSet(1, -2, -2, 0, 0, 0, 0), vector::zero)
|
dimensionedVector("zero", dimensionSet(1, -2, -2, 0, 0, 0, 0), vector::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
volVectorField divDSigmaLargeStrainExp
|
volVectorField divDSigmaLargeStrainExp
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"divDSigmaLargeStrainExp",
|
"divDSigmaLargeStrainExp",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedVector("zero", dimensionSet(1, -2, -2, 0, 0, 0, 0), vector::zero)
|
dimensionedVector("zero", dimensionSet(1, -2, -2, 0, 0, 0, 0), vector::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
constitutiveModel rheology(sigma, DU);
|
constitutiveModel rheology(sigma, DU);
|
||||||
|
|
||||||
|
|
|
@ -4,26 +4,26 @@ solidInterface* solidInterfacePtr(NULL);
|
||||||
|
|
||||||
{
|
{
|
||||||
const dictionary& stressControl =
|
const dictionary& stressControl =
|
||||||
mesh.solutionDict().subDict("solidMechanics");
|
mesh.solutionDict().subDict("solidMechanics");
|
||||||
|
|
||||||
solidInterfaceCorr = Switch(stressControl.lookup("solidInterface"));
|
solidInterfaceCorr = Switch(stressControl.lookup("solidInterface"));
|
||||||
|
|
||||||
if(solidInterfaceCorr)
|
if(solidInterfaceCorr)
|
||||||
{
|
{
|
||||||
Info << "Creating solid interface correction" << endl;
|
Info << "Creating solid interface correction" << endl;
|
||||||
solidInterfacePtr = new solidInterface(mesh, rheology);
|
solidInterfacePtr = new solidInterface(mesh, rheology);
|
||||||
solidInterfacePtr->modifyProperties(muf, lambdaf);
|
solidInterfacePtr->modifyProperties(muf, lambdaf);
|
||||||
|
|
||||||
//- solidInterface needs muf and lambdaf to be used for divDSigmaExp
|
//- solidInterface needs muf and lambdaf to be used for divDSigmaExp
|
||||||
if(divDSigmaExpMethod != "surface" && divDSigmaExpMethod != "decompose")
|
if(divDSigmaExpMethod != "surface" && divDSigmaExpMethod != "decompose")
|
||||||
{
|
{
|
||||||
FatalError << "divDSigmaExp must be decompose or surface when solidInterface is on"
|
FatalError << "divDSigmaExp must be decompose or surface when solidInterface is on"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
if(divDSigmaLargeStrainExpMethod == "surface")
|
if(divDSigmaLargeStrainExpMethod == "surface")
|
||||||
{
|
{
|
||||||
FatalError << "divDSigmaLargeStrainExp must be surface when solidInterface is on"
|
FatalError << "divDSigmaLargeStrainExp must be surface when solidInterface is on"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,20 +3,19 @@ bool solidInterfaceCorr = rheology.solidInterfaceActive();
|
||||||
solidInterface* solidInterfacePtr(NULL);
|
solidInterface* solidInterfacePtr(NULL);
|
||||||
|
|
||||||
if(solidInterfaceCorr)
|
if(solidInterfaceCorr)
|
||||||
{
|
{
|
||||||
solidInterfacePtr = &rheology.solInterface();
|
solidInterfacePtr = &rheology.solInterface();
|
||||||
solidInterfacePtr->modifyProperties(muf, lambdaf);
|
solidInterfacePtr->modifyProperties(muf, lambdaf);
|
||||||
|
|
||||||
//- solidInterface needs muf and lambdaf to be used for divDSigmaExp
|
//- solidInterface needs muf and lambdaf to be used for divDSigmaExp
|
||||||
if(divDSigmaExpMethod != "surface" && divDSigmaExpMethod != "decompose")
|
if(divDSigmaExpMethod != "surface" && divDSigmaExpMethod != "decompose")
|
||||||
{
|
{
|
||||||
FatalError << "divDSigmaExp must be decompose or surface when solidInterface is on"
|
FatalError << "divDSigmaExp must be decompose or surface when solidInterface is on"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
if(divDSigmaLargeStrainExpMethod != "surface")
|
if(divDSigmaLargeStrainExpMethod != "surface")
|
||||||
{
|
{
|
||||||
FatalError << "divDSigmaLargeStrainExp must be surface when solidInterface is on"
|
FatalError << "divDSigmaLargeStrainExp must be surface when solidInterface is on"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,100 +52,101 @@ Author
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
# include "setRootCase.H"
|
# include "setRootCase.H"
|
||||||
# include "createTime.H"
|
# include "createTime.H"
|
||||||
# include "createMesh.H"
|
# include "createMesh.H"
|
||||||
# include "createFields.H"
|
# include "createFields.H"
|
||||||
# include "readDivDSigmaExpMethod.H"
|
# include "readDivDSigmaExpMethod.H"
|
||||||
# include "readDivDSigmaLargeStrainExpMethod.H"
|
# include "readDivDSigmaLargeStrainExpMethod.H"
|
||||||
# include "readMoveMeshMethod.H"
|
# include "readMoveMeshMethod.H"
|
||||||
# include "createSolidInterfaceNonLin.H"
|
# include "createSolidInterfaceNonLin.H"
|
||||||
# include "findGlobalFaceZones.H"
|
# include "findGlobalFaceZones.H"
|
||||||
|
|
||||||
//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Info << "\nStarting time loop\n" << endl;
|
Info<< "\nStarting time loop\n" << endl;
|
||||||
|
|
||||||
for (runTime++; !runTime.end(); runTime++)
|
while(runTime.loop())
|
||||||
{
|
{
|
||||||
Info<< "Time = " << runTime.timeName() << nl << endl;
|
Info<< "Time = " << runTime.timeName() << nl << endl;
|
||||||
|
|
||||||
# include "readSolidMechanicsControls.H"
|
# include "readSolidMechanicsControls.H"
|
||||||
|
|
||||||
int iCorr = 0;
|
int iCorr = 0;
|
||||||
lduMatrix::solverPerformance solverPerf;
|
lduMatrix::solverPerformance solverPerf;
|
||||||
scalar initialResidual = 1.0;
|
scalar initialResidual = 1.0;
|
||||||
scalar relativeResidual = 1.0;
|
scalar relativeResidual = 1.0;
|
||||||
lduMatrix::debug = 0;
|
lduMatrix::debug = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
DU.storePrevIter();
|
DU.storePrevIter();
|
||||||
|
|
||||||
# include "calculateDivDSigmaExp.H"
|
# include "calculateDivDSigmaExp.H"
|
||||||
# include "calculateDivDSigmaLargeStrainExp.H"
|
# include "calculateDivDSigmaLargeStrainExp.H"
|
||||||
|
|
||||||
//- Updated lagrangian momentum equation
|
//- Updated lagrangian momentum equation
|
||||||
fvVectorMatrix DUEqn
|
fvVectorMatrix DUEqn
|
||||||
(
|
(
|
||||||
fvm::d2dt2(rho,DU)
|
fvm::d2dt2(rho,DU)
|
||||||
==
|
==
|
||||||
fvm::laplacian(2*muf + lambdaf, DU, "laplacian(DDU,DU)")
|
fvm::laplacian(2*muf + lambdaf, DU, "laplacian(DDU,DU)")
|
||||||
+ divDSigmaExp
|
+ divDSigmaExp
|
||||||
+ divDSigmaLargeStrainExp
|
+ divDSigmaLargeStrainExp
|
||||||
);
|
);
|
||||||
|
|
||||||
if (solidInterfaceCorr)
|
if (solidInterfaceCorr)
|
||||||
{
|
{
|
||||||
solidInterfacePtr->correct(DUEqn);
|
solidInterfacePtr->correct(DUEqn);
|
||||||
}
|
}
|
||||||
|
|
||||||
solverPerf = DUEqn.solve();
|
solverPerf = DUEqn.solve();
|
||||||
|
|
||||||
if (iCorr == 0)
|
if (iCorr == 0)
|
||||||
{
|
{
|
||||||
initialResidual = solverPerf.initialResidual();
|
initialResidual = solverPerf.initialResidual();
|
||||||
}
|
}
|
||||||
|
|
||||||
DU.relax();
|
DU.relax();
|
||||||
|
|
||||||
gradDU = fvc::grad(DU);
|
gradDU = fvc::grad(DU);
|
||||||
|
|
||||||
# include "calculateDEpsilonDSigma.H"
|
# include "calculateDEpsilonDSigma.H"
|
||||||
# include "calculateRelativeResidual.H"
|
# include "calculateRelativeResidual.H"
|
||||||
|
|
||||||
Info << "\tTime " << runTime.value()
|
Info<< "\tTime " << runTime.value()
|
||||||
<< ", Corrector " << iCorr
|
<< ", Corrector " << iCorr
|
||||||
<< ", Solving for " << DU.name()
|
<< ", Solving for " << DU.name()
|
||||||
<< " using " << solverPerf.solverName()
|
<< " using " << solverPerf.solverName()
|
||||||
<< ", res = " << solverPerf.initialResidual()
|
<< ", res = " << solverPerf.initialResidual()
|
||||||
<< ", rel res = " << relativeResidual
|
<< ", rel res = " << relativeResidual
|
||||||
<< ", inner iters " << solverPerf.nIterations() << endl;
|
<< ", inner iters " << solverPerf.nIterations() << endl;
|
||||||
}
|
}
|
||||||
while
|
while
|
||||||
(
|
(
|
||||||
//solverPerf.initialResidual() > convergenceTolerance
|
//solverPerf.initialResidual() > convergenceTolerance
|
||||||
relativeResidual > convergenceTolerance
|
relativeResidual > convergenceTolerance
|
||||||
&& ++iCorr < nCorr
|
&& ++iCorr < nCorr
|
||||||
);
|
);
|
||||||
|
|
||||||
Info << nl << "Time " << runTime.value() << ", Solving for " << DU.name()
|
Info << nl << "Time " << runTime.value() << ", Solving for " << DU.name()
|
||||||
<< ", Initial residual = " << initialResidual
|
<< ", Initial residual = " << initialResidual
|
||||||
<< ", Final residual = " << solverPerf.initialResidual()
|
<< ", Final residual = " << solverPerf.initialResidual()
|
||||||
<< ", No outer iterations " << iCorr << endl;
|
<< ", No outer iterations " << iCorr << endl;
|
||||||
|
|
||||||
# include "moveMesh.H"
|
# include "moveMesh.H"
|
||||||
# include "rotateFields.H"
|
# include "rotateFields.H"
|
||||||
# include "writeFields.H"
|
# include "writeFields.H"
|
||||||
|
|
||||||
Info<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
Info<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "End\n" << endl;
|
Info<< "End\n" << endl;
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|
|
@ -8,26 +8,26 @@ const fvBoundaryMesh& bm = mesh.boundary();
|
||||||
|
|
||||||
forAll (bm, patchI)
|
forAll (bm, patchI)
|
||||||
{
|
{
|
||||||
// If the patch is empty, skip it
|
// If the patch is empty, skip it
|
||||||
// If the patch is coupled, and there are no cyclic parallels, skip it
|
// If the patch is coupled, and there are no cyclic parallels, skip it
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
!isA<emptyFvPatch>(bm[patchI])
|
!isA<emptyFvPatch>(bm[patchI])
|
||||||
&& !(
|
&& !(
|
||||||
bm[patchI].coupled()
|
bm[patchI].coupled()
|
||||||
//&& Pstream::parRun()
|
//&& Pstream::parRun()
|
||||||
//&& !mesh.parallelData().cyclicParallel()
|
//&& !mesh.parallelData().cyclicParallel()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const labelList& bp = bm[patchI].patch().boundaryPoints();
|
const labelList& bp = bm[patchI].patch().boundaryPoints();
|
||||||
|
|
||||||
const labelList& meshPoints = bm[patchI].patch().meshPoints();
|
const labelList& meshPoints = bm[patchI].patch().meshPoints();
|
||||||
|
|
||||||
forAll (bp, pointI)
|
forAll (bp, pointI)
|
||||||
{
|
{
|
||||||
pointsCorrectionMap.insert(meshPoints[bp[pointI]]);
|
pointsCorrectionMap.insert(meshPoints[bp[pointI]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//- move mesh
|
//- move mesh
|
||||||
//--------------------------------------------------//
|
//--------------------------------------------------//
|
||||||
// if(min(J.internalField()) > 0)
|
// if(min(J.internalField()) > 0)
|
||||||
{
|
{
|
||||||
Info << "Move solid mesh using inverse distance interpolation" << endl;
|
Info << "Move solid mesh using inverse distance interpolation" << endl;
|
||||||
|
|
||||||
// Create point mesh
|
// Create point mesh
|
||||||
|
@ -12,23 +12,23 @@
|
||||||
volPointInterpolation pointInterpolation(mesh);
|
volPointInterpolation pointInterpolation(mesh);
|
||||||
|
|
||||||
wordList types
|
wordList types
|
||||||
(
|
(
|
||||||
pMesh.boundary().size(),
|
pMesh.boundary().size(),
|
||||||
calculatedFvPatchVectorField::typeName
|
calculatedFvPatchVectorField::typeName
|
||||||
);
|
);
|
||||||
|
|
||||||
pointVectorField pointDU
|
pointVectorField pointDU
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"pointDU",
|
"pointDU",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh
|
mesh
|
||||||
),
|
),
|
||||||
pMesh,
|
pMesh,
|
||||||
dimensionedVector("zero", dimLength, vector::zero),
|
dimensionedVector("zero", dimLength, vector::zero),
|
||||||
types
|
types
|
||||||
);
|
);
|
||||||
|
|
||||||
// Calculate mesh points displacement
|
// Calculate mesh points displacement
|
||||||
pointInterpolation.interpolate(DU, pointDU);
|
pointInterpolation.interpolate(DU, pointDU);
|
||||||
|
@ -36,27 +36,27 @@
|
||||||
//- correct edge interpolation
|
//- correct edge interpolation
|
||||||
//- this is the stuff from edgeCorrectedVolPointInterpolation but
|
//- this is the stuff from edgeCorrectedVolPointInterpolation but
|
||||||
//- that class no longer works
|
//- that class no longer works
|
||||||
# include "performEdgeCorrectedVolPointInterpolation.H"
|
# include "performEdgeCorrectedVolPointInterpolation.H"
|
||||||
|
|
||||||
const vectorField& pointDUI =
|
const vectorField& pointDUI =
|
||||||
pointDU.internalField();
|
pointDU.internalField();
|
||||||
|
|
||||||
//- see the effect of correctBCs
|
//- see the effect of correctBCs
|
||||||
|
|
||||||
// Move mesh
|
// Move mesh
|
||||||
vectorField newPoints = mesh.allPoints();
|
vectorField newPoints = mesh.allPoints();
|
||||||
|
|
||||||
forAll (pointDUI, pointI)
|
forAll (pointDUI, pointI)
|
||||||
{
|
{
|
||||||
newPoints[pointI] += pointDUI[pointI];
|
newPoints[pointI] += pointDUI[pointI];
|
||||||
}
|
}
|
||||||
|
|
||||||
twoDPointCorrector twoDCorrector(mesh);
|
twoDPointCorrector twoDCorrector(mesh);
|
||||||
twoDCorrector.correctPoints(newPoints);
|
twoDCorrector.correctPoints(newPoints);
|
||||||
mesh.movePoints(newPoints);
|
mesh.movePoints(newPoints);
|
||||||
mesh.V00();
|
mesh.V00();
|
||||||
mesh.moving(false);
|
mesh.moving(false);
|
||||||
}
|
}
|
||||||
// else
|
// else
|
||||||
// {
|
// {
|
||||||
// FatalErrorIn(args.executable())
|
// FatalErrorIn(args.executable())
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//- move mesh
|
//- move mesh
|
||||||
//--------------------------------------------------//
|
//--------------------------------------------------//
|
||||||
{
|
{
|
||||||
//Info << "Moving mesh using least squares interpolation" << endl;
|
//Info << "Moving mesh using least squares interpolation" << endl;
|
||||||
|
|
||||||
leastSquaresVolPointInterpolation pointInterpolation(mesh);
|
leastSquaresVolPointInterpolation pointInterpolation(mesh);
|
||||||
|
|
||||||
|
@ -112,4 +112,4 @@
|
||||||
|
|
||||||
// Update n
|
// Update n
|
||||||
n = mesh.Sf()/mesh.magSf();
|
n = mesh.Sf()/mesh.magSf();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,38 +7,40 @@ pointVectorField& pf = pointDU;
|
||||||
|
|
||||||
// Do the correction
|
// Do the correction
|
||||||
//GeometricField<Type, pointPatchField, pointMesh> pfCorr
|
//GeometricField<Type, pointPatchField, pointMesh> pfCorr
|
||||||
/*pointVectorField pfCorr
|
/*
|
||||||
|
pointVectorField pfCorr
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
// "edgeCorrectedVolPointInterpolate(" + vf.name() + ")Corr",
|
// "edgeCorrectedVolPointInterpolate(" + vf.name() + ")Corr",
|
||||||
"edgeCorrectedVolPointInterpolate(" + DU.name() + ")Corr",
|
"edgeCorrectedVolPointInterpolate(" + DU.name() + ")Corr",
|
||||||
//vf.instance(),
|
//vf.instance(),
|
||||||
DU,
|
DU,
|
||||||
pMesh,
|
pMesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
pMesh,
|
pMesh,
|
||||||
//dimensioned<Type>("zero", pf.dimensions(), pTraits<Type>::zero),
|
//dimensioned<Type>("zero", pf.dimensions(), pTraits<Type>::zero),
|
||||||
dimensionedVector("zero", pf.dimensions(), vector::zero),
|
dimensionedVector("zero", pf.dimensions(), vector::zero),
|
||||||
pf.boundaryField().types()
|
pf.boundaryField().types()
|
||||||
);*/
|
);
|
||||||
|
*/
|
||||||
|
|
||||||
pointVectorField pfCorr
|
pointVectorField pfCorr
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"pointDUcorr",
|
"pointDUcorr",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
pMesh,
|
pMesh,
|
||||||
dimensionedVector("vector", dimLength, vector::zero),
|
dimensionedVector("vector", dimLength, vector::zero),
|
||||||
"calculated"
|
"calculated"
|
||||||
);
|
);
|
||||||
|
|
||||||
//const labelList& ptc = boundaryPoints();
|
//const labelList& ptc = boundaryPoints();
|
||||||
#include "findBoundaryPoints.H"
|
#include "findBoundaryPoints.H"
|
||||||
|
@ -57,64 +59,68 @@ const labelListList& PointFaces = mesh.pointFaces();
|
||||||
|
|
||||||
forAll (ptc, pointI)
|
forAll (ptc, pointI)
|
||||||
{
|
{
|
||||||
const label curPoint = ptc[pointI];
|
const label curPoint = ptc[pointI];
|
||||||
|
|
||||||
const labelList& curFaces = PointFaces[curPoint];
|
const labelList& curFaces = PointFaces[curPoint];
|
||||||
|
|
||||||
label fI = 0;
|
label fI = 0;
|
||||||
|
|
||||||
// Go through all the faces
|
// Go through all the faces
|
||||||
forAll (curFaces, faceI)
|
forAll (curFaces, faceI)
|
||||||
{
|
{
|
||||||
if (!mesh.isInternalFace(curFaces[faceI]))
|
if (!mesh.isInternalFace(curFaces[faceI]))
|
||||||
{
|
|
||||||
// This is a boundary face. If not in the empty patch
|
|
||||||
// or coupled calculate the extrapolation vector
|
|
||||||
label patchID =
|
|
||||||
mesh.boundaryMesh().whichPatch(curFaces[faceI]);
|
|
||||||
|
|
||||||
if
|
|
||||||
(
|
|
||||||
!isA<emptyFvPatch>(mesh.boundary()[patchID])
|
|
||||||
&& !mesh.boundary()[patchID].coupled()
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
label faceInPatchID =
|
// This is a boundary face. If not in the empty patch
|
||||||
bm[patchID].patch().whichFace(curFaces[faceI]);
|
// or coupled calculate the extrapolation vector
|
||||||
|
label patchID =
|
||||||
|
mesh.boundaryMesh().whichPatch(curFaces[faceI]);
|
||||||
|
|
||||||
pfCorr[curPoint] +=
|
if
|
||||||
w[pointI][fI]*
|
(
|
||||||
(
|
!isA<emptyFvPatch>(mesh.boundary()[patchID])
|
||||||
extraVecs[pointI][fI]
|
&& !mesh.boundary()[patchID].coupled()
|
||||||
& gradDU.boundaryField()[patchID][faceInPatchID]
|
)
|
||||||
);
|
{
|
||||||
|
label faceInPatchID =
|
||||||
|
bm[patchID].patch().whichFace(curFaces[faceI]);
|
||||||
|
|
||||||
fI++;
|
pfCorr[curPoint] +=
|
||||||
|
w[pointI][fI]*
|
||||||
|
(
|
||||||
|
extraVecs[pointI][fI]
|
||||||
|
& gradDU.boundaryField()[patchID][faceInPatchID]
|
||||||
|
);
|
||||||
|
|
||||||
|
fI++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update coupled boundaries
|
// Update coupled boundaries
|
||||||
/*forAll (pfCorr.boundaryField(), patchI)
|
/*
|
||||||
|
forAll (pfCorr.boundaryField(), patchI)
|
||||||
{
|
{
|
||||||
if (pfCorr.boundaryField()[patchI].coupled())
|
if (pfCorr.boundaryField()[patchI].coupled())
|
||||||
{
|
{
|
||||||
pfCorr.boundaryField()[patchI].initAddField();
|
pfCorr.boundaryField()[patchI].initAddField();
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/*forAll (pfCorr.boundaryField(), patchI)
|
/*
|
||||||
|
forAll (pfCorr.boundaryField(), patchI)
|
||||||
{
|
{
|
||||||
if (pfCorr.boundaryField()[patchI].coupled())
|
if (pfCorr.boundaryField()[patchI].coupled())
|
||||||
{
|
{
|
||||||
pfCorr.boundaryField()[patchI].addField(pfCorr.internalField());
|
pfCorr.boundaryField()[patchI].addField(pfCorr.internalField());
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
//Info << "pfCorr: " << pfCorr << endl;
|
//Info << "pfCorr: " << pfCorr << endl;
|
||||||
pfCorr.correctBoundaryConditions();
|
pfCorr.correctBoundaryConditions();
|
||||||
|
|
||||||
//pfCorr.write();
|
//pfCorr.write();
|
||||||
|
|
||||||
|
|
|
@ -1,36 +1,36 @@
|
||||||
if (runTime.outputTime())
|
if (runTime.outputTime())
|
||||||
{
|
{
|
||||||
volScalarField epsilonEq
|
volScalarField epsilonEq
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"epsilonEq",
|
"epsilonEq",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
sqrt((2.0/3.0)*magSqr(dev(epsilon)))
|
sqrt((2.0/3.0)*magSqr(dev(epsilon)))
|
||||||
);
|
);
|
||||||
|
|
||||||
Info<< "Max epsilonEq = " << max(epsilonEq).value()
|
Info<< "Max epsilonEq = " << max(epsilonEq).value()
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
volScalarField sigmaEq
|
volScalarField sigmaEq
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"sigmaEq",
|
"sigmaEq",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
sqrt((3.0/2.0)*magSqr(dev(sigma)))
|
sqrt((3.0/2.0)*magSqr(dev(sigma)))
|
||||||
);
|
);
|
||||||
|
|
||||||
Info<< "Max sigmaEq = " << max(sigmaEq).value()
|
Info<< "Max sigmaEq = " << max(sigmaEq).value()
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
runTime.write();
|
runTime.write();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,26 +6,24 @@ aitkenDelta = (U - U.prevIter()) / aitkenInitialRes;
|
||||||
|
|
||||||
// update relaxation factor
|
// update relaxation factor
|
||||||
if(iCorr == 0)
|
if(iCorr == 0)
|
||||||
{
|
{
|
||||||
aitkenTheta = 0.01;
|
aitkenTheta = 0.01;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vectorField b = aitkenDelta.internalField() - aitkenDelta.prevIter().internalField();
|
vectorField b = aitkenDelta.internalField() - aitkenDelta.prevIter().internalField();
|
||||||
//scalar sumMagB = gSum(mag(b));
|
//scalar sumMagB = gSum(mag(b));
|
||||||
scalar sumMagB = gSum(magSqr(b));
|
scalar sumMagB = gSum(magSqr(b));
|
||||||
if(sumMagB < SMALL)
|
if(sumMagB < SMALL)
|
||||||
{
|
{
|
||||||
//Warning << "Aitken under-relaxation: denominator less then SMALL"
|
//Warning << "Aitken under-relaxation: denominator less then SMALL"
|
||||||
// << endl;
|
// << endl;
|
||||||
sumMagB += SMALL;
|
sumMagB += SMALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
aitkenTheta = -aitkenTheta*
|
aitkenTheta = -aitkenTheta*
|
||||||
gSum(aitkenDelta.prevIter().internalField() & b)
|
gSum(aitkenDelta.prevIter().internalField() & b)/sumMagB;
|
||||||
/
|
}
|
||||||
sumMagB;
|
|
||||||
}
|
|
||||||
|
|
||||||
// correction to the latest U
|
// correction to the latest U
|
||||||
U += aitkenTheta*aitkenDelta*aitkenInitialRes;
|
U += aitkenTheta*aitkenDelta*aitkenInitialRes;
|
||||||
|
|
|
@ -1,25 +1,27 @@
|
||||||
if(divSigmaExpMethod == "standard")
|
if(divSigmaExpMethod == "standard")
|
||||||
{
|
{
|
||||||
//- calculating the full gradient has good convergence and no high freq oscillations
|
//- calculating the full gradient has good convergence and no high freq oscillations
|
||||||
divSigmaExp = fvc::div(C && epsilon) - fvc::div(K & gradU);
|
divSigmaExp = fvc::div(C && epsilon) - fvc::div(K & gradU);
|
||||||
}
|
}
|
||||||
else if(divSigmaExpMethod == "surface")
|
else if(divSigmaExpMethod == "surface")
|
||||||
{
|
{
|
||||||
//- this form seems to have the best convergence
|
//- this form seems to have the best convergence
|
||||||
divSigmaExp =
|
divSigmaExp = fvc::div
|
||||||
fvc::div(mesh.magSf()*
|
(
|
||||||
|
mesh.magSf()*
|
||||||
(
|
(
|
||||||
(n&(Cf && fvc::interpolate(symm(gradU))))
|
(n & (Cf && fvc::interpolate(symm(gradU))))
|
||||||
- (n&(Kf & fvc::interpolate(gradU)))
|
- (n & (Kf & fvc::interpolate(gradU)))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if(divSigmaExpMethod == "laplacian")
|
else if(divSigmaExpMethod == "laplacian")
|
||||||
{
|
{
|
||||||
//- causes high freq oscillations and slow convergence
|
//- causes high freq oscillations and slow convergence
|
||||||
divSigmaExp = fvc::div(sigma) - fvc::laplacian(K,U);
|
divSigmaExp = fvc::div(sigma) - fvc::laplacian(K, U);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FatalError << "divSigmaExp method " << divSigmaExpMethod << " not found!" << endl;
|
FatalErrorIn(args.executable())
|
||||||
}
|
<< "divSigmaExp method " << divSigmaExpMethod << " not found!" << endl;
|
||||||
|
}
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
{
|
{
|
||||||
// force residual is the net force on the model
|
// force residual is the net force on the model
|
||||||
// this should got to zero in a converged steady state model
|
// this should got to zero in a converged steady state model
|
||||||
// should be altered for parallel runs
|
// should be altered for parallel runs
|
||||||
vector netForce = vector::zero;
|
vector netForce = vector::zero;
|
||||||
forAll(mesh.boundary(), patchi)
|
forAll(mesh.boundary(), patchi)
|
||||||
{
|
{
|
||||||
netForce +=
|
netForce += sum
|
||||||
sum(
|
|
||||||
mesh.Sf().boundaryField()[patchi]
|
|
||||||
&
|
|
||||||
(
|
(
|
||||||
2*mu.boundaryField()[patchi]*symm(gradU.boundaryField()[patchi])
|
mesh.Sf().boundaryField()[patchi]
|
||||||
+ lambda*tr(gradU.boundaryField()[patchi])*I
|
&
|
||||||
)
|
(
|
||||||
|
2*mu.boundaryField()[patchi]*symm(gradU.boundaryField()[patchi])
|
||||||
|
+ lambda*tr(gradU.boundaryField()[patchi])*I
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
forceResidual = mag(netForce);
|
forceResidual = mag(netForce);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
{
|
{
|
||||||
surfaceVectorField n = mesh.Sf()/mesh.magSf();
|
surfaceVectorField n = mesh.Sf()/mesh.magSf();
|
||||||
|
|
||||||
// traction = (n&fvc::interpolate(sigma));
|
// traction = (n & fvc::interpolate(sigma));
|
||||||
|
|
||||||
// surfaceTensorField sGradU =
|
// surfaceTensorField sGradU =
|
||||||
// ((I - n*n)&fvc::interpolate(gradU));
|
// ((I - n*n) & fvc::interpolate(gradU));
|
||||||
|
|
||||||
// traction =
|
// traction =
|
||||||
// (2*mu + lambda)*snGradU
|
// (2*mu + lambda)*snGradU
|
||||||
// - (mu + lambda)*(snGradU&(I - n*n))
|
// - (mu + lambda)*(snGradU&(I - n*n))
|
||||||
// + mu*(sGradU&n)
|
// + mu*(sGradU & n)
|
||||||
// + lambda*tr(sGradU&(I - n*n))*n;
|
// + lambda*tr(sGradU&(I - n*n))*n;
|
||||||
|
|
||||||
// traction =
|
// traction =
|
||||||
// (2*mu + lambda)*fvc::snGrad(U)
|
// (2*mu + lambda)*fvc::snGrad(U)
|
||||||
// - (mu + lambda)*(n&sGradU)
|
// - (mu + lambda)*(n & sGradU)
|
||||||
// + mu*(sGradU&n)
|
// + mu*(sGradU & n)
|
||||||
// + lambda*tr(sGradU)*n;
|
// + lambda*tr(sGradU)*n;
|
||||||
|
|
||||||
// philipc
|
// philipc
|
||||||
// I am having trouble with back-calculation of interface tractions from solid interface
|
// I am having trouble with back-calculation of interface tractions from solid interface
|
||||||
|
@ -27,15 +27,15 @@
|
||||||
traction = (n&fvc::interpolate(sigma));
|
traction = (n&fvc::interpolate(sigma));
|
||||||
|
|
||||||
// forAll(traction.boundaryField(), patchi)
|
// forAll(traction.boundaryField(), patchi)
|
||||||
// {
|
// {
|
||||||
// if (mesh.boundary()[patchi].type() == "cohesive")
|
// if (mesh.boundary()[patchi].type() == "cohesive")
|
||||||
// {
|
// {
|
||||||
// forAll(traction.boundaryField()[patchi], facei)
|
// forAll(traction.boundaryField()[patchi], facei)
|
||||||
// {
|
// {
|
||||||
// Pout << "face " << facei << " with traction magnitude "
|
// Pout << "face " << facei << " with traction magnitude "
|
||||||
// << mag(traction.boundaryField()[patchi][facei])/1e6 << " MPa and traction "
|
// << mag(traction.boundaryField()[patchi][facei])/1e6 << " MPa and traction "
|
||||||
// << traction.boundaryField()[patchi][facei]/1e6 << " MPa" << endl;
|
// << traction.boundaryField()[patchi][facei]/1e6 << " MPa" << endl;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,53 +1,53 @@
|
||||||
label cohesivePatchID = -1;
|
label cohesivePatchID = -1;
|
||||||
|
|
||||||
solidCohesiveFvPatchVectorField* cohesivePatchUPtr = NULL;
|
solidCohesiveFvPatchVectorField* cohesivePatchUPtr = NULL;
|
||||||
solidCohesiveFixedModeMixFvPatchVectorField* cohesivePatchUFixedModePtr = NULL;
|
solidCohesiveFixedModeMixFvPatchVectorField* cohesivePatchUFixedModePtr = NULL;
|
||||||
|
|
||||||
forAll (U.boundaryField(), patchI)
|
forAll (U.boundaryField(), patchI)
|
||||||
{
|
{
|
||||||
if (isA<solidCohesiveFvPatchVectorField>(U.boundaryField()[patchI]))
|
if (isA<solidCohesiveFvPatchVectorField>(U.boundaryField()[patchI]))
|
||||||
{
|
{
|
||||||
cohesivePatchID = patchI;
|
cohesivePatchID = patchI;
|
||||||
cohesivePatchUPtr =
|
cohesivePatchUPtr =
|
||||||
&refCast<solidCohesiveFvPatchVectorField>
|
&refCast<solidCohesiveFvPatchVectorField>
|
||||||
(
|
(
|
||||||
U.boundaryField()[cohesivePatchID]
|
U.boundaryField()[cohesivePatchID]
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
else if (isA<solidCohesiveFixedModeMixFvPatchVectorField>(U.boundaryField()[patchI]))
|
||||||
|
{
|
||||||
|
cohesivePatchID = patchI;
|
||||||
|
cohesivePatchUFixedModePtr =
|
||||||
|
&refCast<solidCohesiveFixedModeMixFvPatchVectorField>
|
||||||
|
(
|
||||||
|
U.boundaryField()[cohesivePatchID]
|
||||||
|
);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (isA<solidCohesiveFixedModeMixFvPatchVectorField>(U.boundaryField()[patchI]))
|
|
||||||
{
|
|
||||||
cohesivePatchID = patchI;
|
|
||||||
cohesivePatchUFixedModePtr =
|
|
||||||
&refCast<solidCohesiveFixedModeMixFvPatchVectorField>
|
|
||||||
(
|
|
||||||
U.boundaryField()[cohesivePatchID]
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cohesivePatchID == -1)
|
if(cohesivePatchID == -1)
|
||||||
{
|
{
|
||||||
FatalErrorIn(args.executable())
|
FatalErrorIn(args.executable())
|
||||||
<< "Can't find cohesiveLawFvPatch" << nl
|
<< "Can't find cohesiveLawFvPatch" << nl
|
||||||
<< "One of the boundary patches in " << U.name() << ".boundaryField() "
|
<< "One of the boundary patches in " << U.name() << ".boundaryField() "
|
||||||
<< "should be of type " << solidCohesiveFvPatchVectorField::typeName
|
<< "should be of type " << solidCohesiveFvPatchVectorField::typeName
|
||||||
<< "or " << solidCohesiveFixedModeMixFvPatchVectorField::typeName
|
<< "or " << solidCohesiveFixedModeMixFvPatchVectorField::typeName
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// solidCohesiveFvPatchVectorField& cohesivePatchU =
|
// solidCohesiveFvPatchVectorField& cohesivePatchU =
|
||||||
// refCast<solidCohesiveFvPatchVectorField>
|
// refCast<solidCohesiveFvPatchVectorField>
|
||||||
// (
|
// (
|
||||||
// U.boundaryField()[cohesivePatchID]
|
// U.boundaryField()[cohesivePatchID]
|
||||||
// );
|
// );
|
||||||
|
|
||||||
// philipc: I have moved cohesive stuff to constitutiveModel
|
// philipc: I have moved cohesive stuff to constitutiveModel
|
||||||
// cohesiveZone is an index field
|
// cohesiveZone is an index field
|
||||||
// which allows the user to limit the crack to certain areas at runtime
|
// which allows the user to limit the crack to certain areas at runtime
|
||||||
// 1 for faces within cohesiveZone
|
// 1 for faces within cohesiveZone
|
||||||
// 0 for faces outside cohesiveZone
|
// 0 for faces outside cohesiveZone
|
||||||
surfaceScalarField cohesiveZone
|
surfaceScalarField cohesiveZone
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
|
@ -64,85 +64,87 @@
|
||||||
|
|
||||||
// limit crack to specified boxes
|
// limit crack to specified boxes
|
||||||
{
|
{
|
||||||
const dictionary& stressControl =
|
const dictionary& stressControl =
|
||||||
mesh.solutionDict().subDict("solidMechanics");
|
mesh.solutionDict().subDict("solidMechanics");
|
||||||
|
|
||||||
List<boundBox> userBoxes(stressControl.lookup("crackLimitingBoxes"));
|
List<boundBox> userBoxes(stressControl.lookup("crackLimitingBoxes"));
|
||||||
const surfaceVectorField& Cf = mesh.Cf();
|
const surfaceVectorField& Cf = mesh.Cf();
|
||||||
forAll(cohesiveZone.internalField(), faceI)
|
forAll(cohesiveZone.internalField(), faceI)
|
||||||
{
|
|
||||||
bool faceInsideBox = false;
|
|
||||||
|
|
||||||
forAll(userBoxes, boxi)
|
|
||||||
{
|
{
|
||||||
if(userBoxes[boxi].contains(Cf.internalField()[faceI])) faceInsideBox = true;
|
bool faceInsideBox = false;
|
||||||
}
|
|
||||||
|
|
||||||
if(faceInsideBox)
|
forAll(userBoxes, boxi)
|
||||||
{
|
|
||||||
cohesiveZone.internalField()[faceI] = 1.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
forAll(cohesiveZone.boundaryField(), patchI)
|
|
||||||
{
|
|
||||||
// cracks may go along proc boundaries
|
|
||||||
if(mesh.boundaryMesh()[patchI].type() == processorPolyPatch::typeName)
|
|
||||||
{
|
|
||||||
forAll(cohesiveZone.boundaryField()[patchI], faceI)
|
|
||||||
{
|
|
||||||
bool faceInsideBox = false;
|
|
||||||
|
|
||||||
forAll(userBoxes, boxi)
|
|
||||||
{
|
{
|
||||||
if(userBoxes[boxi].contains(Cf.boundaryField()[patchI][faceI])) faceInsideBox = true;
|
if(userBoxes[boxi].contains(Cf.internalField()[faceI])) faceInsideBox = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(faceInsideBox)
|
if(faceInsideBox)
|
||||||
{
|
{
|
||||||
cohesiveZone.boundaryField()[patchI][faceI] = 1.0;
|
cohesiveZone.internalField()[faceI] = 1.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Info << "\nThere are " << gSum(cohesiveZone.internalField()) << " potential internal crack faces" << nl << endl;
|
forAll(cohesiveZone.boundaryField(), patchI)
|
||||||
Info << "\nThere are " << gSum(cohesiveZone.boundaryField())/2 << " potential coupled boundary crack faces" << nl << endl;
|
{
|
||||||
|
// cracks may go along proc boundaries
|
||||||
|
if(mesh.boundaryMesh()[patchI].type() == processorPolyPatch::typeName)
|
||||||
|
{
|
||||||
|
forAll(cohesiveZone.boundaryField()[patchI], faceI)
|
||||||
|
{
|
||||||
|
bool faceInsideBox = false;
|
||||||
|
|
||||||
// write field for visualisation
|
forAll(userBoxes, boxi)
|
||||||
volScalarField cohesiveZoneVol
|
{
|
||||||
(
|
if(userBoxes[boxi].contains(Cf.boundaryField()[patchI][faceI])) faceInsideBox = true;
|
||||||
IOobject
|
}
|
||||||
(
|
|
||||||
"cohesiveZoneVol",
|
if(faceInsideBox)
|
||||||
runTime.timeName(),
|
{
|
||||||
mesh,
|
cohesiveZone.boundaryField()[patchI][faceI] = 1.0;
|
||||||
IOobject::NO_READ,
|
}
|
||||||
IOobject::AUTO_WRITE
|
}
|
||||||
),
|
}
|
||||||
mesh,
|
|
||||||
dimensionedScalar("zero", dimless, 0.0)
|
|
||||||
);
|
|
||||||
forAll(cohesiveZone.internalField(), facei)
|
|
||||||
{
|
|
||||||
if(cohesiveZone.internalField()[facei])
|
|
||||||
{
|
|
||||||
cohesiveZoneVol.internalField()[mesh.owner()[facei]] = 1.0;
|
|
||||||
cohesiveZoneVol.internalField()[mesh.neighbour()[facei]] = 1.0;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
forAll(cohesiveZone.boundaryField(), patchi)
|
Info << "\nThere are " << gSum(cohesiveZone.internalField()) << " potential internal crack faces" << nl << endl;
|
||||||
{
|
Info << "\nThere are " << gSum(cohesiveZone.boundaryField())/2 << " potential coupled boundary crack faces" << nl << endl;
|
||||||
forAll(cohesiveZone.boundaryField()[patchi], facei)
|
|
||||||
|
// write field for visualisation
|
||||||
|
volScalarField cohesiveZoneVol
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"cohesiveZoneVol",
|
||||||
|
runTime.timeName(),
|
||||||
|
mesh,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
),
|
||||||
|
mesh,
|
||||||
|
dimensionedScalar("zero", dimless, 0.0)
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(cohesiveZone.internalField(), facei)
|
||||||
{
|
{
|
||||||
if(cohesiveZone.boundaryField()[patchi][facei] > 0.0)
|
if(cohesiveZone.internalField()[facei])
|
||||||
|
{
|
||||||
|
cohesiveZoneVol.internalField()[mesh.owner()[facei]] = 1.0;
|
||||||
|
cohesiveZoneVol.internalField()[mesh.neighbour()[facei]] = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(cohesiveZone.boundaryField(), patchi)
|
||||||
{
|
{
|
||||||
cohesiveZoneVol.boundaryField()[patchi][facei] = 1.0;
|
forAll(cohesiveZone.boundaryField()[patchi], facei)
|
||||||
|
{
|
||||||
|
if(cohesiveZone.boundaryField()[patchi][facei] > 0.0)
|
||||||
|
{
|
||||||
|
cohesiveZoneVol.boundaryField()[patchi][facei] = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
Info << "Writing cohesiveZone field" << endl;
|
||||||
}
|
cohesiveZoneVol.write();
|
||||||
Info << "Writing cohesiveZone field" << endl;
|
|
||||||
cohesiveZoneVol.write();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,8 @@
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedVector("zero", dimless, vector::zero)
|
dimensionedVector("zero", dimless, vector::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
volVectorField V
|
volVectorField V
|
||||||
|
@ -80,19 +80,19 @@
|
||||||
dimensionedSymmTensor("zero", dimForce/dimArea, symmTensor::zero)
|
dimensionedSymmTensor("zero", dimForce/dimArea, symmTensor::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
volVectorField divSigmaExp
|
volVectorField divSigmaExp
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"divSigmaExp",
|
"divSigmaExp",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedVector("zero", dimForce/dimVolume, vector::zero)
|
dimensionedVector("zero", dimForce/dimVolume, vector::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
constitutiveModel rheology(sigma, U);
|
constitutiveModel rheology(sigma, U);
|
||||||
|
|
||||||
|
@ -122,11 +122,12 @@
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedVector("zero", dimLength, vector::zero)
|
dimensionedVector("zero", dimLength, vector::zero)
|
||||||
);
|
);
|
||||||
// aitken relaxation factor
|
|
||||||
scalar aitkenInitialRes = 1.0;
|
// aitken relaxation factor
|
||||||
scalar aitkenTheta = 0.1;
|
scalar aitkenInitialRes = 1.0;
|
||||||
|
scalar aitkenTheta = 0.1;
|
||||||
|
|
||||||
// volVectorField resid
|
// volVectorField resid
|
||||||
// (
|
// (
|
||||||
|
@ -139,5 +140,5 @@ scalar aitkenTheta = 0.1;
|
||||||
// IOobject::AUTO_WRITE
|
// IOobject::AUTO_WRITE
|
||||||
// ),
|
// ),
|
||||||
// mesh,
|
// mesh,
|
||||||
// dimensionedVector("zero", dimless, vector::zero)
|
// dimensionedVector("zero", dimless, vector::zero)
|
||||||
// );
|
// );
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
OFstream * filePtr(NULL);
|
OFstream* filePtr(NULL);
|
||||||
word historyPatchName(mesh.solutionDict().subDict("solidMechanics").lookup("historyPatch"));
|
word historyPatchName(mesh.solutionDict().subDict("solidMechanics").lookup("historyPatch"));
|
||||||
label historyPatchID = mesh.boundaryMesh().findPatchID(historyPatchName);
|
label historyPatchID = mesh.boundaryMesh().findPatchID(historyPatchName);
|
||||||
if(historyPatchID == -1)
|
if(historyPatchID == -1)
|
||||||
{
|
{
|
||||||
Warning << "history patch " << historyPatchName
|
Warning << "history patch " << historyPatchName
|
||||||
<< " not found. Force-displacement will not be written"
|
<< " not found. Force-displacement will not be written"
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
else if(Pstream::master())
|
else if(Pstream::master())
|
||||||
{
|
{
|
||||||
Info << "Force-displacement for patch " << historyPatchName
|
Info << "Force-displacement for patch " << historyPatchName
|
||||||
<< " will be written to forceDisp.dat"
|
<< " will be written to forceDisp.dat"
|
||||||
<< endl;
|
<< endl;
|
||||||
|
@ -17,4 +17,4 @@ if(historyPatchID == -1)
|
||||||
filePtr = new OFstream(hisDirName/historyPatchName+"forceDisp.dat");
|
filePtr = new OFstream(hisDirName/historyPatchName+"forceDisp.dat");
|
||||||
OFstream& forceDispFile = *filePtr;
|
OFstream& forceDispFile = *filePtr;
|
||||||
forceDispFile << "#Disp(mm)\tForce(N)" << endl;
|
forceDispFile << "#Disp(mm)\tForce(N)" << endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,213 +58,212 @@ Author
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
# include "setRootCase.H"
|
# include "setRootCase.H"
|
||||||
# include "createTime.H"
|
# include "createTime.H"
|
||||||
# include "createCrackerMesh.H"
|
# include "createCrackerMesh.H"
|
||||||
# include "createFields.H"
|
# include "createFields.H"
|
||||||
# include "createCrack.H"
|
# include "createCrack.H"
|
||||||
//# include "createReference.H"
|
//# include "createReference.H"
|
||||||
# include "createHistory.H"
|
# include "createHistory.H"
|
||||||
# include "readDivSigmaExpMethod.H"
|
# include "readDivSigmaExpMethod.H"
|
||||||
# include "createSolidInterfaceNoModify.H"
|
# include "createSolidInterfaceNoModify.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Info<< "\nStarting time loop\n" << endl;
|
Info<< "\nStarting time loop\n" << endl;
|
||||||
|
|
||||||
lduMatrix::debug = 0;
|
lduMatrix::debug = 0;
|
||||||
|
|
||||||
scalar maxEffTractionFraction = 0;
|
scalar maxEffTractionFraction = 0;
|
||||||
|
|
||||||
// time rates for predictor
|
// time rates for predictor
|
||||||
volTensorField gradV = fvc::ddt(gradU);
|
volTensorField gradV = fvc::ddt(gradU);
|
||||||
surfaceVectorField snGradV =
|
surfaceVectorField snGradV =
|
||||||
(snGradU - snGradU.oldTime())/runTime.deltaT();
|
(snGradU - snGradU.oldTime())/runTime.deltaT();
|
||||||
|
|
||||||
//# include "initialiseSolution.H"
|
//# include "initialiseSolution.H"
|
||||||
|
|
||||||
while (runTime.run())
|
while (runTime.run())
|
||||||
{
|
{
|
||||||
# include "readSolidMechanicsControls.H"
|
# include "readSolidMechanicsControls.H"
|
||||||
# include "setDeltaT.H"
|
# include "setDeltaT.H"
|
||||||
|
|
||||||
runTime++;
|
runTime++;
|
||||||
|
|
||||||
Info<< "\nTime: " << runTime.timeName() << " s\n" << endl;
|
Info<< "\nTime = " << runTime.timeName() << " s\n" << endl;
|
||||||
|
|
||||||
volScalarField rho = rheology.rho();
|
volScalarField rho = rheology.rho();
|
||||||
volDiagTensorField K = rheology.K();
|
volDiagTensorField K = rheology.K();
|
||||||
surfaceDiagTensorField Kf = fvc::interpolate(K, "K");
|
surfaceDiagTensorField Kf = fvc::interpolate(K, "K");
|
||||||
volSymmTensor4thOrderField C = rheology.C();
|
volSymmTensor4thOrderField C = rheology.C();
|
||||||
surfaceSymmTensor4thOrderField Cf = fvc::interpolate(C, "C");
|
surfaceSymmTensor4thOrderField Cf = fvc::interpolate(C, "C");
|
||||||
|
|
||||||
solidInterfacePtr->modifyProperties(Cf, Kf);
|
solidInterfacePtr->modifyProperties(Cf, Kf);
|
||||||
|
|
||||||
//# include "waveCourantNo.H"
|
//# include "waveCourantNo.H"
|
||||||
|
|
||||||
int iCorr = 0;
|
int iCorr = 0;
|
||||||
lduMatrix::solverPerformance solverPerf;
|
lduMatrix::solverPerformance solverPerf;
|
||||||
scalar initialResidual = 0;
|
scalar initialResidual = 0;
|
||||||
scalar relativeResidual = 1;
|
scalar relativeResidual = 1;
|
||||||
//scalar forceResidual = 1;
|
//scalar forceResidual = 1;
|
||||||
label nFacesToBreak = 0;
|
label nFacesToBreak = 0;
|
||||||
label nCoupledFacesToBreak = 0;
|
label nCoupledFacesToBreak = 0;
|
||||||
bool topoChange = false;
|
bool topoChange = false;
|
||||||
|
|
||||||
//bool noMoreCracks = false;
|
//bool noMoreCracks = false;
|
||||||
|
|
||||||
// Predictor step using time rates
|
// Predictor step using time rates
|
||||||
if (predictor)
|
if (predictor)
|
||||||
{
|
{
|
||||||
Info << "Predicting U, gradU and snGradU using velocity"
|
Info<< "Predicting U, gradU and snGradU using velocity"
|
||||||
<< endl;
|
<< endl;
|
||||||
U += V*runTime.deltaT();
|
U += V*runTime.deltaT();
|
||||||
gradU += gradV*runTime.deltaT();
|
gradU += gradV*runTime.deltaT();
|
||||||
snGradU += snGradV*runTime.deltaT();
|
snGradU += snGradV*runTime.deltaT();
|
||||||
}
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
surfaceVectorField n = mesh.Sf()/mesh.magSf();
|
surfaceVectorField n = mesh.Sf()/mesh.magSf();
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
U.storePrevIter();
|
U.storePrevIter();
|
||||||
|
|
||||||
# include "calculateDivSigmaExp.H"
|
# include "calculateDivSigmaExp.H"
|
||||||
|
|
||||||
fvVectorMatrix UEqn
|
fvVectorMatrix UEqn
|
||||||
(
|
(
|
||||||
rho*fvm::d2dt2(U)
|
rho*fvm::d2dt2(U)
|
||||||
==
|
==
|
||||||
fvm::laplacian(Kf, U, "laplacian(K,U)")
|
fvm::laplacian(Kf, U, "laplacian(K,U)")
|
||||||
+ divSigmaExp
|
+ divSigmaExp
|
||||||
);
|
);
|
||||||
|
|
||||||
//# include "setReference.H"
|
//# include "setReference.H"
|
||||||
|
|
||||||
if(solidInterfacePtr)
|
if(solidInterfacePtr)
|
||||||
{
|
{
|
||||||
solidInterfacePtr->correct(UEqn);
|
solidInterfacePtr->correct(UEqn);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (relaxEqn)
|
if (relaxEqn)
|
||||||
{
|
{
|
||||||
UEqn.relax();
|
UEqn.relax();
|
||||||
}
|
}
|
||||||
|
|
||||||
solverPerf = UEqn.solve();
|
solverPerf = UEqn.solve();
|
||||||
|
|
||||||
if (aitkenRelax)
|
if (aitkenRelax)
|
||||||
{
|
{
|
||||||
# include "aitkenRelaxation.H"
|
# include "aitkenRelaxation.H"
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
U.relax();
|
U.relax();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iCorr == 0)
|
if (iCorr == 0)
|
||||||
{
|
{
|
||||||
initialResidual = solverPerf.initialResidual();
|
initialResidual = solverPerf.initialResidual();
|
||||||
aitkenInitialRes = gMax(mag(U.internalField()));
|
aitkenInitialRes = gMax(mag(U.internalField()));
|
||||||
}
|
}
|
||||||
|
|
||||||
//gradU = solidInterfacePtr->grad(U);
|
//gradU = solidInterfacePtr->grad(U);
|
||||||
// use leastSquaresSolidInterface grad scheme
|
// use leastSquaresSolidInterface grad scheme
|
||||||
gradU = fvc::grad(U);
|
gradU = fvc::grad(U);
|
||||||
|
|
||||||
|
# include "calculateRelativeResidual.H"
|
||||||
|
|
||||||
# include "calculateRelativeResidual.H"
|
if (iCorr % infoFrequency == 0)
|
||||||
|
{
|
||||||
|
Info<< "\tTime " << runTime.value()
|
||||||
|
<< ", Corr " << iCorr
|
||||||
|
<< ", Solving for " << U.name()
|
||||||
|
<< " using " << solverPerf.solverName()
|
||||||
|
<< ", res = " << solverPerf.initialResidual()
|
||||||
|
<< ", rel res = " << relativeResidual;
|
||||||
|
if (aitkenRelax)
|
||||||
|
{
|
||||||
|
Info << ", aitken = " << aitkenTheta;
|
||||||
|
}
|
||||||
|
Info << ", inner iters " << solverPerf.nIterations() << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while
|
||||||
|
(
|
||||||
|
//iCorr++ == 0
|
||||||
|
iCorr++ < 10
|
||||||
|
||
|
||||||
|
(
|
||||||
|
//solverPerf.initialResidual() > convergenceTolerance
|
||||||
|
relativeResidual > convergenceTolerance
|
||||||
|
&& iCorr < nCorr
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
if (iCorr % infoFrequency == 0)
|
Info<< "Solving for " << U.name() << " using "
|
||||||
{
|
<< solverPerf.solverName()
|
||||||
Info << "\tTime " << runTime.value()
|
<< ", Initial residual = " << initialResidual
|
||||||
<< ", Corr " << iCorr
|
<< ", Final residual = " << solverPerf.initialResidual()
|
||||||
<< ", Solving for " << U.name()
|
<< ", No outer iterations " << iCorr
|
||||||
<< " using " << solverPerf.solverName()
|
<< ", Relative residual " << relativeResidual << endl;
|
||||||
<< ", res = " << solverPerf.initialResidual()
|
|
||||||
<< ", rel res = " << relativeResidual;
|
|
||||||
if (aitkenRelax)
|
|
||||||
{
|
|
||||||
Info << ", aitken = " << aitkenTheta;
|
|
||||||
}
|
|
||||||
Info << ", inner iters " << solverPerf.nIterations() << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while
|
|
||||||
(
|
|
||||||
//iCorr++ == 0
|
|
||||||
iCorr++ < 10
|
|
||||||
||
|
|
||||||
(
|
|
||||||
//solverPerf.initialResidual() > convergenceTolerance
|
|
||||||
relativeResidual > convergenceTolerance
|
|
||||||
&&
|
|
||||||
iCorr < nCorr
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
Info<< "Solving for " << U.name() << " using "
|
# include "calculateTraction.H"
|
||||||
<< solverPerf.solverName()
|
# include "updateCrack.H"
|
||||||
<< ", Initial residual = " << initialResidual
|
|
||||||
<< ", Final residual = " << solverPerf.initialResidual()
|
|
||||||
<< ", No outer iterations " << iCorr
|
|
||||||
<< ", Relative residual " << relativeResidual << endl;
|
|
||||||
|
|
||||||
# include "calculateTraction.H"
|
Info<< "Max effective traction fraction: "
|
||||||
# include "updateCrack.H"
|
<< maxEffTractionFraction << endl;
|
||||||
|
|
||||||
Info << "Max effective traction fraction: "
|
// reset counter if faces want to crack
|
||||||
<< maxEffTractionFraction << endl;
|
if ((nFacesToBreak > 0) || (nCoupledFacesToBreak > 0)) iCorr = 0;
|
||||||
|
}
|
||||||
|
while( (nFacesToBreak > 0) || (nCoupledFacesToBreak > 0));
|
||||||
|
|
||||||
// reset counter if faces want to crack
|
if (cohesivePatchUPtr)
|
||||||
if ((nFacesToBreak > 0) || (nCoupledFacesToBreak > 0)) iCorr = 0;
|
{
|
||||||
}
|
if (returnReduce(cohesivePatchUPtr->size(), sumOp<label>()))
|
||||||
while( (nFacesToBreak > 0) || (nCoupledFacesToBreak > 0));
|
{
|
||||||
|
cohesivePatchUPtr->cracking();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
returnReduce
|
||||||
|
(
|
||||||
|
cohesivePatchUFixedModePtr->size(),
|
||||||
|
sumOp<label>()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Pout << "Number of faces in crack: "
|
||||||
|
<< cohesivePatchUFixedModePtr->size() << endl;
|
||||||
|
cohesivePatchUFixedModePtr->relativeSeparationDistance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (cohesivePatchUPtr)
|
// update time rates for predictor
|
||||||
{
|
if (predictor)
|
||||||
if (returnReduce(cohesivePatchUPtr->size(), sumOp<label>()))
|
{
|
||||||
{
|
V = fvc::ddt(U);
|
||||||
cohesivePatchUPtr->cracking();
|
gradV = fvc::ddt(gradU);
|
||||||
}
|
snGradV = (snGradU - snGradU.oldTime())/runTime.deltaT();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if
|
|
||||||
(
|
|
||||||
returnReduce
|
|
||||||
(
|
|
||||||
cohesivePatchUFixedModePtr->size(),
|
|
||||||
sumOp<label>())
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Pout << "Number of faces in crack: "
|
|
||||||
<< cohesivePatchUFixedModePtr->size() << endl;
|
|
||||||
cohesivePatchUFixedModePtr->relativeSeparationDistance();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// update time rates for predictor
|
# include "calculateEpsilonSigma.H"
|
||||||
if (predictor)
|
# include "writeFields.H"
|
||||||
{
|
# include "writeHistory.H"
|
||||||
V = fvc::ddt(U);
|
|
||||||
gradV = fvc::ddt(gradU);
|
|
||||||
snGradV = (snGradU - snGradU.oldTime())/runTime.deltaT();
|
|
||||||
}
|
|
||||||
|
|
||||||
# include "calculateEpsilonSigma.H"
|
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||||
# include "writeFields.H"
|
<< " ClockTime = " << runTime.elapsedClockTime() << " s\n\n"
|
||||||
# include "writeHistory.H"
|
<< endl;
|
||||||
|
|
||||||
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
|
||||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s\n\n"
|
|
||||||
<< endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "End\n" << endl;
|
Info<< "End\n" << endl;
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,8 @@ word divSigmaExpMethod(mesh.solutionDict().subDict("solidMechanics").lookup("div
|
||||||
Info << "Selecting divSigmaExp calculation method " << divSigmaExpMethod << endl;
|
Info << "Selecting divSigmaExp calculation method " << divSigmaExpMethod << endl;
|
||||||
// if(divSigmaExpMethod != "standard" && divSigmaExpMethod != "surface" && divSigmaExpMethod != "decompose" && divSigmaExpMethod != "laplacian")
|
// if(divSigmaExpMethod != "standard" && divSigmaExpMethod != "surface" && divSigmaExpMethod != "decompose" && divSigmaExpMethod != "laplacian")
|
||||||
if(divSigmaExpMethod != "standard" && divSigmaExpMethod != "surface" && divSigmaExpMethod != "laplacian")
|
if(divSigmaExpMethod != "standard" && divSigmaExpMethod != "surface" && divSigmaExpMethod != "laplacian")
|
||||||
{
|
{
|
||||||
FatalError << "divSigmaExp method " << divSigmaExpMethod << " not found!" << nl
|
FatalError << "divSigmaExp method " << divSigmaExpMethod << " not found!" << nl
|
||||||
<< "valid methods are:\nstandard\nsurface\nlaplacian"
|
<< "valid methods are:\nstandard\nsurface\nlaplacian"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ Switch aitkenRelax(stressControl.lookup("aitkenRelaxation"));
|
||||||
Switch relaxEqn(stressControl.lookup("relaxEqn"));
|
Switch relaxEqn(stressControl.lookup("relaxEqn"));
|
||||||
|
|
||||||
if(relaxEqn && solidInterfaceCorr)
|
if(relaxEqn && solidInterfaceCorr)
|
||||||
{
|
{
|
||||||
FatalError << "relaxEqn and solidInterface may not be used concurrently"
|
FatalError << "relaxEqn and solidInterface may not be used concurrently"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +1,36 @@
|
||||||
if (dynamicTimeStep)
|
if (dynamicTimeStep)
|
||||||
{
|
{
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
//(maxEffTraction < 0.999*CzLaw.sigmaMax().value())
|
//(maxEffTraction < 0.999*CzLaw.sigmaMax().value())
|
||||||
(returnReduce(maxEffTractionFraction, maxOp<scalar>()) < 0.99)
|
(returnReduce(maxEffTractionFraction, maxOp<scalar>()) < 0.99)
|
||||||
//&& (cohesivePatchU.size() == 0)
|
//&& (cohesivePatchU.size() == 0)
|
||||||
&& (mag(runTime.deltaT().value() - deltaTmax) < SMALL)
|
&& (mag(runTime.deltaT().value() - deltaTmax) < SMALL)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
runTime.setDeltaT(deltaTmax);
|
runTime.setDeltaT(deltaTmax);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
scalar newDeltaT = deltaTmin;
|
scalar newDeltaT = deltaTmin;
|
||||||
|
|
||||||
if (newDeltaT/runTime.deltaT().value() < 0.5)
|
if (newDeltaT/runTime.deltaT().value() < 0.5)
|
||||||
{
|
{
|
||||||
newDeltaT = 0.5*runTime.deltaT().value();
|
newDeltaT = 0.5*runTime.deltaT().value();
|
||||||
Info << "Reducing time step" << nl;
|
Info << "Reducing time step" << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
runTime.setDeltaT(newDeltaT);
|
runTime.setDeltaT(newDeltaT);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pout << "Current time step size: "
|
Pout << "Current time step size: "
|
||||||
<< runTime.deltaT().value() << " s" << endl;
|
<< runTime.deltaT().value() << " s" << endl;
|
||||||
|
|
||||||
scalar maxDT = runTime.deltaT().value();
|
scalar maxDT = runTime.deltaT().value();
|
||||||
|
|
||||||
if(mag(returnReduce(maxDT, maxOp<scalar>()) - runTime.deltaT().value()) > SMALL)
|
if(mag(returnReduce(maxDT, maxOp<scalar>()) - runTime.deltaT().value()) > SMALL)
|
||||||
{
|
{
|
||||||
FatalError << "Processors have different time-steps!"
|
FatalError << "Processors have different time-steps!"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ nCoupledFacesToBreak = 0;
|
||||||
//scalarField effTractionFraction = effTraction/sigmaMax;
|
//scalarField effTractionFraction = effTraction/sigmaMax;
|
||||||
scalarField effTractionFraction(normalTraction.size(), 0.0);
|
scalarField effTractionFraction(normalTraction.size(), 0.0);
|
||||||
|
|
||||||
if (cohesivePatchUPtr)
|
if(cohesivePatchUPtr)
|
||||||
{
|
{
|
||||||
effTractionFraction =
|
effTractionFraction =
|
||||||
(normalTraction/sigmaMaxI)*(normalTraction/sigmaMaxI)
|
(normalTraction/sigmaMaxI)*(normalTraction/sigmaMaxI)
|
||||||
|
@ -41,6 +41,7 @@ nCoupledFacesToBreak = 0;
|
||||||
(normalTraction/sigmaMaxI)*(normalTraction/sigmaMaxI)
|
(normalTraction/sigmaMaxI)*(normalTraction/sigmaMaxI)
|
||||||
+ (shearTraction/sigmaMaxI)*(shearTraction/sigmaMaxI);
|
+ (shearTraction/sigmaMaxI)*(shearTraction/sigmaMaxI);
|
||||||
}
|
}
|
||||||
|
|
||||||
maxEffTractionFraction = gMax(effTractionFraction);
|
maxEffTractionFraction = gMax(effTractionFraction);
|
||||||
|
|
||||||
SLList<label> facesToBreakList;
|
SLList<label> facesToBreakList;
|
||||||
|
@ -85,7 +86,6 @@ nCoupledFacesToBreak = 0;
|
||||||
{
|
{
|
||||||
faceToBreakEffTractionFraction =
|
faceToBreakEffTractionFraction =
|
||||||
facesToBreakEffTractionFraction[faceI];
|
facesToBreakEffTractionFraction[faceI];
|
||||||
|
|
||||||
faceToBreakIndex = facesToBreak[faceI];
|
faceToBreakIndex = facesToBreak[faceI];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,59 +135,59 @@ nCoupledFacesToBreak = 0;
|
||||||
if (mesh.boundary()[patchI].coupled())
|
if (mesh.boundary()[patchI].coupled())
|
||||||
{
|
{
|
||||||
// scalarField pEffTraction =
|
// scalarField pEffTraction =
|
||||||
// cohesiveZone.boundaryField()[patchI] *
|
// cohesiveZone.boundaryField()[patchI]*
|
||||||
// mag(traction.boundaryField()[patchI]);
|
// mag(traction.boundaryField()[patchI]);
|
||||||
// scalarField pEffTractionFraction = pEffTraction/sigmaMax.boundaryField()[patchI];
|
// scalarField pEffTractionFraction = pEffTraction/sigmaMax.boundaryField()[patchI];
|
||||||
|
|
||||||
scalarField pNormalTraction =
|
scalarField pNormalTraction =
|
||||||
cohesiveZone.boundaryField()[patchI] *
|
cohesiveZone.boundaryField()[patchI]*
|
||||||
( n.boundaryField()[patchI] & traction.boundaryField()[patchI] );
|
( n.boundaryField()[patchI] & traction.boundaryField()[patchI] );
|
||||||
|
|
||||||
// only consider tensile tractions
|
// only consider tensile tractions
|
||||||
pNormalTraction = max(pNormalTraction, scalar(0));
|
pNormalTraction = max(pNormalTraction, scalar(0));
|
||||||
scalarField pShearTraction =
|
|
||||||
cohesiveZone.boundaryField()[patchI] *
|
|
||||||
mag( (I - Foam::sqr(n.boundaryField()[patchI])) & traction.boundaryField()[patchI] );
|
|
||||||
|
|
||||||
// the traction fraction is monitored to decide which faces to break:
|
scalarField pShearTraction =
|
||||||
// ie (tN/tNC)^2 + (tS/tSC)^2 >1 to crack a face
|
cohesiveZone.boundaryField()[patchI]*
|
||||||
const scalarField& pSigmaMax = sigmaMax.boundaryField()[patchI];
|
mag( (I - Foam::sqr(n.boundaryField()[patchI])) & traction.boundaryField()[patchI] );
|
||||||
const scalarField& pTauMax = tauMax.boundaryField()[patchI];
|
|
||||||
|
|
||||||
scalarField pEffTractionFraction(pNormalTraction.size(), 0);
|
// the traction fraction is monitored to decide which faces to break:
|
||||||
|
// ie (tN/tNC)^2 + (tS/tSC)^2 >1 to crack a face
|
||||||
|
const scalarField& pSigmaMax = sigmaMax.boundaryField()[patchI];
|
||||||
|
const scalarField& pTauMax = tauMax.boundaryField()[patchI];
|
||||||
|
|
||||||
if(cohesivePatchUPtr)
|
scalarField pEffTractionFraction(pNormalTraction.size(), 0.0);
|
||||||
{
|
if(cohesivePatchUPtr)
|
||||||
pEffTractionFraction =
|
{
|
||||||
(pNormalTraction/pSigmaMax)*(pNormalTraction/pSigmaMax)
|
pEffTractionFraction =
|
||||||
+ (pShearTraction/pTauMax)*(pShearTraction/pTauMax);
|
(pNormalTraction/pSigmaMax)*(pNormalTraction/pSigmaMax)
|
||||||
}
|
+ (pShearTraction/pTauMax)*(pShearTraction/pTauMax);
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
// solidCohesiveFixedModeMix only uses sigmaMax
|
{
|
||||||
pEffTractionFraction =
|
// solidCohesiveFixedModeMix only uses sigmaMax
|
||||||
(pNormalTraction/pSigmaMax)*(pNormalTraction/pSigmaMax)
|
pEffTractionFraction =
|
||||||
+ (pShearTraction/pSigmaMax)*(pShearTraction/pSigmaMax);
|
(pNormalTraction/pSigmaMax)*(pNormalTraction/pSigmaMax)
|
||||||
}
|
+ (pShearTraction/pSigmaMax)*(pShearTraction/pSigmaMax);
|
||||||
|
}
|
||||||
|
|
||||||
label start = mesh.boundaryMesh()[patchI].start();
|
label start = mesh.boundaryMesh()[patchI].start();
|
||||||
|
|
||||||
forAll(pEffTractionFraction, faceI)
|
forAll(pEffTractionFraction, faceI)
|
||||||
{
|
{
|
||||||
if (pEffTractionFraction[faceI] > maxEffTractionFraction)
|
if (pEffTractionFraction[faceI] > maxEffTractionFraction)
|
||||||
{
|
{
|
||||||
maxEffTractionFraction = pEffTractionFraction[faceI];
|
maxEffTractionFraction = pEffTractionFraction[faceI];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pEffTractionFraction[faceI] > 1.0)
|
if (pEffTractionFraction[faceI] > 1.0)
|
||||||
{
|
{
|
||||||
coupledFacesToBreakList.insert(start + faceI);
|
coupledFacesToBreakList.insert(start + faceI);
|
||||||
coupledFacesToBreakEffTractionFractionList.insert
|
coupledFacesToBreakEffTractionFractionList.insert
|
||||||
(
|
(
|
||||||
pEffTractionFraction[faceI]
|
pEffTractionFraction[faceI]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,8 +274,8 @@ nCoupledFacesToBreak = 0;
|
||||||
labelList index(Pstream::nProcs(), -1);
|
labelList index(Pstream::nProcs(), -1);
|
||||||
if (nCoupledFacesToBreak)
|
if (nCoupledFacesToBreak)
|
||||||
{
|
{
|
||||||
label patchID =
|
label patchID =
|
||||||
mesh.boundaryMesh().whichPatch(coupledFaceToBreakIndex);
|
mesh.boundaryMesh().whichPatch(coupledFaceToBreakIndex);
|
||||||
|
|
||||||
label start = mesh.boundaryMesh()[patchID].start();
|
label start = mesh.boundaryMesh()[patchID].start();
|
||||||
label localIndex = coupledFaceToBreakIndex - start;
|
label localIndex = coupledFaceToBreakIndex - start;
|
||||||
|
@ -333,6 +333,7 @@ nCoupledFacesToBreak = 0;
|
||||||
vector faceToBreakNormal = vector::zero;
|
vector faceToBreakNormal = vector::zero;
|
||||||
scalar faceToBreakSigmaMax = 0.0;
|
scalar faceToBreakSigmaMax = 0.0;
|
||||||
scalar faceToBreakTauMax = 0.0;
|
scalar faceToBreakTauMax = 0.0;
|
||||||
|
|
||||||
// Set faces to break
|
// Set faces to break
|
||||||
if (nFacesToBreak > 0)
|
if (nFacesToBreak > 0)
|
||||||
{
|
{
|
||||||
|
@ -340,31 +341,39 @@ nCoupledFacesToBreak = 0;
|
||||||
faceToBreakNormal = n.internalField()[faceToBreakIndex];
|
faceToBreakNormal = n.internalField()[faceToBreakIndex];
|
||||||
|
|
||||||
// Scale broken face traction
|
// Scale broken face traction
|
||||||
faceToBreakSigmaMax = sigmaMaxI[faceToBreakIndex];
|
faceToBreakSigmaMax = sigmaMaxI[faceToBreakIndex];
|
||||||
faceToBreakTauMax = tauMaxI[faceToBreakIndex];
|
faceToBreakTauMax = tauMaxI[faceToBreakIndex];
|
||||||
scalar normalTrac = faceToBreakNormal & faceToBreakTraction;
|
scalar normalTrac = faceToBreakNormal & faceToBreakTraction;
|
||||||
normalTrac = max(normalTrac, 0.0);
|
normalTrac = max(normalTrac, 0.0);
|
||||||
scalar shearTrac = mag( (I - sqr(faceToBreakNormal)) & faceToBreakTraction );
|
scalar shearTrac = mag( (I - sqr(faceToBreakNormal)) & faceToBreakTraction );
|
||||||
scalar scaleFactor = 1;
|
scalar scaleFactor = 1;
|
||||||
if(cohesivePatchUPtr)
|
if(cohesivePatchUPtr)
|
||||||
{
|
|
||||||
scaleFactor =
|
|
||||||
::sqrt(1 / (
|
|
||||||
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
|
|
||||||
+ (shearTrac/faceToBreakTauMax)*(shearTrac/faceToBreakTauMax)
|
|
||||||
) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// solidCohesiveFixedModeMix only uses sigmaMax
|
scaleFactor =
|
||||||
scaleFactor =
|
Foam::sqrt
|
||||||
::sqrt(1 / (
|
(
|
||||||
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
|
1 /
|
||||||
+ (shearTrac/faceToBreakSigmaMax)*(shearTrac/faceToBreakSigmaMax)
|
(
|
||||||
) );
|
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
|
||||||
|
+ (shearTrac/faceToBreakTauMax)*(shearTrac/faceToBreakTauMax)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// solidCohesiveFixedModeMix only uses sigmaMax
|
||||||
|
scaleFactor =
|
||||||
|
Foam::sqrt
|
||||||
|
(
|
||||||
|
1 /
|
||||||
|
(
|
||||||
|
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
|
||||||
|
+ (shearTrac/faceToBreakSigmaMax)*(shearTrac/faceToBreakSigmaMax)
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
faceToBreakTraction *= scaleFactor;
|
faceToBreakTraction *= scaleFactor;
|
||||||
|
|
||||||
topoChange = true;
|
topoChange = true;
|
||||||
}
|
}
|
||||||
|
@ -379,29 +388,37 @@ nCoupledFacesToBreak = 0;
|
||||||
faceToBreakNormal = n.boundaryField()[patchID][localIndex];
|
faceToBreakNormal = n.boundaryField()[patchID][localIndex];
|
||||||
|
|
||||||
// Scale broken face traction
|
// Scale broken face traction
|
||||||
faceToBreakSigmaMax = sigmaMax.boundaryField()[patchID][localIndex];
|
faceToBreakSigmaMax = sigmaMax.boundaryField()[patchID][localIndex];
|
||||||
faceToBreakTauMax = tauMax.boundaryField()[patchID][localIndex];
|
faceToBreakTauMax = tauMax.boundaryField()[patchID][localIndex];
|
||||||
scalar normalTrac = faceToBreakNormal & faceToBreakTraction;
|
scalar normalTrac = faceToBreakNormal & faceToBreakTraction;
|
||||||
normalTrac = max(normalTrac, 0.0);
|
normalTrac = max(normalTrac, 0.0);
|
||||||
scalar shearTrac = mag( (I - sqr(faceToBreakNormal)) & faceToBreakTraction );
|
scalar shearTrac = mag( (I - sqr(faceToBreakNormal)) & faceToBreakTraction );
|
||||||
scalar scaleFactor = 1;
|
scalar scaleFactor = 1;
|
||||||
if(cohesivePatchUPtr)
|
if(cohesivePatchUPtr)
|
||||||
{
|
{
|
||||||
scaleFactor =
|
scaleFactor =
|
||||||
::sqrt(1 / (
|
Foam::sqrt
|
||||||
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
|
(
|
||||||
+ (shearTrac/faceToBreakTauMax)*(shearTrac/faceToBreakTauMax)
|
1 /
|
||||||
) );
|
(
|
||||||
}
|
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
|
||||||
else
|
+ (shearTrac/faceToBreakTauMax)*(shearTrac/faceToBreakTauMax)
|
||||||
{
|
)
|
||||||
// solidCohesiveFixedModeMix only uses sigmaMax
|
);
|
||||||
scaleFactor =
|
}
|
||||||
::sqrt(1 / (
|
else
|
||||||
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
|
{
|
||||||
+ (shearTrac/faceToBreakSigmaMax)*(shearTrac/faceToBreakSigmaMax)
|
// solidCohesiveFixedModeMix only uses sigmaMax
|
||||||
) );
|
scaleFactor =
|
||||||
}
|
Foam::sqrt
|
||||||
|
(
|
||||||
|
1 /
|
||||||
|
(
|
||||||
|
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
|
||||||
|
+ (shearTrac/faceToBreakSigmaMax)*(shearTrac/faceToBreakSigmaMax)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
faceToBreakTraction *= scaleFactor;
|
faceToBreakTraction *= scaleFactor;
|
||||||
|
|
||||||
|
@ -441,20 +458,20 @@ nCoupledFacesToBreak = 0;
|
||||||
Cf = fvc::interpolate(C);
|
Cf = fvc::interpolate(C);
|
||||||
Kf = fvc::interpolate(K);
|
Kf = fvc::interpolate(K);
|
||||||
|
|
||||||
// we need to modify propertiess after cracking otherwise momentum equation is wrong
|
// we need to modify propertiess after cracking otherwise momentum equation is wrong
|
||||||
// but solidInterface seems to hold some information about old mesh
|
// but solidInterface seems to hold some information about old mesh
|
||||||
// so we will delete it and make another
|
// so we will delete it and make another
|
||||||
// we could probably add a public clearout function
|
// we could probably add a public clearout function
|
||||||
// create new solidInterface
|
// create new solidInterface
|
||||||
//Pout << "Creating new solidInterface" << endl;
|
//Pout << "Creating new solidInterface" << endl;
|
||||||
//delete solidInterfacePtr;
|
//delete solidInterfacePtr;
|
||||||
//solidInterfacePtr = new solidInterface(mesh, rheology);
|
//solidInterfacePtr = new solidInterface(mesh, rheology);
|
||||||
// delete demand driven data as the mesh has changed
|
// delete demand driven data as the mesh has changed
|
||||||
if(rheology.solidInterfaceActive())
|
if(rheology.solidInterfaceActive())
|
||||||
{
|
{
|
||||||
rheology.solInterface().clearOut();
|
rheology.solInterface().clearOut();
|
||||||
solidInterfacePtr->modifyProperties(Cf, Kf);
|
solidInterfacePtr->modifyProperties(Cf, Kf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Local crack displacement
|
// Local crack displacement
|
||||||
vectorField UpI =
|
vectorField UpI =
|
||||||
|
@ -466,21 +483,21 @@ nCoupledFacesToBreak = 0;
|
||||||
vectorField globalUpI = mesh.globalCrackField(UpI);
|
vectorField globalUpI = mesh.globalCrackField(UpI);
|
||||||
vectorField globalOldUpI = mesh.globalCrackField(oldUpI);
|
vectorField globalOldUpI = mesh.globalCrackField(oldUpI);
|
||||||
|
|
||||||
// C and K field on new crack faces must be updated
|
// C and K field on new crack faces must be updated
|
||||||
symmTensor4thOrderField CPI = C.boundaryField()[cohesivePatchID].patchInternalField();
|
symmTensor4thOrderField CPI = C.boundaryField()[cohesivePatchID].patchInternalField();
|
||||||
diagTensorField KPI = K.boundaryField()[cohesivePatchID].patchInternalField();
|
diagTensorField KPI = K.boundaryField()[cohesivePatchID].patchInternalField();
|
||||||
symmTensor4thOrderField globalCPI = mesh.globalCrackField(CPI);
|
symmTensor4thOrderField globalCPI = mesh.globalCrackField(CPI);
|
||||||
diagTensorField globalKPI = mesh.globalCrackField(KPI);
|
diagTensorField globalKPI = mesh.globalCrackField(KPI);
|
||||||
|
|
||||||
// cohesivePatchU.size()
|
// cohesivePatchU.size()
|
||||||
int cohesivePatchSize(cohesivePatchUPtr ? cohesivePatchUPtr->size() : cohesivePatchUFixedModePtr->size());
|
int cohesivePatchSize(cohesivePatchUPtr ? cohesivePatchUPtr->size() : cohesivePatchUFixedModePtr->size());
|
||||||
|
|
||||||
// Initialise U for new cohesive face
|
// Initialise U for new cohesive face
|
||||||
const labelList& gcfa = mesh.globalCrackFaceAddressing();
|
const labelList& gcfa = mesh.globalCrackFaceAddressing();
|
||||||
label globalIndex = mesh.localCrackStart();
|
label globalIndex = mesh.localCrackStart();
|
||||||
// for (label i=0; i<cohesivePatchU.size(); i++)
|
// for (label i=0; i<cohesivePatchU.size(); i++)
|
||||||
for (label i=0; i<cohesivePatchSize; i++)
|
for (label i=0; i<cohesivePatchSize; i++)
|
||||||
{
|
{
|
||||||
label oldFaceIndex = faceMap[start+i];
|
label oldFaceIndex = faceMap[start+i];
|
||||||
|
|
||||||
// If new face
|
// If new face
|
||||||
|
@ -499,10 +516,10 @@ nCoupledFacesToBreak = 0;
|
||||||
+ globalOldUpI[gcfa[globalIndex]]
|
+ globalOldUpI[gcfa[globalIndex]]
|
||||||
);
|
);
|
||||||
|
|
||||||
// initialise C and K on new faces
|
// initialise C and K on new faces
|
||||||
// set new face value to value of internal cell
|
// set new face value to value of internal cell
|
||||||
Cf.boundaryField()[cohesivePatchID][i] = globalCPI[globalIndex];
|
Cf.boundaryField()[cohesivePatchID][i] = globalCPI[globalIndex];
|
||||||
Kf.boundaryField()[cohesivePatchID][i] = globalKPI[globalIndex];
|
Kf.boundaryField()[cohesivePatchID][i] = globalKPI[globalIndex];
|
||||||
|
|
||||||
globalIndex++;
|
globalIndex++;
|
||||||
}
|
}
|
||||||
|
@ -513,87 +530,85 @@ nCoupledFacesToBreak = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we must calculate grad using interface
|
// we must calculate grad using interface
|
||||||
// U at the interface has not been calculated yet as interface.correct()
|
// U at the interface has not been calculated yet as interface.correct()
|
||||||
// has not been called yet
|
// has not been called yet
|
||||||
// not really a problem as gradU is correct in second outer iteration
|
// not really a problem as gradU is correct in second outer iteration
|
||||||
// as long as this does not cause convergence problems for the first iterations.
|
// as long as this does not cause convergence problems for the first iterations.
|
||||||
// we should be able to calculate the interface displacements without
|
// we should be able to calculate the interface displacements without
|
||||||
// having to call interface.correct()
|
// having to call interface.correct()
|
||||||
// todo: add calculateInterfaceU() function
|
// todo: add calculateInterfaceU() function
|
||||||
// interface grad uses Gauss, we need least squares
|
// interface grad uses Gauss, we need least squares
|
||||||
//gradU = solidInterfacePtr->grad(U);
|
//gradU = solidInterfacePtr->grad(U);
|
||||||
gradU = fvc::grad(U); // leastSquaresSolidInterface grad scheme
|
gradU = fvc::grad(U); // leastSquaresSolidInterface grad scheme
|
||||||
//snGradU = fvc::snGrad(U);
|
//snGradU = fvc::snGrad(U);
|
||||||
|
|
||||||
# include "calculateTraction.H"
|
# include "calculateTraction.H"
|
||||||
//if (nFacesToBreak || nCoupledFacesToBreak) mesh.write(); traction.write();
|
//if (nFacesToBreak || nCoupledFacesToBreak) mesh.write(); traction.write();
|
||||||
|
|
||||||
// Initialise initiation traction for new cohesive patch face
|
// Initialise initiation traction for new cohesive patch face
|
||||||
// for (label i=0; i<cohesivePatchU.size(); i++)
|
// for (label i=0; i<cohesivePatchU.size(); i++)
|
||||||
for (label i=0; i<cohesivePatchSize; i++)
|
for (label i=0; i<cohesivePatchSize; i++)
|
||||||
{
|
|
||||||
label oldFaceIndex = faceMap[start+i];
|
|
||||||
|
|
||||||
// If new face
|
|
||||||
if
|
|
||||||
(
|
|
||||||
(oldFaceIndex == faceToBreakIndex)
|
|
||||||
|| (oldFaceIndex == coupledFaceToBreakIndex)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
vector n0 =
|
label oldFaceIndex = faceMap[start+i];
|
||||||
mesh.Sf().boundaryField()[cohesivePatchID][i]
|
|
||||||
/mesh.magSf().boundaryField()[cohesivePatchID][i];
|
|
||||||
//vector n1 = -n0;
|
|
||||||
|
|
||||||
if ((n0&faceToBreakNormal) > SMALL)
|
// If new face
|
||||||
|
if
|
||||||
|
(
|
||||||
|
(oldFaceIndex == faceToBreakIndex)
|
||||||
|
|| (oldFaceIndex == coupledFaceToBreakIndex)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
traction.boundaryField()[cohesivePatchID][i] =
|
vector n0 =
|
||||||
faceToBreakTraction;
|
mesh.Sf().boundaryField()[cohesivePatchID][i]
|
||||||
|
/mesh.magSf().boundaryField()[cohesivePatchID][i];
|
||||||
|
//vector n1 = -n0;
|
||||||
|
|
||||||
traction.oldTime().boundaryField()[cohesivePatchID][i] =
|
if ((n0 & faceToBreakNormal) > SMALL)
|
||||||
faceToBreakTraction;
|
|
||||||
|
|
||||||
if(cohesivePatchUPtr)
|
|
||||||
{
|
{
|
||||||
cohesivePatchUPtr->traction()[i] = faceToBreakTraction;
|
traction.boundaryField()[cohesivePatchID][i] =
|
||||||
|
faceToBreakTraction;
|
||||||
|
|
||||||
|
traction.oldTime().boundaryField()[cohesivePatchID][i] =
|
||||||
|
faceToBreakTraction;
|
||||||
|
|
||||||
|
if(cohesivePatchUPtr)
|
||||||
|
{
|
||||||
|
cohesivePatchUPtr->traction()[i] = faceToBreakTraction;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cohesivePatchUFixedModePtr->traction()[i] =
|
||||||
|
faceToBreakTraction;
|
||||||
|
|
||||||
|
cohesivePatchUFixedModePtr->initiationTraction()[i] =
|
||||||
|
faceToBreakTraction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cohesivePatchUFixedModePtr->traction()[i] =
|
traction.boundaryField()[cohesivePatchID][i] =
|
||||||
faceToBreakTraction;
|
-faceToBreakTraction;
|
||||||
|
traction.oldTime().boundaryField()[cohesivePatchID][i] =
|
||||||
cohesivePatchUFixedModePtr->initiationTraction()[i] =
|
|
||||||
faceToBreakTraction;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
traction.boundaryField()[cohesivePatchID][i] =
|
|
||||||
-faceToBreakTraction;
|
|
||||||
|
|
||||||
traction.oldTime().boundaryField()[cohesivePatchID][i] =
|
|
||||||
-faceToBreakTraction;
|
|
||||||
|
|
||||||
//cohesivePatchU.traction()[i] = -faceToBreakTraction;
|
|
||||||
if(cohesivePatchUPtr)
|
|
||||||
{
|
|
||||||
cohesivePatchUPtr->traction()[i] = -faceToBreakTraction;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cohesivePatchUFixedModePtr->traction()[i] =
|
|
||||||
-faceToBreakTraction;
|
-faceToBreakTraction;
|
||||||
|
|
||||||
cohesivePatchUFixedModePtr->initiationTraction()[i] =
|
//cohesivePatchU.traction()[i] = -faceToBreakTraction;
|
||||||
-faceToBreakTraction;
|
if(cohesivePatchUPtr)
|
||||||
|
{
|
||||||
|
cohesivePatchUPtr->traction()[i] = -faceToBreakTraction;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cohesivePatchUFixedModePtr->traction()[i] =
|
||||||
|
-faceToBreakTraction;
|
||||||
|
cohesivePatchUFixedModePtr->initiationTraction()[i] =
|
||||||
|
-faceToBreakTraction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// hmmnn we only need a reference for very small groups of cells
|
// hmmnn we only need a reference for very small groups of cells
|
||||||
// turn off for now
|
// turn off for now
|
||||||
//# include "updateReference.H"
|
//# include "updateReference.H"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,20 +4,21 @@
|
||||||
|
|
||||||
forAll(U.boundaryField(), patchI)
|
forAll(U.boundaryField(), patchI)
|
||||||
{
|
{
|
||||||
// philipc - this used to set a reference on
|
// philipc - this used to set a reference on
|
||||||
// processors which did not have a patch that fixesValue
|
// processors which did not have a patch that fixesValue
|
||||||
// so processor in the centre of the domain all had
|
// so processor in the centre of the domain all had
|
||||||
// a referece set causing stress peaks and resulting
|
// a referece set causing stress peaks and resulting
|
||||||
// in an incorrect solution
|
// in an incorrect solution
|
||||||
// so a quick fix is to not set a reference on regions
|
// so a quick fix is to not set a reference on regions
|
||||||
// with a processor boundary
|
// with a processor boundary
|
||||||
//if (U.boundaryField()[patchI].fixesValue())
|
//if (U.boundaryField()[patchI].fixesValue())
|
||||||
if (
|
if
|
||||||
U.boundaryField()[patchI].fixesValue()
|
(
|
||||||
||
|
U.boundaryField()[patchI].fixesValue()
|
||||||
mesh.boundaryMesh()[patchI].type()
|
||
|
||||||
== processorPolyPatch::typeName
|
mesh.boundaryMesh()[patchI].type()
|
||||||
)
|
== processorPolyPatch::typeName
|
||||||
|
)
|
||||||
{
|
{
|
||||||
const unallocLabelList& curFaceCells =
|
const unallocLabelList& curFaceCells =
|
||||||
mesh.boundary()[patchI].faceCells();
|
mesh.boundary()[patchI].faceCells();
|
||||||
|
|
|
@ -85,62 +85,62 @@ if (runTime.outputTime() || topoChange)
|
||||||
|
|
||||||
//- cohesive damage and cracking, and GII and GII
|
//- cohesive damage and cracking, and GII and GII
|
||||||
volScalarField damageAndCracks
|
volScalarField damageAndCracks
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"damageAndCracks",
|
"damageAndCracks",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedScalar("zero", dimless, 0.0),
|
dimensionedScalar("zero", dimless, 0.0),
|
||||||
calculatedFvPatchVectorField::typeName
|
calculatedFvPatchVectorField::typeName
|
||||||
);
|
);
|
||||||
volScalarField GI
|
volScalarField GI
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"GI",
|
"GI",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedScalar("zero", dimless, 0.0),
|
dimensionedScalar("zero", dimless, 0.0),
|
||||||
calculatedFvPatchVectorField::typeName
|
calculatedFvPatchVectorField::typeName
|
||||||
);
|
);
|
||||||
volScalarField GII
|
volScalarField GII
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"GII",
|
"GII",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedScalar("zero", dimless, 0.0),
|
dimensionedScalar("zero", dimless, 0.0),
|
||||||
calculatedFvPatchVectorField::typeName
|
calculatedFvPatchVectorField::typeName
|
||||||
);
|
);
|
||||||
forAll(U.boundaryField(), patchi)
|
forAll(U.boundaryField(), patchi)
|
||||||
{
|
{
|
||||||
// if(U.boundaryField()[patchi].type() == cohesiveLawMultiMatFvPatchVectorField::typeName)
|
// if(U.boundaryField()[patchi].type() == cohesiveLawMultiMatFvPatchVectorField::typeName)
|
||||||
if(U.boundaryField()[patchi].type() == solidCohesiveFvPatchVectorField::typeName)
|
if(U.boundaryField()[patchi].type() == solidCohesiveFvPatchVectorField::typeName)
|
||||||
{
|
{
|
||||||
// cohesiveLawMultiMatFvPatchVectorField& Upatch =
|
// cohesiveLawMultiMatFvPatchVectorField& Upatch =
|
||||||
// refCast<cohesiveLawMultiMatFvPatchVectorField>(U.boundaryField()[patchi]);
|
// refCast<cohesiveLawMultiMatFvPatchVectorField>(U.boundaryField()[patchi]);
|
||||||
solidCohesiveFvPatchVectorField& Upatch =
|
solidCohesiveFvPatchVectorField& Upatch =
|
||||||
refCast<solidCohesiveFvPatchVectorField>(U.boundaryField()[patchi]);
|
refCast<solidCohesiveFvPatchVectorField>(U.boundaryField()[patchi]);
|
||||||
|
|
||||||
GI.boundaryField()[patchi] = Upatch.GI();
|
GI.boundaryField()[patchi] = Upatch.GI();
|
||||||
GII.boundaryField()[patchi] = Upatch.GII();
|
GII.boundaryField()[patchi] = Upatch.GII();
|
||||||
damageAndCracks.boundaryField()[patchi] = Upatch.crackingAndDamage();
|
damageAndCracks.boundaryField()[patchi] = Upatch.crackingAndDamage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
volScalarField GTotal("GTotal", GI + GII);
|
volScalarField GTotal("GTotal", GI + GII);
|
||||||
GTotal.write();
|
GTotal.write();
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
//- write force displacement to file
|
//- write force displacement to file
|
||||||
if(historyPatchID != -1)
|
if(historyPatchID != -1)
|
||||||
{
|
{
|
||||||
Info << "Found patch "<<historyPatchName<<", writing y force and displacement to file"
|
Info << "Found patch "<<historyPatchName<<", writing y force and displacement to file"
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
//- for small strain or moving mesh
|
//- for small strain or moving mesh
|
||||||
vector force = gSum(mesh.boundary()[historyPatchID].Sf() & sigma.boundaryField()[historyPatchID]);
|
vector force = gSum(mesh.boundary()[historyPatchID].Sf() & sigma.boundaryField()[historyPatchID]);
|
||||||
|
|
||||||
vector avDisp = gAverage(U.boundaryField()[historyPatchID]);
|
vector avDisp = gAverage(U.boundaryField()[historyPatchID]);
|
||||||
|
|
||||||
//- write to file
|
//- write to file
|
||||||
if(Pstream::master())
|
if(Pstream::master())
|
||||||
{
|
{
|
||||||
OFstream& forceDispFile = *filePtr;
|
OFstream& forceDispFile = *filePtr;
|
||||||
forceDispFile << avDisp.x() << " " << avDisp.y() << " " << avDisp.z() << " "
|
forceDispFile << avDisp.x() << " " << avDisp.y() << " " << avDisp.z() << " "
|
||||||
<< force.x() << " " << force.y() << " " << force.z() << endl;
|
<< force.x() << " " << force.y() << " " << force.z() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,35 @@
|
||||||
if(rheology.planeStress())
|
if(rheology.planeStress())
|
||||||
{
|
{
|
||||||
//- add higher order terms
|
//- add higher order terms
|
||||||
volScalarField higherTerms = -0.5*volTensorField(gradDU&gradDU.T()).component(tensor::ZZ);
|
volScalarField higherTerms = -0.5*volTensorField(gradDU&gradDU.T()).component(tensor::ZZ);
|
||||||
|
|
||||||
forAll(gradDU.internalField(), celli)
|
forAll(gradDU.internalField(), celli)
|
||||||
{
|
{
|
||||||
gradDU.internalField()[celli][tensor::ZZ] =
|
gradDU.internalField()[celli][tensor::ZZ] =
|
||||||
((-C.internalField()[celli][symmTensor4thOrder::XXZZ]*DEpsilon.internalField()[celli][symmTensor::XX]
|
(
|
||||||
- C.internalField()[celli][symmTensor4thOrder::YYZZ]*DEpsilon.internalField()[celli][symmTensor::YY])
|
(-C.internalField()[celli][symmTensor4thOrder::XXZZ]*DEpsilon.internalField()[celli][symmTensor::XX]
|
||||||
/
|
- C.internalField()[celli][symmTensor4thOrder::YYZZ]*DEpsilon.internalField()[celli][symmTensor::YY]
|
||||||
C.internalField()[celli][symmTensor4thOrder::ZZZZ])
|
)
|
||||||
-higherTerms.internalField()[celli];
|
/
|
||||||
}
|
C.internalField()[celli][symmTensor4thOrder::ZZZZ])
|
||||||
|
- higherTerms.internalField()[celli];
|
||||||
|
}
|
||||||
forAll(gradDU.boundaryField(), patchi)
|
forAll(gradDU.boundaryField(), patchi)
|
||||||
{
|
{
|
||||||
forAll(gradDU.boundaryField()[patchi], facei)
|
forAll(gradDU.boundaryField()[patchi], facei)
|
||||||
{
|
{
|
||||||
gradDU.boundaryField()[patchi][facei][tensor::ZZ] =
|
gradDU.boundaryField()[patchi][facei][tensor::ZZ] =
|
||||||
((-C.boundaryField()[patchi][facei][symmTensor4thOrder::XXZZ]*DEpsilon.boundaryField()[patchi][facei][symmTensor::XX]
|
(
|
||||||
- C.boundaryField()[patchi][facei][symmTensor4thOrder::YYZZ]*DEpsilon.boundaryField()[patchi][facei][symmTensor::YY])
|
(
|
||||||
/
|
- C.boundaryField()[patchi][facei][symmTensor4thOrder::XXZZ]*
|
||||||
C.boundaryField()[patchi][facei][symmTensor4thOrder::ZZZZ])
|
DEpsilon.boundaryField()[patchi][facei][symmTensor::XX]
|
||||||
- higherTerms.boundaryField()[patchi][facei];
|
- C.boundaryField()[patchi][facei][symmTensor4thOrder::YYZZ]*
|
||||||
}
|
DEpsilon.boundaryField()[patchi][facei][symmTensor::YY]
|
||||||
}
|
)
|
||||||
}
|
/
|
||||||
|
C.boundaryField()[patchi][facei][symmTensor4thOrder::ZZZZ]
|
||||||
|
)
|
||||||
|
- higherTerms.boundaryField()[patchi][facei];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
dimensionedVector("zero", dimLength, vector::zero)
|
dimensionedVector("zero", dimLength, vector::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Info << "Reading accumulated strain field epsilon\n" << endl;
|
||||||
volSymmTensorField epsilon
|
volSymmTensorField epsilon
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
|
@ -57,6 +58,7 @@
|
||||||
dimensionedSymmTensor("zero", dimless, symmTensor::zero)
|
dimensionedSymmTensor("zero", dimless, symmTensor::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Info << "Reading accumulated stress field sigma\n" << endl;
|
||||||
volSymmTensorField sigma
|
volSymmTensorField sigma
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
|
@ -72,6 +74,7 @@
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
Info << "Reading incremental stress field DSigma\n" << endl;
|
||||||
volSymmTensorField DSigma
|
volSymmTensorField DSigma
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
|
@ -86,16 +89,16 @@
|
||||||
dimensionedSymmTensor("zero", dimForce/dimArea, symmTensor::zero)
|
dimensionedSymmTensor("zero", dimForce/dimArea, symmTensor::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
//- material properties
|
//- material properties
|
||||||
constitutiveModel rheology(sigma, DU);
|
constitutiveModel rheology(sigma, DU);
|
||||||
volSymmTensor4thOrderField C = rheology.C();
|
volSymmTensor4thOrderField C = rheology.C();
|
||||||
volDiagTensorField K = rheology.K();
|
volDiagTensorField K = rheology.K();
|
||||||
//surfaceSymmTensor4thOrderField Cf = fvc::interpolate(C);
|
//surfaceSymmTensor4thOrderField Cf = fvc::interpolate(C);
|
||||||
//surfaceDiagTensorField Kf = fvc::interpolate(K);
|
//surfaceDiagTensorField Kf = fvc::interpolate(K);
|
||||||
|
|
||||||
surfaceVectorField n = mesh.Sf()/mesh.magSf();
|
surfaceVectorField n = mesh.Sf()/mesh.magSf();
|
||||||
|
|
||||||
//volScalarField rho = rheology.rho();
|
//volScalarField rho = rheology.rho();
|
||||||
volScalarField rho
|
volScalarField rho
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
|
@ -109,7 +112,7 @@
|
||||||
rheology.rho()
|
rheology.rho()
|
||||||
);
|
);
|
||||||
|
|
||||||
// if(rheology.planeStress())
|
// if(rheology.planeStress())
|
||||||
// {
|
// {
|
||||||
// Info << nl << "Plane stress is set to yes -> the zz stress will be zero" << nl << endl;
|
// Info << nl << "Plane stress is set to yes -> the zz stress will be zero" << nl << endl;
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -62,123 +62,123 @@ Author
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
# include "setRootCase.H"
|
# include "setRootCase.H"
|
||||||
# include "createTime.H"
|
# include "createTime.H"
|
||||||
# include "createMesh.H"
|
# include "createMesh.H"
|
||||||
# include "createFields.H"
|
# include "createFields.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Info<< "\nStarting time loop\n" << endl;
|
Info<< "\nStarting time loop\n" << endl;
|
||||||
|
|
||||||
for (runTime++; !runTime.end(); runTime++)
|
while(runTime.loop())
|
||||||
{
|
{
|
||||||
Info<< "Time: " << runTime.timeName() << nl << endl;
|
Info<< "Time = " << runTime.timeName() << nl << endl;
|
||||||
|
|
||||||
# include "readSolidMechanicsControls.H"
|
# include "readSolidMechanicsControls.H"
|
||||||
|
|
||||||
int iCorr = 0;
|
int iCorr = 0;
|
||||||
lduMatrix::solverPerformance solverPerf;
|
lduMatrix::solverPerformance solverPerf;
|
||||||
scalar initialResidual = 1.0;
|
scalar initialResidual = 1.0;
|
||||||
lduMatrix::debug = 0;
|
lduMatrix::debug = 0;
|
||||||
|
|
||||||
//- div(sigmaOld) should be zero but I will include
|
//- div(sigmaOld) should be zero but I will include
|
||||||
//- it to make sure errors don't accumulate
|
//- it to make sure errors don't accumulate
|
||||||
volVectorField* oldErrorPtr = NULL;
|
volVectorField* oldErrorPtr = NULL;
|
||||||
if (ensureTotalEquilibrium)
|
if (ensureTotalEquilibrium)
|
||||||
{
|
{
|
||||||
oldErrorPtr = new volVectorField
|
oldErrorPtr = new volVectorField
|
||||||
(
|
(
|
||||||
fvc::d2dt2(rho.oldTime(), U.oldTime())
|
fvc::d2dt2(rho.oldTime(), U.oldTime())
|
||||||
- fvc::div(sigma)
|
- fvc::div(sigma)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
DU.storePrevIter();
|
DU.storePrevIter();
|
||||||
|
|
||||||
//- Updated lagrangian momentum equation
|
//- Updated lagrangian momentum equation
|
||||||
fvVectorMatrix DUEqn
|
fvVectorMatrix DUEqn
|
||||||
(
|
(
|
||||||
fvm::d2dt2(rho, DU)
|
fvm::d2dt2(rho, DU)
|
||||||
+ fvc::d2dt2(rho, U)
|
+ fvc::d2dt2(rho, U)
|
||||||
==
|
==
|
||||||
fvm::laplacian(K, DU, "laplacian(K,DU)")
|
fvm::laplacian(K, DU, "laplacian(K,DU)")
|
||||||
+ fvc::div(
|
+ fvc::div
|
||||||
DSigma
|
(
|
||||||
- (K & gradDU)
|
DSigma
|
||||||
+ ( (sigma + DSigma) & gradDU ),
|
- (K & gradDU)
|
||||||
"div(sigma)"
|
+ ( (sigma + DSigma) & gradDU ),
|
||||||
)
|
"div(sigma)"
|
||||||
//- fvc::laplacian(K, DU)
|
)
|
||||||
);
|
//- fvc::laplacian(K, DU)
|
||||||
|
);
|
||||||
|
|
||||||
if (ensureTotalEquilibrium)
|
if (ensureTotalEquilibrium)
|
||||||
{
|
{
|
||||||
//- to stop accumulation of errors
|
//- to stop accumulation of errors
|
||||||
DUEqn += *oldErrorPtr;
|
DUEqn += *oldErrorPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
solverPerf = DUEqn.solve();
|
solverPerf = DUEqn.solve();
|
||||||
|
|
||||||
if (iCorr == 0)
|
if (iCorr == 0)
|
||||||
{
|
{
|
||||||
initialResidual = solverPerf.initialResidual();
|
initialResidual = solverPerf.initialResidual();
|
||||||
}
|
}
|
||||||
|
|
||||||
DU.relax();
|
DU.relax();
|
||||||
|
|
||||||
gradDU = fvc::grad(DU);
|
gradDU = fvc::grad(DU);
|
||||||
|
|
||||||
//- for 2-D plane stress simulations, the zz component of gradDU
|
//- for 2-D plane stress simulations, the zz component of gradDU
|
||||||
//- ensures sigma.zz() is zero
|
//- ensures sigma.zz() is zero
|
||||||
//- it is assumed that z is the empty direction
|
//- it is assumed that z is the empty direction
|
||||||
//# include "checkPlaneStress.H"
|
//# include "checkPlaneStress.H"
|
||||||
|
|
||||||
//- sigma needs to be calculated inside the momentum loop as
|
//- sigma needs to be calculated inside the momentum loop as
|
||||||
//- it is used in the momentum equation
|
//- it is used in the momentum equation
|
||||||
DEpsilon = symm(gradDU) + 0.5*symm(gradDU & gradDU.T());
|
DEpsilon = symm(gradDU) + 0.5*symm(gradDU & gradDU.T());
|
||||||
DSigma = C && DEpsilon;
|
DSigma = C && DEpsilon;
|
||||||
|
|
||||||
if (iCorr % infoFrequency == 0)
|
if (iCorr % infoFrequency == 0)
|
||||||
{
|
{
|
||||||
Info << "\tTime " << runTime.value()
|
Info<< "\tTime " << runTime.value()
|
||||||
<< ", Corr " << iCorr
|
<< ", Corr " << iCorr
|
||||||
<< ", Solving for " << DU.name()
|
<< ", Solving for " << DU.name()
|
||||||
<< " using " << solverPerf.solverName()
|
<< " using " << solverPerf.solverName()
|
||||||
<< ", res = " << solverPerf.initialResidual()
|
<< ", res = " << solverPerf.initialResidual()
|
||||||
//<< ", rel res = " << relativeResidual
|
//<< ", rel res = " << relativeResidual
|
||||||
<< ", inner iters " << solverPerf.nIterations() << endl;
|
<< ", inner iters " << solverPerf.nIterations() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while
|
while
|
||||||
(
|
(
|
||||||
solverPerf.initialResidual() > convergenceTolerance
|
solverPerf.initialResidual() > convergenceTolerance
|
||||||
&&
|
&& ++iCorr < nCorr
|
||||||
++iCorr < nCorr
|
);
|
||||||
);
|
|
||||||
|
|
||||||
Info << nl << "Time " << runTime.value() << ", Solving for " << DU.name()
|
Info<< nl << "Time " << runTime.value() << ", Solving for " << DU.name()
|
||||||
<< ", Initial residual = " << initialResidual
|
<< ", Initial residual = " << initialResidual
|
||||||
<< ", Final residual = " << solverPerf.initialResidual()
|
<< ", Final residual = " << solverPerf.initialResidual()
|
||||||
<< ", No outer iterations " << iCorr
|
<< ", No outer iterations " << iCorr
|
||||||
<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
# include "moveMeshLeastSquares.H"
|
# include "moveMeshLeastSquares.H"
|
||||||
# include "rotateFields.H"
|
# include "rotateFields.H"
|
||||||
# include "writeFields.H"
|
# include "writeFields.H"
|
||||||
|
|
||||||
Info<< "ExecutionTime = "
|
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||||
<< runTime.elapsedCpuTime()
|
<< " ClockTime = " << runTime.elapsedClockTime() << " s\n\n"
|
||||||
<< " s\n\n" << endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "End\n" << endl;
|
Info<< "End\n" << endl;
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//- move mesh
|
//- move mesh
|
||||||
//--------------------------------------------------//
|
//--------------------------------------------------//
|
||||||
// if(min(J.internalField()) > 0)
|
// if(min(J.internalField()) > 0)
|
||||||
{
|
{
|
||||||
Info << "Moving mesh using least squares interpolation" << endl;
|
Info << "Moving mesh using least squares interpolation" << endl;
|
||||||
|
|
||||||
leastSquaresVolPointInterpolation pointInterpolation(mesh);
|
leastSquaresVolPointInterpolation pointInterpolation(mesh);
|
||||||
|
@ -11,43 +11,42 @@
|
||||||
pointMesh pMesh(mesh);
|
pointMesh pMesh(mesh);
|
||||||
|
|
||||||
wordList types
|
wordList types
|
||||||
(
|
(
|
||||||
pMesh.boundary().size(),
|
pMesh.boundary().size(),
|
||||||
calculatedFvPatchVectorField::typeName
|
calculatedFvPatchVectorField::typeName
|
||||||
);
|
);
|
||||||
|
|
||||||
pointVectorField pointDU
|
pointVectorField pointDU
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"pointDU",
|
"pointDU",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh
|
mesh
|
||||||
),
|
),
|
||||||
pMesh,
|
pMesh,
|
||||||
dimensionedVector("zero", dimLength, vector::zero),
|
dimensionedVector("zero", dimLength, vector::zero),
|
||||||
types
|
types
|
||||||
);
|
);
|
||||||
|
|
||||||
pointInterpolation.interpolate(DU, pointDU);
|
pointInterpolation.interpolate(DU, pointDU);
|
||||||
|
|
||||||
const vectorField& pointDUI =
|
const vectorField& pointDUI = pointDU.internalField();
|
||||||
pointDU.internalField();
|
|
||||||
|
|
||||||
//- Move mesh
|
//- Move mesh
|
||||||
vectorField newPoints = mesh.allPoints();
|
vectorField newPoints = mesh.allPoints();
|
||||||
|
|
||||||
forAll (pointDUI, pointI)
|
forAll (pointDUI, pointI)
|
||||||
{
|
{
|
||||||
newPoints[pointI] += pointDUI[pointI];
|
newPoints[pointI] += pointDUI[pointI];
|
||||||
}
|
}
|
||||||
|
|
||||||
twoDPointCorrector twoDCorrector(mesh);
|
twoDPointCorrector twoDCorrector(mesh);
|
||||||
twoDCorrector.correctPoints(newPoints);
|
twoDCorrector.correctPoints(newPoints);
|
||||||
mesh.movePoints(newPoints);
|
mesh.movePoints(newPoints);
|
||||||
mesh.V00();
|
mesh.V00();
|
||||||
mesh.moving(false);
|
mesh.moving(false);
|
||||||
}
|
}
|
||||||
// else
|
// else
|
||||||
// {
|
// {
|
||||||
// FatalErrorIn(args.executable())
|
// FatalErrorIn(args.executable())
|
||||||
|
|
|
@ -2,47 +2,47 @@
|
||||||
//- rotate fields
|
//- rotate fields
|
||||||
//--------------------------------------------------//
|
//--------------------------------------------------//
|
||||||
{
|
{
|
||||||
Info << "Rotating fields" << endl;
|
Info << "Rotating fields" << endl;
|
||||||
|
|
||||||
volTensorField F = I + gradDU;
|
volTensorField F = I + gradDU;
|
||||||
|
|
||||||
U += DU;
|
U += DU;
|
||||||
|
|
||||||
epsilon += DEpsilon;
|
epsilon += DEpsilon;
|
||||||
|
|
||||||
sigma += DSigma;
|
sigma += DSigma;
|
||||||
|
|
||||||
volTensorField Finv = inv(F);
|
volTensorField Finv = inv(F);
|
||||||
|
|
||||||
volScalarField J = det(F);
|
volScalarField J = det(F);
|
||||||
if(min(J.internalField()) < 0)
|
if(min(J.internalField()) < 0)
|
||||||
{
|
{
|
||||||
FatalErrorIn(args.executable())
|
FatalErrorIn(args.executable())
|
||||||
<< "Negative Jacobian - a cell volume has become negative!"
|
<< "Negative Jacobian - a cell volume has become negative!"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
rho = rho/J;
|
rho = rho/J;
|
||||||
|
|
||||||
n = mesh.Sf()/mesh.magSf();
|
n = mesh.Sf()/mesh.magSf();
|
||||||
|
|
||||||
//- rotate strain
|
//- rotate strain
|
||||||
//epsilon = symm(Finv & epsilon & Finv.T());
|
//epsilon = symm(Finv & epsilon & Finv.T());
|
||||||
epsilon = transform(Finv, epsilon);
|
epsilon = transform(Finv, epsilon);
|
||||||
|
|
||||||
//- rotate stress
|
//- rotate stress
|
||||||
//sigma = 1/J * symm(F.T() & sigma & F);
|
//sigma = 1/J * symm(F.T() & sigma & F);
|
||||||
sigma = (1/J) * transform(F.T(), sigma);
|
sigma = (1/J) * transform(F.T(), sigma);
|
||||||
|
|
||||||
//- rotate elastic constitutive tensor
|
//- rotate elastic constitutive tensor
|
||||||
C = transform(F.T(), C);
|
C = transform(F.T(), C);
|
||||||
|
|
||||||
// - update implicit stiffness tensor
|
// - update implicit stiffness tensor
|
||||||
forAll(K, celli)
|
forAll(K, celli)
|
||||||
{
|
{
|
||||||
K[celli].xx() = C[celli].xxxx();
|
K[celli].xx() = C[celli].xxxx();
|
||||||
K[celli].yy() = C[celli].yyyy();
|
K[celli].yy() = C[celli].yyyy();
|
||||||
K[celli].zz() = C[celli].zzzz();
|
K[celli].zz() = C[celli].zzzz();
|
||||||
}
|
}
|
||||||
K.correctBoundaryConditions();
|
K.correctBoundaryConditions();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,61 +1,59 @@
|
||||||
if (runTime.outputTime())
|
if (runTime.outputTime())
|
||||||
{
|
{
|
||||||
//C.write();
|
//C.write();
|
||||||
|
|
||||||
volScalarField epsilonEq
|
volScalarField epsilonEq
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"epsilonEq",
|
"epsilonEq",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
sqrt((2.0/3.0)*magSqr(dev(epsilon)))
|
sqrt((2.0/3.0)*magSqr(dev(epsilon)))
|
||||||
);
|
);
|
||||||
|
|
||||||
Info<< "Max epsilonEq = " << max(epsilonEq).value()
|
Info<< "Max epsilonEq = " << max(epsilonEq).value() << endl;
|
||||||
<< endl;
|
|
||||||
|
|
||||||
volScalarField sigmaEq
|
volScalarField sigmaEq
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"sigmaEq",
|
"sigmaEq",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
sqrt((3.0/2.0)*magSqr(dev(sigma)))
|
sqrt((3.0/2.0)*magSqr(dev(sigma)))
|
||||||
);
|
);
|
||||||
|
|
||||||
Info<< "Max sigmaEq = " << max(sigmaEq).value()
|
Info<< "Max sigmaEq = " << max(sigmaEq).value() << endl;
|
||||||
<< endl;
|
|
||||||
|
|
||||||
// volVectorField traction
|
// volVectorField traction
|
||||||
// (
|
// (
|
||||||
// IOobject
|
// IOobject
|
||||||
// (
|
// (
|
||||||
// "traction",
|
// "traction",
|
||||||
// runTime.timeName(),
|
// runTime.timeName(),
|
||||||
// mesh,
|
|
||||||
// IOobject::NO_READ,
|
|
||||||
// IOobject::AUTO_WRITE
|
|
||||||
// ),
|
|
||||||
// mesh,
|
// mesh,
|
||||||
// dimensionedVector("zero", dimForce/dimArea, vector::zero)
|
// IOobject::NO_READ,
|
||||||
// );
|
// IOobject::AUTO_WRITE
|
||||||
// forAll(mesh.boundary(), patchi)
|
// ),
|
||||||
// {
|
// mesh,
|
||||||
|
// dimensionedVector("zero", dimForce/dimArea, vector::zero)
|
||||||
|
// );
|
||||||
|
// forAll(mesh.boundary(), patchi)
|
||||||
|
// {
|
||||||
// traction.boundaryField()[patchi] =
|
// traction.boundaryField()[patchi] =
|
||||||
// n.boundaryField()[patchi] & sigma.boundaryField()[patchi];
|
// n.boundaryField()[patchi] & sigma.boundaryField()[patchi];
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// //- patch forces
|
// //- patch forces
|
||||||
// forAll(mesh.boundary(), patchi)
|
// forAll(mesh.boundary(), patchi)
|
||||||
// {
|
// {
|
||||||
// Info << "Patch " << mesh.boundary()[patchi].name() << endl;
|
// Info << "Patch " << mesh.boundary()[patchi].name() << endl;
|
||||||
// vectorField totalForce = mesh.Sf().boundaryField()[patchi] & sigma.boundaryField()[patchi];
|
// vectorField totalForce = mesh.Sf().boundaryField()[patchi] & sigma.boundaryField()[patchi];
|
||||||
// vector force = sum( totalForce );
|
// vector force = sum( totalForce );
|
||||||
|
@ -66,7 +64,7 @@ if (runTime.outputTime())
|
||||||
// Info << "\tnormal force is " << normalForce << " N" << endl;
|
// Info << "\tnormal force is " << normalForce << " N" << endl;
|
||||||
// scalar shearForce = mag(sum( (I - sqr(n.boundaryField()[patchi])) & totalForce ));
|
// scalar shearForce = mag(sum( (I - sqr(n.boundaryField()[patchi])) & totalForce ));
|
||||||
// Info << "\tshear force is " << shearForce << " N" << endl;
|
// Info << "\tshear force is " << shearForce << " N" << endl;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
runTime.write();
|
runTime.write();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,29 @@
|
||||||
if(divSigmaExpMethod == "standard")
|
if(divSigmaExpMethod == "standard")
|
||||||
{
|
{
|
||||||
//- calculating the full gradient has good convergence and no high freq oscillations
|
//- calculating the full gradient has good convergence and no high freq oscillations
|
||||||
divSigmaExp =
|
divSigmaExp = fvc::div((C && symm(gradU)) - (K & gradU), "div(sigma)");
|
||||||
fvc::div(
|
}
|
||||||
(C && symm(gradU))
|
else if(divSigmaExpMethod == "surface")
|
||||||
- (K & gradU),
|
{
|
||||||
"div(sigma)"
|
//- this form seems to have the best convergence
|
||||||
);
|
divSigmaExp = fvc::div
|
||||||
}
|
(
|
||||||
else if(divSigmaExpMethod == "surface")
|
mesh.magSf()*
|
||||||
{
|
|
||||||
//- this form seems to have the best convergence
|
|
||||||
divSigmaExp =
|
|
||||||
fvc::div(mesh.magSf()*
|
|
||||||
(
|
(
|
||||||
(n&(Cf && fvc::interpolate(symm(gradU))))
|
(n & (Cf && fvc::interpolate(symm(gradU))))
|
||||||
- (n&(Kf & fvc::interpolate(gradU)))
|
- (n & (Kf & fvc::interpolate(gradU)))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if(divSigmaExpMethod == "laplacian")
|
else if(divSigmaExpMethod == "laplacian")
|
||||||
{
|
{
|
||||||
//- can cause high freq oscillations and slow convergence
|
//- can cause high freq oscillations and slow convergence
|
||||||
divSigmaExp =
|
divSigmaExp =
|
||||||
fvc::div(C && symm(epsilon), "div(sigma)")
|
fvc::div(C && symm(epsilon), "div(sigma)")
|
||||||
- fvc::laplacian(K,U, "laplacian(K,U)");
|
- fvc::laplacian(K, U, "laplacian(K, U)");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FatalError << "divSigmaExp method " << divSigmaExpMethod << " not found!" << endl;
|
FatalErrorIn(args.executable())
|
||||||
}
|
<< "divSigmaExp method " << divSigmaExpMethod << " not found!" << endl;
|
||||||
|
}
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
OFstream * filePtr(NULL);
|
OFstream* filePtr(NULL);
|
||||||
word historyPatchName(mesh.solutionDict().subDict("solidMechanics").lookup("historyPatch"));
|
word historyPatchName(mesh.solutionDict().subDict("solidMechanics").lookup("historyPatch"));
|
||||||
label historyPatchID = mesh.boundaryMesh().findPatchID(historyPatchName);
|
label historyPatchID = mesh.boundaryMesh().findPatchID(historyPatchName);
|
||||||
if(historyPatchID == -1)
|
if(historyPatchID == -1)
|
||||||
{
|
{
|
||||||
Warning << "history patch " << historyPatchName
|
Warning << "history patch " << historyPatchName
|
||||||
<< " not found. Force-displacement will not be written"
|
<< " not found. Force-displacement will not be written"
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
else if(Pstream::master())
|
else if(Pstream::master())
|
||||||
{
|
{
|
||||||
Info << "Force-displacement for patch " << historyPatchName
|
Info << "Force-displacement for patch " << historyPatchName
|
||||||
<< " will be written to forceDisp.dat"
|
<< " will be written to forceDisp.dat"
|
||||||
<< endl;
|
<< endl;
|
||||||
|
@ -17,4 +17,4 @@ if(historyPatchID == -1)
|
||||||
filePtr = new OFstream(hisDirName/historyPatchName+"forceDisp.dat");
|
filePtr = new OFstream(hisDirName/historyPatchName+"forceDisp.dat");
|
||||||
OFstream& forceDispFile = *filePtr;
|
OFstream& forceDispFile = *filePtr;
|
||||||
forceDispFile << "#Disp(mm)\tForce(N)" << endl;
|
forceDispFile << "#Disp(mm)\tForce(N)" << endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,103 +48,102 @@ Author
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
# include "setRootCase.H"
|
# include "setRootCase.H"
|
||||||
# include "createTime.H"
|
# include "createTime.H"
|
||||||
# include "createMesh.H"
|
# include "createMesh.H"
|
||||||
# include "createFields.H"
|
# include "createFields.H"
|
||||||
# include "createHistory.H"
|
# include "createHistory.H"
|
||||||
# include "readDivSigmaExpMethod.H"
|
# include "readDivSigmaExpMethod.H"
|
||||||
# include "createSolidInterfaceOrthotropic.H"
|
# include "createSolidInterfaceOrthotropic.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Info<< "\nStarting time loop\n" << endl;
|
Info<< "\nStarting time loop\n" << endl;
|
||||||
|
|
||||||
for (runTime++; !runTime.end(); runTime++)
|
while(runTime.loop())
|
||||||
{
|
{
|
||||||
Info<< "Time: " << runTime.timeName() << nl << endl;
|
Info<< "Time = " << runTime.timeName() << nl << endl;
|
||||||
|
|
||||||
# include "readSolidMechanicsControls.H"
|
# include "readSolidMechanicsControls.H"
|
||||||
|
|
||||||
int iCorr = 0;
|
int iCorr = 0;
|
||||||
lduMatrix::solverPerformance solverPerf;
|
lduMatrix::solverPerformance solverPerf;
|
||||||
scalar initialResidual = 1.0;
|
scalar initialResidual = 1.0;
|
||||||
scalar relativeResidual = 1.0;
|
scalar relativeResidual = 1.0;
|
||||||
lduMatrix::debug = 0;
|
lduMatrix::debug = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
U.storePrevIter();
|
U.storePrevIter();
|
||||||
|
|
||||||
# include "calculateDivSigmaExp.H"
|
# include "calculateDivSigmaExp.H"
|
||||||
|
|
||||||
//- Linear momentum equation
|
//- Linear momentum equation
|
||||||
fvVectorMatrix UEqn
|
fvVectorMatrix UEqn
|
||||||
(
|
(
|
||||||
rho*fvm::d2dt2(U)
|
rho*fvm::d2dt2(U)
|
||||||
==
|
==
|
||||||
fvm::laplacian(Kf, U, "laplacian(K,U)")
|
fvm::laplacian(Kf, U, "laplacian(K,U)")
|
||||||
+ divSigmaExp
|
+ divSigmaExp
|
||||||
);
|
|
||||||
|
|
||||||
if (solidInterfaceCorr)
|
|
||||||
{
|
|
||||||
solidInterfacePtr->correct(UEqn);
|
|
||||||
}
|
|
||||||
|
|
||||||
solverPerf = UEqn.solve();
|
|
||||||
|
|
||||||
if (iCorr == 0)
|
|
||||||
{
|
|
||||||
initialResidual = solverPerf.initialResidual();
|
|
||||||
}
|
|
||||||
|
|
||||||
U.relax();
|
|
||||||
|
|
||||||
gradU = fvc::grad(U); // use leastSquaresSolidInterface
|
|
||||||
|
|
||||||
//# include "setPlaneStressGradU.H"
|
|
||||||
|
|
||||||
# include "calculateRelativeResidual.H"
|
|
||||||
|
|
||||||
if (iCorr % infoFrequency == 0)
|
|
||||||
{
|
|
||||||
Info << "\tTime " << runTime.value()
|
|
||||||
<< ", Corr " << iCorr
|
|
||||||
<< ", Solving for " << U.name()
|
|
||||||
<< " using " << solverPerf.solverName()
|
|
||||||
<< ", res = " << solverPerf.initialResidual()
|
|
||||||
<< ", rel res = " << relativeResidual
|
|
||||||
<< ", inner iters " << solverPerf.nIterations() << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while
|
|
||||||
(
|
|
||||||
solverPerf.initialResidual() > convergenceTolerance
|
|
||||||
&&
|
|
||||||
++iCorr < nCorr
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Info<< nl << "Time " << runTime.value() << ", Solving for " << U.name()
|
if (solidInterfaceCorr)
|
||||||
<< ", Initial residual = " << initialResidual
|
{
|
||||||
<< ", Final residual = " << solverPerf.initialResidual()
|
solidInterfacePtr->correct(UEqn);
|
||||||
<< ", No outer iterations " << iCorr
|
}
|
||||||
<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
|
||||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
|
||||||
<< endl;
|
|
||||||
|
|
||||||
# include "calculateEpsilonSigma.H"
|
solverPerf = UEqn.solve();
|
||||||
# include "writeFields.H"
|
|
||||||
# include "writeHistory.H"
|
|
||||||
|
|
||||||
Info<< "ExecutionTime = "
|
if (iCorr == 0)
|
||||||
<< runTime.elapsedCpuTime()
|
{
|
||||||
<< " s\n\n" << endl;
|
initialResidual = solverPerf.initialResidual();
|
||||||
|
}
|
||||||
|
|
||||||
|
U.relax();
|
||||||
|
|
||||||
|
gradU = fvc::grad(U); // use leastSquaresSolidInterface
|
||||||
|
|
||||||
|
//# include "setPlaneStressGradU.H"
|
||||||
|
|
||||||
|
# include "calculateRelativeResidual.H"
|
||||||
|
|
||||||
|
if (iCorr % infoFrequency == 0)
|
||||||
|
{
|
||||||
|
Info<< "\tTime " << runTime.value()
|
||||||
|
<< ", Corr " << iCorr
|
||||||
|
<< ", Solving for " << U.name()
|
||||||
|
<< " using " << solverPerf.solverName()
|
||||||
|
<< ", res = " << solverPerf.initialResidual()
|
||||||
|
<< ", rel res = " << relativeResidual
|
||||||
|
<< ", inner iters " << solverPerf.nIterations() << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while
|
||||||
|
(
|
||||||
|
solverPerf.initialResidual() > convergenceTolerance
|
||||||
|
&& ++iCorr < nCorr
|
||||||
|
);
|
||||||
|
|
||||||
|
Info<< nl << "Time " << runTime.value() << ", Solving for " << U.name()
|
||||||
|
<< ", Initial residual = " << initialResidual
|
||||||
|
<< ", Final residual = " << solverPerf.initialResidual()
|
||||||
|
<< ", No outer iterations " << iCorr
|
||||||
|
<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||||
|
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
# include "calculateEpsilonSigma.H"
|
||||||
|
# include "writeFields.H"
|
||||||
|
# include "writeHistory.H"
|
||||||
|
|
||||||
|
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||||
|
<< " ClockTime = " << runTime.elapsedClockTime() << " s\n\n"
|
||||||
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "End\n" << endl;
|
Info<< "End\n" << endl;
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
word divSigmaExpMethod(mesh.solutionDict().subDict("solidMechanics").lookup("divSigmaExp"));
|
word divSigmaExpMethod(mesh.solutionDict().subDict("solidMechanics").lookup("divSigmaExp"));
|
||||||
Info << "Calculation of divSigmaExp Method: " << divSigmaExpMethod << endl;
|
Info << "Calculation of divSigmaExp Method: " << divSigmaExpMethod << endl;
|
||||||
if(divSigmaExpMethod != "standard" && divSigmaExpMethod != "surface" && divSigmaExpMethod != "laplacian")
|
if(divSigmaExpMethod != "standard" && divSigmaExpMethod != "surface" && divSigmaExpMethod != "laplacian")
|
||||||
{
|
{
|
||||||
FatalError << "divSigmaExp method " << divSigmaExpMethod << " not found!" << nl
|
FatalError << "divSigmaExp method " << divSigmaExpMethod << " not found!" << nl
|
||||||
<< "valid methods are:\nstandard\nsurface\nlaplacian"
|
<< "valid methods are:\nstandard\nsurface\nlaplacian"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
//- set gradU.zz() for plane stress
|
//- set gradU.zz() for plane stress
|
||||||
if(rheology.planeStress())
|
if(rheology.planeStress())
|
||||||
{
|
{
|
||||||
forAll(gradU.internalField(), celli)
|
forAll(gradU.internalField(), celli)
|
||||||
{
|
{
|
||||||
gradU.internalField()[celli].zz() =
|
gradU.internalField()[celli].zz() =
|
||||||
(-C.internalField()[celli].xxzz()*epsilon.internalField()[celli].xx()
|
(
|
||||||
- C.internalField()[celli].yyzz()*epsilon.internalField()[celli].yy())
|
- C.internalField()[celli].xxzz()*epsilon.internalField()[celli].xx()
|
||||||
|
- C.internalField()[celli].yyzz()*epsilon.internalField()[celli].yy()
|
||||||
|
)
|
||||||
/
|
/
|
||||||
C.internalField()[celli].zzzz();
|
C.internalField()[celli].zzzz();
|
||||||
}
|
}
|
||||||
gradU.correctBoundaryConditions();
|
gradU.correctBoundaryConditions();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,38 +1,36 @@
|
||||||
if (runTime.outputTime())
|
if (runTime.outputTime())
|
||||||
{
|
{
|
||||||
//K.write();
|
//K.write();
|
||||||
|
|
||||||
volScalarField epsilonEq
|
volScalarField epsilonEq
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"epsilonEq",
|
"epsilonEq",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
sqrt((2.0/3.0)*magSqr(dev(epsilon)))
|
sqrt((2.0/3.0)*magSqr(dev(epsilon)))
|
||||||
);
|
);
|
||||||
|
|
||||||
Info<< "Max epsilonEq = " << max(epsilonEq).value()
|
Info<< "Max epsilonEq = " << max(epsilonEq).value() << endl;
|
||||||
<< endl;
|
|
||||||
|
|
||||||
volScalarField sigmaEq
|
volScalarField sigmaEq
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"sigmaEq",
|
"sigmaEq",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
sqrt((3.0/2.0)*magSqr(dev(sigma)))
|
sqrt((3.0/2.0)*magSqr(dev(sigma)))
|
||||||
);
|
);
|
||||||
|
|
||||||
Info<< "Max sigmaEq = " << max(sigmaEq).value()
|
Info<< "Max sigmaEq = " << max(sigmaEq).value() << endl;
|
||||||
<< endl;
|
|
||||||
|
|
||||||
runTime.write();
|
runTime.write();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
//- write force displacement to file
|
//- write force displacement to file
|
||||||
if(historyPatchID != -1)
|
if(historyPatchID != -1)
|
||||||
{
|
{
|
||||||
Info << "Writing disp and force of patch "<<historyPatchName<<" to file"
|
Info << "Writing disp and force of patch "<<historyPatchName<<" to file"
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
//- for small strain or moving mesh
|
//- for small strain or moving mesh
|
||||||
vector force = gSum(mesh.boundary()[historyPatchID].Sf() & sigma.boundaryField()[historyPatchID]);
|
vector force = gSum(mesh.boundary()[historyPatchID].Sf() & sigma.boundaryField()[historyPatchID]);
|
||||||
|
|
||||||
vector avDisp = gAverage(U.boundaryField()[historyPatchID]);
|
vector avDisp = gAverage(U.boundaryField()[historyPatchID]);
|
||||||
|
|
||||||
//- write to file
|
//- write to file
|
||||||
if(Pstream::master())
|
if(Pstream::master())
|
||||||
{
|
{
|
||||||
OFstream& forceDispFile = *filePtr;
|
OFstream& forceDispFile = *filePtr;
|
||||||
forceDispFile << avDisp.x() << " " << avDisp.y() << " " << avDisp.z() << " "
|
forceDispFile << avDisp.x() << " " << avDisp.y() << " " << avDisp.z() << " "
|
||||||
<< force.x() << " " << force.y() << " " << force.z() << endl;
|
<< force.x() << " " << force.y() << " " << force.z() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,26 +11,24 @@ aitkenDelta = (DU - DU.prevIter()) / aitkenInitialRes;
|
||||||
|
|
||||||
// update relaxation factor
|
// update relaxation factor
|
||||||
if(iCorr == 0)
|
if(iCorr == 0)
|
||||||
{
|
{
|
||||||
aitkenTheta = 0.1;
|
aitkenTheta = 0.1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vectorField b = aitkenDelta.internalField() - aitkenDelta.prevIter().internalField();
|
vectorField b = aitkenDelta.internalField() - aitkenDelta.prevIter().internalField();
|
||||||
//scalar sumMagB = gSum(mag(b));
|
//scalar sumMagB = gSum(mag(b));
|
||||||
scalar sumMagB = gSum(magSqr(b));
|
scalar sumMagB = gSum(magSqr(b));
|
||||||
if(sumMagB < SMALL)
|
if(sumMagB < SMALL)
|
||||||
{
|
{
|
||||||
//Warning << "Aitken under-relaxation: denominator less then SMALL"
|
//Warning << "Aitken under-relaxation: denominator less then SMALL"
|
||||||
// << endl;
|
// << endl;
|
||||||
sumMagB += SMALL;
|
sumMagB += SMALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
aitkenTheta = -aitkenTheta*
|
aitkenTheta = -aitkenTheta*
|
||||||
gSum(aitkenDelta.prevIter().internalField() & b)
|
gSum(aitkenDelta.prevIter().internalField() & b)/sumMagB;
|
||||||
/
|
}
|
||||||
sumMagB;
|
|
||||||
}
|
|
||||||
|
|
||||||
// correction to the latest DU
|
// correction to the latest DU
|
||||||
DU += aitkenTheta*aitkenDelta*aitkenInitialRes;
|
DU += aitkenTheta*aitkenDelta*aitkenInitialRes;
|
||||||
|
|
|
@ -2,9 +2,7 @@ if(divDSigmaExpMethod == "standard")
|
||||||
{
|
{
|
||||||
divDSigmaExp = fvc::div
|
divDSigmaExp = fvc::div
|
||||||
(
|
(
|
||||||
(mu*gradDU.T())
|
mu*gradDU.T() + lambda*(I*tr(gradDU)) - (mu + lambda)*gradDU,
|
||||||
+ (lambda*(I*tr(gradDU)))
|
|
||||||
- ((mu + lambda)*gradDU),
|
|
||||||
"div(sigma)"
|
"div(sigma)"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -21,11 +19,11 @@ else if(divDSigmaExpMethod == "surface")
|
||||||
);
|
);
|
||||||
|
|
||||||
// divDSigmaExp = fvc::div
|
// divDSigmaExp = fvc::div
|
||||||
// (
|
// (
|
||||||
// muf*(mesh.Sf() & fvc::interpolate(gradDU.T()))
|
// muf*(mesh.Sf() & fvc::interpolate(gradDU.T()))
|
||||||
// + lambdaf*(mesh.Sf() & I*fvc::interpolate(tr(gradDU)))
|
// + lambdaf*(mesh.Sf() & I*fvc::interpolate(tr(gradDU)))
|
||||||
// - (muf + lambdaf)*(mesh.Sf() & fvc::interpolate(gradDU))
|
// - (muf + lambdaf)*(mesh.Sf() & fvc::interpolate(gradDU))
|
||||||
// );
|
// );
|
||||||
}
|
}
|
||||||
else if(divDSigmaExpMethod == "decompose")
|
else if(divDSigmaExpMethod == "decompose")
|
||||||
{
|
{
|
||||||
|
@ -42,25 +40,20 @@ else if(divDSigmaExpMethod == "decompose")
|
||||||
);
|
);
|
||||||
|
|
||||||
// divDSigmaExp = fvc::div
|
// divDSigmaExp = fvc::div
|
||||||
// (
|
// (
|
||||||
// mesh.magSf()
|
// mesh.magSf()*
|
||||||
// *(
|
// (
|
||||||
// - (muf + lambdaf)*(fvc::snGrad(DU)&(I - n*n))
|
// - (muf + lambdaf)*(fvc::snGrad(DU)&(I - n*n))
|
||||||
// + lambdaf*tr(shearGradDU&(I - n*n))*n
|
// + lambdaf*tr(shearGradDU&(I - n*n))*n
|
||||||
// + muf*(shearGradDU&n)
|
// + muf*(shearGradDU&n)
|
||||||
// )
|
// )
|
||||||
// );
|
// );
|
||||||
}
|
}
|
||||||
else if(divDSigmaExpMethod == "laplacian")
|
else if(divDSigmaExpMethod == "laplacian")
|
||||||
{
|
{
|
||||||
divDSigmaExp =
|
divDSigmaExp =
|
||||||
- fvc::laplacian(mu + lambda, DU, "laplacian(DDU,DU)")
|
- fvc::laplacian(mu + lambda, DU, "laplacian(DDU,DU)")
|
||||||
+ fvc::div
|
+ fvc::div(mu*gradDU.T() + lambda*(I*tr(gradDU)), "div(sigma)");
|
||||||
(
|
|
||||||
mu*gradDU.T()
|
|
||||||
+ lambda*(I*tr(gradDU)),
|
|
||||||
"div(sigma)"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,17 +6,17 @@
|
||||||
|
|
||||||
// volVectorField divThirdOrderTerm
|
// volVectorField divThirdOrderTerm
|
||||||
// (
|
// (
|
||||||
// IOobject
|
// IOobject
|
||||||
// (
|
// (
|
||||||
// "divThirdOrderTerm",
|
// "divThirdOrderTerm",
|
||||||
// runTime.timeName(),
|
// runTime.timeName(),
|
||||||
// mesh,
|
// mesh,
|
||||||
// IOobject::NO_READ,
|
// IOobject::NO_READ,
|
||||||
// IOobject::NO_WRITE
|
// IOobject::NO_WRITE
|
||||||
// ),
|
// ),
|
||||||
// mesh,
|
// mesh,
|
||||||
// dimensionedVector("zero", dimForce/dimVolume, vector::zero)
|
// dimensionedVector("zero", dimForce/dimVolume, vector::zero)
|
||||||
// );
|
// );
|
||||||
|
|
||||||
// average gradDU of neighbouring cell centres
|
// average gradDU of neighbouring cell centres
|
||||||
// interpolation scheme should be midPoint
|
// interpolation scheme should be midPoint
|
||||||
|
@ -25,17 +25,17 @@ surfaceTensorField averageGradDU("averageGradDU", fvc::interpolate(gradDU, "aver
|
||||||
// average face gradDU extrapolated from neighbouring cell centres
|
// average face gradDU extrapolated from neighbouring cell centres
|
||||||
surfaceTensorField extrapGradDU
|
surfaceTensorField extrapGradDU
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"extrapGradDU",
|
"extrapGradDU",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedTensor("zero", dimless, tensor::zero)
|
dimensionedTensor("zero", dimless, tensor::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
volVectorField gradGradDUcompXX = fvc::grad(gradDU.component(tensor::XX), "gradGradDU");
|
volVectorField gradGradDUcompXX = fvc::grad(gradDU.component(tensor::XX), "gradGradDU");
|
||||||
volVectorField gradGradDUcompXY = fvc::grad(gradDU.component(tensor::XY), "gradGradDU");
|
volVectorField gradGradDUcompXY = fvc::grad(gradDU.component(tensor::XY), "gradGradDU");
|
||||||
|
@ -86,180 +86,181 @@ volScalarField gradGradDUZZZ = gradGradDUcompZZ.component(vector::Z);
|
||||||
|
|
||||||
forAll(extrapGradDU.internalField(), facei)
|
forAll(extrapGradDU.internalField(), facei)
|
||||||
{
|
{
|
||||||
const label own = mesh.owner()[facei];
|
const label own = mesh.owner()[facei];
|
||||||
const label nei = mesh.neighbour()[facei];
|
const label nei = mesh.neighbour()[facei];
|
||||||
const vector deltaOwn = mesh.Cf()[facei] - mesh.C()[own];
|
const vector deltaOwn = mesh.Cf()[facei] - mesh.C()[own];
|
||||||
const vector deltaNei = mesh.Cf()[facei] - mesh.C()[nei];
|
const vector deltaNei = mesh.Cf()[facei] - mesh.C()[nei];
|
||||||
const tensor& gradDUOwn = gradDU.internalField()[own];
|
const tensor& gradDUOwn = gradDU.internalField()[own];
|
||||||
const tensor& gradDUNei = gradDU.internalField()[nei];
|
const tensor& gradDUNei = gradDU.internalField()[nei];
|
||||||
|
|
||||||
// as there is there is no thirdOrderTensor class, we will
|
// as there is there is no thirdOrderTensor class, we will
|
||||||
// calculate (deltaOwn&gradGradDUOwn) out manually
|
// calculate (deltaOwn&gradGradDUOwn) out manually
|
||||||
// tensor deltaOwnDotgradGradDUOwn = tensor::zero;
|
// tensor deltaOwnDotgradGradDUOwn = tensor::zero;
|
||||||
// tensor deltaNeiDotgradGradDUNei = tensor::zero;
|
// tensor deltaNeiDotgradGradDUNei = tensor::zero;
|
||||||
|
|
||||||
// deltaOwnDotgradGradDUOwn[tensor::XX] = deltaOwn & gradGradDUcompXX.internalField()[own];
|
// deltaOwnDotgradGradDUOwn[tensor::XX] = deltaOwn & gradGradDUcompXX.internalField()[own];
|
||||||
// deltaNeiDotgradGradDUNei[tensor::XX] = deltaNei & gradGradDUcompXX.internalField()[nei];
|
// deltaNeiDotgradGradDUNei[tensor::XX] = deltaNei & gradGradDUcompXX.internalField()[nei];
|
||||||
// deltaOwnDotgradGradDUOwn[tensor::XY] = deltaOwn & gradGradDUcompXY.internalField()[own];
|
// deltaOwnDotgradGradDUOwn[tensor::XY] = deltaOwn & gradGradDUcompXY.internalField()[own];
|
||||||
// deltaNeiDotgradGradDUNei[tensor::XY] = deltaNei & gradGradDUcompXY.internalField()[nei];
|
// deltaNeiDotgradGradDUNei[tensor::XY] = deltaNei & gradGradDUcompXY.internalField()[nei];
|
||||||
// deltaOwnDotgradGradDUOwn[tensor::XZ] = deltaOwn & gradGradDUcompXZ.internalField()[own];
|
// deltaOwnDotgradGradDUOwn[tensor::XZ] = deltaOwn & gradGradDUcompXZ.internalField()[own];
|
||||||
// deltaNeiDotgradGradDUNei[tensor::XZ] = deltaNei & gradGradDUcompXZ.internalField()[nei];
|
// deltaNeiDotgradGradDUNei[tensor::XZ] = deltaNei & gradGradDUcompXZ.internalField()[nei];
|
||||||
|
|
||||||
// deltaOwnDotgradGradDUOwn[tensor::YX] = deltaOwn & gradGradDUcompYX.internalField()[own];
|
// deltaOwnDotgradGradDUOwn[tensor::YX] = deltaOwn & gradGradDUcompYX.internalField()[own];
|
||||||
// deltaNeiDotgradGradDUNei[tensor::YX] = deltaNei & gradGradDUcompYX.internalField()[nei];
|
// deltaNeiDotgradGradDUNei[tensor::YX] = deltaNei & gradGradDUcompYX.internalField()[nei];
|
||||||
// deltaOwnDotgradGradDUOwn[tensor::YY] = deltaOwn & gradGradDUcompYY.internalField()[own];
|
// deltaOwnDotgradGradDUOwn[tensor::YY] = deltaOwn & gradGradDUcompYY.internalField()[own];
|
||||||
// deltaNeiDotgradGradDUNei[tensor::YY] = deltaNei & gradGradDUcompYY.internalField()[nei];
|
// deltaNeiDotgradGradDUNei[tensor::YY] = deltaNei & gradGradDUcompYY.internalField()[nei];
|
||||||
// deltaOwnDotgradGradDUOwn[tensor::YZ] = deltaOwn & gradGradDUcompYZ.internalField()[own];
|
// deltaOwnDotgradGradDUOwn[tensor::YZ] = deltaOwn & gradGradDUcompYZ.internalField()[own];
|
||||||
// deltaNeiDotgradGradDUNei[tensor::YZ] = deltaNei & gradGradDUcompYZ.internalField()[nei];
|
// deltaNeiDotgradGradDUNei[tensor::YZ] = deltaNei & gradGradDUcompYZ.internalField()[nei];
|
||||||
|
|
||||||
// deltaOwnDotgradGradDUOwn[tensor::ZX] = deltaOwn & gradGradDUcompZX.internalField()[own];
|
// deltaOwnDotgradGradDUOwn[tensor::ZX] = deltaOwn & gradGradDUcompZX.internalField()[own];
|
||||||
// deltaNeiDotgradGradDUNei[tensor::ZX] = deltaNei & gradGradDUcompZX.internalField()[nei];
|
// deltaNeiDotgradGradDUNei[tensor::ZX] = deltaNei & gradGradDUcompZX.internalField()[nei];
|
||||||
// deltaOwnDotgradGradDUOwn[tensor::ZY] = deltaOwn & gradGradDUcompZY.internalField()[own];
|
// deltaOwnDotgradGradDUOwn[tensor::ZY] = deltaOwn & gradGradDUcompZY.internalField()[own];
|
||||||
// deltaNeiDotgradGradDUNei[tensor::ZY] = deltaNei & gradGradDUcompZY.internalField()[nei];
|
// deltaNeiDotgradGradDUNei[tensor::ZY] = deltaNei & gradGradDUcompZY.internalField()[nei];
|
||||||
// deltaOwnDotgradGradDUOwn[tensor::ZZ] = deltaOwn & gradGradDUcompZZ.internalField()[own];
|
// deltaOwnDotgradGradDUOwn[tensor::ZZ] = deltaOwn & gradGradDUcompZZ.internalField()[own];
|
||||||
// deltaNeiDotgradGradDUNei[tensor::ZZ] = deltaNei & gradGradDUcompZZ.internalField()[nei];
|
// deltaNeiDotgradGradDUNei[tensor::ZZ] = deltaNei & gradGradDUcompZZ.internalField()[nei];
|
||||||
|
|
||||||
scalar gradGradDUXXXOwn = gradGradDUXXX.internalField()[own];
|
scalar gradGradDUXXXOwn = gradGradDUXXX.internalField()[own];
|
||||||
scalar gradGradDUXXYOwn = gradGradDUXXY.internalField()[own];
|
scalar gradGradDUXXYOwn = gradGradDUXXY.internalField()[own];
|
||||||
scalar gradGradDUXXZOwn = gradGradDUXXZ.internalField()[own];
|
scalar gradGradDUXXZOwn = gradGradDUXXZ.internalField()[own];
|
||||||
|
|
||||||
scalar gradGradDUXYXOwn = gradGradDUXYX.internalField()[own];
|
scalar gradGradDUXYXOwn = gradGradDUXYX.internalField()[own];
|
||||||
scalar gradGradDUXYYOwn = gradGradDUXYY.internalField()[own];
|
scalar gradGradDUXYYOwn = gradGradDUXYY.internalField()[own];
|
||||||
scalar gradGradDUXYZOwn = gradGradDUXYZ.internalField()[own];
|
scalar gradGradDUXYZOwn = gradGradDUXYZ.internalField()[own];
|
||||||
|
|
||||||
scalar gradGradDUXZXOwn = gradGradDUXZX.internalField()[own];
|
scalar gradGradDUXZXOwn = gradGradDUXZX.internalField()[own];
|
||||||
scalar gradGradDUXZYOwn = gradGradDUXZY.internalField()[own];
|
scalar gradGradDUXZYOwn = gradGradDUXZY.internalField()[own];
|
||||||
scalar gradGradDUXZZOwn = gradGradDUXZZ.internalField()[own];
|
scalar gradGradDUXZZOwn = gradGradDUXZZ.internalField()[own];
|
||||||
|
|
||||||
|
|
||||||
scalar gradGradDUYXXOwn = gradGradDUYXX.internalField()[own];
|
scalar gradGradDUYXXOwn = gradGradDUYXX.internalField()[own];
|
||||||
scalar gradGradDUYXYOwn = gradGradDUYXY.internalField()[own];
|
scalar gradGradDUYXYOwn = gradGradDUYXY.internalField()[own];
|
||||||
scalar gradGradDUYXZOwn = gradGradDUYXZ.internalField()[own];
|
scalar gradGradDUYXZOwn = gradGradDUYXZ.internalField()[own];
|
||||||
|
|
||||||
scalar gradGradDUYYXOwn = gradGradDUYYX.internalField()[own];
|
scalar gradGradDUYYXOwn = gradGradDUYYX.internalField()[own];
|
||||||
scalar gradGradDUYYYOwn = gradGradDUYYY.internalField()[own];
|
scalar gradGradDUYYYOwn = gradGradDUYYY.internalField()[own];
|
||||||
scalar gradGradDUYYZOwn = gradGradDUYYZ.internalField()[own];
|
scalar gradGradDUYYZOwn = gradGradDUYYZ.internalField()[own];
|
||||||
|
|
||||||
scalar gradGradDUYZXOwn = gradGradDUYZX.internalField()[own];
|
scalar gradGradDUYZXOwn = gradGradDUYZX.internalField()[own];
|
||||||
scalar gradGradDUYZYOwn = gradGradDUYZY.internalField()[own];
|
scalar gradGradDUYZYOwn = gradGradDUYZY.internalField()[own];
|
||||||
scalar gradGradDUYZZOwn = gradGradDUYZZ.internalField()[own];
|
scalar gradGradDUYZZOwn = gradGradDUYZZ.internalField()[own];
|
||||||
|
|
||||||
|
|
||||||
scalar gradGradDUZXXOwn = gradGradDUZXX.internalField()[own];
|
scalar gradGradDUZXXOwn = gradGradDUZXX.internalField()[own];
|
||||||
scalar gradGradDUZXYOwn = gradGradDUZXY.internalField()[own];
|
scalar gradGradDUZXYOwn = gradGradDUZXY.internalField()[own];
|
||||||
scalar gradGradDUZXZOwn = gradGradDUZXZ.internalField()[own];
|
scalar gradGradDUZXZOwn = gradGradDUZXZ.internalField()[own];
|
||||||
|
|
||||||
scalar gradGradDUZYXOwn = gradGradDUZYX.internalField()[own];
|
scalar gradGradDUZYXOwn = gradGradDUZYX.internalField()[own];
|
||||||
scalar gradGradDUZYYOwn = gradGradDUZYY.internalField()[own];
|
scalar gradGradDUZYYOwn = gradGradDUZYY.internalField()[own];
|
||||||
scalar gradGradDUZYZOwn = gradGradDUZYZ.internalField()[own];
|
scalar gradGradDUZYZOwn = gradGradDUZYZ.internalField()[own];
|
||||||
|
|
||||||
scalar gradGradDUZZXOwn = gradGradDUZZX.internalField()[own];
|
scalar gradGradDUZZXOwn = gradGradDUZZX.internalField()[own];
|
||||||
scalar gradGradDUZZYOwn = gradGradDUZZY.internalField()[own];
|
scalar gradGradDUZZYOwn = gradGradDUZZY.internalField()[own];
|
||||||
scalar gradGradDUZZZOwn = gradGradDUZZZ.internalField()[own];
|
scalar gradGradDUZZZOwn = gradGradDUZZZ.internalField()[own];
|
||||||
|
|
||||||
|
|
||||||
// nei
|
// nei
|
||||||
scalar gradGradDUXXXNei = gradGradDUXXX.internalField()[nei];
|
scalar gradGradDUXXXNei = gradGradDUXXX.internalField()[nei];
|
||||||
scalar gradGradDUXXYNei = gradGradDUXXY.internalField()[nei];
|
scalar gradGradDUXXYNei = gradGradDUXXY.internalField()[nei];
|
||||||
scalar gradGradDUXXZNei = gradGradDUXXZ.internalField()[nei];
|
scalar gradGradDUXXZNei = gradGradDUXXZ.internalField()[nei];
|
||||||
|
|
||||||
scalar gradGradDUXYXNei = gradGradDUXYX.internalField()[nei];
|
scalar gradGradDUXYXNei = gradGradDUXYX.internalField()[nei];
|
||||||
scalar gradGradDUXYYNei = gradGradDUXYY.internalField()[nei];
|
scalar gradGradDUXYYNei = gradGradDUXYY.internalField()[nei];
|
||||||
scalar gradGradDUXYZNei = gradGradDUXYZ.internalField()[nei];
|
scalar gradGradDUXYZNei = gradGradDUXYZ.internalField()[nei];
|
||||||
|
|
||||||
scalar gradGradDUXZXNei = gradGradDUXZX.internalField()[nei];
|
scalar gradGradDUXZXNei = gradGradDUXZX.internalField()[nei];
|
||||||
scalar gradGradDUXZYNei = gradGradDUXZY.internalField()[nei];
|
scalar gradGradDUXZYNei = gradGradDUXZY.internalField()[nei];
|
||||||
scalar gradGradDUXZZNei = gradGradDUXZZ.internalField()[nei];
|
scalar gradGradDUXZZNei = gradGradDUXZZ.internalField()[nei];
|
||||||
|
|
||||||
|
|
||||||
scalar gradGradDUYXXNei = gradGradDUYXX.internalField()[nei];
|
scalar gradGradDUYXXNei = gradGradDUYXX.internalField()[nei];
|
||||||
scalar gradGradDUYXYNei = gradGradDUYXY.internalField()[nei];
|
scalar gradGradDUYXYNei = gradGradDUYXY.internalField()[nei];
|
||||||
scalar gradGradDUYXZNei = gradGradDUYXZ.internalField()[nei];
|
scalar gradGradDUYXZNei = gradGradDUYXZ.internalField()[nei];
|
||||||
|
|
||||||
scalar gradGradDUYYXNei = gradGradDUYYX.internalField()[nei];
|
scalar gradGradDUYYXNei = gradGradDUYYX.internalField()[nei];
|
||||||
scalar gradGradDUYYYNei = gradGradDUYYY.internalField()[nei];
|
scalar gradGradDUYYYNei = gradGradDUYYY.internalField()[nei];
|
||||||
scalar gradGradDUYYZNei = gradGradDUYYZ.internalField()[nei];
|
scalar gradGradDUYYZNei = gradGradDUYYZ.internalField()[nei];
|
||||||
|
|
||||||
scalar gradGradDUYZXNei = gradGradDUYZX.internalField()[nei];
|
scalar gradGradDUYZXNei = gradGradDUYZX.internalField()[nei];
|
||||||
scalar gradGradDUYZYNei = gradGradDUYZY.internalField()[nei];
|
scalar gradGradDUYZYNei = gradGradDUYZY.internalField()[nei];
|
||||||
scalar gradGradDUYZZNei = gradGradDUYZZ.internalField()[nei];
|
scalar gradGradDUYZZNei = gradGradDUYZZ.internalField()[nei];
|
||||||
|
|
||||||
|
|
||||||
scalar gradGradDUZXXNei = gradGradDUZXX.internalField()[nei];
|
scalar gradGradDUZXXNei = gradGradDUZXX.internalField()[nei];
|
||||||
scalar gradGradDUZXYNei = gradGradDUZXY.internalField()[nei];
|
scalar gradGradDUZXYNei = gradGradDUZXY.internalField()[nei];
|
||||||
scalar gradGradDUZXZNei = gradGradDUZXZ.internalField()[nei];
|
scalar gradGradDUZXZNei = gradGradDUZXZ.internalField()[nei];
|
||||||
|
|
||||||
scalar gradGradDUZYXNei = gradGradDUZYX.internalField()[nei];
|
scalar gradGradDUZYXNei = gradGradDUZYX.internalField()[nei];
|
||||||
scalar gradGradDUZYYNei = gradGradDUZYY.internalField()[nei];
|
scalar gradGradDUZYYNei = gradGradDUZYY.internalField()[nei];
|
||||||
scalar gradGradDUZYZNei = gradGradDUZYZ.internalField()[nei];
|
scalar gradGradDUZYZNei = gradGradDUZYZ.internalField()[nei];
|
||||||
|
|
||||||
scalar gradGradDUZZXNei = gradGradDUZZX.internalField()[nei];
|
scalar gradGradDUZZXNei = gradGradDUZZX.internalField()[nei];
|
||||||
scalar gradGradDUZZYNei = gradGradDUZZY.internalField()[nei];
|
scalar gradGradDUZZYNei = gradGradDUZZY.internalField()[nei];
|
||||||
scalar gradGradDUZZZNei = gradGradDUZZZ.internalField()[nei];
|
scalar gradGradDUZZZNei = gradGradDUZZZ.internalField()[nei];
|
||||||
|
|
||||||
tensor deltaOwnDotgradGradDUOwn =
|
tensor deltaOwnDotgradGradDUOwn = tensor
|
||||||
tensor(
|
|
||||||
deltaOwn.x()*gradGradDUXXXOwn + deltaOwn.y()*gradGradDUYXXOwn + deltaOwn.z()*gradGradDUZXXOwn,
|
|
||||||
deltaOwn.x()*gradGradDUXXYOwn + deltaOwn.y()*gradGradDUYXYOwn + deltaOwn.z()*gradGradDUZXYOwn,
|
|
||||||
deltaOwn.x()*gradGradDUXXZOwn + deltaOwn.y()*gradGradDUYXZOwn + deltaOwn.z()*gradGradDUZXZOwn,
|
|
||||||
|
|
||||||
deltaOwn.x()*gradGradDUXYXOwn + deltaOwn.y()*gradGradDUYYXOwn + deltaOwn.z()*gradGradDUZYXOwn,
|
|
||||||
deltaOwn.x()*gradGradDUXYYOwn + deltaOwn.y()*gradGradDUYYYOwn + deltaOwn.z()*gradGradDUZYYOwn,
|
|
||||||
deltaOwn.x()*gradGradDUXYZOwn + deltaOwn.y()*gradGradDUYYZOwn + deltaOwn.z()*gradGradDUZYZOwn,
|
|
||||||
|
|
||||||
deltaOwn.x()*gradGradDUXZXOwn + deltaOwn.y()*gradGradDUYZXOwn + deltaOwn.z()*gradGradDUZZXOwn,
|
|
||||||
deltaOwn.x()*gradGradDUXZYOwn + deltaOwn.y()*gradGradDUYZYOwn + deltaOwn.z()*gradGradDUZZYOwn,
|
|
||||||
deltaOwn.x()*gradGradDUXZZOwn + deltaOwn.y()*gradGradDUYZZOwn + deltaOwn.z()*gradGradDUZZZOwn
|
|
||||||
);
|
|
||||||
|
|
||||||
tensor deltaNeiDotgradGradDUNei =
|
|
||||||
tensor(
|
|
||||||
deltaNei.x()*gradGradDUXXXNei + deltaNei.y()*gradGradDUYXXNei + deltaNei.z()*gradGradDUZXXNei,
|
|
||||||
deltaNei.x()*gradGradDUXXYNei + deltaNei.y()*gradGradDUYXYNei + deltaNei.z()*gradGradDUZXYNei,
|
|
||||||
deltaNei.x()*gradGradDUXXZNei + deltaNei.y()*gradGradDUYXZNei + deltaNei.z()*gradGradDUZXZNei,
|
|
||||||
|
|
||||||
deltaNei.x()*gradGradDUXYXNei + deltaNei.y()*gradGradDUYYXNei + deltaNei.z()*gradGradDUZYXNei,
|
|
||||||
deltaNei.x()*gradGradDUXYYNei + deltaNei.y()*gradGradDUYYYNei + deltaNei.z()*gradGradDUZYYNei,
|
|
||||||
deltaNei.x()*gradGradDUXYZNei + deltaNei.y()*gradGradDUYYZNei + deltaNei.z()*gradGradDUZYZNei,
|
|
||||||
|
|
||||||
deltaNei.x()*gradGradDUXZXNei + deltaNei.y()*gradGradDUYZXNei + deltaNei.z()*gradGradDUZZXNei,
|
|
||||||
deltaNei.x()*gradGradDUXZYNei + deltaNei.y()*gradGradDUYZYNei + deltaNei.z()*gradGradDUZZYNei,
|
|
||||||
deltaNei.x()*gradGradDUXZZNei + deltaNei.y()*gradGradDUYZZNei + deltaNei.z()*gradGradDUZZZNei
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// get average of extrapolated values
|
|
||||||
tensor extrapFaceGrad =
|
|
||||||
0.5*
|
|
||||||
(
|
(
|
||||||
gradDUOwn + (deltaOwnDotgradGradDUOwn)
|
deltaOwn.x()*gradGradDUXXXOwn + deltaOwn.y()*gradGradDUYXXOwn + deltaOwn.z()*gradGradDUZXXOwn,
|
||||||
+
|
deltaOwn.x()*gradGradDUXXYOwn + deltaOwn.y()*gradGradDUYXYOwn + deltaOwn.z()*gradGradDUZXYOwn,
|
||||||
gradDUNei + (deltaNeiDotgradGradDUNei)
|
deltaOwn.x()*gradGradDUXXZOwn + deltaOwn.y()*gradGradDUYXZOwn + deltaOwn.z()*gradGradDUZXZOwn,
|
||||||
);
|
|
||||||
|
|
||||||
extrapGradDU.internalField()[facei] = extrapFaceGrad;
|
deltaOwn.x()*gradGradDUXYXOwn + deltaOwn.y()*gradGradDUYYXOwn + deltaOwn.z()*gradGradDUZYXOwn,
|
||||||
|
deltaOwn.x()*gradGradDUXYYOwn + deltaOwn.y()*gradGradDUYYYOwn + deltaOwn.z()*gradGradDUZYYOwn,
|
||||||
|
deltaOwn.x()*gradGradDUXYZOwn + deltaOwn.y()*gradGradDUYYZOwn + deltaOwn.z()*gradGradDUZYZOwn,
|
||||||
|
|
||||||
|
deltaOwn.x()*gradGradDUXZXOwn + deltaOwn.y()*gradGradDUYZXOwn + deltaOwn.z()*gradGradDUZZXOwn,
|
||||||
|
deltaOwn.x()*gradGradDUXZYOwn + deltaOwn.y()*gradGradDUYZYOwn + deltaOwn.z()*gradGradDUZZYOwn,
|
||||||
|
deltaOwn.x()*gradGradDUXZZOwn + deltaOwn.y()*gradGradDUYZZOwn + deltaOwn.z()*gradGradDUZZZOwn
|
||||||
|
);
|
||||||
|
|
||||||
|
tensor deltaNeiDotgradGradDUNei = tensor
|
||||||
|
(
|
||||||
|
deltaNei.x()*gradGradDUXXXNei + deltaNei.y()*gradGradDUYXXNei + deltaNei.z()*gradGradDUZXXNei,
|
||||||
|
deltaNei.x()*gradGradDUXXYNei + deltaNei.y()*gradGradDUYXYNei + deltaNei.z()*gradGradDUZXYNei,
|
||||||
|
deltaNei.x()*gradGradDUXXZNei + deltaNei.y()*gradGradDUYXZNei + deltaNei.z()*gradGradDUZXZNei,
|
||||||
|
|
||||||
|
deltaNei.x()*gradGradDUXYXNei + deltaNei.y()*gradGradDUYYXNei + deltaNei.z()*gradGradDUZYXNei,
|
||||||
|
deltaNei.x()*gradGradDUXYYNei + deltaNei.y()*gradGradDUYYYNei + deltaNei.z()*gradGradDUZYYNei,
|
||||||
|
deltaNei.x()*gradGradDUXYZNei + deltaNei.y()*gradGradDUYYZNei + deltaNei.z()*gradGradDUZYZNei,
|
||||||
|
|
||||||
|
deltaNei.x()*gradGradDUXZXNei + deltaNei.y()*gradGradDUYZXNei + deltaNei.z()*gradGradDUZZXNei,
|
||||||
|
deltaNei.x()*gradGradDUXZYNei + deltaNei.y()*gradGradDUYZYNei + deltaNei.z()*gradGradDUZZYNei,
|
||||||
|
deltaNei.x()*gradGradDUXZZNei + deltaNei.y()*gradGradDUYZZNei + deltaNei.z()*gradGradDUZZZNei
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// get average of extrapolated values
|
||||||
|
tensor extrapFaceGrad =
|
||||||
|
0.5*
|
||||||
|
(
|
||||||
|
gradDUOwn + (deltaOwnDotgradGradDUOwn)
|
||||||
|
+
|
||||||
|
gradDUNei + (deltaNeiDotgradGradDUNei)
|
||||||
|
);
|
||||||
|
|
||||||
|
extrapGradDU.internalField()[facei] = extrapFaceGrad;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// correction is zero on boundary
|
// correction is zero on boundary
|
||||||
forAll(extrapGradDU.boundaryField(), patchi)
|
forAll(extrapGradDU.boundaryField(), patchi)
|
||||||
{
|
{
|
||||||
extrapGradDU.boundaryField()[patchi] =
|
extrapGradDU.boundaryField()[patchi] =
|
||||||
averageGradDU.boundaryField()[patchi];
|
averageGradDU.boundaryField()[patchi];
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate thirdOrderTerm
|
// calculate thirdOrderTerm
|
||||||
volVectorField divThirdOrderTerm (
|
volVectorField divThirdOrderTerm
|
||||||
"thirdOrderTerm",
|
(
|
||||||
fvc::div(
|
"thirdOrderTerm",
|
||||||
(2*muf+lambdaf)*mesh.Sf()
|
fvc::div
|
||||||
& (extrapGradDU - averageGradDU)
|
(
|
||||||
)
|
(2*muf+lambdaf)*mesh.Sf() & (extrapGradDU - averageGradDU)
|
||||||
);
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// if(runTime.outputTime())
|
// if(runTime.outputTime())
|
||||||
// {
|
// {
|
||||||
// divThirdOrderTerm.write();
|
// divThirdOrderTerm.write();
|
||||||
// averageGradDU.write();
|
// averageGradDU.write();
|
||||||
// extrapGradDU.write();
|
// extrapGradDU.write();
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
volTensorField gradDU = fvc::grad(DU);
|
volTensorField gradDU = fvc::grad(DU);
|
||||||
|
|
||||||
|
Info<< "Creating field U\n" << endl;
|
||||||
volVectorField U
|
volVectorField U
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
|
@ -24,23 +25,23 @@
|
||||||
IOobject::READ_IF_PRESENT,
|
IOobject::READ_IF_PRESENT,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedVector("zero", dimLength, vector::zero)
|
dimensionedVector("zero", dimLength, vector::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
volTensorField gradU
|
volTensorField gradU
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"grad(U)",
|
"grad(U)",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::READ_IF_PRESENT,
|
IOobject::READ_IF_PRESENT,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedTensor("zero", dimless, tensor::zero)
|
dimensionedTensor("zero", dimless, tensor::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Increment of Green finite strain tensor
|
//- Increment of Green finite strain tensor
|
||||||
volSymmTensorField DEpsilon
|
volSymmTensorField DEpsilon
|
||||||
|
@ -53,8 +54,8 @@
|
||||||
IOobject::READ_IF_PRESENT,
|
IOobject::READ_IF_PRESENT,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedSymmTensor("zero", dimless, symmTensor::zero)
|
dimensionedSymmTensor("zero", dimless, symmTensor::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
volSymmTensorField epsilon
|
volSymmTensorField epsilon
|
||||||
|
@ -67,8 +68,8 @@
|
||||||
IOobject::READ_IF_PRESENT,
|
IOobject::READ_IF_PRESENT,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedSymmTensor("zero", dimless, symmTensor::zero)
|
dimensionedSymmTensor("zero", dimless, symmTensor::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
//- plastic strain
|
//- plastic strain
|
||||||
|
@ -113,42 +114,41 @@
|
||||||
IOobject::READ_IF_PRESENT,
|
IOobject::READ_IF_PRESENT,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedSymmTensor("zero", dimForce/dimArea, symmTensor::zero)
|
dimensionedSymmTensor("zero", dimForce/dimArea, symmTensor::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
volVectorField divDSigmaExp
|
volVectorField divDSigmaExp
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"divDSigmaExp",
|
"divDSigmaExp",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedVector("zero", dimensionSet(1,-2,-2,0,0,0,0), vector::zero)
|
dimensionedVector("zero", dimensionSet(1, -2, -2, 0, 0, 0, 0), vector::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
volVectorField divDSigmaNonLinExp
|
volVectorField divDSigmaNonLinExp
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"divDSigmaNonLinExp",
|
"divDSigmaNonLinExp",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedVector("zero", dimensionSet(1,-2,-2,0,0,0,0), vector::zero)
|
dimensionedVector("zero", dimensionSet(1,-2,-2,0,0,0,0), vector::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
constitutiveModel rheology(sigma, DU);
|
constitutiveModel rheology(sigma, DU);
|
||||||
|
|
||||||
volScalarField rho = rheology.rho();
|
volScalarField rho = rheology.rho();
|
||||||
|
|
||||||
volScalarField mu = rheology.mu();
|
volScalarField mu = rheology.mu();
|
||||||
volScalarField lambda = rheology.lambda();
|
volScalarField lambda = rheology.lambda();
|
||||||
surfaceScalarField muf = fvc::interpolate(mu, "mu");
|
surfaceScalarField muf = fvc::interpolate(mu, "mu");
|
||||||
|
@ -156,11 +156,11 @@
|
||||||
|
|
||||||
surfaceVectorField n = mesh.Sf()/mesh.magSf();
|
surfaceVectorField n = mesh.Sf()/mesh.magSf();
|
||||||
|
|
||||||
// plastic strain increment
|
// plastic strain increment
|
||||||
const volSymmTensorField& DEpsilonP = rheology.DEpsilonP();
|
const volSymmTensorField& DEpsilonP = rheology.DEpsilonP();
|
||||||
|
|
||||||
// for aitken relaxation
|
// for aitken relaxation
|
||||||
volVectorField aitkenDelta
|
volVectorField aitkenDelta
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
|
@ -171,22 +171,23 @@
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedVector("zero", dimLength, vector::zero)
|
dimensionedVector("zero", dimLength, vector::zero)
|
||||||
);
|
);
|
||||||
// aitken relaxation factor
|
|
||||||
scalar aitkenInitialRes = 1.0;
|
// aitken relaxation factor
|
||||||
scalar aitkenTheta = 0.1;
|
scalar aitkenInitialRes = 1.0;
|
||||||
|
scalar aitkenTheta = 0.1;
|
||||||
|
|
||||||
// volVectorField resid
|
// volVectorField resid
|
||||||
// (
|
// (
|
||||||
// IOobject
|
// IOobject
|
||||||
// (
|
// (
|
||||||
// "resid",
|
// "resid",
|
||||||
// runTime.timeName(),
|
// runTime.timeName(),
|
||||||
// mesh,
|
// mesh,
|
||||||
// IOobject::NO_READ,
|
// IOobject::NO_READ,
|
||||||
// IOobject::AUTO_WRITE
|
// IOobject::AUTO_WRITE
|
||||||
// ),
|
// ),
|
||||||
// mesh,
|
// mesh,
|
||||||
// dimensionedVector("zero", dimless, vector::zero)
|
// dimensionedVector("zero", dimless, vector::zero)
|
||||||
// );
|
// );
|
||||||
|
|
|
@ -1,36 +1,36 @@
|
||||||
OFstream * forceFilePtr(NULL);
|
OFstream* forceFilePtr(NULL);
|
||||||
OFstream * stressFilePtr(NULL);
|
OFstream* stressFilePtr(NULL);
|
||||||
word historyPatchName(mesh.solutionDict().subDict("solidMechanics").lookup("historyPatch"));
|
word historyPatchName(mesh.solutionDict().subDict("solidMechanics").lookup("historyPatch"));
|
||||||
label historyPatchID = mesh.boundaryMesh().findPatchID(historyPatchName);
|
label historyPatchID = mesh.boundaryMesh().findPatchID(historyPatchName);
|
||||||
if(historyPatchID == -1)
|
if(historyPatchID == -1)
|
||||||
{
|
{
|
||||||
Warning << "history patch " << historyPatchName
|
Warning << "history patch " << historyPatchName
|
||||||
<< " not found. Force-displacement will not be written"
|
<< " not found. Force-displacement will not be written"
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
else if(Pstream::master())
|
else if(Pstream::master())
|
||||||
{
|
{
|
||||||
fileName historyDir = "history";
|
fileName historyDir = "history";
|
||||||
mkDir(historyDir);
|
mkDir(historyDir);
|
||||||
|
|
||||||
{
|
{
|
||||||
fileName forceFileName(historyDir/"forceDisp_"+historyPatchName+".dat");
|
fileName forceFileName(historyDir/"forceDisp_"+historyPatchName+".dat");
|
||||||
Info << "\nForce-displacement for patch " << historyPatchName
|
Info << "\nForce-displacement for patch " << historyPatchName
|
||||||
<< " will be written to " << forceFileName
|
<< " will be written to " << forceFileName
|
||||||
<< endl;
|
<< endl;
|
||||||
forceFilePtr = new OFstream(forceFileName);
|
forceFilePtr = new OFstream(forceFileName);
|
||||||
OFstream& forceDispFile = *forceFilePtr;
|
OFstream& forceDispFile = *forceFilePtr;
|
||||||
forceDispFile << "#Disp(mm)\tForce(N)" << endl;
|
forceDispFile << "#Disp(mm)\tForce(N)" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
fileName stressFileName(historyDir/"stressStrain_"+historyPatchName+".dat");
|
fileName stressFileName(historyDir/"stressStrain_"+historyPatchName+".dat");
|
||||||
Info << "\nStress(2nd Piola-Kirchoff)-strain(Green) for patch "
|
Info << "\nStress(2nd Piola-Kirchoff)-strain(Green) for patch "
|
||||||
<< historyPatchName
|
<< historyPatchName
|
||||||
<< " will be written to " << stressFileName
|
<< " will be written to " << stressFileName
|
||||||
<< endl;
|
<< endl;
|
||||||
stressFilePtr = new OFstream(stressFileName);
|
stressFilePtr = new OFstream(stressFileName);
|
||||||
OFstream& stressStrainFile = *stressFilePtr;
|
OFstream& stressStrainFile = *stressFilePtr;
|
||||||
stressStrainFile << "#Strain(-)\tStress(Pa)" << endl;
|
stressStrainFile << "#Strain(-)\tStress(Pa)" << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,158 +54,158 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Info<< "\nStarting time loop\n" << endl;
|
Info<< "\nStarting time loop\n" << endl;
|
||||||
|
|
||||||
while(runTime.loop())
|
while(runTime.loop())
|
||||||
{
|
{
|
||||||
Info<< "Time: " << runTime.timeName() << nl << endl;
|
Info<< "Time = " << runTime.timeName() << nl << endl;
|
||||||
|
|
||||||
# include "readSolidMechanicsControls.H"
|
# include "readSolidMechanicsControls.H"
|
||||||
|
|
||||||
int iCorr = 0;
|
int iCorr = 0;
|
||||||
scalar initialResidual = 0;
|
scalar initialResidual = 0;
|
||||||
lduMatrix::solverPerformance solverPerf;
|
lduMatrix::solverPerformance solverPerf;
|
||||||
scalar relativeResidual = GREAT;
|
scalar relativeResidual = GREAT;
|
||||||
lduMatrix::debug = 0;
|
lduMatrix::debug = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
DU.storePrevIter();
|
DU.storePrevIter();
|
||||||
|
|
||||||
# include "calculateDivDSigmaExp.H"
|
# include "calculateDivDSigmaExp.H"
|
||||||
# include "calculateDivDSigmaNonLinExp.H"
|
# include "calculateDivDSigmaNonLinExp.H"
|
||||||
|
|
||||||
// Incremental form of the
|
// Incremental form of the
|
||||||
// linear momentum conservation
|
// linear momentum conservation
|
||||||
// ensuring conservation of total momentum
|
// ensuring conservation of total momentum
|
||||||
fvVectorMatrix DUEqn
|
fvVectorMatrix DUEqn
|
||||||
(
|
(
|
||||||
fvm::d2dt2(rho, DU)
|
fvm::d2dt2(rho, DU)
|
||||||
==
|
==
|
||||||
fvm::laplacian(2*muf + lambdaf, DU, "laplacian(DDU,DU)")
|
fvm::laplacian(2*muf + lambdaf, DU, "laplacian(DDU,DU)")
|
||||||
+ divDSigmaExp
|
+ divDSigmaExp
|
||||||
+ divDSigmaNonLinExp
|
+ divDSigmaNonLinExp
|
||||||
//- fvc::div(2*mu*DEpsilonP, "div(sigma)")
|
//- fvc::div(2*mu*DEpsilonP, "div(sigma)")
|
||||||
- fvc::div
|
- fvc::div
|
||||||
(
|
(
|
||||||
2*muf*(mesh.Sf() & fvc::interpolate(DEpsilonP))
|
2*muf*(mesh.Sf() & fvc::interpolate(DEpsilonP))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (largeStrainOverRelax)
|
if (largeStrainOverRelax)
|
||||||
{
|
{
|
||||||
// the terms (gradDU & gradU.T()) and (gradU & gradDU.T())
|
// the terms (gradDU & gradU.T()) and (gradU & gradDU.T())
|
||||||
// are linearly dependent of DU and represent initial
|
// are linearly dependent of DU and represent initial
|
||||||
// displacement effect
|
// displacement effect
|
||||||
// which can cause convergence difficulties when treated
|
// which can cause convergence difficulties when treated
|
||||||
// explicitly
|
// explicitly
|
||||||
// so we implicitly over-relax with gradU & gradDU here
|
// so we implicitly over-relax with gradU & gradDU here
|
||||||
// which tends to help convergence
|
// which tends to help convergence
|
||||||
// this should improve convergence when gradU is large
|
// this should improve convergence when gradU is large
|
||||||
// but maybe not execution time
|
// but maybe not execution time
|
||||||
DUEqn -=
|
DUEqn -=
|
||||||
fvm::laplacian
|
fvm::laplacian
|
||||||
(
|
(
|
||||||
(2*mu + lambda)*gradU, DU, "laplacian(DDU,DU)"
|
(2*mu + lambda)*gradU, DU, "laplacian(DDU,DU)"
|
||||||
)
|
)
|
||||||
- fvc::div((2*mu + lambda)*(gradU & gradDU), "div(sigma)");
|
- fvc::div((2*mu + lambda)*(gradU & gradDU), "div(sigma)");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nonLinearSemiImplicit)
|
if (nonLinearSemiImplicit)
|
||||||
{
|
{
|
||||||
// experimental
|
// experimental
|
||||||
// we can treat the nonlinear term (gradDU & gradDU.T()) in a
|
// we can treat the nonlinear term (gradDU & gradDU.T()) in a
|
||||||
// semi-implicit over-relaxed manner
|
// semi-implicit over-relaxed manner
|
||||||
// this should improve convergence when gradDU is large
|
// this should improve convergence when gradDU is large
|
||||||
// but maybe not execution time
|
// but maybe not execution time
|
||||||
DUEqn -=
|
DUEqn -=
|
||||||
fvm::laplacian
|
fvm::laplacian
|
||||||
(
|
(
|
||||||
(2*mu + lambda)*gradDU, DU, "laplacian(DDU,DU)"
|
(2*mu + lambda)*gradDU, DU, "laplacian(DDU,DU)"
|
||||||
)
|
)
|
||||||
- fvc::div((2*mu + lambda)*(gradDU & gradDU), "div(sigma)");
|
- fvc::div((2*mu + lambda)*(gradDU & gradDU), "div(sigma)");
|
||||||
}
|
}
|
||||||
|
|
||||||
solverPerf = DUEqn.solve();
|
solverPerf = DUEqn.solve();
|
||||||
|
|
||||||
if (iCorr == 0)
|
if (iCorr == 0)
|
||||||
{
|
{
|
||||||
initialResidual = solverPerf.initialResidual();
|
initialResidual = solverPerf.initialResidual();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aitkenRelax)
|
if (aitkenRelax)
|
||||||
{
|
{
|
||||||
# include "aitkenRelaxation.H"
|
# include "aitkenRelaxation.H"
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DU.relax();
|
DU.relax();
|
||||||
}
|
}
|
||||||
|
|
||||||
gradDU = fvc::grad(DU);
|
gradDU = fvc::grad(DU);
|
||||||
|
|
||||||
// correct plasticty term
|
// correct plasticty term
|
||||||
rheology.correct();
|
rheology.correct();
|
||||||
|
|
||||||
# include "calculateDEpsilonDSigma.H"
|
# include "calculateDEpsilonDSigma.H"
|
||||||
# include "calculateRelativeResidual.H"
|
# include "calculateRelativeResidual.H"
|
||||||
|
|
||||||
if (iCorr % infoFrequency == 0)
|
if(iCorr % infoFrequency == 0)
|
||||||
{
|
{
|
||||||
Info<< "\tTime " << runTime.value()
|
Info<< "\tTime " << runTime.value()
|
||||||
<< ", Corrector " << iCorr
|
<< ", Corrector " << iCorr
|
||||||
<< ", Solving for " << DU.name()
|
<< ", Solving for " << DU.name()
|
||||||
<< " using " << solverPerf.solverName()
|
<< " using " << solverPerf.solverName()
|
||||||
<< ", res = " << solverPerf.initialResidual()
|
<< ", res = " << solverPerf.initialResidual()
|
||||||
<< ", rel res = " << relativeResidual;
|
<< ", rel res = " << relativeResidual;
|
||||||
|
|
||||||
if (aitkenRelax)
|
if(aitkenRelax)
|
||||||
{
|
{
|
||||||
Info << ", aitken = " << aitkenTheta;
|
Info<< ", aitken = " << aitkenTheta;
|
||||||
}
|
}
|
||||||
Info << ", iters = " << solverPerf.nIterations() << endl;
|
Info<< ", iters = " << solverPerf.nIterations() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while
|
while
|
||||||
(
|
(
|
||||||
iCorr++ == 0
|
iCorr++ == 0
|
||||||
||
|
||
|
||||||
(
|
(
|
||||||
//solverPerf.initialResidual() > convergenceTolerance
|
//solverPerf.initialResidual() > convergenceTolerance
|
||||||
relativeResidual > convergenceTolerance
|
relativeResidual > convergenceTolerance
|
||||||
&& iCorr < nCorr
|
&& iCorr < nCorr
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
Info<< nl << "Time " << runTime.value() << ", Solving for " << DU.name()
|
Info<< nl << "Time " << runTime.value() << ", Solving for " << DU.name()
|
||||||
<< ", Initial residual = " << initialResidual
|
<< ", Initial residual = " << initialResidual
|
||||||
<< ", Final residual = " << solverPerf.initialResidual()
|
<< ", Final residual = " << solverPerf.initialResidual()
|
||||||
<< ", Relative residual = " << relativeResidual
|
<< ", Relative residual = " << relativeResidual
|
||||||
<< ", No outer iterations " << iCorr
|
<< ", No outer iterations " << iCorr
|
||||||
<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
// Update total quantities
|
// Update total quantities
|
||||||
U += DU;
|
U += DU;
|
||||||
gradU += gradDU;
|
gradU += gradDU;
|
||||||
epsilon += DEpsilon;
|
epsilon += DEpsilon;
|
||||||
epsilonP += rheology.DEpsilonP();
|
epsilonP += rheology.DEpsilonP();
|
||||||
sigma += DSigma;
|
sigma += DSigma;
|
||||||
rheology.updateYieldStress();
|
rheology.updateYieldStress();
|
||||||
rho = rho/det(I+gradU);
|
rho = rho/det(I+gradU);
|
||||||
|
|
||||||
# include "writeFields.H"
|
# include "writeFields.H"
|
||||||
# include "writeHistory.H"
|
# include "writeHistory.H"
|
||||||
|
|
||||||
Info<< "ExecutionTime = "
|
Info<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||||
<< runTime.elapsedCpuTime()
|
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||||
<< " s\n\n" << endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "End\n" << endl;
|
Info<< "End\n" << endl;
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
word divDSigmaNonLinExpMethod(mesh.solutionDict().subDict("solidMechanics").lookup("divSigmaNonLinExp"));
|
word divDSigmaNonLinExpMethod(mesh.solutionDict().subDict("solidMechanics").lookup("divSigmaNonLinExp"));
|
||||||
Info << "divSigmaNonLinExp method " << divDSigmaNonLinExpMethod << endl;
|
Info << "divSigmaNonLinExp method " << divDSigmaNonLinExpMethod << endl;
|
||||||
if(divDSigmaNonLinExpMethod != "standard" && divDSigmaNonLinExpMethod != "surface")
|
if(divDSigmaNonLinExpMethod != "standard" && divDSigmaNonLinExpMethod != "surface")
|
||||||
{
|
{
|
||||||
FatalError << "divSigmaNonLinExp method " << divDSigmaNonLinExpMethod << " not found!" << nl
|
FatalError << "divSigmaNonLinExp method " << divDSigmaNonLinExpMethod << " not found!" << nl
|
||||||
<< "valid methods are:\nstandard\nsurface"
|
<< "valid methods are:\nstandard\nsurface"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,45 +1,45 @@
|
||||||
//- write force displacement to file
|
//- write force displacement to file
|
||||||
if(historyPatchID != -1)
|
if(historyPatchID != -1)
|
||||||
{
|
{
|
||||||
Info << "Writing disp-force to file for patch " << historyPatchName
|
Info << "Writing disp-force to file for patch " << historyPatchName
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
//- for small strain or moving mesh
|
//- for small strain or moving mesh
|
||||||
//scalar force = gSum(
|
//scalar force = gSum(
|
||||||
// direction &
|
// direction &
|
||||||
// (mesh.boundary()[historyPatchID].Sf() & sigma.boundaryField()[historyPatchID])
|
// (mesh.boundary()[historyPatchID].Sf() & sigma.boundaryField()[historyPatchID])
|
||||||
// );
|
//);
|
||||||
|
|
||||||
//- for large strain total lagrangian
|
//- for large strain total lagrangian
|
||||||
tensorField F = I + gradU.boundaryField()[historyPatchID];
|
tensorField F = I + gradU.boundaryField()[historyPatchID];
|
||||||
vector force = gSum(mesh.Sf().boundaryField()[historyPatchID] & (sigma.boundaryField()[historyPatchID] & F));
|
vector force = gSum(mesh.Sf().boundaryField()[historyPatchID] & (sigma.boundaryField()[historyPatchID] & F));
|
||||||
vector disp = gAverage(U.boundaryField()[historyPatchID]);
|
vector disp = gAverage(U.boundaryField()[historyPatchID]);
|
||||||
|
|
||||||
|
|
||||||
Info << "Writing strain-stress to file for patch " << historyPatchName
|
Info << "Writing strain-stress to file for patch " << historyPatchName
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
// avaerage stress strain
|
// average stress strain
|
||||||
symmTensor stress = gAverage(sigma.boundaryField()[historyPatchID]);
|
symmTensor stress = gAverage(sigma.boundaryField()[historyPatchID]);
|
||||||
symmTensor strain = gAverage(epsilon.boundaryField()[historyPatchID]);
|
symmTensor strain = gAverage(epsilon.boundaryField()[historyPatchID]);
|
||||||
|
|
||||||
|
|
||||||
// write to file
|
// write to file
|
||||||
if(Pstream::master())
|
if(Pstream::master())
|
||||||
{
|
{
|
||||||
OFstream& forceDispFile = *forceFilePtr;
|
OFstream& forceDispFile = *forceFilePtr;
|
||||||
label width = 20;
|
label width = 20;
|
||||||
forceDispFile << disp.x() << " " << disp.y() << " " << disp.z();
|
forceDispFile << disp.x() << " " << disp.y() << " " << disp.z();
|
||||||
forceDispFile.width(width);
|
forceDispFile.width(width);
|
||||||
forceDispFile << force.x() << " " << force.y() << " " << force.z()
|
forceDispFile << force.x() << " " << force.y() << " " << force.z()
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
OFstream& stressStrainFile = *stressFilePtr;
|
OFstream& stressStrainFile = *stressFilePtr;
|
||||||
stressStrainFile << strain.xx() << " " << strain.xy() << " " << strain.xz() << " "
|
stressStrainFile << strain.xx() << " " << strain.xy() << " " << strain.xz() << " "
|
||||||
<< strain.yy() << " " << strain.yz() << " " << strain.zz();
|
<< strain.yy() << " " << strain.yz() << " " << strain.zz();
|
||||||
stressStrainFile.width(width);
|
stressStrainFile.width(width);
|
||||||
stressStrainFile << stress.xx() << " " << stress.xy() << " " << stress.xz() << " "
|
stressStrainFile << stress.xx() << " " << stress.xy() << " " << stress.xz() << " "
|
||||||
<< stress.yy() << " " << stress.yz() << " " << stress.zz()
|
<< stress.yy() << " " << stress.yz() << " " << stress.zz()
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
// aitken acceleration
|
// aitken acceleration
|
||||||
if(iCorr == 0)
|
if(iCorr == 0)
|
||||||
{
|
{
|
||||||
aitkenInitialRes = gMax(mag(DU.internalField()));
|
aitkenInitialRes = gMax(mag(DU.internalField()));
|
||||||
}
|
}
|
||||||
|
|
||||||
aitkenDelta.storePrevIter();
|
aitkenDelta.storePrevIter();
|
||||||
|
|
||||||
|
@ -11,26 +11,24 @@ aitkenDelta = (DU - DU.prevIter()) / aitkenInitialRes;
|
||||||
|
|
||||||
// update relaxation factor
|
// update relaxation factor
|
||||||
if(iCorr == 0)
|
if(iCorr == 0)
|
||||||
{
|
{
|
||||||
aitkenTheta = 0.1;
|
aitkenTheta = 0.1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vectorField b = aitkenDelta.internalField() - aitkenDelta.prevIter().internalField();
|
vectorField b = aitkenDelta.internalField() - aitkenDelta.prevIter().internalField();
|
||||||
//scalar sumMagB = gSum(mag(b));
|
//scalar sumMagB = gSum(mag(b));
|
||||||
scalar sumMagB = gSum(magSqr(b));
|
scalar sumMagB = gSum(magSqr(b));
|
||||||
if(sumMagB < SMALL)
|
if(sumMagB < SMALL)
|
||||||
{
|
{
|
||||||
//Warning << "Aitken under-relaxation: denominator less then SMALL"
|
//Warning << "Aitken under-relaxation: denominator less then SMALL"
|
||||||
// << endl;
|
// << endl;
|
||||||
sumMagB += SMALL;
|
sumMagB += SMALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
aitkenTheta = -aitkenTheta*
|
aitkenTheta = -aitkenTheta*
|
||||||
gSum(aitkenDelta.prevIter().internalField() & b)
|
gSum(aitkenDelta.prevIter().internalField() & b)/sumMagB;
|
||||||
/
|
}
|
||||||
sumMagB;
|
|
||||||
}
|
|
||||||
|
|
||||||
// correction to the latest DU
|
// correction to the latest DU
|
||||||
DU += aitkenTheta*aitkenDelta*aitkenInitialRes;
|
DU += aitkenTheta*aitkenDelta*aitkenInitialRes;
|
||||||
|
|
|
@ -1,47 +1,43 @@
|
||||||
if(divDSigmaExpMethod == "standard")
|
if(divDSigmaExpMethod == "standard")
|
||||||
{
|
{
|
||||||
divDSigmaExp = fvc::div
|
divDSigmaExp = fvc::div
|
||||||
(
|
(
|
||||||
mu*gradDU.T() + lambda*(I*tr(gradDU)) - (mu + lambda)*gradDU,
|
mu*gradDU.T() + lambda*(I*tr(gradDU)) - (mu + lambda)*gradDU,
|
||||||
"div(sigma)"
|
"div(sigma)"
|
||||||
);
|
|
||||||
}
|
|
||||||
else if(divDSigmaExpMethod == "surface")
|
|
||||||
{
|
|
||||||
divDSigmaExp = fvc::div
|
|
||||||
(
|
|
||||||
muf*(mesh.Sf() & fvc::interpolate(gradDU.T()))
|
|
||||||
+ lambdaf*(mesh.Sf() & I*fvc::interpolate(tr(gradDU)))
|
|
||||||
- (muf + lambdaf)*(mesh.Sf() & fvc::interpolate(gradDU))
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if(divDSigmaExpMethod == "decompose")
|
else if(divDSigmaExpMethod == "surface")
|
||||||
{
|
{
|
||||||
surfaceTensorField shearGradDU =
|
divDSigmaExp = fvc::div
|
||||||
((I - n*n)&fvc::interpolate(gradDU));
|
(
|
||||||
|
muf*(mesh.Sf() & fvc::interpolate(gradDU.T()))
|
||||||
|
+ lambdaf*(mesh.Sf() & I*fvc::interpolate(tr(gradDU)))
|
||||||
|
- (muf + lambdaf)*(mesh.Sf() & fvc::interpolate(gradDU))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if(divDSigmaExpMethod == "decompose")
|
||||||
|
{
|
||||||
|
surfaceTensorField shearGradDU = ((I - n*n) & fvc::interpolate(gradDU));
|
||||||
|
|
||||||
divDSigmaExp = fvc::div
|
divDSigmaExp = fvc::div
|
||||||
(
|
(
|
||||||
mesh.magSf()
|
mesh.magSf()*
|
||||||
*(
|
(
|
||||||
- (muf + lambdaf)*(fvc::snGrad(DU)&(I - n*n))
|
- (muf + lambdaf)*(fvc::snGrad(DU) & (I - n*n))
|
||||||
+ lambdaf*tr(shearGradDU&(I - n*n))*n
|
+ lambdaf*tr(shearGradDU&(I - n*n))*n
|
||||||
+ muf*(shearGradDU&n)
|
+ muf*(shearGradDU&n)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if(divDSigmaExpMethod == "laplacian")
|
else if(divDSigmaExpMethod == "laplacian")
|
||||||
{
|
{
|
||||||
divDSigmaExp =
|
divDSigmaExp =
|
||||||
- fvc::laplacian(mu + lambda, DU, "laplacian(DDU,DU)")
|
- fvc::laplacian(mu + lambda, DU, "laplacian(DDU,DU)")
|
||||||
+ fvc::div
|
+ fvc::div(mu*gradDU.T() + lambda*(I*tr(gradDU)), "div(sigma)");
|
||||||
(
|
}
|
||||||
mu*gradDU.T()
|
else
|
||||||
+ lambda*(I*tr(gradDU)),
|
{
|
||||||
"div(sigma)"
|
FatalErrorIn(args.executable())
|
||||||
);
|
<< "divDSigmaExp method " << divDSigmaExpMethod << " not found!"
|
||||||
}
|
<< abort(FatalError);
|
||||||
else
|
}
|
||||||
{
|
|
||||||
FatalError << "divDSigmaExp method " << divDSigmaExpMethod << " not found!" << endl;
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
//----------------------------------------------------//
|
//----------------------------------------------------//
|
||||||
if(divDSigmaLargeStrainExpMethod == "standard")
|
if(divDSigmaLargeStrainExpMethod == "standard")
|
||||||
{
|
{
|
||||||
divDSigmaLargeStrainExp =
|
divDSigmaLargeStrainExp = fvc::div
|
||||||
fvc::div
|
|
||||||
(
|
(
|
||||||
mu*(gradDU & gradDU.T())
|
mu*(gradDU & gradDU.T())
|
||||||
+ 0.5*lambda*(gradDU && gradDU)*I //- equivalent to 0.5*lambda*(I*tr(gradDU & gradDU.T()))
|
+ 0.5*lambda*(gradDU && gradDU)*I //- equivalent to 0.5*lambda*(I*tr(gradDU & gradDU.T()))
|
||||||
|
@ -14,8 +13,7 @@ if(divDSigmaLargeStrainExpMethod == "standard")
|
||||||
}
|
}
|
||||||
else if(divDSigmaLargeStrainExpMethod == "surface")
|
else if(divDSigmaLargeStrainExpMethod == "surface")
|
||||||
{
|
{
|
||||||
divDSigmaLargeStrainExp =
|
divDSigmaLargeStrainExp = fvc::div
|
||||||
fvc::div
|
|
||||||
(
|
(
|
||||||
muf * (mesh.Sf() & fvc::interpolate(gradDU & gradDU.T()))
|
muf * (mesh.Sf() & fvc::interpolate(gradDU & gradDU.T()))
|
||||||
+ 0.5*lambdaf * (mesh.Sf() & (fvc::interpolate(gradDU && gradDU)*I))
|
+ 0.5*lambdaf * (mesh.Sf() & (fvc::interpolate(gradDU && gradDU)*I))
|
||||||
|
@ -25,9 +23,9 @@ else if(divDSigmaLargeStrainExpMethod == "surface")
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FatalError
|
FatalError
|
||||||
<< "divDSigmaLargeStrainMethod not found!"
|
<< "divDSigmaLargeStrainMethod not found!"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
//- relax
|
//- relax
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
if(divDSigmaNonLinExpMethod == "standard")
|
if(divDSigmaNonLinExpMethod == "standard")
|
||||||
{
|
{
|
||||||
divDSigmaNonLinExp = fvc::div
|
divDSigmaNonLinExp = fvc::div
|
||||||
(
|
(
|
||||||
( mu * (gradDU & gradDU.T()) )
|
( mu * (gradDU & gradDU.T()) )
|
||||||
+ ( 0.5 * lambda * tr(gradDU & gradDU.T()) * I )
|
+ ( 0.5 * lambda * tr(gradDU & gradDU.T()) * I )
|
||||||
+ ( (sigma + DSigma) & gradDU ),
|
+ ( (sigma + DSigma) & gradDU ),
|
||||||
"div(sigma)"
|
"div(sigma)"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if(divDSigmaNonLinExpMethod == "surface")
|
else if(divDSigmaNonLinExpMethod == "surface")
|
||||||
{
|
{
|
||||||
divDSigmaNonLinExp =
|
divDSigmaNonLinExp = fvc::div
|
||||||
fvc::div(
|
(
|
||||||
mesh.magSf()
|
mesh.magSf()*
|
||||||
*(
|
(
|
||||||
( muf * (n & fvc::interpolate( gradDU & gradDU.T() )) )
|
( muf * (n & fvc::interpolate( gradDU & gradDU.T() )) )
|
||||||
+ ( 0.5*lambdaf * (n * tr(fvc::interpolate( gradDU & gradDU.T() ))) )
|
+ ( 0.5*lambdaf * (n * tr(fvc::interpolate( gradDU & gradDU.T() ))) )
|
||||||
+ (n & fvc::interpolate( (sigma + DSigma) & gradDU ))
|
+ (n & fvc::interpolate( (sigma + DSigma) & gradDU ))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FatalError << "divDSigmaExp method " << divDSigmaExpMethod << " not found!" << endl;
|
FatalError << "divDSigmaExp method " << divDSigmaExpMethod << " not found!" << endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,59 +15,57 @@
|
||||||
FieldField<Field, vector> extraVecs(ptc.size());
|
FieldField<Field, vector> extraVecs(ptc.size());
|
||||||
|
|
||||||
{
|
{
|
||||||
const labelListList& pfaces = mesh.pointFaces();
|
const labelListList& pfaces = mesh.pointFaces();
|
||||||
|
|
||||||
const volVectorField& centres = mesh.C();
|
const volVectorField& centres = mesh.C();
|
||||||
|
|
||||||
const fvBoundaryMesh& bm = mesh.boundary();
|
const fvBoundaryMesh& bm = mesh.boundary();
|
||||||
|
|
||||||
forAll (ptc, pointI)
|
forAll (ptc, pointI)
|
||||||
{
|
{
|
||||||
const label curPoint = ptc[pointI];
|
const label curPoint = ptc[pointI];
|
||||||
|
|
||||||
const labelList& curFaces = pfaces[curPoint];
|
const labelList& curFaces = pfaces[curPoint];
|
||||||
|
|
||||||
// extraVecs.hook(new vectorField(curFaces.size())); //- no hook function
|
// extraVecs.hook(new vectorField(curFaces.size())); //- no hook function
|
||||||
extraVecs.set
|
extraVecs.set
|
||||||
(
|
|
||||||
pointI,
|
|
||||||
new vectorField(curFaces.size())
|
|
||||||
);
|
|
||||||
|
|
||||||
vectorField& curExtraVectors = extraVecs[pointI];
|
|
||||||
|
|
||||||
label nFacesAroundPoint = 0;
|
|
||||||
|
|
||||||
const vector& pointLoc = mesh.points()[curPoint];
|
|
||||||
|
|
||||||
// Go through all the faces
|
|
||||||
forAll (curFaces, faceI)
|
|
||||||
{
|
|
||||||
if (!mesh.isInternalFace(curFaces[faceI]))
|
|
||||||
{
|
|
||||||
// This is a boundary face. If not in the empty patch
|
|
||||||
// or coupled calculate the extrapolation vector
|
|
||||||
label patchID =
|
|
||||||
mesh.boundaryMesh().whichPatch(curFaces[faceI]);
|
|
||||||
|
|
||||||
if
|
|
||||||
(
|
(
|
||||||
!isA<emptyFvPatch>(bm[patchID])
|
pointI,
|
||||||
&& !bm[patchID].coupled()
|
new vectorField(curFaces.size())
|
||||||
)
|
);
|
||||||
|
|
||||||
|
vectorField& curExtraVectors = extraVecs[pointI];
|
||||||
|
|
||||||
|
label nFacesAroundPoint = 0;
|
||||||
|
|
||||||
|
const vector& pointLoc = mesh.points()[curPoint];
|
||||||
|
|
||||||
|
// Go through all the faces
|
||||||
|
forAll (curFaces, faceI)
|
||||||
{
|
{
|
||||||
// Found a face for extrapolation
|
if (!mesh.isInternalFace(curFaces[faceI]))
|
||||||
curExtraVectors[nFacesAroundPoint] =
|
{
|
||||||
pointLoc
|
// This is a boundary face. If not in the empty patch
|
||||||
- centres.boundaryField()[patchID]
|
// or coupled calculate the extrapolation vector
|
||||||
[bm[patchID].patch().whichFace(curFaces[faceI])];
|
label patchID =
|
||||||
|
mesh.boundaryMesh().whichPatch(curFaces[faceI]);
|
||||||
|
|
||||||
nFacesAroundPoint++;
|
if
|
||||||
|
(
|
||||||
|
!isA<emptyFvPatch>(bm[patchID]) && !bm[patchID].coupled()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Found a face for extrapolation
|
||||||
|
curExtraVectors[nFacesAroundPoint] =
|
||||||
|
pointLoc
|
||||||
|
- centres.boundaryField()[patchID]
|
||||||
|
[bm[patchID].patch().whichFace(curFaces[faceI])];
|
||||||
|
|
||||||
|
nFacesAroundPoint++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
curExtraVectors.setSize(nFacesAroundPoint);
|
curExtraVectors.setSize(nFacesAroundPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,114 +8,114 @@
|
||||||
FieldField<Field, scalar> w(ptc.size());
|
FieldField<Field, scalar> w(ptc.size());
|
||||||
|
|
||||||
{
|
{
|
||||||
const labelListList& pf = mesh.pointFaces();
|
const labelListList& pf = mesh.pointFaces();
|
||||||
|
|
||||||
const volVectorField& centres = mesh.C();
|
const volVectorField& centres = mesh.C();
|
||||||
|
|
||||||
const fvBoundaryMesh& bm = mesh.boundary();
|
const fvBoundaryMesh& bm = mesh.boundary();
|
||||||
|
|
||||||
pointScalarField volPointSumWeights
|
pointScalarField volPointSumWeights
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
|
||||||
"volPointSumWeights",
|
|
||||||
mesh.polyMesh::instance(),
|
|
||||||
mesh
|
|
||||||
),
|
|
||||||
pMesh,
|
|
||||||
dimensionedScalar("zero", dimless, 0)
|
|
||||||
);
|
|
||||||
|
|
||||||
forAll (ptc, pointI)
|
|
||||||
{
|
|
||||||
const label curPoint = ptc[pointI];
|
|
||||||
|
|
||||||
const labelList& curFaces = pf[curPoint];
|
|
||||||
|
|
||||||
//w.hook(new scalarField(curFaces.size())); //philipc no hook function
|
|
||||||
w.set
|
|
||||||
(
|
|
||||||
pointI,
|
|
||||||
new scalarField(curFaces.size())
|
|
||||||
);
|
|
||||||
|
|
||||||
scalarField& curWeights = w[pointI];
|
|
||||||
|
|
||||||
label nFacesAroundPoint = 0;
|
|
||||||
|
|
||||||
const vector& pointLoc = mesh.points()[curPoint];
|
|
||||||
|
|
||||||
// Go through all the faces
|
|
||||||
forAll (curFaces, faceI)
|
|
||||||
{
|
|
||||||
if (!mesh.isInternalFace(curFaces[faceI]))
|
|
||||||
{
|
|
||||||
// This is a boundary face. If not in the empty patch
|
|
||||||
// or coupled calculate the extrapolation vector
|
|
||||||
label patchID =
|
|
||||||
mesh.boundaryMesh().whichPatch(curFaces[faceI]);
|
|
||||||
|
|
||||||
if
|
|
||||||
(
|
(
|
||||||
!isA<emptyFvPatch>(bm[patchID])
|
"volPointSumWeights",
|
||||||
&& !(
|
mesh.polyMesh::instance(),
|
||||||
bm[patchID].coupled()
|
mesh
|
||||||
//&& Pstream::parRun()
|
),
|
||||||
//&& !mesh.parallelData().cyclicParallel()
|
pMesh,
|
||||||
)
|
dimensionedScalar("zero", dimless, 0)
|
||||||
)
|
|
||||||
{
|
|
||||||
curWeights[nFacesAroundPoint] =
|
|
||||||
1.0/mag
|
|
||||||
(
|
|
||||||
pointLoc
|
|
||||||
- centres.boundaryField()[patchID]
|
|
||||||
[
|
|
||||||
bm[patchID].patch().whichFace(curFaces[faceI])
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
nFacesAroundPoint++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset the sizes of the local weights
|
|
||||||
curWeights.setSize(nFacesAroundPoint);
|
|
||||||
|
|
||||||
// Collect the sum of weights for parallel correction
|
|
||||||
volPointSumWeights[curPoint] += sum(curWeights);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do parallel correction of weights
|
|
||||||
|
|
||||||
// Update coupled boundaries
|
|
||||||
// Work-around for cyclic parallels.
|
|
||||||
/*if (Pstream::parRun() && !mesh.parallelData().cyclicParallel())
|
|
||||||
{
|
|
||||||
forAll (volPointSumWeights.boundaryField(), patchI)
|
|
||||||
{
|
|
||||||
if (volPointSumWeights.boundaryField()[patchI].coupled())
|
|
||||||
{
|
|
||||||
volPointSumWeights.boundaryField()[patchI].initAddField();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
forAll (volPointSumWeights.boundaryField(), patchI)
|
|
||||||
{
|
|
||||||
if (volPointSumWeights.boundaryField()[patchI].coupled())
|
|
||||||
{
|
|
||||||
volPointSumWeights.boundaryField()[patchI].addField
|
|
||||||
(
|
|
||||||
volPointSumWeights.internalField()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
forAll (ptc, pointI)
|
||||||
|
{
|
||||||
|
const label curPoint = ptc[pointI];
|
||||||
|
|
||||||
|
const labelList& curFaces = pf[curPoint];
|
||||||
|
|
||||||
|
//w.hook(new scalarField(curFaces.size())); //philipc no hook function
|
||||||
|
w.set
|
||||||
|
(
|
||||||
|
pointI,
|
||||||
|
new scalarField(curFaces.size())
|
||||||
|
);
|
||||||
|
|
||||||
|
scalarField& curWeights = w[pointI];
|
||||||
|
|
||||||
|
label nFacesAroundPoint = 0;
|
||||||
|
|
||||||
|
const vector& pointLoc = mesh.points()[curPoint];
|
||||||
|
|
||||||
|
// Go through all the faces
|
||||||
|
forAll (curFaces, faceI)
|
||||||
|
{
|
||||||
|
if (!mesh.isInternalFace(curFaces[faceI]))
|
||||||
|
{
|
||||||
|
// This is a boundary face. If not in the empty patch
|
||||||
|
// or coupled calculate the extrapolation vector
|
||||||
|
label patchID =
|
||||||
|
mesh.boundaryMesh().whichPatch(curFaces[faceI]);
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
!isA<emptyFvPatch>(bm[patchID])
|
||||||
|
&& !(
|
||||||
|
bm[patchID].coupled()
|
||||||
|
//&& Pstream::parRun()
|
||||||
|
//&& !mesh.parallelData().cyclicParallel()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
curWeights[nFacesAroundPoint] =
|
||||||
|
1.0/mag
|
||||||
|
(
|
||||||
|
pointLoc
|
||||||
|
- centres.boundaryField()[patchID]
|
||||||
|
[
|
||||||
|
bm[patchID].patch().whichFace(curFaces[faceI])
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
nFacesAroundPoint++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the sizes of the local weights
|
||||||
|
curWeights.setSize(nFacesAroundPoint);
|
||||||
|
|
||||||
|
// Collect the sum of weights for parallel correction
|
||||||
|
volPointSumWeights[curPoint] += sum(curWeights);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// Do parallel correction of weights
|
||||||
|
|
||||||
|
// Update coupled boundaries
|
||||||
|
// Work-around for cyclic parallels.
|
||||||
|
/*if (Pstream::parRun() && !mesh.parallelData().cyclicParallel())
|
||||||
|
{
|
||||||
|
forAll (volPointSumWeights.boundaryField(), patchI)
|
||||||
|
{
|
||||||
|
if (volPointSumWeights.boundaryField()[patchI].coupled())
|
||||||
|
{
|
||||||
|
volPointSumWeights.boundaryField()[patchI].initAddField();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll (volPointSumWeights.boundaryField(), patchI)
|
||||||
|
{
|
||||||
|
if (volPointSumWeights.boundaryField()[patchI].coupled())
|
||||||
|
{
|
||||||
|
volPointSumWeights.boundaryField()[patchI].addField
|
||||||
|
(
|
||||||
|
volPointSumWeights.internalField()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
// Re-scale the weights for the current point
|
// Re-scale the weights for the current point
|
||||||
forAll (ptc, pointI)
|
forAll (ptc, pointI)
|
||||||
{
|
{
|
||||||
w[pointI] /= volPointSumWeights[ptc[pointI]];
|
w[pointI] /= volPointSumWeights[ptc[pointI]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,36 +107,35 @@
|
||||||
//- explicit terms in the momentum equation
|
//- explicit terms in the momentum equation
|
||||||
volVectorField divDSigmaExp
|
volVectorField divDSigmaExp
|
||||||
(
|
(
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
"divDSigmaExp",
|
|
||||||
runTime.timeName(),
|
|
||||||
mesh,
|
|
||||||
IOobject::NO_READ,
|
|
||||||
IOobject::NO_WRITE
|
|
||||||
),
|
|
||||||
mesh,
|
|
||||||
dimensionedVector("zero", dimensionSet(1, -2, -2, 0, 0, 0, 0), vector::zero)
|
|
||||||
);
|
|
||||||
|
|
||||||
volVectorField divDSigmaNonLinExp
|
|
||||||
(
|
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"divDSigmaNonLinExp",
|
"divDSigmaExp",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
|
mesh,
|
||||||
|
dimensionedVector("zero", dimensionSet(1, -2, -2, 0, 0, 0, 0), vector::zero)
|
||||||
|
);
|
||||||
|
|
||||||
|
volVectorField divDSigmaNonLinExp
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"divDSigmaNonLinExp",
|
||||||
|
runTime.timeName(),
|
||||||
|
mesh,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::NO_WRITE
|
||||||
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedVector("zero", dimensionSet(1,-2,-2,0,0,0,0), vector::zero)
|
dimensionedVector("zero", dimensionSet(1,-2,-2,0,0,0,0), vector::zero)
|
||||||
);
|
);
|
||||||
|
|
||||||
constitutiveModel rheology(sigma, DU);
|
constitutiveModel rheology(sigma, DU);
|
||||||
|
|
||||||
volScalarField rho = rheology.rho();
|
volScalarField rho = rheology.rho();
|
||||||
|
|
||||||
volScalarField mu = rheology.mu();
|
volScalarField mu = rheology.mu();
|
||||||
volScalarField lambda = rheology.lambda();
|
volScalarField lambda = rheology.lambda();
|
||||||
surfaceScalarField muf = fvc::interpolate(rheology.mu());
|
surfaceScalarField muf = fvc::interpolate(rheology.mu());
|
||||||
|
@ -144,37 +143,38 @@
|
||||||
|
|
||||||
surfaceVectorField n = mesh.Sf()/mesh.magSf();
|
surfaceVectorField n = mesh.Sf()/mesh.magSf();
|
||||||
|
|
||||||
// plastic strain increment
|
// plastic strain increment
|
||||||
const volSymmTensorField& DEpsilonP = rheology.DEpsilonP();
|
const volSymmTensorField& DEpsilonP = rheology.DEpsilonP();
|
||||||
|
|
||||||
// for aitken relaxation
|
// for aitken relaxation
|
||||||
volVectorField aitkenDelta
|
volVectorField aitkenDelta
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"aitkenDelta",
|
"aitkenDelta",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
mesh,
|
mesh,
|
||||||
dimensionedVector("zero", dimLength, vector::zero)
|
dimensionedVector("zero", dimLength, vector::zero)
|
||||||
);
|
);
|
||||||
// aitken relaxation factor
|
|
||||||
scalar aitkenInitialRes = 1.0;
|
// aitken relaxation factor
|
||||||
scalar aitkenTheta = 0.1;
|
scalar aitkenInitialRes = 1.0;
|
||||||
|
scalar aitkenTheta = 0.1;
|
||||||
|
|
||||||
// volVectorField resid
|
// volVectorField resid
|
||||||
// (
|
// (
|
||||||
// IOobject
|
// IOobject
|
||||||
// (
|
// (
|
||||||
// "resid",
|
// "resid",
|
||||||
// runTime.timeName(),
|
// runTime.timeName(),
|
||||||
// mesh,
|
// mesh,
|
||||||
// IOobject::NO_READ,
|
// IOobject::NO_READ,
|
||||||
// IOobject::AUTO_WRITE
|
// IOobject::AUTO_WRITE
|
||||||
// ),
|
// ),
|
||||||
// mesh,
|
// mesh,
|
||||||
// dimensionedVector("zero", dimless, vector::zero)
|
// dimensionedVector("zero", dimless, vector::zero)
|
||||||
// );
|
// );
|
||||||
|
|
|
@ -1,36 +1,36 @@
|
||||||
OFstream * forceFilePtr(NULL);
|
OFstream* forceFilePtr(NULL);
|
||||||
OFstream * stressFilePtr(NULL);
|
OFstream* stressFilePtr(NULL);
|
||||||
word historyPatchName(mesh.solutionDict().subDict("solidMechanics").lookup("historyPatch"));
|
word historyPatchName(mesh.solutionDict().subDict("solidMechanics").lookup("historyPatch"));
|
||||||
label historyPatchID = mesh.boundaryMesh().findPatchID(historyPatchName);
|
label historyPatchID = mesh.boundaryMesh().findPatchID(historyPatchName);
|
||||||
if(historyPatchID == -1)
|
if(historyPatchID == -1)
|
||||||
{
|
{
|
||||||
Warning << "history patch " << historyPatchName
|
Warning << "history patch " << historyPatchName
|
||||||
<< " not found. Force-displacement will not be written"
|
<< " not found. Force-displacement will not be written"
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
else if(Pstream::master())
|
else if(Pstream::master())
|
||||||
{
|
{
|
||||||
fileName historyDir = "history";
|
fileName historyDir = "history";
|
||||||
mkDir(historyDir);
|
mkDir(historyDir);
|
||||||
|
|
||||||
{
|
{
|
||||||
fileName forceFileName(historyDir/"forceDisp_"+historyPatchName+".dat");
|
fileName forceFileName(historyDir/"forceDisp_"+historyPatchName+".dat");
|
||||||
Info << "\nForce-displacement for patch " << historyPatchName
|
Info << "\nForce-displacement for patch " << historyPatchName
|
||||||
<< " will be written to " << forceFileName
|
<< " will be written to " << forceFileName
|
||||||
<< endl;
|
<< endl;
|
||||||
forceFilePtr = new OFstream(forceFileName);
|
forceFilePtr = new OFstream(forceFileName);
|
||||||
OFstream& forceDispFile = *forceFilePtr;
|
OFstream& forceDispFile = *forceFilePtr;
|
||||||
forceDispFile << "#Disp(mm)\tForce(N)" << endl;
|
forceDispFile << "#Disp(mm)\tForce(N)" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
fileName stressFileName(historyDir/"stressStrain_"+historyPatchName+".dat");
|
fileName stressFileName(historyDir/"stressStrain_"+historyPatchName+".dat");
|
||||||
Info << "\nCauchy Stress vs. Almansi Strain for patch "
|
Info << "\nCauchy Stress vs. Almansi Strain for patch "
|
||||||
<< historyPatchName
|
<< historyPatchName
|
||||||
<< " will be written to " << stressFileName
|
<< " will be written to " << stressFileName
|
||||||
<< endl;
|
<< endl;
|
||||||
stressFilePtr = new OFstream(stressFileName);
|
stressFilePtr = new OFstream(stressFileName);
|
||||||
OFstream& stressStrainFile = *stressFilePtr;
|
OFstream& stressStrainFile = *stressFilePtr;
|
||||||
stressStrainFile << "#Strain(-)\tStress(Pa)" << endl;
|
stressStrainFile << "#Strain(-)\tStress(Pa)" << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,26 +4,26 @@ solidInterface* solidInterfacePtr(NULL);
|
||||||
|
|
||||||
{
|
{
|
||||||
const dictionary& stressControl =
|
const dictionary& stressControl =
|
||||||
mesh.solutionDict().subDict("solidMechanics");
|
mesh.solutionDict().subDict("solidMechanics");
|
||||||
|
|
||||||
solidInterfaceCorr = Switch(stressControl.lookup("solidInterface"));
|
solidInterfaceCorr = Switch(stressControl.lookup("solidInterface"));
|
||||||
|
|
||||||
if(solidInterfaceCorr)
|
if(solidInterfaceCorr)
|
||||||
{
|
{
|
||||||
Info << "Creating solid interface correction" << endl;
|
Info << "Creating solid interface correction" << endl;
|
||||||
solidInterfacePtr = new solidInterface(mesh, rheology);
|
solidInterfacePtr = new solidInterface(mesh, rheology);
|
||||||
solidInterfacePtr->modifyProperties(muf, lambdaf);
|
solidInterfacePtr->modifyProperties(muf, lambdaf);
|
||||||
|
|
||||||
//- solidInterface needs muf and lambdaf to be used for divDSigmaExp
|
//- solidInterface needs muf and lambdaf to be used for divDSigmaExp
|
||||||
if(divDSigmaExpMethod != "surface" && divDSigmaExpMethod != "decompose")
|
if(divDSigmaExpMethod != "surface" && divDSigmaExpMethod != "decompose")
|
||||||
{
|
{
|
||||||
FatalError << "divDSigmaExp must be decompose or surface when solidInterface is on"
|
FatalError << "divDSigmaExp must be decompose or surface when solidInterface is on"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
if(divDSigmaLargeStrainExpMethod == "surface")
|
if(divDSigmaLargeStrainExpMethod == "surface")
|
||||||
{
|
{
|
||||||
FatalError << "divDSigmaLargeStrainExp must be surface when solidInterface is on"
|
FatalError << "divDSigmaLargeStrainExp must be surface when solidInterface is on"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,26 +4,26 @@ solidInterfaceNonLin* solidInterfacePtr(NULL);
|
||||||
|
|
||||||
{
|
{
|
||||||
const dictionary& stressControl =
|
const dictionary& stressControl =
|
||||||
mesh.solutionDict().subDict("solidMechanics");
|
mesh.solutionDict().subDict("solidMechanics");
|
||||||
|
|
||||||
solidInterfaceCorr = Switch(stressControl.lookup("solidInterface"));
|
solidInterfaceCorr = Switch(stressControl.lookup("solidInterface"));
|
||||||
|
|
||||||
if(solidInterfaceCorr)
|
if(solidInterfaceCorr)
|
||||||
{
|
{
|
||||||
Info << "Creating solid interface nonlinear correction" << endl;
|
Info << "Creating solid interface nonlinear correction" << endl;
|
||||||
solidInterfacePtr = new solidInterfaceNonLin(mesh, rheology);
|
solidInterfacePtr = new solidInterfaceNonLin(mesh, rheology);
|
||||||
solidInterfacePtr->modifyProperties(muf, lambdaf);
|
solidInterfacePtr->modifyProperties(muf, lambdaf);
|
||||||
|
|
||||||
//- solidInterface needs muf and lambdaf to be used for divDSigmaExp
|
//- solidInterface needs muf and lambdaf to be used for divDSigmaExp
|
||||||
if(divDSigmaExpMethod != "surface" && divDSigmaExpMethod != "decompose")
|
if(divDSigmaExpMethod != "surface" && divDSigmaExpMethod != "decompose")
|
||||||
{
|
{
|
||||||
FatalError << "divDSigmaExp must be decompose or surface when solidInterface is on"
|
FatalError << "divDSigmaExp must be decompose or surface when solidInterface is on"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
if(divDSigmaLargeStrainExpMethod != "surface")
|
if(divDSigmaLargeStrainExpMethod != "surface")
|
||||||
{
|
{
|
||||||
FatalError << "divDSigmaLargeStrainExp must be surface when solidInterface is on"
|
FatalError << "divDSigmaLargeStrainExp must be surface when solidInterface is on"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,139 +69,141 @@ int main(int argc, char *argv[])
|
||||||
# include "readMoveMeshMethod.H"
|
# include "readMoveMeshMethod.H"
|
||||||
# include "findGlobalFaceZones.H"
|
# include "findGlobalFaceZones.H"
|
||||||
|
|
||||||
//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Info << "\nStarting time loop\n" << endl;
|
Info<< "\nStarting time loop\n" << endl;
|
||||||
|
|
||||||
for (runTime++; !runTime.end(); runTime++)
|
while(runTime.loop())
|
||||||
{
|
{
|
||||||
Info<< "Time = " << runTime.timeName() << nl << endl;
|
Info<< "Time = " << runTime.timeName() << nl << endl;
|
||||||
|
|
||||||
# include "readSolidMechanicsControls.H"
|
# include "readSolidMechanicsControls.H"
|
||||||
|
|
||||||
int iCorr = 0;
|
int iCorr = 0;
|
||||||
lduMatrix::solverPerformance solverPerf;
|
lduMatrix::solverPerformance solverPerf;
|
||||||
scalar initialResidual = 0;
|
scalar initialResidual = 0;
|
||||||
scalar relativeResidual = 1.0;
|
scalar relativeResidual = 1.0;
|
||||||
lduMatrix::debug = 0;
|
lduMatrix::debug = 0;
|
||||||
|
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
DU.storePrevIter();
|
DU.storePrevIter();
|
||||||
|
|
||||||
# include "calculateDivDSigmaExp.H"
|
# include "calculateDivDSigmaExp.H"
|
||||||
# include "calculateDivDSigmaNonLinExp.H"
|
# include "calculateDivDSigmaNonLinExp.H"
|
||||||
|
|
||||||
// Updated lagrangian large strain momentum equation
|
// Updated lagrangian large strain momentum equation
|
||||||
fvVectorMatrix DUEqn
|
fvVectorMatrix DUEqn
|
||||||
(
|
(
|
||||||
fvm::d2dt2(rho,DU)
|
fvm::d2dt2(rho,DU)
|
||||||
==
|
==
|
||||||
fvm::laplacian(2*muf + lambdaf, DU, "laplacian(DDU,DU)")
|
fvm::laplacian(2*muf + lambdaf, DU, "laplacian(DDU,DU)")
|
||||||
+ divDSigmaExp
|
+ divDSigmaExp
|
||||||
+ divDSigmaNonLinExp
|
+ divDSigmaNonLinExp
|
||||||
//- fvc::div(2*mu*DEpsilonP, "div(sigma)")
|
//- fvc::div(2*mu*DEpsilonP, "div(sigma)")
|
||||||
- fvc::div(2*muf*( mesh.Sf() & fvc::interpolate(DEpsilonP)) )
|
- fvc::div(2*muf*( mesh.Sf() & fvc::interpolate(DEpsilonP)) )
|
||||||
);
|
);
|
||||||
|
|
||||||
if(nonLinearSemiImplicit)
|
if(nonLinearSemiImplicit)
|
||||||
{
|
{
|
||||||
// experimental
|
// experimental
|
||||||
// we can treat the nonlinear term (gradDU & gradDU.T()) in a
|
// we can treat the nonlinear term (gradDU & gradDU.T()) in a
|
||||||
// semi-implicit over-relaxed manner
|
// semi-implicit over-relaxed manner
|
||||||
// this should improve convergence when gradDU is large
|
// this should improve convergence when gradDU is large
|
||||||
// but maybe not execution time
|
// but maybe not execution time
|
||||||
DUEqn -=
|
DUEqn -=
|
||||||
fvm::laplacian
|
fvm::laplacian
|
||||||
(
|
(
|
||||||
(2*mu + lambda)*gradDU, DU, "laplacian(DDU,DU)"
|
(2*mu + lambda)*gradDU, DU, "laplacian(DDU,DU)"
|
||||||
)
|
)
|
||||||
- fvc::div( (2*mu + lambda)*(gradDU&gradDU), "div(sigma)");
|
- fvc::div( (2*mu + lambda)*(gradDU&gradDU), "div(sigma)");
|
||||||
}
|
}
|
||||||
|
|
||||||
solverPerf = DUEqn.solve();
|
solverPerf = DUEqn.solve();
|
||||||
|
|
||||||
if(iCorr == 0)
|
if(iCorr == 0)
|
||||||
{
|
{
|
||||||
initialResidual = solverPerf.initialResidual();
|
initialResidual = solverPerf.initialResidual();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(aitkenRelax)
|
if(aitkenRelax)
|
||||||
{
|
{
|
||||||
# include "aitkenRelaxation.H"
|
# include "aitkenRelaxation.H"
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DU.relax();
|
DU.relax();
|
||||||
}
|
}
|
||||||
|
|
||||||
gradDU = fvc::grad(DU);
|
gradDU = fvc::grad(DU);
|
||||||
|
|
||||||
// correct plasticty term
|
// correct plasticty term
|
||||||
rheology.correct();
|
rheology.correct();
|
||||||
|
|
||||||
// correct elastic properties
|
// correct elastic properties
|
||||||
// for nonlinear elastic materials
|
// for nonlinear elastic materials
|
||||||
//mu = rheology.newMu();
|
//mu = rheology.newMu();
|
||||||
//lambda = rheology.newLambda();
|
//lambda = rheology.newLambda();
|
||||||
//muf = fvc::interpolate(mu);
|
//muf = fvc::interpolate(mu);
|
||||||
//lambdaf = fvc::interpolate(lambda);
|
//lambdaf = fvc::interpolate(lambda);
|
||||||
|
|
||||||
# include "calculateDEpsilonDSigma.H"
|
# include "calculateDEpsilonDSigma.H"
|
||||||
# include "calculateRelativeResidual.H"
|
# include "calculateRelativeResidual.H"
|
||||||
|
|
||||||
if(iCorr % infoFrequency == 0)
|
if(iCorr % infoFrequency == 0)
|
||||||
{
|
{
|
||||||
Info<< "\tTime " << runTime.value()
|
Info<< "\tTime " << runTime.value()
|
||||||
<< ", Corrector " << iCorr
|
<< ", Corrector " << iCorr
|
||||||
<< ", Solving for " << DU.name()
|
<< ", Solving for " << DU.name()
|
||||||
<< " using " << solverPerf.solverName()
|
<< " using " << solverPerf.solverName()
|
||||||
<< ", res = " << solverPerf.initialResidual()
|
<< ", res = " << solverPerf.initialResidual()
|
||||||
<< ", rel res = " << relativeResidual;
|
<< ", rel res = " << relativeResidual;
|
||||||
if(aitkenRelax)
|
if(aitkenRelax)
|
||||||
{
|
{
|
||||||
Info<< ", aitken = " << aitkenTheta;
|
Info<< ", aitken = " << aitkenTheta;
|
||||||
}
|
}
|
||||||
Info<< ", iters = " << solverPerf.nIterations() << endl;
|
Info<< ", iters = " << solverPerf.nIterations() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while
|
while
|
||||||
(
|
(
|
||||||
iCorr++ < 2
|
iCorr++ < 2
|
||||||
||
|
||
|
||||||
(//solverPerf.initialResidual() > convergenceTolerance
|
(
|
||||||
relativeResidual > convergenceTolerance
|
//solverPerf.initialResidual() > convergenceTolerance
|
||||||
&&
|
relativeResidual > convergenceTolerance
|
||||||
iCorr < nCorr)
|
&& iCorr < nCorr
|
||||||
);
|
)
|
||||||
|
);
|
||||||
|
|
||||||
Info<< nl << "Time " << runTime.value() << ", Solving for " << DU.name()
|
Info<< nl << "Time " << runTime.value() << ", Solving for " << DU.name()
|
||||||
<< ", Initial residual = " << initialResidual
|
<< ", Initial residual = " << initialResidual
|
||||||
<< ", Final residual = " << solverPerf.initialResidual()
|
<< ", Final residual = " << solverPerf.initialResidual()
|
||||||
<< ", Final rel residual = " << relativeResidual
|
<< ", Final rel residual = " << relativeResidual
|
||||||
<< ", No outer iterations " << iCorr << endl;
|
<< ", No outer iterations " << iCorr << endl;
|
||||||
|
|
||||||
rheology.updateYieldStress();
|
rheology.updateYieldStress();
|
||||||
|
|
||||||
U += DU;
|
U += DU;
|
||||||
epsilon += DEpsilon;
|
epsilon += DEpsilon;
|
||||||
epsilonP += DEpsilonP;
|
epsilonP += DEpsilonP;
|
||||||
sigma += DSigma;
|
sigma += DSigma;
|
||||||
|
|
||||||
# include "moveMesh.H"
|
# include "moveMesh.H"
|
||||||
# include "rotateFields.H"
|
# include "rotateFields.H"
|
||||||
# include "writeFields.H"
|
# include "writeFields.H"
|
||||||
# include "writeHistory.H"
|
# include "writeHistory.H"
|
||||||
|
|
||||||
Info<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
Info<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "End\n" << endl;
|
Info<< "End\n" << endl;
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|
|
@ -8,26 +8,26 @@ const fvBoundaryMesh& bm = mesh.boundary();
|
||||||
|
|
||||||
forAll (bm, patchI)
|
forAll (bm, patchI)
|
||||||
{
|
{
|
||||||
// If the patch is empty, skip it
|
// If the patch is empty, skip it
|
||||||
// If the patch is coupled, and there are no cyclic parallels, skip it
|
// If the patch is coupled, and there are no cyclic parallels, skip it
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
!isA<emptyFvPatch>(bm[patchI])
|
!isA<emptyFvPatch>(bm[patchI])
|
||||||
&& !(
|
&& !(
|
||||||
bm[patchI].coupled()
|
bm[patchI].coupled()
|
||||||
//&& Pstream::parRun()
|
//&& Pstream::parRun()
|
||||||
//&& !mesh.parallelData().cyclicParallel()
|
//&& !mesh.parallelData().cyclicParallel()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const labelList& bp = bm[patchI].patch().boundaryPoints();
|
const labelList& bp = bm[patchI].patch().boundaryPoints();
|
||||||
|
|
||||||
const labelList& meshPoints = bm[patchI].patch().meshPoints();
|
const labelList& meshPoints = bm[patchI].patch().meshPoints();
|
||||||
|
|
||||||
forAll (bp, pointI)
|
forAll (bp, pointI)
|
||||||
{
|
{
|
||||||
pointsCorrectionMap.insert(meshPoints[bp[pointI]]);
|
pointsCorrectionMap.insert(meshPoints[bp[pointI]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue