Rearranging solidMechanics solvers and src, and added wmake darwin rules

This commit is contained in:
Philip Cardiff 2013-10-11 14:31:14 +01:00
parent 2fa97bf862
commit ab6cd72839
777 changed files with 45905 additions and 35089 deletions

View file

@ -1,9 +0,0 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
set -x
wmake libso materialModels
wmake newStressedFoam
wmake newContactStressFoam

View file

@ -1,35 +0,0 @@
rheologyModel/rheologyModel.C
rheologyLaws = rheologyModel/rheologyLaws
$(rheologyLaws)/rheologyLaw/rheologyLaw.C
$(rheologyLaws)/rheologyLaw/newRheologyLaw.C
$(rheologyLaws)/linearElastic/linearElastic.C
$(rheologyLaws)/multiMaterial/multiMaterial.C
$(rheologyLaws)/MaxwellViscoelastic/MaxwellViscoelastic.C
$(rheologyLaws)/BurgersViscoelastic/BurgersViscoelastic.C
$(rheologyLaws)/KelvinSLSViscoelastic/KelvinSLSViscoelastic.C
$(rheologyLaws)/MaxwellSLSViscoelastic/MaxwellSLSViscoelastic.C
$(rheologyLaws)/MaxwellElasticViscoelastic/MaxwellElasticViscoelastic.C
$(rheologyLaws)/PronyViscoelastic/PronyViscoelastic.C
thermalModel/thermalModel.C
thermalLaws = thermalModel/thermalLaws
$(thermalLaws)/thermalLaw/thermalLaw.C
$(thermalLaws)/thermalLaw/newThermalLaw.C
$(thermalLaws)/constantThermal/constantThermal.C
$(thermalLaws)/multiMaterialThermal/multiMaterialThermal.C
cohesiveLaws/cohesiveLaw/cohesiveLaw.C
cohesiveLaws/Dugdale/DugdaleCohesiveLaw.C
cohesiveLaws/linear/linearCohesiveLaw.C
fvPatchFields/tractionDisplacement/tractionDisplacementFvPatchVectorField.C
fvPatchFields/tractionDisplacementThermo/tractionDisplacementThermoFvPatchVectorField.C
fvPatchFields/nusselt/nusseltFvPatchScalarField.C
fvPatchFields/newDirectionMixed/newDirectionMixedFvPatchFields.C
fvPatchFields/cohesiveLaw/cohesiveLawFvPatchVectorField.C
fvPatchFields/cohesiveZone/cohesiveZoneFvPatchVectorField.C
LIB = $(FOAM_LIBBIN)/libmaterialModels

View file

@ -1,5 +0,0 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude
EXE_LIBS = \
-lfiniteVolume

View file

@ -1,88 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
Dugdale cohesive law.
\*---------------------------------------------------------------------------*/
#include "DugdaleCohesiveLaw.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(DugdaleCohesiveLaw, 0);
addToRunTimeSelectionTable(cohesiveLaw, DugdaleCohesiveLaw, dictionary);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components
Foam::DugdaleCohesiveLaw::DugdaleCohesiveLaw
(
const word& cohesiveLawName,
const dictionary& dict
)
:
cohesiveLaw(cohesiveLawName, dict),
deltaC_(GIc()/sigmaMax())
{}
Foam::DugdaleCohesiveLaw::DugdaleCohesiveLaw
(
const DugdaleCohesiveLaw& dcl
)
:
cohesiveLaw(dcl),
deltaC_(dcl.deltaC_)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::DugdaleCohesiveLaw::~DugdaleCohesiveLaw()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
//- Return current holding traction
Foam::scalar Foam::DugdaleCohesiveLaw::traction(scalar delta) const
{
if (delta > deltaC().value())
{
return 0.0;
}
else if (delta < 0)
{
return sigmaMax().value();
}
return sigmaMax().value();
}
// ************************************************************************* //

View file

@ -1,112 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
Virtual base class for cohesive law.
\*---------------------------------------------------------------------------*/
#include "cohesiveLaw.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cohesiveLaw, 0);
defineRunTimeSelectionTable(cohesiveLaw, dictionary);
}
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
Foam::autoPtr<Foam::cohesiveLaw> Foam::cohesiveLaw::New
(
const word& cohesiveLawName,
const dictionary& dict
)
{
Info << "Selecting cohesive law: " << cohesiveLawName << endl;
dictionaryConstructorTable::iterator cstrIter =
dictionaryConstructorTablePtr_->find(cohesiveLawName);
if (cstrIter == dictionaryConstructorTablePtr_->end())
{
FatalErrorIn
(
"cohesiveLaw::New(const word& cohesiveLawName, "
"const dictionary& dict)"
) << "Unknown cohesive law " << cohesiveLawName
<< endl << endl
<< "Valid cohesive laws are :" << endl
<< dictionaryConstructorTablePtr_->toc()
<< exit(FatalError);
}
return autoPtr<cohesiveLaw>(cstrIter()(cohesiveLawName, dict));
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components
Foam::cohesiveLaw::cohesiveLaw
(
const word& cohesiveLawName,
const dictionary& dict
)
:
cohesiveLawCoeffs_(dict.subDict(cohesiveLawName + "Coeffs")),
GIc_(cohesiveLawCoeffs_.lookup("GIc")),
sigmaMax_(cohesiveLawCoeffs_.lookup("sigmaMax"))
{}
Foam::cohesiveLaw::cohesiveLaw
(
const cohesiveLaw& cl
)
:
refCount(),
cohesiveLawCoeffs_(cl.cohesiveLawCoeffs_),
GIc_(cl.GIc_),
sigmaMax_(cl.sigmaMax_)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cohesiveLaw::~cohesiveLaw()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::cohesiveLaw::writeDict(Ostream& os) const
{
os.writeKeyword(word(type() + "Coeffs"))
<< cohesiveLawCoeffs();
}
// ************************************************************************* //

View file

@ -1,165 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
cohesiveLaw
Description
Virtual base class for cohesive zone model.
SourceFiles
cohesiveLaw.C
\*---------------------------------------------------------------------------*/
#ifndef cohesiveLaw_H
#define cohesiveLaw_H
#include "IOdictionary.H"
#include "autoPtr.H"
#include "runTimeSelectionTables.H"
#include "dimensionedTypes.H"
#include "tmp.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cohesiveLaw Declaration
\*---------------------------------------------------------------------------*/
class cohesiveLaw
:
public refCount
{
private:
// Private data
//- Cohesive law coefficients
dictionary cohesiveLawCoeffs_;
//- Fracture energy
dimensionedScalar GIc_;
//- Maximum cohesive strength
dimensionedScalar sigmaMax_;
public:
//- Runtime type information
TypeName("cohesiveLaw");
// Declare run-time constructor selection tables
declareRunTimeSelectionTable
(
autoPtr,
cohesiveLaw,
dictionary,
(
const word& cohesiveLawName,
const dictionary& dict
),
(cohesiveLawName, dict)
);
// Selectors
//- Select null constructed
static autoPtr<cohesiveLaw> New
(
const word& cohesiveLawName,
const dictionary& dict
);
// Constructors
//- Construct from components
cohesiveLaw
(
const word& cohesiveLawName,
const dictionary& dict
);
//- Construct as copy
cohesiveLaw(const cohesiveLaw&);
//- Construct and return a clone
virtual autoPtr<cohesiveLaw> clone() const = 0;
// Destructor
virtual ~cohesiveLaw();
// Member Functions
//- Return cohesive law coefficients
const dictionary& cohesiveLawCoeffs() const
{
return cohesiveLawCoeffs_;
}
//- Return reference to fracture energy
const dimensionedScalar& GIc() const
{
return GIc_;
}
//- Return reference to maximum cohesive strength
const dimensionedScalar& sigmaMax() const
{
return sigmaMax_;
}
//- Return reference to critical separation distance
virtual const dimensionedScalar& deltaC() const = 0;
//- Return current holding traction
virtual scalar traction(scalar delta) const = 0;
//- Write dictionary
void writeDict(Ostream& os) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -1,237 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
componentReference
Description
Class contains data for a component reference as used in stress
analysis solvers.
SourceFiles
componentReferenceI.H
componentReference.C
componentReferenceIO.C
\*---------------------------------------------------------------------------*/
#ifndef componentReference_H
#define componentReference_H
#include "polyPatchID.H"
#include "fvMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class componentReference Declaration
\*---------------------------------------------------------------------------*/
class componentReference
{
// Private data
//- Patch ID
polyPatchID patchID_;
//- Face index
label faceIndex_;
//- Direction
direction dir_;
//- Value in direction
scalar value_;
// Private Member Functions
//- Create direction given a name
direction getDir(const dictionary& dict) const
{
word dirName(dict.lookup("direction"));
if (dirName == "x" || dirName == "X")
{
return vector::X;
}
else if (dirName == "y" || dirName == "Y")
{
return vector::Y;
}
else if (dirName == "z" || dirName == "Z")
{
return vector::Z;
}
else
{
FatalIOErrorIn
(
"vector::component componentReference::getComp("
"const word& dirName) const",
dict
) << "Direction " << dirName << " not recognised. Please "
<< "use x, y or z" << abort(FatalIOError);
// Dummy return to keep compiler happy
return vector::X;
}
}
//- Check if patch face is in range
void checkPatchFace(const fvMesh& mesh) const
{
if
(
!patchID_.active()
|| faceIndex_ >= mesh.boundaryMesh()[patchID_.index()].size()
)
{
FatalErrorIn
(
"void checkPatchFace(const componentReference::fvMesh&)"
"const"
) << "Non-existing patch or index out of range."
<< abort(FatalError);
}
}
public:
// Public classes
//- Class used for the read-construction of
// PtrLists of componentReference
class iNew
{
const fvMesh& mesh_;
public:
iNew(const fvMesh& mesh)
:
mesh_(mesh)
{}
autoPtr<componentReference> operator()(Istream& is) const
{
dictionary crDict(is);
autoPtr<componentReference> cr
(
new componentReference(mesh_, crDict)
);
return cr;
}
};
// Constructors
//- Construct from components
componentReference
(
const fvMesh& mesh,
const word& patchName,
const label faceIndex,
const direction dir,
const scalar value
)
:
patchID_(patchName, mesh.boundaryMesh()),
faceIndex_(faceIndex),
dir_(dir),
value_(value)
{
checkPatchFace(mesh);
}
//- Construct from dictionary
componentReference
(
const fvMesh& mesh,
const dictionary& dict
)
:
patchID_(dict.lookup("patch"), mesh.boundaryMesh()),
faceIndex_(readLabel(dict.lookup("face"))),
dir_(getDir(dict)),
value_(readScalar(dict.lookup("value")))
{
checkPatchFace(mesh);
}
//- Clone
autoPtr<componentReference> clone() const
{
return autoPtr<componentReference>(new componentReference(*this));
}
// Destructor - default
// Member Functions
//- Return patch index
label patchIndex() const
{
return patchID_.index();
}
//- Return face index
label faceIndex() const
{
return faceIndex_;
}
//- Return direction
direction dir() const
{
return dir_;
}
//- Return value
scalar value() const
{
return value_;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -1,56 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Type
componentReferenceList
Description
container classes for componentReference
\*---------------------------------------------------------------------------*/
#ifndef componentReferenceList_H
#define componentReferenceList_H
#include "componentReference.H"
#include "PtrList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
typedef PtrList<componentReference> componentReferenceList;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -1,265 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
\*---------------------------------------------------------------------------*/
#include "cohesiveLawFvPatchVectorField.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
#include "rheologyModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
cohesiveLawFvPatchVectorField::cohesiveLawFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF
)
:
fixedGradientFvPatchVectorField(p, iF),
cohesiveLawPtr_(NULL),
relaxationFactor_(1.0),
traction_(p.size(), vector::zero)
{}
cohesiveLawFvPatchVectorField::cohesiveLawFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const dictionary& dict
)
:
fixedGradientFvPatchVectorField(p, iF),
cohesiveLawPtr_
(
cohesiveLaw::New(dict.lookup("cohesiveLaw"), dict).ptr()
),
relaxationFactor_(readScalar(dict.lookup("relaxationFactor"))),
traction_(p.size(), vector::zero)
{
fvPatchVectorField::operator=(patchInternalField());
gradient() = vector::zero;
}
cohesiveLawFvPatchVectorField::cohesiveLawFvPatchVectorField
(
const cohesiveLawFvPatchVectorField& cpf
)
:
fixedGradientFvPatchVectorField(cpf),
cohesiveLawPtr_(cpf.cohesiveLawPtr_->clone().ptr()),
relaxationFactor_(cpf.relaxationFactor_),
traction_(cpf.traction_)
{}
cohesiveLawFvPatchVectorField::cohesiveLawFvPatchVectorField
(
const cohesiveLawFvPatchVectorField& cpf,
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedGradientFvPatchVectorField(cpf, p, iF, mapper),
cohesiveLawPtr_(cpf.cohesiveLawPtr_->clone().ptr()),
relaxationFactor_(cpf.relaxationFactor_),
traction_(cpf.traction_, mapper)
{}
cohesiveLawFvPatchVectorField::cohesiveLawFvPatchVectorField
(
const cohesiveLawFvPatchVectorField& cpf,
const DimensionedField<vector, volMesh>& iF
)
:
fixedGradientFvPatchVectorField(cpf, iF),
cohesiveLawPtr_(cpf.cohesiveLawPtr_->clone().ptr()),
relaxationFactor_(cpf.relaxationFactor_),
traction_(cpf.traction_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const cohesiveLaw& cohesiveLawFvPatchVectorField::law() const
{
if (!cohesiveLawPtr_)
{
FatalErrorIn
(
"const cohesiveLaw& cohesiveLawFvPatchVectorField::law() const"
) << "Law pointer not set" << abort(FatalError);
}
return *cohesiveLawPtr_;
}
void cohesiveLawFvPatchVectorField::autoMap
(
const fvPatchFieldMapper& m
)
{
if (cohesiveLawPtr_ == NULL)
{
FatalErrorIn("cohesiveFvPatchVectorField::autoMap")
<< "NULL cohesive law"
<< abort(FatalError);
}
fixedGradientFvPatchVectorField::autoMap(m);
traction_.autoMap(m);
}
// Reverse-map the given fvPatchField onto this fvPatchField
void cohesiveLawFvPatchVectorField::rmap
(
const fvPatchVectorField& ptf,
const labelList& addr
)
{
fixedGradientFvPatchVectorField::rmap(ptf, addr);
const cohesiveLawFvPatchVectorField& dmptf =
refCast<const cohesiveLawFvPatchVectorField>(ptf);
// No need to grab the cohesive zone pointer more than once
if (!cohesiveLawPtr_)
{
cohesiveLawPtr_ = dmptf.cohesiveLawPtr_->clone().ptr();
relaxationFactor_ = dmptf.relaxationFactor_;
}
traction_.rmap(dmptf.traction_, addr);
}
// Update the coefficients associated with the patch field
void cohesiveLawFvPatchVectorField::updateCoeffs()
{
if (updated())
{
return;
}
// Looking up rheology
const fvPatchField<scalar>& mu =
lookupPatchField<volScalarField, scalar>("mu");
const fvPatchField<scalar>& lambda =
lookupPatchField<volScalarField, scalar>("lambda");
vectorField n = patch().nf();
const fvPatchField<tensor>& gradU =
lookupPatchField<volTensorField, tensor>("grad(U)");
// Patch displacement
const vectorField& U = *this;
// Patch stress
tensorField sigma = mu*(gradU + gradU.T()) + I*(lambda*tr(gradU));
// Normal stress component
scalarField sigmaN = (n & (n & sigma));
scalarField delta = -(n & U);
label sizeByTwo = patch().size()/2;
for(label i = 0; i < sizeByTwo; i++)
{
scalar tmp = delta[i];
delta[i] += delta[sizeByTwo + i];
delta[sizeByTwo + i] += tmp;
}
forAll (traction_, faceI)
{
if (delta[faceI] < 0)
{
// Return from traction to symmetryPlane??
traction_[faceI] = law().sigmaMax().value()*n[faceI];
}
else if(delta[faceI] > law().deltaC().value())
{
// Traction free
traction_[faceI] = vector::zero;
}
else
{
// Calculate cohesive traction from cohesive zone model
traction_[faceI] = law().traction(delta[faceI])*n[faceI];
}
}
gradient() =
(
traction_
- (n & (mu*gradU.T() - (mu + lambda)*gradU))
- n*lambda*tr(gradU)
)/(2.0*mu + lambda);
fixedGradientFvPatchVectorField::updateCoeffs();
}
// Write
void cohesiveLawFvPatchVectorField::write(Ostream& os) const
{
fvPatchVectorField::write(os);
traction_.writeEntry("traction", os);
os.writeKeyword("cohesiveLaw") << law().type()
<< token::END_STATEMENT << nl;
os.writeKeyword("relaxationFactor") << relaxationFactor_
<< token::END_STATEMENT << nl;
law().writeDict(os);
writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField(fvPatchVectorField, cohesiveLawFvPatchVectorField);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -1,325 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
cohesiveZoneFvPatchVectorField
Description
\*---------------------------------------------------------------------------*/
#include "cohesiveZoneFvPatchVectorField.H"
#include "addToRunTimeSelectionTable.H"
#include "transformField.H"
#include "volFields.H"
#include "rheologyModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
cohesiveZoneFvPatchVectorField::cohesiveZoneFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF
)
:
directionMixedFvPatchVectorField(p, iF),
UName_("undefined"),
rheologyName_("undefined"),
cohesiveLawPtr_(NULL),
relaxationFactor_(1.0)
{}
cohesiveZoneFvPatchVectorField::cohesiveZoneFvPatchVectorField
(
const cohesiveZoneFvPatchVectorField& ptf,
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
directionMixedFvPatchVectorField(ptf, p, iF, mapper),
UName_(ptf.UName_),
rheologyName_(ptf.rheologyName_),
cohesiveLawPtr_(ptf.cohesiveLawPtr_),
relaxationFactor_(ptf.relaxationFactor_)
{}
cohesiveZoneFvPatchVectorField::cohesiveZoneFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const dictionary& dict
)
:
directionMixedFvPatchVectorField(p, iF),
UName_(dict.lookup("U")),
rheologyName_(dict.lookup("rheology")),
cohesiveLawPtr_
(
cohesiveLaw::New(dict.lookup("cohesiveLaw"), dict).ptr()
),
relaxationFactor_(readScalar(dict.lookup("relaxationFactor")))
{
if (dict.found("refValue"))
{
this->refValue() = vectorField("refValue", dict, p.size());
}
else
{
this->refValue() = vector::zero;
}
if (dict.found("refGradient"))
{
this->refGrad() = vectorField("refGradient", dict, p.size());
}
else
{
this->refGrad() = vector::zero;
}
if (dict.found("valueFraction"))
{
this->valueFraction() =
symmTensorField("valueFraction", dict, p.size());
}
else
{
vectorField n = patch().nf();
this->valueFraction() = sqr(n);
}
if (dict.found("value"))
{
Field<vector>::operator=(vectorField("value", dict, p.size()));
}
else
{
Field<vector> normalValue = transform(valueFraction(), refValue());
Field<vector> gradValue =
this->patchInternalField() + refGrad()/this->patch().deltaCoeffs();
Field<vector> transformGradValue =
transform(I - valueFraction(), gradValue);
Field<vector>::operator=(normalValue + transformGradValue);
}
}
cohesiveZoneFvPatchVectorField::cohesiveZoneFvPatchVectorField
(
const cohesiveZoneFvPatchVectorField& ptf,
const DimensionedField<vector, volMesh>& iF
)
:
directionMixedFvPatchVectorField(ptf, iF),
UName_(ptf.UName_),
rheologyName_(ptf.rheologyName_),
cohesiveLawPtr_(ptf.cohesiveLawPtr_),
relaxationFactor_(ptf.relaxationFactor_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Map from self
void cohesiveZoneFvPatchVectorField::autoMap
(
const fvPatchFieldMapper& m
)
{
if (cohesiveLawPtr_ == NULL)
{
FatalErrorIn("cohesiveZoneFvPatchVectorField::autoMap")
<< "NULL cohesive law"
<< abort(FatalError);
}
directionMixedFvPatchVectorField::autoMap(m);
}
// Reverse-map the given fvPatchField onto this fvPatchField
void cohesiveZoneFvPatchVectorField::rmap
(
const fvPatchField<vector>& ptf,
const labelList& addr
)
{
directionMixedFvPatchVectorField::rmap(ptf, addr);
const cohesiveZoneFvPatchVectorField& dmptf =
refCast<const cohesiveZoneFvPatchVectorField>(ptf);
// No need to grab the cohesive zone pointer more than once
if (!cohesiveLawPtr_)
{
cohesiveLawPtr_ = dmptf.cohesiveLawPtr_->clone().ptr();
relaxationFactor_ = dmptf.relaxationFactor_;
}
}
void cohesiveZoneFvPatchVectorField::updateCoeffs()
{
if (this->updated())
{
return;
}
// Looking up rheology
const rheologyModel& rheology =
this->db().objectRegistry::lookupObject<rheologyModel>(rheologyName_);
const scalarField mu =
rheology.mu()().boundaryField()[patch().index()];
const scalarField lambda =
rheology.lambda()().boundaryField()[patch().index()];
const fvPatchField<tensor>& gradU =
lookupPatchField<volTensorField, tensor>
(
"grad(" +UName_ + ")"
);
// Patch displacement
const vectorField& U = *this;
// Patch stress
tensorField sigma = mu*(gradU + gradU.T()) + I*(lambda*tr(gradU));
// Patch normal
vectorField n = patch().nf();
// Normal stress component
scalarField sigmaN = (n&(n&sigma));
// Chech crack propagation
forAll(sigmaN, faceI)
{
vector cohesiveTraction = vector::zero;
if
(
(magSqr(valueFraction()[faceI]) > 1-SMALL)
&& (sigmaN[faceI] >= law().sigmaMax().value())
)
{
// Switch to full traction boundary condition
valueFraction()[faceI] = symmTensor::zero;
Info << "Crack started at face: " << faceI << endl;
// Cohesive traction
cohesiveTraction = n[faceI]*law().sigmaMax().value();
}
else if(magSqr(valueFraction()[faceI]) < SMALL)
{
// Normal displacement
scalar Un = -(n[faceI]&U[faceI]);
if(Un < 0)
{
// Return from traction to symmetryPlane
refValue()[faceI] = vector::zero;
refGrad() = vector::zero;
valueFraction()[faceI] = sqr(n[faceI]);
Info << "Face removed from crack: " << faceI << endl;
}
else if(Un > law().deltaC().value()/2)
{
// Traction free
cohesiveTraction = vector::zero;
}
else
{
// Calculate cohesive traction from cohesive zone model
cohesiveTraction = law().traction(2*Un)*n[faceI];
}
}
if(magSqr(valueFraction()[faceI]) < SMALL)
{
cohesiveTraction =
relaxationFactor_*cohesiveTraction
+ (1.0 - relaxationFactor_)*sigmaN[faceI]*n[faceI];
refGrad()[faceI] =
(
cohesiveTraction
- (
n[faceI]
& (
mu[faceI]*gradU[faceI].T()
- (mu[faceI] + lambda[faceI])*gradU[faceI]
)
)
- n[faceI]*lambda[faceI]*tr(gradU[faceI])
)
/(2.0*mu[faceI] + lambda[faceI]);
}
}
directionMixedFvPatchVectorField::updateCoeffs();
}
// Write
void cohesiveZoneFvPatchVectorField::write(Ostream& os) const
{
directionMixedFvPatchVectorField::write(os);
os.writeKeyword("U") << UName_ << token::END_STATEMENT << nl;
os.writeKeyword("rheology") << rheologyName_ << token::END_STATEMENT << nl;
os.writeKeyword("cohesiveLaw") << law().type()
<< token::END_STATEMENT << nl;
os.writeKeyword("relaxationFactor") << relaxationFactor_
<< token::END_STATEMENT << nl;
law().writeDict(os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField(fvPatchVectorField, cohesiveZoneFvPatchVectorField);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -1,328 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
newDirectionMixedFvPatchField
Description
Doubly mixed fixed value-fixed gradient boundary condition
separated into a normal and a tangential component given a
direction vector. The mixture is controlled by two separate
valueFraction coefficients in the normal and tangential direction.
\*---------------------------------------------------------------------------*/
#include "newDirectionMixedFvPatchField.H"
#include "transformField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
void newDirectionMixedFvPatchField<Type>::checkNHat()
{
scalarField magNHat(Foam::mag(nHat_));
if (min(magNHat) < SMALL)
{
FatalErrorIn("void newDirectionMixedFvPatchField<Type>::checkNHat()")
<< "Incorrectly defined normal direction. mag = "
<< min(magNHat)
<< abort(FatalError);
}
magNHat /= mag(magNHat);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
newDirectionMixedFvPatchField<Type>::newDirectionMixedFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
:
fvPatchField<Type>(p, iF),
refValue_(p.size()),
refGrad_(p.size()),
nHat_(p.size()),
normalValueFraction_(p.size()),
tangentialValueFraction_(p.size())
{}
template<class Type>
newDirectionMixedFvPatchField<Type>::newDirectionMixedFvPatchField
(
const newDirectionMixedFvPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fvPatchField<Type>(ptf, p, iF, mapper),
refValue_(ptf.refValue_, mapper),
refGrad_(ptf.refGrad_, mapper),
nHat_(ptf.nHat_, mapper),
normalValueFraction_(ptf.normalValueFraction_, mapper),
tangentialValueFraction_(ptf.tangentialValueFraction_, mapper)
{
this->checkNHat();
}
template<class Type>
newDirectionMixedFvPatchField<Type>::newDirectionMixedFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
fvPatchField<Type>(p, iF, dict),
refValue_("refValue", dict, p.size()),
refGrad_("refGradient", dict, p.size()),
nHat_("nHat", dict, p.size()),
normalValueFraction_("normalValueFraction", dict, p.size()),
tangentialValueFraction_("tangentialValueFraction", dict, p.size())
{
this->checkNHat();
evaluate();
}
template<class Type>
newDirectionMixedFvPatchField<Type>::newDirectionMixedFvPatchField
(
const newDirectionMixedFvPatchField<Type>& ptf,
const DimensionedField<Type, volMesh>& iF
)
:
fvPatchField<Type>(ptf, iF),
refValue_(ptf.refValue_),
refGrad_(ptf.refGrad_),
nHat_(ptf.nHat_),
normalValueFraction_(ptf.normalValueFraction_),
tangentialValueFraction_(ptf.tangentialValueFraction_)
{
this->checkNHat();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Map from self
template<class Type>
void newDirectionMixedFvPatchField<Type>::autoMap
(
const fvPatchFieldMapper& m
)
{
Field<Type>::autoMap(m);
refValue_.autoMap(m);
refGrad_.autoMap(m);
nHat_.autoMap(m);
normalValueFraction_.autoMap(m);
tangentialValueFraction_.autoMap(m);
}
// Reverse-map the given fvPatchField onto this fvPatchField
template<class Type>
void newDirectionMixedFvPatchField<Type>::rmap
(
const fvPatchField<Type>& ptf,
const labelList& addr
)
{
fvPatchField<Type>::rmap(ptf, addr);
const newDirectionMixedFvPatchField<Type>& dmptf =
refCast<const newDirectionMixedFvPatchField<Type> >(ptf);
refValue_.rmap(dmptf.refValue_, addr);
refGrad_.rmap(dmptf.refGrad_, addr);
nHat_.rmap(dmptf.nHat_, addr);
normalValueFraction_.rmap(dmptf.normalValueFraction_, addr);
tangentialValueFraction_.rmap(dmptf.tangentialValueFraction_, addr);
}
// Return gradient at boundary
template<class Type>
tmp<Field<Type> > newDirectionMixedFvPatchField<Type>::snGrad() const
{
Field<Type> pif = this->patchInternalField();
const scalarField& deltaCoeffs = this->patch().deltaCoeffs();
const tensorField nn= nHat_*nHat_;
Field<Type> normalValue =
normalValueFraction_*transform(nn, refValue_)
+ (1.0 - normalValueFraction_)*transform(nn, pif + refGrad_/deltaCoeffs);
Field<Type> tangentialValue =
tangentialValueFraction_*transform(I - nn, refValue_)
+ (1.0 - tangentialValueFraction_)*
transform(I - nn, pif + refGrad_/deltaCoeffs);
return (normalValue + tangentialValue - pif)*deltaCoeffs;
}
// Evaluate the field on the patch
template<class Type>
void newDirectionMixedFvPatchField<Type>::evaluate()
{
if (!this->updated())
{
this->updateCoeffs();
}
Field<Type> pif = this->patchInternalField();
const scalarField& deltaCoeffs = this->patch().deltaCoeffs();
const tensorField nn = nHat_*nHat_;
Field<Type> normalValue =
normalValueFraction_*transform(nn, refValue_)
+ (1.0 - normalValueFraction_)*transform(nn, pif + refGrad_/deltaCoeffs);
Field<Type> tangentialValue =
tangentialValueFraction_*transform(I - nn, refValue_)
+ (1.0 - tangentialValueFraction_)*
transform(I - nn, pif + refGrad_/deltaCoeffs);
Field<Type>::operator=(normalValue + tangentialValue);
fvPatchField<Type>::evaluate();
}
//- Return the matrix diagonal coefficients corresponding to the
// evaluation of the value of this patchField
template<class Type>
tmp<Field<Type> > newDirectionMixedFvPatchField<Type>::valueInternalCoeffs
(
const tmp<scalarField>&
) const
{
const Field<Type> one(this->size(), pTraits<Type>::one);
const tensorField nn= nHat_*nHat_;
return
transform(nn, one)*(1.0 - normalValueFraction_)
+ transform(I - nn, one)*(1.0 - tangentialValueFraction_);
}
//- Return the matrix source coefficients corresponding to the
// evaluation of the value of this patchField
template<class Type>
tmp<Field<Type> > newDirectionMixedFvPatchField<Type>::valueBoundaryCoeffs
(
const tmp<scalarField>&
) const
{
const scalarField& deltaCoeffs = this->patch().deltaCoeffs();
const tensorField nn= nHat_*nHat_;
return
normalValueFraction_*transform(nn, refValue_)
+ (1.0 - normalValueFraction_)*transform(nn, refGrad_)/deltaCoeffs
+ tangentialValueFraction_*transform(I - nn, refValue_)
+ (1.0 - tangentialValueFraction_)*
transform(I - nn, refGrad_)/deltaCoeffs;
// Alternative; allows fiddling internal/boundary split for value coeffs
// return
// *this
// - scale
// (
// valueInternalCoeffs(this->patch().weights()),
// this->patchInternalField()
// );
}
//- Return the matrix diagonal coefficients corresponding to the
// evaluation of the gradient of this patchField
template<class Type>
tmp<Field<Type> >
newDirectionMixedFvPatchField<Type>::gradientInternalCoeffs() const
{
const scalarField& deltaCoeffs = this->patch().deltaCoeffs();
const Field<Type> one(this->size(), pTraits<Type>::one);
const tensorField nn= nHat_*nHat_;
return
-transform(nn, one)*normalValueFraction_*deltaCoeffs
- transform(I - nn, one)*tangentialValueFraction_*deltaCoeffs;
}
//- Return the matrix source coefficients corresponding to the
// evaluation of the gradient of this patchField
template<class Type>
tmp<Field<Type> >
newDirectionMixedFvPatchField<Type>::gradientBoundaryCoeffs() const
{
const scalarField& deltaCoeffs = this->patch().deltaCoeffs();
const tensorField nn= nHat_*nHat_;
return
normalValueFraction_*deltaCoeffs*transform(nn, refValue_)
+ (1.0 - normalValueFraction_)*transform(nn, refGrad_)
+ tangentialValueFraction_*deltaCoeffs*transform(I - nn, refValue_)
+ (1.0 - tangentialValueFraction_)*transform(I - nn, refGrad_);
// Alternative; allows fiddling internal/boundary split for grad coeffs
// return
// snGrad()
// - scale(gradientInternalCoeffs(), this->patchInternalField());
}
// Write
template<class Type>
void newDirectionMixedFvPatchField<Type>::write(Ostream& os) const
{
fvPatchField<Type>::write(os);
refValue_.writeEntry("refValue", os);
refGrad_.writeEntry("refGradient", os);
nHat_.writeEntry("nHat", os);
normalValueFraction_.writeEntry("normalValueFraction", os);
tangentialValueFraction_.writeEntry("tangentialValueFraction", os);
this->writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -1,302 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
newDirectionMixedFvPatchField
Description
Doubly mixed fixed value-fixed gradient boundary condition
separated into a normal and a tangential component given a
direction vector. The mixture is controlled by two separate
valueFraction coefficients in the normal and tangential direction.
SourceFiles
newDirectionMixedFvPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef newDirectionMixedFvPatchField_H
#define newDirectionMixedFvPatchField_H
#include "fvPatchField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class directionMixedFvPatch Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class newDirectionMixedFvPatchField
:
public fvPatchField<Type>
{
// Private data
//- Value field
Field<Type> refValue_;
//- Gradient field
Field<Type> refGrad_;
//- Normal direction
vectorField nHat_;
//- Fraction (0-1) of value used for normal component
scalarField normalValueFraction_;
//- Fraction (0-1) of value used for tangential component
scalarField tangentialValueFraction_;
// Private Member Functions
//- Check and normalize nHat
void checkNHat();
public:
//- Runtime type information
TypeName("newDirectionMixed");
// Constructors
//- Construct from patch and internal field
newDirectionMixedFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&
);
//- Construct from patch, internal field and dictionary
newDirectionMixedFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const dictionary&
);
//- Construct by mapping given newDirectionMixedFvPatchField onto
// a new patch
newDirectionMixedFvPatchField
(
const newDirectionMixedFvPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct and return a clone
virtual tmp<fvPatchField<Type> > clone() const
{
return tmp<fvPatchField<Type> >
(
new newDirectionMixedFvPatchField<Type>(*this)
);
}
//- Construct as copy setting internal field reference
newDirectionMixedFvPatchField
(
const newDirectionMixedFvPatchField<Type>&,
const DimensionedField<Type, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchField<Type> > clone
(
const DimensionedField<Type, volMesh>& iF
) const
{
return tmp<fvPatchField<Type> >
(
new newDirectionMixedFvPatchField<Type>(*this, iF)
);
}
// Member functions
// Access
//- Return true if this patch field fixes a value.
// Needed to check if a level has to be specified while solving
// Poissons equations.
virtual bool fixesValue() const
{
return true;
}
// Mapping functions
//- Map (and resize as needed) from self given a mapping object
virtual void autoMap
(
const fvPatchFieldMapper&
);
//- Reverse map the given fvPatchField onto this fvPatchField
virtual void rmap
(
const fvPatchField<Type>&,
const labelList&
);
// Return defining fields
virtual Field<Type>& refValue()
{
return refValue_;
}
virtual const Field<Type>& refValue() const
{
return refValue_;
}
virtual Field<Type>& refGrad()
{
return refGrad_;
}
virtual const Field<Type>& refGrad() const
{
return refGrad_;
}
virtual vectorField& nHat()
{
return nHat_;
}
virtual const vectorField& nHat() const
{
return nHat_;
}
virtual scalarField& normalValueFraction()
{
return normalValueFraction_;
}
virtual const scalarField& normalValueFraction() const
{
return normalValueFraction_;
}
virtual scalarField& tangentialValueFraction()
{
return tangentialValueFraction_;
}
virtual const scalarField& tangentialValueFraction() const
{
return tangentialValueFraction_;
}
// Evaluation functions
//- Return gradient at boundary
virtual tmp<Field<Type> > snGrad() const;
//- Evaluate the patch field
virtual void evaluate();
//- Return the matrix diagonal coefficients corresponding to the
// evaluation of the value of this patchField with given weights
virtual tmp<Field<Type> > valueInternalCoeffs
(
const tmp<scalarField>&
) const;
//- Return the matrix source coefficients corresponding to the
// evaluation of the value of this patchField with given weights
virtual tmp<Field<Type> > valueBoundaryCoeffs
(
const tmp<scalarField>&
) const;
//- Return the matrix diagonal coefficients corresponding to the
// evaluation of the gradient of this patchField
virtual tmp<Field<Type> > gradientInternalCoeffs() const;
//- Return the matrix source coefficients corresponding to the
// evaluation of the gradient of this patchField
virtual tmp<Field<Type> > gradientBoundaryCoeffs() const;
//- Write
virtual void write(Ostream&) const;
// Member operators
virtual void operator=(const fvPatchField<Type>&) {}
virtual void operator+=(const fvPatchField<Type>&) {}
virtual void operator-=(const fvPatchField<Type>&) {}
virtual void operator*=(const fvPatchField<Type>&) {}
virtual void operator/=(const fvPatchField<Type>&) {}
virtual void operator=(const Field<Type>&) {}
virtual void operator+=(const Field<Type>&) {}
virtual void operator-=(const Field<Type>&) {}
virtual void operator*=(const Field<scalar>&) {}
virtual void operator/=(const Field<scalar>&) {}
virtual void operator=(const Type&) {}
virtual void operator+=(const Type&) {}
virtual void operator-=(const Type&) {}
virtual void operator*=(const scalar) {}
virtual void operator/=(const scalar) {}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "newDirectionMixedFvPatchField.C"
#else
# ifdef xlC
# pragma implementation("newDirectionMixedFvPatchField.C")
# endif
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -1,243 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*---------------------------------------------------------------------------*/
#include "nusseltFvPatchScalarField.H"
#include "addToRunTimeSelectionTable.H"
#include "fvPatchFieldMapper.H"
#include "volFields.H"
#include "surfaceFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
nusseltFvPatchScalarField::nusseltFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF
)
:
mixedFvPatchScalarField(p, iF),
DTName_("undefined"),
Tinf_(0.0),
alpha_(p.size(), 0.0)
{
refValue() = 0.0;
refGrad() = 0.0;
valueFraction() = 0.0;
}
nusseltFvPatchScalarField::nusseltFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const dictionary& dict
)
:
mixedFvPatchScalarField(p, iF),
DTName_(dict.lookup("DT")),
Tinf_(readScalar(dict.lookup("Tinf"))),
alpha_("alpha", dict, p.size())
{
if (dict.found("value"))
{
fvPatchField<scalar>::operator=
(
scalarField("value", dict, p.size())
);
}
else
{
fvPatchField<scalar>::operator=(patchInternalField());
}
refValue() = *this;
refGrad() = 0.0;
valueFraction() = 0.0;
if (Tinf_ < SMALL)
{
FatalIOErrorIn
(
"nusseltFvPatchScalarField::nusseltFvPatchScalarField\n"
"(\n"
" const fvPatch&,\n"
" const DimensionedField<scalar, volMesh>&,\n"
" const dictionary&\n"
")",
dict
) << "unphysical Tinf specified (Tinf = 0 or negative)"
<< exit(FatalError);
}
if (min(alpha_) < -SMALL)
{
FatalIOErrorIn
(
"nusseltFvPatchScalarField::nusseltFvPatchScalarField\n"
"(\n"
" const fvPatch&,\n"
" const DimensionedField<scalar, volMesh>&,\n"
" const dictionary&\n"
")",
dict
) << "unphysical alpha specified (alpha = 0 or negative)" << endl
<< exit(FatalError);
}
}
nusseltFvPatchScalarField::nusseltFvPatchScalarField
(
const nusseltFvPatchScalarField& ptf,
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
mixedFvPatchScalarField(ptf, p, iF, mapper),
DTName_(ptf.DTName_),
Tinf_(ptf.Tinf_),
alpha_(ptf.alpha_)
{}
nusseltFvPatchScalarField::nusseltFvPatchScalarField
(
const nusseltFvPatchScalarField& ptf
)
:
mixedFvPatchScalarField(ptf),
DTName_(ptf.DTName_),
Tinf_(ptf.Tinf_),
alpha_(ptf.alpha_)
{}
nusseltFvPatchScalarField::nusseltFvPatchScalarField
(
const nusseltFvPatchScalarField& ptpsf,
const DimensionedField<scalar, volMesh>& iF
)
:
mixedFvPatchScalarField(ptpsf, iF),
DTName_(ptpsf.DTName_),
Tinf_(ptpsf.Tinf_),
alpha_(ptpsf.alpha_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Map from self
void nusseltFvPatchScalarField::autoMap
(
const fvPatchFieldMapper& m
)
{
mixedFvPatchScalarField::autoMap(m);
alpha_.autoMap(m);
}
// Reverse-map the given fvPatchField onto this fvPatchField
void nusseltFvPatchScalarField::rmap
(
const fvPatchField<scalar>& ptf,
const labelList& addr
)
{
mixedFvPatchField<scalar>::rmap(ptf, addr);
const nusseltFvPatchScalarField& npsf =
refCast<const nusseltFvPatchScalarField>(ptf);
alpha_.rmap(npsf.alpha_, addr);
}
// Update the coefficients associated with the patch field
void nusseltFvPatchScalarField::updateCoeffs()
{
if (updated())
{
return;
}
scalarField Tinternal = patchInternalField();
// Lookup temperature diffusivity of the patch
const fvPatchField<scalar>& DT =
this->lookupPatchField<volScalarField, scalar>(DTName_);
// Calculate flux
scalarField tempFlux = alpha_*(Tinternal - Tinf_);
refValue() =
neg(tempFlux)*
min
(
Tinternal - tempFlux/(DT*patch().deltaCoeffs()),
Tinf_
)
+ pos(tempFlux)*
max
(
Tinternal - tempFlux/(DT*patch().deltaCoeffs()),
Tinf_
);
refGrad() = -tempFlux;
valueFraction() = pos(tempFlux);
mixedFvPatchScalarField::updateCoeffs();
}
// Write
void nusseltFvPatchScalarField::write(Ostream& os) const
{
fvPatchScalarField::write(os);
os.writeKeyword("DT") << DTName_ << token::END_STATEMENT << nl;
os.writeKeyword("Tinf") << Tinf_ << token::END_STATEMENT << endl;
alpha_.writeEntry("alpha", os);
writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField(fvPatchScalarField, nusseltFvPatchScalarField);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -1,201 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
nusseltFvPatchScalarField
Description
Nusselt boundary condition for temperature
SourceFiles
nusseltFvPatchScalarField.C
\*---------------------------------------------------------------------------*/
#ifndef nusseltFvPatchScalarFields_H
#define nusseltFvPatchScalarFields_H
#include "mixedFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class nusseltFvPatch Declaration
\*---------------------------------------------------------------------------*/
class nusseltFvPatchScalarField
:
public mixedFvPatchScalarField
{
// Private data
//- Name of the displacement field
const word DTName_;
//- Reference temperature at infinity
scalar Tinf_;
//- Heat transfer coefficient
scalarField alpha_;
public:
//- Runtime type information
TypeName("nusselt");
// Constructors
//- Construct from patch and internal field
nusseltFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&
);
//- Construct from patch, internal field and dictionary
nusseltFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const dictionary&
);
//- Construct by mapping given nusseltFvPatchScalarField
// onto a new patch
nusseltFvPatchScalarField
(
const nusseltFvPatchScalarField&,
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
nusseltFvPatchScalarField
(
const nusseltFvPatchScalarField&
);
//- Construct and return a clone
virtual tmp<fvPatchScalarField> clone() const
{
return tmp<fvPatchScalarField>
(
new nusseltFvPatchScalarField(*this)
);
}
//- Construct as copy setting internal field reference
nusseltFvPatchScalarField
(
const nusseltFvPatchScalarField&,
const DimensionedField<scalar, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchScalarField> clone
(
const DimensionedField<scalar, volMesh>& iF
) const
{
return tmp<fvPatchScalarField>
(
new nusseltFvPatchScalarField(*this, iF)
);
}
// Member functions
// Access
//- Return the temperature at infinity
scalar Tinf() const
{
return Tinf_;
}
//- Return reference to the temperature at infinity
// to allow adjustment
scalar& Tinf()
{
return Tinf_;
}
//- Return the heat transfer coefficient
const scalarField& alpha() const
{
return alpha_;
}
//- Return reference to the heat transfer coefficient
// to allow adjustment
scalarField& alpha()
{
return alpha_;
}
// Mapping functions
//- Map (and resize as needed) from self given a mapping object
virtual void autoMap
(
const fvPatchFieldMapper&
);
//- Reverse map the given fvPatchField onto this fvPatchField
virtual void rmap
(
const fvPatchField<scalar>&,
const labelList&
);
// Evaluation functions
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -1,205 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*---------------------------------------------------------------------------*/
#include "tractionDisplacementFvPatchVectorField.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
#include "rheologyModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
tractionDisplacementFvPatchVectorField::
tractionDisplacementFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF
)
:
fixedGradientFvPatchVectorField(p, iF),
UName_("undefined"),
rheologyName_("undefined"),
traction_(p.size(), vector::zero),
pressure_(p.size(), 0.0)
{
fvPatchVectorField::operator=(patchInternalField());
gradient() = vector::zero;
}
tractionDisplacementFvPatchVectorField::
tractionDisplacementFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const dictionary& dict
)
:
fixedGradientFvPatchVectorField(p, iF),
UName_(dict.lookup("U")),
rheologyName_(dict.lookup("rheology")),
traction_("traction", dict, p.size()),
pressure_("pressure", dict, p.size())
{
fvPatchVectorField::operator=(patchInternalField());
gradient() = vector::zero;
Info << "rf: " << rheologyName_ << endl;
}
tractionDisplacementFvPatchVectorField::
tractionDisplacementFvPatchVectorField
(
const tractionDisplacementFvPatchVectorField& tdpvf,
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedGradientFvPatchVectorField(tdpvf, p, iF, mapper),
UName_(tdpvf.UName_),
rheologyName_(tdpvf.rheologyName_),
traction_(tdpvf.traction_, mapper),
pressure_(tdpvf.pressure_, mapper)
{}
tractionDisplacementFvPatchVectorField::
tractionDisplacementFvPatchVectorField
(
const tractionDisplacementFvPatchVectorField& tdpvf
)
:
fixedGradientFvPatchVectorField(tdpvf),
UName_(tdpvf.UName_),
rheologyName_(tdpvf.rheologyName_),
traction_(tdpvf.traction_),
pressure_(tdpvf.pressure_)
{}
tractionDisplacementFvPatchVectorField::
tractionDisplacementFvPatchVectorField
(
const tractionDisplacementFvPatchVectorField& tdpvf,
const DimensionedField<vector, volMesh>& iF
)
:
fixedGradientFvPatchVectorField(tdpvf, iF),
UName_(tdpvf.UName_),
rheologyName_(tdpvf.rheologyName_),
traction_(tdpvf.traction_),
pressure_(tdpvf.pressure_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void tractionDisplacementFvPatchVectorField::autoMap
(
const fvPatchFieldMapper& m
)
{
fixedGradientFvPatchVectorField::autoMap(m);
traction_.autoMap(m);
pressure_.autoMap(m);
}
// Reverse-map the given fvPatchField onto this fvPatchField
void tractionDisplacementFvPatchVectorField::rmap
(
const fvPatchVectorField& ptf,
const labelList& addr
)
{
fixedGradientFvPatchVectorField::rmap(ptf, addr);
const tractionDisplacementFvPatchVectorField& dmptf =
refCast<const tractionDisplacementFvPatchVectorField>(ptf);
traction_.rmap(dmptf.traction_, addr);
pressure_.rmap(dmptf.pressure_, addr);
}
// Update the coefficients associated with the patch field
void tractionDisplacementFvPatchVectorField::updateCoeffs()
{
if (updated())
{
return;
}
// Looking up rheology
const rheologyModel& rheology =
this->db().objectRegistry::lookupObject<rheologyModel>(rheologyName_);
const scalarField mu = rheology.mu()().boundaryField()[patch().index()];
const scalarField lambda =
rheology.lambda()().boundaryField()[patch().index()];
vectorField n = patch().nf();
const fvPatchField<tensor>& gradU =
lookupPatchField<volTensorField, tensor>("grad(" +UName_ + ")");
gradient() =
(
(traction_ - (pressure_)*n)
- (n & (mu*gradU.T() - (mu + lambda)*gradU))
- n*lambda*tr(gradU)
)/(2.0*mu + lambda);
fixedGradientFvPatchVectorField::updateCoeffs();
}
// Write
void tractionDisplacementFvPatchVectorField::write(Ostream& os) const
{
fvPatchVectorField::write(os);
os.writeKeyword("U") << UName_ << token::END_STATEMENT << nl;
os.writeKeyword("rheology") << rheologyName_ << token::END_STATEMENT << nl;
traction_.writeEntry("traction", os);
pressure_.writeEntry("pressure", os);
writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField(fvPatchVectorField, tractionDisplacementFvPatchVectorField);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -1,199 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
tractionDisplacementFvPatchVectorField
Description
Fixed traction boundary condition for the standard linear elastic, fixed
coefficient displacement equation (stressedFoam).
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved
SourceFiles
tractionDisplacementFvPatchVectorField.C
\*---------------------------------------------------------------------------*/
#ifndef tractionDisplacementFvPatchVectorField_H
#define tractionDisplacementFvPatchVectorField_H
#include "fvPatchFields.H"
#include "fixedGradientFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class tractionDisplacementFvPatchVectorField Declaration
\*---------------------------------------------------------------------------*/
class tractionDisplacementFvPatchVectorField
:
public fixedGradientFvPatchVectorField
{
// Private Data
//- Name of the displacement field
const word UName_;
//- Name of rheology model
const word rheologyName_;
//- Traction
vectorField traction_;
//- Pressure
scalarField pressure_;
public:
//- Runtime type information
TypeName("tractionDisplacement");
// Constructors
//- Construct from patch and internal field
tractionDisplacementFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&
);
//- Construct from patch, internal field and dictionary
tractionDisplacementFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const dictionary&
);
//- Construct by mapping given
// tractionDisplacementFvPatchVectorField onto a new patch
tractionDisplacementFvPatchVectorField
(
const tractionDisplacementFvPatchVectorField&,
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
tractionDisplacementFvPatchVectorField
(
const tractionDisplacementFvPatchVectorField&
);
//- Construct and return a clone
virtual tmp<fvPatchVectorField> clone() const
{
return tmp<fvPatchVectorField>
(
new tractionDisplacementFvPatchVectorField(*this)
);
}
//- Construct as copy setting internal field reference
tractionDisplacementFvPatchVectorField
(
const tractionDisplacementFvPatchVectorField&,
const DimensionedField<vector, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchVectorField> clone
(
const DimensionedField<vector, volMesh>& iF
) const
{
return tmp<fvPatchVectorField>
(
new tractionDisplacementFvPatchVectorField(*this, iF)
);
}
// Member functions
// Access
virtual const vectorField& traction() const
{
return traction_;
}
virtual vectorField& traction()
{
return traction_;
}
virtual const scalarField& pressure() const
{
return pressure_;
}
virtual scalarField& pressure()
{
return pressure_;
}
// Mapping functions
//- Map (and resize as needed) from self given a mapping object
virtual void autoMap
(
const fvPatchFieldMapper&
);
//- Reverse map the given fvPatchField onto this fvPatchField
virtual void rmap
(
const fvPatchVectorField&,
const labelList&
);
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -1,243 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*---------------------------------------------------------------------------*/
#include "tractionDisplacementThermoFvPatchVectorField.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
#include "rheologyModel.H"
#include "thermalModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
tractionDisplacementThermoFvPatchVectorField::
tractionDisplacementThermoFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF
)
:
fixedGradientFvPatchVectorField(p, iF),
UName_("undefined"),
TName_("undefined"),
rheologyName_("undefined"),
thermoName_("undefined"),
traction_(p.size(), vector::zero),
pressure_(p.size(), 0.0)
{
fvPatchVectorField::operator=(patchInternalField());
gradient() = vector::zero;
}
tractionDisplacementThermoFvPatchVectorField::
tractionDisplacementThermoFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const dictionary& dict
)
:
fixedGradientFvPatchVectorField(p, iF),
UName_(dict.lookup("U")),
TName_(dict.lookup("T")),
rheologyName_(dict.lookup("rheology")),
thermoName_(dict.lookup("thermo")),
traction_("traction", dict, p.size()),
pressure_("pressure", dict, p.size())
{
fvPatchVectorField::operator=(patchInternalField());
gradient() = vector::zero;
}
tractionDisplacementThermoFvPatchVectorField::
tractionDisplacementThermoFvPatchVectorField
(
const tractionDisplacementThermoFvPatchVectorField& tdpvf,
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedGradientFvPatchVectorField(tdpvf, p, iF, mapper),
UName_(tdpvf.UName_),
TName_(tdpvf.TName_),
rheologyName_(tdpvf.rheologyName_),
thermoName_(tdpvf.thermoName_),
traction_(tdpvf.traction_, mapper),
pressure_(tdpvf.pressure_, mapper)
{}
tractionDisplacementThermoFvPatchVectorField::
tractionDisplacementThermoFvPatchVectorField
(
const tractionDisplacementThermoFvPatchVectorField& tdpvf
)
:
fixedGradientFvPatchVectorField(tdpvf),
UName_(tdpvf.UName_),
TName_(tdpvf.TName_),
rheologyName_(tdpvf.rheologyName_),
thermoName_(tdpvf.thermoName_),
traction_(tdpvf.traction_),
pressure_(tdpvf.pressure_)
{}
tractionDisplacementThermoFvPatchVectorField::
tractionDisplacementThermoFvPatchVectorField
(
const tractionDisplacementThermoFvPatchVectorField& tdpvf,
const DimensionedField<vector, volMesh>& iF
)
:
fixedGradientFvPatchVectorField(tdpvf, iF),
UName_(tdpvf.UName_),
TName_(tdpvf.TName_),
rheologyName_(tdpvf.rheologyName_),
thermoName_(tdpvf.thermoName_),
traction_(tdpvf.traction_),
pressure_(tdpvf.pressure_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void tractionDisplacementThermoFvPatchVectorField::autoMap
(
const fvPatchFieldMapper& m
)
{
fixedGradientFvPatchVectorField::autoMap(m);
traction_.autoMap(m);
pressure_.autoMap(m);
}
// Reverse-map the given fvPatchField onto this fvPatchField
void tractionDisplacementThermoFvPatchVectorField::rmap
(
const fvPatchVectorField& ptf,
const labelList& addr
)
{
fixedGradientFvPatchVectorField::rmap(ptf, addr);
const tractionDisplacementThermoFvPatchVectorField& dmptf =
refCast<const tractionDisplacementThermoFvPatchVectorField>(ptf);
traction_.rmap(dmptf.traction_, addr);
pressure_.rmap(dmptf.pressure_, addr);
}
// Update the coefficients associated with the patch field
void tractionDisplacementThermoFvPatchVectorField::updateCoeffs()
{
if (updated())
{
return;
}
// Looking up rheology
const rheologyModel& rheology =
this->db().objectRegistry::
lookupObject<rheologyModel>(rheologyName_);
const scalarField mu = rheology.mu()().boundaryField()[patch().index()];
const scalarField lambda =
rheology.lambda()().boundaryField()[patch().index()];
vectorField n = patch().nf();
const fvPatchField<tensor>& gradU =
lookupPatchField<volTensorField, tensor>("grad(" +UName_ + ")");
// Thermal component
// Looking up thermo
const thermalModel& thermo =
this->db().objectRegistry::lookupObject<thermalModel>(thermoName_);
const fvPatchField<scalar>& T =
lookupPatchField<volScalarField, scalar>(TName_);
const scalarField rhoThreeKalpha =
rheology.rho()().boundaryField()[patch().index()]*
rheology.threeK()().boundaryField()[patch().index()]*
thermo.alpha()().boundaryField()[patch().index()];
const scalarField T0 = thermo.T0()().boundaryField()[patch().index()];
gradient() =
(
(traction_ - (pressure_)*n)
- (n & (mu*gradU.T() - (mu + lambda)*gradU))
- n*lambda*tr(gradU)
+ n*rhoThreeKalpha*(T - T0)
)/(2.0*mu + lambda);
fixedGradientFvPatchVectorField::updateCoeffs();
}
// Write
void tractionDisplacementThermoFvPatchVectorField::write
(
Ostream& os
) const
{
fvPatchVectorField::write(os);
os.writeKeyword("U") << UName_ << token::END_STATEMENT << nl;
os.writeKeyword("T") << TName_ << token::END_STATEMENT << nl;
os.writeKeyword("rheology") << rheologyName_ << token::END_STATEMENT << nl;
os.writeKeyword("thermo") << thermoName_ << token::END_STATEMENT << nl;
traction_.writeEntry("traction", os);
pressure_.writeEntry("pressure", os);
writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField
(
fvPatchVectorField,
tractionDisplacementThermoFvPatchVectorField
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -1,201 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
tractionDisplacementThermoFvPatchVectorField
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved
SourceFiles
tractionDisplacementThermoFvPatchVectorField.C
\*---------------------------------------------------------------------------*/
#ifndef tractionDisplacementThermoFvPatchVectorField_H
#define tractionDisplacementThermoFvPatchVectorField_H
#include "fvPatchFields.H"
#include "fixedGradientFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class tractionDisplacementThermoFvPatchVectorField Declaration
\*---------------------------------------------------------------------------*/
class tractionDisplacementThermoFvPatchVectorField
:
public fixedGradientFvPatchVectorField
{
// Private Data
//- Name of the displacement field
const word UName_;
//- Name of the temperature field
const word TName_;
//- Name of rheology model
const word rheologyName_;
//- Name of thermal model
const word thermoName_;
//- Traction
vectorField traction_;
//- Pressure
scalarField pressure_;
public:
//- Runtime type information
TypeName("tractionDisplacementThermo");
// Constructors
//- Construct from patch and internal field
tractionDisplacementThermoFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&
);
//- Construct from patch, internal field and dictionary
tractionDisplacementThermoFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const dictionary&
);
//- Construct by mapping given
// tractionDisplacementThermoFvPatchVectorField onto a new patch
tractionDisplacementThermoFvPatchVectorField
(
const tractionDisplacementThermoFvPatchVectorField&,
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
tractionDisplacementThermoFvPatchVectorField
(
const tractionDisplacementThermoFvPatchVectorField&
);
//- Construct and return a clone
virtual tmp<fvPatchVectorField> clone() const
{
return tmp<fvPatchVectorField>
(
new tractionDisplacementThermoFvPatchVectorField(*this)
);
}
//- Construct as copy setting internal field reference
tractionDisplacementThermoFvPatchVectorField
(
const tractionDisplacementThermoFvPatchVectorField&,
const DimensionedField<vector, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchVectorField> clone
(
const DimensionedField<vector, volMesh>& iF
) const
{
return tmp<fvPatchVectorField>
(
new tractionDisplacementThermoFvPatchVectorField(*this, iF)
);
}
// Member functions
// Access
virtual const vectorField& traction() const
{
return traction_;
}
virtual vectorField& traction()
{
return traction_;
}
virtual const scalarField& pressure() const
{
return pressure_;
}
virtual scalarField& pressure()
{
return pressure_;
}
// Mapping functions
//- Map (and resize as needed) from self given a mapping object
virtual void autoMap
(
const fvPatchFieldMapper&
);
//- Reverse map the given fvPatchField onto this fvPatchField
virtual void rmap
(
const fvPatchVectorField&,
const labelList&
);
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -1,210 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
\*---------------------------------------------------------------------------*/
#include "BurgersViscoelastic.H"
#include "addToRunTimeSelectionTable.H"
#include "zeroGradientFvPatchFields.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(BurgersViscoelastic, 0);
addToRunTimeSelectionTable(rheologyLaw, BurgersViscoelastic, dictionary);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from dictionary
Foam::BurgersViscoelastic::BurgersViscoelastic
(
const word& name,
const volSymmTensorField& sigma,
const dictionary& dict
)
:
rheologyLaw(name, sigma, dict),
rho_(dict.lookup("rho")),
k1_(dict.lookup("k1")),
eta1_(dict.lookup("eta1")),
k2_(dict.lookup("k2")),
eta2_(dict.lookup("eta2")),
nu_(dict.lookup("nu"))
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::BurgersViscoelastic::~BurgersViscoelastic()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField> Foam::BurgersViscoelastic::rho(scalar t) const
{
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"rho",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
rho_,
zeroGradientFvPatchScalarField::typeName
)
);
tresult().correctBoundaryConditions();
return tresult;
}
Foam::tmp<Foam::volScalarField> Foam::BurgersViscoelastic::E(scalar t) const
{
scalar E = 0.0;
if(t>=0)
{
scalar p1 = eta1_.value()/k1_.value()
+ eta1_.value()/k2_.value()
+ eta2_.value()/k2_.value();
scalar p2 = eta1_.value()*eta2_.value()/(k1_.value()*k2_.value());
scalar q1 = eta1_.value();
scalar q2 = eta1_.value()*eta2_.value()/k2_.value();
scalar A = sqrt(sqr(p1) - 4*p2);
scalar r1 = (p1 - A)/(2*p2);
scalar r2 = (p1 + A)/(2*p2);
E = (q1 - q2*r1)*exp(-r1*t)/A - (q1 - q2*r2)*exp(-r2*t)/A;
}
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"E",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
dimensionedScalar("E", k1_.dimensions(), E),
zeroGradientFvPatchScalarField::typeName
)
);
tresult().correctBoundaryConditions();
return tresult;
}
Foam::tmp<Foam::volScalarField> Foam::BurgersViscoelastic::nu(scalar t) const
{
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"nu",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
nu_,
zeroGradientFvPatchScalarField::typeName
)
);
tresult().correctBoundaryConditions();
return tresult;
}
Foam::tmp<Foam::volScalarField> Foam::BurgersViscoelastic::J(scalar t) const
{
scalar J = 0.0;
if(t >= 0)
{
J = 1.0/k1_.value()
+ (1 - exp(-k2_.value()*t/eta2_.value()))/k2_.value()
+ t/eta1_.value();
}
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"J",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
dimensionedScalar("J", dimless/k1_.dimensions(), J),
zeroGradientFvPatchScalarField::typeName
)
);
tresult().correctBoundaryConditions();
return tresult;
}
// ************************************************************************* //

View file

@ -1,154 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BurgersViscoelastic
Description
Linear elastic rheology
SourceFiles
BurgersViscoelastic.C
\*---------------------------------------------------------------------------*/
#ifndef BurgersViscoelastic_H
#define BurgersViscoelastic_H
#include "rheologyLaw.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class BurgersViscoelastic Declaration
\*---------------------------------------------------------------------------*/
class BurgersViscoelastic
:
public rheologyLaw
{
// Private data
//- Density
dimensionedScalar rho_;
//- Linear spring constant of Maxwell model
dimensionedScalar k1_;
//- Coefficient of viscosity of Maxwell model
dimensionedScalar eta1_;
//- Linear spring constant of Kelvin model
dimensionedScalar k2_;
//- Coefficient of viscosity of Kelvin model
dimensionedScalar eta2_;
//- Poisson's ratio
dimensionedScalar nu_;
// Private Member Functions
//- Disallow default bitwise copy construct
BurgersViscoelastic(const BurgersViscoelastic&);
//- Disallow default bitwise assignment
void operator=(const BurgersViscoelastic&);
public:
//- Runtime type information
TypeName("BurgersViscoelastic");
// Static data members
// Constructors
//- Construct from dictionary
BurgersViscoelastic
(
const word& name,
const volSymmTensorField& sigma,
const dictionary& dict
);
// Destructor
virtual ~BurgersViscoelastic();
// Member Functions
//- Return density
virtual tmp<volScalarField> rho() const
{
return rho(0);
}
//- Return modulus of elasticity
virtual tmp<volScalarField> E() const
{
return E(0);
}
//- Return Poisson's ratio
virtual tmp<volScalarField> nu() const
{
return nu(0);
}
//- Return density
virtual tmp<volScalarField> rho(scalar t) const;
//- Return modulus of elasticity
virtual tmp<volScalarField> E(scalar t) const;
//- Return Poisson's ratio
virtual tmp<volScalarField> nu(scalar t) const;
//- Return creep compliance
virtual tmp<volScalarField> J(scalar t) const;
//- Correct the rheological model
virtual void correct()
{}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -1,203 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
\*---------------------------------------------------------------------------*/
#include "KelvinSLSViscoelastic.H"
#include "addToRunTimeSelectionTable.H"
#include "zeroGradientFvPatchFields.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(KelvinSLSViscoelastic, 0);
addToRunTimeSelectionTable(rheologyLaw, KelvinSLSViscoelastic, dictionary);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from dictionary
Foam::KelvinSLSViscoelastic::KelvinSLSViscoelastic
(
const word& name,
const volSymmTensorField& sigma,
const dictionary& dict
)
:
rheologyLaw(name, sigma, dict),
rho_(dict.lookup("rho")),
k1_(dict.lookup("k1")),
k2_(dict.lookup("k2")),
eta2_(dict.lookup("eta2")),
nu_(dict.lookup("nu"))
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::KelvinSLSViscoelastic::~KelvinSLSViscoelastic()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField> Foam::KelvinSLSViscoelastic::rho(scalar t) const
{
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"rho",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
rho_,
zeroGradientFvPatchScalarField::typeName
)
);
tresult().correctBoundaryConditions();
return tresult;
}
Foam::tmp<Foam::volScalarField> Foam::KelvinSLSViscoelastic::E(scalar t) const
{
scalar E = 0.0;
if(t>=0)
{
scalar p1 = eta2_.value()/(k1_.value() + k2_.value());
scalar q0 = k1_.value()*k2_.value()/(k1_.value() + k2_.value());
scalar q1 = k1_.value()*eta2_.value()/(k1_.value() + k2_.value());
E = q0 + (q1/p1 - q0)*exp(-t/p1);
}
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"E",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
dimensionedScalar("E", k1_.dimensions(), E),
zeroGradientFvPatchScalarField::typeName
)
);
tresult().correctBoundaryConditions();
return tresult;
}
Foam::tmp<Foam::volScalarField> Foam::KelvinSLSViscoelastic::nu(scalar t) const
{
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"nu",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
nu_,
zeroGradientFvPatchScalarField::typeName
)
);
tresult().correctBoundaryConditions();
return tresult;
}
Foam::tmp<Foam::volScalarField> Foam::KelvinSLSViscoelastic::J(scalar t) const
{
scalar J = 0.0;
if(t >= 0)
{
scalar p1 = eta2_.value()/(k1_.value() + k2_.value());
scalar q0 = k1_.value()*k2_.value()/(k1_.value() + k2_.value());
scalar q1 = k1_.value()*eta2_.value()/(k1_.value() + k2_.value());
J = 1.0/q0 + (p1/q1 - 1.0/q0)*exp(-q0*t/q1);
}
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"J",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
dimensionedScalar("J", dimless/k1_.dimensions(), J),
zeroGradientFvPatchScalarField::typeName
)
);
tresult().correctBoundaryConditions();
return tresult;
}
// ************************************************************************* //

View file

@ -1,204 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
\*---------------------------------------------------------------------------*/
#include "MaxwellElasticViscoelastic.H"
#include "addToRunTimeSelectionTable.H"
#include "zeroGradientFvPatchFields.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(MaxwellElasticViscoelastic, 0);
addToRunTimeSelectionTable
(
rheologyLaw,
MaxwellElasticViscoelastic,
dictionary
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from dictionary
Foam::MaxwellElasticViscoelastic::MaxwellElasticViscoelastic
(
const word& name,
const volSymmTensorField& sigma,
const dictionary& dict
)
:
rheologyLaw(name, sigma, dict),
rho_(dict.lookup("rho")),
k_(dict.lookup("k")),
eta_(dict.lookup("eta")),
nu_(dict.lookup("nu"))
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::MaxwellElasticViscoelastic::~MaxwellElasticViscoelastic()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField>
Foam::MaxwellElasticViscoelastic::rho(scalar t) const
{
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"rho",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
rho_,
zeroGradientFvPatchScalarField::typeName
)
);
tresult().correctBoundaryConditions();
return tresult;
}
Foam::tmp<Foam::volScalarField>
Foam::MaxwellElasticViscoelastic::E(scalar t) const
{
scalar tau = eta_.value()/k_.value();
tmp<volScalarField> tE
(
new volScalarField
(
IOobject
(
"E",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
k_*exp(-t/tau),
zeroGradientFvPatchScalarField::typeName
)
);
if (t < 0)
{
tE().internalField() = 0.0;
tE().correctBoundaryConditions();
}
return tE;
}
Foam::tmp<Foam::volScalarField>
Foam::MaxwellElasticViscoelastic::nu(scalar t) const
{
scalar tau = eta_.value()/k_.value();
scalar E0 = k_.value();
scalar Et = k_.value()*exp(-t/tau);
scalar nu = 0.5 - Et/(6*E0);
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"nu",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
dimensionedScalar("nu", dimless, nu),
zeroGradientFvPatchScalarField::typeName
)
);
tresult().correctBoundaryConditions();
return tresult;
}
Foam::tmp<Foam::volScalarField>
Foam::MaxwellElasticViscoelastic::J(scalar t) const
{
tmp<volScalarField> tJ
(
new volScalarField
(
IOobject
(
"J",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
dimensionedScalar
(
"J",
dimless/k_.dimensions(),
1.0/k_.value() + t/eta_.value()
),
zeroGradientFvPatchScalarField::typeName
)
);
if (t < 0)
{
tJ().internalField() = 0.0;
tJ().correctBoundaryConditions();
}
return tJ;
}
// ************************************************************************* //

View file

@ -1,148 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
MaxwellElasticViscoelastic
Description
Linear elastic rheology
SourceFiles
MaxwellElasticViscoelastic.C
\*---------------------------------------------------------------------------*/
#ifndef MaxwellElasticViscoelastic_H
#define MaxwellElasticViscoelastic_H
#include "rheologyLaw.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class MaxwellElasticViscoelastic Declaration
\*---------------------------------------------------------------------------*/
class MaxwellElasticViscoelastic
:
public rheologyLaw
{
// Private data
//- Density
dimensionedScalar rho_;
//- Linear spring constant
dimensionedScalar k_;
//- Coefficient of viscosity
dimensionedScalar eta_;
//- Poisson's ratio
dimensionedScalar nu_;
// Private Member Functions
//- Disallow default bitwise copy construct
MaxwellElasticViscoelastic(const MaxwellElasticViscoelastic&);
//- Disallow default bitwise assignment
void operator=(const MaxwellElasticViscoelastic&);
public:
//- Runtime type information
TypeName("MaxwellElasticViscoelastic");
// Static data members
// Constructors
//- Construct from dictionary
MaxwellElasticViscoelastic
(
const word& name,
const volSymmTensorField& sigma,
const dictionary& dict
);
// Destructor
virtual ~MaxwellElasticViscoelastic();
// Member Functions
//- Return density
virtual tmp<volScalarField> rho() const
{
return rho(0);
}
//- Return modulus of elasticity
virtual tmp<volScalarField> E() const
{
return E(0);
}
//- Return Poisson's ratio
virtual tmp<volScalarField> nu() const
{
return nu(0);
}
//- Return density
virtual tmp<volScalarField> rho(scalar t) const;
//- Return modulus of elasticity
virtual tmp<volScalarField> E(scalar t) const;
//- Return Poisson's ratio
virtual tmp<volScalarField> nu(scalar t) const;
//- Return creep compliance
virtual tmp<volScalarField> J(scalar t) const;
//- Correct the rheological model
virtual void correct()
{}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -1,197 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
\*---------------------------------------------------------------------------*/
#include "MaxwellSLSViscoelastic.H"
#include "addToRunTimeSelectionTable.H"
#include "zeroGradientFvPatchFields.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(MaxwellSLSViscoelastic, 0);
addToRunTimeSelectionTable(rheologyLaw, MaxwellSLSViscoelastic, dictionary);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from dictionary
Foam::MaxwellSLSViscoelastic::MaxwellSLSViscoelastic
(
const word& name,
const volSymmTensorField& sigma,
const dictionary& dict
)
:
rheologyLaw(name, sigma, dict),
rho_(dict.lookup("rho")),
k1_(dict.lookup("k1")),
eta1_(dict.lookup("eta1")),
k2_(dict.lookup("k2")),
nu_(dict.lookup("nu"))
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::MaxwellSLSViscoelastic::~MaxwellSLSViscoelastic()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField>
Foam::MaxwellSLSViscoelastic::rho(scalar t) const
{
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"rho",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
rho_,
zeroGradientFvPatchScalarField::typeName
)
);
tresult().correctBoundaryConditions();
return tresult;
}
Foam::tmp<Foam::volScalarField> Foam::MaxwellSLSViscoelastic::E(scalar t) const
{
scalar E = 0.0;
if(t>=0)
{
E = k2_.value() + k1_.value()*exp(-k1_.value()*t/eta1_.value());
}
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"E",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
dimensionedScalar("E", k1_.dimensions(), E),
zeroGradientFvPatchScalarField::typeName
)
);
tresult().correctBoundaryConditions();
return tresult;
}
Foam::tmp<Foam::volScalarField> Foam::MaxwellSLSViscoelastic::nu(scalar t) const
{
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"nu",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
nu_,
zeroGradientFvPatchScalarField::typeName
)
);
tresult().correctBoundaryConditions();
return tresult;
}
Foam::tmp<Foam::volScalarField> Foam::MaxwellSLSViscoelastic::J(scalar t) const
{
scalar J = 0.0;
if(t>=0)
{
scalar Jg = 1.0/(k2_.value() + k1_.value());
scalar Jr = 1.0/k2_.value();
scalar tau = eta1_.value()/k1_.value();
scalar tauC = tau*(k1_.value() + k2_.value())/k2_.value();
J = Jg + (Jr - Jg)*(1.0 - exp(-t/tauC));
}
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"J",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
dimensionedScalar("J", dimless/k1_.dimensions(), J),
zeroGradientFvPatchScalarField::typeName
)
);
tresult().correctBoundaryConditions();
return tresult;
}
// ************************************************************************* //

View file

@ -1,150 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
MaxwellSLSViscoelastic
Description
Linear elastic rheology
SourceFiles
MaxwellSLSViscoelastic.C
\*---------------------------------------------------------------------------*/
#ifndef MaxwellSLSViscoelastic_H
#define MaxwellSLSViscoelastic_H
#include "rheologyLaw.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class MaxwellSLSViscoelastic Declaration
\*---------------------------------------------------------------------------*/
class MaxwellSLSViscoelastic
:
public rheologyLaw
{
// Private data
//- Density
dimensionedScalar rho_;
//- Linear spring constant of Maxwell model
dimensionedScalar k1_;
//- Coefficient of viscosity of Maxwell model
dimensionedScalar eta1_;
//- Linear spring constant
dimensionedScalar k2_;
//- Poisson's ratio
dimensionedScalar nu_;
// Private Member Functions
//- Disallow default bitwise copy construct
MaxwellSLSViscoelastic(const MaxwellSLSViscoelastic&);
//- Disallow default bitwise assignment
void operator=(const MaxwellSLSViscoelastic&);
public:
//- Runtime type information
TypeName("MaxwellSLSViscoelastic");
// Static data members
// Constructors
//- Construct from dictionary
MaxwellSLSViscoelastic
(
const word& name,
const volSymmTensorField& sigma,
const dictionary& dict
);
// Destructor
virtual ~MaxwellSLSViscoelastic();
// Member Functions
//- Return density
virtual tmp<volScalarField> rho() const
{
return rho(0);
}
//- Return modulus of elasticity
virtual tmp<volScalarField> E() const
{
return E(0);
}
//- Return Poisson's ratio
virtual tmp<volScalarField> nu() const
{
return nu(0);
}
//- Return density
virtual tmp<volScalarField> rho(scalar t) const;
//- Return modulus of elasticity
virtual tmp<volScalarField> E(scalar t) const;
//- Return Poisson's ratio
virtual tmp<volScalarField> nu(scalar t) const;
//- Return creep compliance
virtual tmp<volScalarField> J(scalar t) const;
//- Correct the rheological model
virtual void correct()
{}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -1,190 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
\*---------------------------------------------------------------------------*/
#include "MaxwellViscoelastic.H"
#include "addToRunTimeSelectionTable.H"
#include "zeroGradientFvPatchFields.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(MaxwellViscoelastic, 0);
addToRunTimeSelectionTable(rheologyLaw, MaxwellViscoelastic, dictionary);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from dictionary
Foam::MaxwellViscoelastic::MaxwellViscoelastic
(
const word& name,
const volSymmTensorField& sigma,
const dictionary& dict
)
:
rheologyLaw(name, sigma, dict),
rho_(dict.lookup("rho")),
k_(dict.lookup("k")),
eta_(dict.lookup("eta")),
nu_(dict.lookup("nu"))
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::MaxwellViscoelastic::~MaxwellViscoelastic()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField> Foam::MaxwellViscoelastic::rho(scalar t) const
{
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"rho",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
rho_,
zeroGradientFvPatchScalarField::typeName
)
);
tresult().correctBoundaryConditions();
return tresult;
}
Foam::tmp<Foam::volScalarField> Foam::MaxwellViscoelastic::E(scalar t) const
{
scalar tau = eta_.value()/k_.value();
tmp<volScalarField> tE
(
new volScalarField
(
IOobject
(
"E",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
k_*exp(-t/tau),
zeroGradientFvPatchScalarField::typeName
)
);
if (t < 0)
{
tE().internalField() = 0.0;
tE().correctBoundaryConditions();
}
return tE;
}
Foam::tmp<Foam::volScalarField> Foam::MaxwellViscoelastic::nu(scalar t) const
{
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"nu",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
nu_,
zeroGradientFvPatchScalarField::typeName
)
);
tresult().correctBoundaryConditions();
return tresult;
}
Foam::tmp<Foam::volScalarField> Foam::MaxwellViscoelastic::J(scalar t) const
{
tmp<volScalarField> tJ
(
new volScalarField
(
IOobject
(
"J",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
dimensionedScalar
(
"J",
dimless/k_.dimensions(),
1.0/k_.value() + t/eta_.value()
),
zeroGradientFvPatchScalarField::typeName
)
);
if (t < 0)
{
tJ().internalField() = 0.0;
tJ().correctBoundaryConditions();
}
return tJ;
}
// ************************************************************************* //

View file

@ -1,170 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
\*---------------------------------------------------------------------------*/
#include "PronyViscoelastic.H"
#include "addToRunTimeSelectionTable.H"
#include "zeroGradientFvPatchFields.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(PronyViscoelastic, 0);
addToRunTimeSelectionTable(rheologyLaw, PronyViscoelastic, dictionary);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from dictionary
Foam::PronyViscoelastic::PronyViscoelastic
(
const word& name,
const volSymmTensorField& sigma,
const dictionary& dict
)
:
rheologyLaw(name, sigma, dict),
rho_(dict.lookup("rho")),
k_("k", dict, readInt(dict.lookup("size"))),
kDimensions_(dict.lookup("kDimensions")),
tau_("tau", dict, readInt(dict.lookup("size"))),
tauDimensions_(dict.lookup("tauDimensions")),
nu_(dict.lookup("nu"))
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::PronyViscoelastic::~PronyViscoelastic()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField> Foam::PronyViscoelastic::rho(scalar t) const
{
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"rho",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
rho_,
zeroGradientFvPatchScalarField::typeName
)
);
tresult().correctBoundaryConditions();
return tresult;
}
Foam::tmp<Foam::volScalarField> Foam::PronyViscoelastic::E(scalar t) const
{
scalar E = 0.0;
E = k_[0];
for(int i=1; i<k_.size(); i++)
{
E += k_[i]*exp(-t/tau_[i]);
}
if(t < 0)
{
E = 0;
}
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"E",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
dimensionedScalar("E", kDimensions_, E),
zeroGradientFvPatchScalarField::typeName
)
);
tresult().correctBoundaryConditions();
return tresult;
}
Foam::tmp<Foam::volScalarField> Foam::PronyViscoelastic::nu(scalar t) const
{
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"nu",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
nu_,
zeroGradientFvPatchScalarField::typeName
)
);
tresult().correctBoundaryConditions();
return tresult;
}
Foam::tmp<Foam::volScalarField> Foam::PronyViscoelastic::J(scalar t) const
{
notImplemented(type() + "::J(scalar t)");
return 1.0/E(t);
}
// ************************************************************************* //

View file

@ -1,153 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
PronyViscoelastic
Description
Linear elastic rheology
SourceFiles
PronyViscoelastic.C
\*---------------------------------------------------------------------------*/
#ifndef PronyViscoelastic_H
#define PronyViscoelastic_H
#include "rheologyLaw.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class PronyViscoelastic Declaration
\*---------------------------------------------------------------------------*/
class PronyViscoelastic
:
public rheologyLaw
{
// Private data
//- Density
dimensionedScalar rho_;
//- Linear spring constants of generalised Maxwell model
Field<scalar> k_;
//- Dimension set for k field
dimensionSet kDimensions_;
//- Relaxation times of generalised Maxwell model
Field<scalar> tau_;
//- Dimension set for tau field
dimensionSet tauDimensions_;
//- Poisson's ratio
dimensionedScalar nu_;
// Private Member Functions
//- Disallow default bitwise copy construct
PronyViscoelastic(const PronyViscoelastic&);
//- Disallow default bitwise assignment
void operator=(const PronyViscoelastic&);
public:
//- Runtime type information
TypeName("PronyViscoelastic");
// Static data members
// Constructors
//- Construct from dictionary
PronyViscoelastic
(
const word& name,
const volSymmTensorField& sigma,
const dictionary& dict
);
// Destructor
virtual ~PronyViscoelastic();
// Member Functions
//- Return density
virtual tmp<volScalarField> rho() const
{
return rho(0);
}
//- Return modulus of elasticity
virtual tmp<volScalarField> E() const
{
return E(0);
}
//- Return Poisson's ratio
virtual tmp<volScalarField> nu() const
{
return nu(0);
}
//- Return density
virtual tmp<volScalarField> rho(scalar t) const;
//- Return modulus of elasticity
virtual tmp<volScalarField> E(scalar t) const;
//- Return Poisson's ratio
virtual tmp<volScalarField> nu(scalar t) const;
//- Return creep compliance
virtual tmp<volScalarField> J(scalar t) const;
//- Correct the rheological model
virtual void correct()
{}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -1,148 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
\*---------------------------------------------------------------------------*/
#include "linearElastic.H"
#include "addToRunTimeSelectionTable.H"
#include "zeroGradientFvPatchFields.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(linearElastic, 0);
addToRunTimeSelectionTable(rheologyLaw, linearElastic, dictionary);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from dictionary
Foam::linearElastic::linearElastic
(
const word& name,
const volSymmTensorField& sigma,
const dictionary& dict
)
:
rheologyLaw(name, sigma, dict),
rho_(dict.lookup("rho")),
E_(dict.lookup("E")),
nu_(dict.lookup("nu"))
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::linearElastic::~linearElastic()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField> Foam::linearElastic::rho() const
{
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"rho",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
rho_,
zeroGradientFvPatchScalarField::typeName
)
);
tresult().correctBoundaryConditions();
return tresult;
}
Foam::tmp<Foam::volScalarField> Foam::linearElastic::E() const
{
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"E",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
E_,
zeroGradientFvPatchScalarField::typeName
)
);
tresult().correctBoundaryConditions();
return tresult;
}
Foam::tmp<Foam::volScalarField> Foam::linearElastic::nu() const
{
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"nu",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
nu_,
zeroGradientFvPatchScalarField::typeName
)
);
tresult().correctBoundaryConditions();
return tresult;
}
// ************************************************************************* //

View file

@ -1,261 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
Zoned multi-material rheology controlled by a material indicator field.
\*---------------------------------------------------------------------------*/
#include "multiMaterial.H"
#include "addToRunTimeSelectionTable.H"
#include "zeroGradientFvPatchFields.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(multiMaterial, 0);
addToRunTimeSelectionTable(rheologyLaw, multiMaterial, dictionary);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::tmp<Foam::scalarField> Foam::multiMaterial::indicator
(
const label i
) const
{
const scalarField& mat = materials_.internalField();
tmp<scalarField> tresult(new scalarField(mat.size(), 0.0));
scalarField& result = tresult();
forAll (mat, matI)
{
if (mat[matI] > i - SMALL && mat[matI] < i + 1 - SMALL)
{
result[matI] = 1.0;
}
}
return tresult;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from dictionary
Foam::multiMaterial::multiMaterial
(
const word& name,
const volSymmTensorField& sigma,
const dictionary& dict
)
:
rheologyLaw(name, sigma, dict),
PtrList<rheologyLaw>(),
materials_
(
IOobject
(
"materials",
mesh().time().timeName(),
mesh(),
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh()
)
{
PtrList<rheologyLaw>& laws = *this;
PtrList<entry> lawEntries(dict.lookup("laws"));
laws.setSize(lawEntries.size());
forAll (laws, lawI)
{
laws.set
(
lawI,
rheologyLaw::New
(
lawEntries[lawI].keyword(),
sigma,
lawEntries[lawI].dict()
)
);
}
if
(
min(materials_).value() < 0
|| max(materials_).value() > laws.size() + SMALL
)
{
FatalErrorIn
(
"multiMaterial::multiMaterial\n"
"(\n"
" const word& name,\n"
" const volSymmTensorField& sigma,\n"
" const dictionary& dict\n"
")"
) << "Invalid definition of material indicator field. "
<< "Number of materials: " << laws.size()
<< " max index: " << max(materials_)
<< ". Should be " << laws.size() - 1
<< abort(FatalError);
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::multiMaterial::~multiMaterial()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField> Foam::multiMaterial::rho() const
{
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"rho",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
dimensionedScalar("zeroRho", dimDensity, 0),
zeroGradientFvPatchScalarField::typeName
)
);
volScalarField& result = tresult();
// Accumulate data for all fields
const PtrList<rheologyLaw>& laws = *this;
forAll (laws, lawI)
{
result.internalField() +=
indicator(lawI)*laws[lawI].rho()().internalField();
}
result.correctBoundaryConditions();
return tresult;
}
Foam::tmp<Foam::volScalarField> Foam::multiMaterial::E() const
{
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"E",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
dimensionedScalar("zeroE", dimForce/dimArea, 0),
zeroGradientFvPatchScalarField::typeName
)
);
volScalarField& result = tresult();
// Accumulate data for all fields
const PtrList<rheologyLaw>& laws = *this;
forAll (laws, lawI)
{
result.internalField() +=
indicator(lawI)*laws[lawI].E()().internalField();
}
result.correctBoundaryConditions();
return tresult;
}
Foam::tmp<Foam::volScalarField> Foam::multiMaterial::nu() const
{
tmp<volScalarField> tresult
(
new volScalarField
(
IOobject
(
"nu",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh(),
dimensionedScalar("zeroE", dimless, 0),
zeroGradientFvPatchScalarField::typeName
)
);
volScalarField& result = tresult();
// Accumulate data for all fields
const PtrList<rheologyLaw>& laws = *this;
forAll (laws, lawI)
{
result.internalField() +=
indicator(lawI)*laws[lawI].nu()().internalField();
}
result.correctBoundaryConditions();
return tresult;
}
void Foam::multiMaterial::correct()
{
PtrList<rheologyLaw>& laws = *this;
forAll (laws, lawI)
{
laws[lawI].correct();
}
}
// ************************************************************************* //

View file

@ -1,282 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2008 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
rheologyModel
Description
Material rheology for solids.
\*---------------------------------------------------------------------------*/
#include "rheologyModel.H"
#include "volFields.H"
#include "fvc.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(rheologyModel, 0);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
rheologyModel::rheologyModel
(
const volSymmTensorField& sigma
)
:
IOdictionary
(
IOobject
(
"rheologyProperties",
sigma.time().constant(),
sigma.db(),
IOobject::MUST_READ,
IOobject::NO_WRITE
)
),
sigma_(sigma),
planeStress_(lookup("planeStress")),
lawPtr_(rheologyLaw::New("law", sigma_, subDict("rheology")))
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
// Return first Lame's coefficient
tmp<volScalarField> rheologyModel::mu() const
{
volScalarField lawE = lawPtr_->E();
volScalarField lawNu = lawPtr_->nu();
return tmp<volScalarField>
(
new volScalarField
(
IOobject
(
"mu",
sigma_.time().timeName(),
sigma_.db(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
lawE/(2.0*(1.0 + lawNu))
)
);
}
// Return second Lame's coefficient
tmp<volScalarField> rheologyModel::lambda() const
{
volScalarField lawE = lawPtr_->E();
volScalarField lawNu = lawPtr_->nu();
if (planeStress())
{
return tmp<volScalarField>
(
new volScalarField
(
IOobject
(
"lambda",
sigma_.time().timeName(),
sigma_.db(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
lawNu*lawE/((1.0 + lawNu)*(1.0 - lawNu))
)
);
}
else
{
return tmp<volScalarField>
(
new volScalarField
(
IOobject
(
"lambda",
sigma_.time().timeName(),
sigma_.db(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
lawNu*lawE/((1.0 + lawNu)*(1.0 - 2.0*lawNu))
)
);
}
}
// Return threeK
tmp<volScalarField> rheologyModel::threeK() const
{
volScalarField lawRho = lawPtr_->rho();
volScalarField lawE = lawPtr_->E();
volScalarField lawNu = lawPtr_->nu();
if (planeStress())
{
return tmp<volScalarField>
(
new volScalarField
(
IOobject
(
"threeK",
sigma_.time().timeName(),
sigma_.db(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
lawE/(lawRho*(1 - lawNu))
)
);
}
else
{
return tmp<volScalarField>
(
new volScalarField
(
IOobject
(
"threeK",
sigma_.time().timeName(),
sigma_.db(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
lawE/(lawRho*(1 - 2*lawNu))
)
);
}
}
// Return first Lame's coefficient
tmp<volScalarField> rheologyModel::mu(scalar t) const
{
volScalarField lawE = lawPtr_->E(t);
volScalarField lawNu = lawPtr_->nu(t);
return tmp<volScalarField>
(
new volScalarField
(
IOobject
(
"mu",
sigma_.time().timeName(),
sigma_.db(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
lawE/(2.0*(1.0 + lawNu))
)
);
}
// Return second Lame's coefficient
tmp<volScalarField> rheologyModel::lambda(scalar t) const
{
volScalarField lawE = lawPtr_->E(t);
volScalarField lawNu = lawPtr_->nu(t);
if (planeStress())
{
return tmp<volScalarField>
(
new volScalarField
(
IOobject
(
"lambda",
sigma_.time().timeName(),
sigma_.db(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
lawNu*lawE/((1.0 + lawNu)*(1.0 - lawNu))
)
);
}
else
{
return tmp<volScalarField>
(
new volScalarField
(
IOobject
(
"lambda",
sigma_.time().timeName(),
sigma_.db(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
lawNu*lawE/((1.0 + lawNu)*(1.0 - 2.0*lawNu))
)
);
}
}
void rheologyModel::correct()
{
lawPtr_->correct();
}
bool rheologyModel::read()
{
if (regIOobject::read())
{
lookup("planeStress") >> planeStress_;
lawPtr_ = rheologyLaw::New("law", sigma_, subDict("rheology"));
return true;
}
else
{
return false;
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -1,158 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
rheologyModel
Description
Material rheology for solids.
SourceFiles
rheologyModel.C
\*---------------------------------------------------------------------------*/
#ifndef rheologyModel_H
#define rheologyModel_H
#include "IOdictionary.H"
#include "typeInfo.H"
#include "runTimeSelectionTables.H"
#include "volFields.H"
#include "tmp.H"
#include "rheologyLaw.H"
#include "Switch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class rheologyModel Declaration
\*---------------------------------------------------------------------------*/
class rheologyModel
:
public IOdictionary
{
// Private data
//- Reference to stress field
const volSymmTensorField& sigma_;
//- Plane stress
Switch planeStress_;
//- Rheology law
autoPtr<rheologyLaw> lawPtr_;
// Private Member Functions
//- Disallow copy construct
rheologyModel(const rheologyModel&);
//- Disallow default bitwise assignment
void operator=(const rheologyModel&);
public:
//- Runtime type information
TypeName("rheologyModel");
// Constructors
//- Construct from dictionary
rheologyModel
(
const volSymmTensorField& sigma
);
// Destructor
virtual ~rheologyModel()
{}
// Member Functions
//- Return true for plane stress
const Switch& planeStress() const
{
return planeStress_;
}
//- Return rheology law
const rheologyLaw& law() const
{
return lawPtr_();
}
//- Return density
tmp<volScalarField> rho() const
{
return lawPtr_->rho();
}
//- Return first Lame's coefficient
tmp<volScalarField> mu() const;
//- Return second Lame's coefficient
tmp<volScalarField> lambda() const;
//- Return threeK
tmp<volScalarField> threeK() const;
//- Return density
tmp<volScalarField> rho(scalar t) const
{
return lawPtr_->rho(t);
}
//- Return first Lame's coefficient
tmp<volScalarField> mu(scalar t) const;
//- Return second Lame's coefficient
tmp<volScalarField> lambda(scalar t) const;
//- Correct the rheological model
void correct();
//- Read rheologyProperties dictionary
virtual bool read();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -1,5 +0,0 @@
contactProblem.C
contactPatchPair.C
newContactStressFoam.C
EXE = $(FOAM_APPBIN)/newContactStressFoam

View file

@ -1,11 +0,0 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I../materialModels/lnInclude \
-I../newStressedFoam/
EXE_LIBS = \
-lfiniteVolume \
-lmaterialModels \
-llduSolvers

View file

@ -1,5 +0,0 @@
if (runTime.outputTime())
{
volScalarField ca = contact.contactArea();
ca.write();
}

View file

@ -1,447 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
\*---------------------------------------------------------------------------*/
#include "contactPatchPair.H"
#include "contactProblem.H"
#include "surfaceFields.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components
Foam::contactPatchPair::contactPatchPair
(
const word& name,
const contactProblem& cp,
const word& masterPatchName,
const word& slavePatchName,
const dimensionedScalar& frictionCoeff,
const scalar contactTol,
const intersection::algorithm alg,
const intersection::direction dir
)
:
name_(name),
cp_(cp),
masterPatch_(masterPatchName, cp.mesh().boundaryMesh()),
slavePatch_(slavePatchName, cp.mesh().boundaryMesh()),
frictionCoeff_(frictionCoeff),
contactTol_(contactTol),
masterInterpolate_
(
cp.mesh().boundaryMesh()[masterPatch_.index()]
),
slaveInterpolate_
(
cp.mesh().boundaryMesh()[slavePatch_.index()]
),
masterToSlaveInterpolate_
(
cp.mesh().boundaryMesh()[masterPatch_.index()], // from patch
cp.mesh().boundaryMesh()[slavePatch_.index()], // to patch
alg,
dir
),
slaveToMasterInterpolate_
(
cp.mesh().boundaryMesh()[slavePatch_.index()], // from patch
cp.mesh().boundaryMesh()[masterPatch_.index()], // to patch
alg,
dir
)
{}
// Construct from dictionary
Foam::contactPatchPair::contactPatchPair
(
const word& name,
const contactProblem& cp,
const dictionary& dict
)
:
name_(name),
cp_(cp),
masterPatch_(dict.lookup("masterPatch"), cp.mesh().boundaryMesh()),
slavePatch_(dict.lookup("slavePatch"), cp.mesh().boundaryMesh()),
frictionCoeff_(dict.lookup("frictionCoeff")),
contactTol_(readScalar(dict.lookup("contactTol"))),
masterInterpolate_
(
cp.mesh().boundaryMesh()[masterPatch_.index()]
),
slaveInterpolate_
(
cp.mesh().boundaryMesh()[slavePatch_.index()]
),
masterToSlaveInterpolate_
(
cp.mesh().boundaryMesh()[masterPatch_.index()], // from patch
cp.mesh().boundaryMesh()[slavePatch_.index()], // to patch
intersection::algorithmNames_.read(dict.lookup("projectionAlgo")),
intersection::directionNames_.read(dict.lookup("projectionDir"))
),
slaveToMasterInterpolate_
(
cp.mesh().boundaryMesh()[slavePatch_.index()], // from patch
cp.mesh().boundaryMesh()[masterPatch_.index()], // to patch
intersection::algorithmNames_.read(dict.lookup("projectionAlgo")),
intersection::directionNames_.read(dict.lookup("projectionDir"))
)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::scalarField>
Foam::contactPatchPair::masterTouchFraction() const
{
// Get reference to displacement field and mesh
const volVectorField& U = cp_.U();
const fvMesh& mesh = cp_.mesh();
// Interpolate slave displacement into master vertices
vectorField masterVertexU =
slaveToMasterInterpolate_.pointInterpolate<vector>
(
slaveInterpolate_.faceToPointInterpolate
(
U.boundaryField()[slavePatch_.index()]
)
);
const vectorField& projectionDir =
mesh.boundaryMesh()[masterPatch_.index()].pointNormals();
// Calculate master gap function
scalarField vertexMasterGap =
(
(
masterVertexU
- masterInterpolate_.faceToPointInterpolate
(
U.boundaryField()[masterPatch_.index()]
)
)
& projectionDir
) + slaveToMasterInterpolate_.pointDistanceToIntersection() - contactTol_;
// Calculate area in contact
const faceList& masterPatchLocalFaces =
mesh.boundaryMesh()[masterPatch_.index()].localFaces();
const pointField& masterPatchLocalPoints =
mesh.boundaryMesh()[masterPatch_.index()].localPoints();
tmp<scalarField> ttouchFrac
(
new scalarField(masterPatchLocalFaces.size(), 0)
);
scalarField& touchFrac = ttouchFrac();
forAll (masterPatchLocalFaces, faceI)
{
touchFrac[faceI] =
masterPatchLocalFaces[faceI].areaInContact
(
masterPatchLocalPoints,
vertexMasterGap
);
}
return ttouchFrac;
}
Foam::tmp<Foam::scalarField>
Foam::contactPatchPair::slaveTouchFraction() const
{
// Get reference to displacement field and mesh
const volVectorField& U = cp_.U();
const fvMesh& mesh = cp_.mesh();
// Interpolate master displacement into slave vertices
vectorField slaveVertexU =
masterToSlaveInterpolate_.pointInterpolate<vector>
(
masterInterpolate_.faceToPointInterpolate
(
U.boundaryField()[masterPatch_.index()]
)
);
const vectorField& projectionDir =
mesh.boundaryMesh()[slavePatch_.index()].pointNormals();
// Calculate slave gap function
scalarField vertexSlaveGap =
(
(
slaveVertexU
- slaveInterpolate_.faceToPointInterpolate
(
U.boundaryField()[slavePatch_.index()]
)
)
& projectionDir
) + masterToSlaveInterpolate_.pointDistanceToIntersection() - contactTol_;
// Calculate area in contact
const faceList& slavePatchLocalFaces =
mesh.boundaryMesh()[slavePatch_.index()].localFaces();
const pointField& slavePatchLocalPoints =
mesh.boundaryMesh()[slavePatch_.index()].localPoints();
tmp<scalarField> ttouchFrac
(
new scalarField(slavePatchLocalFaces.size(), 0)
);
scalarField& touchFrac = ttouchFrac();
forAll (slavePatchLocalFaces, faceI)
{
touchFrac[faceI] =
slavePatchLocalFaces[faceI].areaInContact
(
slavePatchLocalPoints,
vertexSlaveGap
);
}
return ttouchFrac;
}
void Foam::contactPatchPair::correct
(
const FieldField<Field, vector>& curTraction,
FieldField<Field, vector>& newTraction,
FieldField<Field, vector>& refValue,
FieldField<Field, scalar>& valueFraction
)
{
// Get reference to displacement field and mesh
const volVectorField::GeometricBoundaryField& Upatches =
cp_.U().boundaryField();
const fvMesh& mesh = cp_.mesh();
const surfaceVectorField::GeometricBoundaryField& Apatches =
mesh.Sf().boundaryField();
const surfaceScalarField::GeometricBoundaryField& magApatches =
mesh.magSf().boundaryField();
// Get patch indices
const label masterIndex = masterPatch_.index();
const label slaveIndex = slavePatch_.index();
// Calculate patch normals
vectorField nMasterPatch = Apatches[masterIndex]/magApatches[masterIndex];
vectorField nSlavePatch = Apatches[slaveIndex]/magApatches[slaveIndex];
// Calculate slave pressure and tangential force
scalarField slavePressure = -( nSlavePatch & curTraction[slaveIndex]);
// Enforce gradient condition on the master patch
// Calculate relative tangential velocity for master patch
vectorField relUmaster =
slaveToMasterInterpolate_.faceInterpolate<vector>
(
Upatches[slaveIndex]
)
- Upatches[masterIndex];
relUmaster -= nMasterPatch*(nMasterPatch & relUmaster);
relUmaster /= mag(relUmaster) + VSMALL;
// Calculate tangential master traction
scalarField magMasterTangential =
Foam::mag((I - nMasterPatch*nMasterPatch) & curTraction[masterIndex]);
// Calculate master pressure
scalarField masterPressure =
max
(
slaveToMasterInterpolate_.faceInterpolate<scalar>
(
slavePressure
),
0.0
);
// Calculate master traction, using the positive part of
// slave pressure and tangential fricton
// Mind the signs: pressure = negative gradient (minus master normal)
// friction = positive pressure
newTraction[masterIndex] +=
masterTouchFraction()*
(
-nMasterPatch*masterPressure
+ relUmaster*
min
(
frictionCoeff_.value()*masterPressure,
magMasterTangential
)
);
// Enforce direction mixed condition on the slave patch
// Calculate slave fraction. Correct for negative pressure
// (if the pressure is negative, the contact is released)
//HJ, fiddle pos pressure!!!
scalarField slaveFrac = slaveTouchFraction();
// Calculate slave displacement
vectorField slaveVertexU =
masterToSlaveInterpolate_.pointInterpolate<vector>
(
masterInterpolate_.faceToPointInterpolate
(
Upatches[masterIndex]
)
);
const vectorField& projectionDir =
mesh.boundaryMesh()[slaveIndex].pointNormals();
// Calculate slave displacement
vectorField slaveDisp =
slaveInterpolate_.pointToFaceInterpolate
(
slaveVertexU
+ masterToSlaveInterpolate_.pointDistanceToIntersection()
*projectionDir
);
// Accumulate normal of slave displacement
refValue[slaveIndex] +=
nSlavePatch*
min
(
pos(slaveFrac)*
(
(nSlavePatch & Upatches[slaveIndex])
+ slaveFrac*contactTol_
),
(nSlavePatch & slaveDisp)
);
// Accumulate slave friction
// Calculate relative tangential velocity for slave patch
vectorField relUslave =
masterToSlaveInterpolate_.faceInterpolate<vector>
(
Upatches[masterIndex]
)
- Upatches[slaveIndex];
relUslave -= nSlavePatch*(nSlavePatch & relUslave);
relUslave /= mag(relUslave) + VSMALL;
// Take out normal component out of slave traction and find the
// magnitude of the tangential traction.
scalarField magSlaveTangential =
Foam::mag((I - nSlavePatch*nSlavePatch) & curTraction[slaveIndex]);
// Calculate slave traction
newTraction[slaveIndex] +=
slaveFrac*relUslave*
min
(
frictionCoeff_.value()*max(slavePressure, scalar(0)),
magSlaveTangential
);
// Accumulate slave touch fraction
valueFraction[slaveIndex] += slaveFrac;
/*
Info << "slavePressure: " << slavePressure << nl
<< "slaveTouchFrac: " << slaveTouchFraction() << nl
// << "slaveFrac: " << slaveFrac << nl
<< "refValueSlave: " << refValue[slaveIndex].component(vector::Y) << nl
// << "slaveTraction: " << newTraction[slaveIndex] << nl
<< "masterTouchFrac: " << masterTouchFraction() << nl
// << "interpolated slave pressure: "
// << slaveToMasterInterpolate_.faceInterpolate<scalar>
// (
// slavePressure
// )
// << nl
// << "masterTraction: "
// << newTraction[masterIndex].component(vector::Y)
<< endl;
*/
}
void Foam::contactPatchPair::writeDict(Ostream& os) const
{
os << nl << name() << nl << token::BEGIN_BLOCK;
os << "masterPatch " << masterPatch_.name() << token::END_STATEMENT << nl
<< "slavePatch " << slavePatch_.name() << token::END_STATEMENT << nl
<< "frictionCoeff " << frictionCoeff_ << token::END_STATEMENT << nl
<< "contactTol " << contactTol_ << token::END_STATEMENT << nl
<< "projectionAlgo "
<< intersection::algorithmNames_
[masterToSlaveInterpolate_.projectionAlgo()]
<< token::END_STATEMENT << nl
<< "projectionDir "
<< intersection::directionNames_
[masterToSlaveInterpolate_.projectionDir()]
<< token::END_STATEMENT << nl
<< token::END_BLOCK << endl;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
// ************************************************************************* //

View file

@ -1,178 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
contactPatchPair
Description
A pair of surfaces in contact.
SourceFiles
contactPatchPair.C
\*---------------------------------------------------------------------------*/
#ifndef contactPatchPair_H
#define contactPatchPair_H
#include "polyPatchID.H"
#include "dimensionedTypes.H"
#include "volFieldsFwd.H"
#include "primitivePatchInterpolation.H"
#include "patchToPatchInterpolation.H"
#include "FieldFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class contactProblem;
/*---------------------------------------------------------------------------*\
Class contactPatchPair Declaration
\*---------------------------------------------------------------------------*/
class contactPatchPair
{
private:
// Private data
//- Name
const word name_;
//- Reference to contact problem
const contactProblem& cp_;
//- Master patch ID. Gradient condition will be enforced
const polyPatchID masterPatch_;
//- Slave patch ID. Direction mixed condition will be enforced
const polyPatchID slavePatch_;
//- Friction coefficient
dimensionedScalar frictionCoeff_;
//- Contact tolerance
const scalar contactTol_;
//- Master patch interpolator
primitivePatchInterpolation masterInterpolate_;
//- Slave patch interpolator
primitivePatchInterpolation slaveInterpolate_;
//- Master to slave patch interpolator
patchToPatchInterpolation masterToSlaveInterpolate_;
//- Master to slave patch interpolator
patchToPatchInterpolation slaveToMasterInterpolate_;
// Private Member Functions
//- Disallow default bitwise copy construct
contactPatchPair(const contactPatchPair&);
//- Disallow default bitwise assignment
void operator=(const contactPatchPair&);
public:
// Constructors
//- Construct from components
contactPatchPair
(
const word& name,
const contactProblem& cp,
const word& masterPatchName,
const word& slavePatchName,
const dimensionedScalar& frictionCoeff,
const scalar contactTol,
const intersection::algorithm alg = intersection::FULL_RAY,
const intersection::direction dir = intersection::CONTACT_SPHERE
);
//- Construct from components
contactPatchPair
(
const word& name,
const contactProblem& cp,
const dictionary& dict
);
// Member Functions
//- Return name
const word& name() const
{
return name_;
}
//- Return master patch ID
const polyPatchID masterPatch() const
{
return masterPatch_;
}
//- Return slave patch ID
const polyPatchID& slavePatch() const
{
return slavePatch_;
}
//- Return master touch fraction
tmp<scalarField> masterTouchFraction() const;
//- Return slave touch fraction
tmp<scalarField> slaveTouchFraction() const;
//- Correct contact data
void correct
(
const FieldField<Field, vector>& curTraction,
FieldField<Field, vector>& newTraction,
FieldField<Field, vector>& refValue,
FieldField<Field, scalar>& normalValueFraction
);
//- Write dictionary
void writeDict(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -1,56 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Type
contactPatchPairList
Description
Container classes for contactPatchPair
\*---------------------------------------------------------------------------*/
#ifndef contactPatchPairList_H
#define contactPatchPairList_H
#include "contactPatchPair.H"
#include "PtrList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
typedef PtrList<contactPatchPair> contactPatchPairList;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -1,336 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
Class describes a multiple body contact problem. Each individual contact
is described by a contactPatchPair. contactProblem handles
multiple contact updates and sets the boundary conditions on the
displacement field.
\*---------------------------------------------------------------------------*/
#include "contactProblem.H"
#include "fvMesh.H"
#include "FieldFields.H"
#include "directionMixedFvPatchFields.H"
#include "surfaceFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(contactProblem, 0);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Read constructor given IOobject
contactProblem::contactProblem
(
volVectorField& U,
const volTensorField& gradU
)
:
IOdictionary
(
IOobject
(
"contactProperties",
U.time().constant(),
U.db(),
IOobject::MUST_READ,
IOobject::NO_WRITE
)
),
contactPatchPairList(),
U_(U),
gradU_(gradU),
urfValue_(readScalar(lookup("urfValue"))),
urfTraction_(readScalar(lookup("urfTraction"))),
urfFraction_(readScalar(lookup("urfFraction")))
{
// Read contactPatchPairList
Istream& is = lookup("contacts");
PtrList<entry> contactEntries(is);
contactPatchPairList& contacts = *this;
contacts.setSize(contactEntries.size());
forAll(contacts, contactI)
{
contacts.set
(
contactI,
new contactPatchPair
(
contactEntries[contactI].keyword(),
*this,
contactEntries[contactI].dict()
)
);
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void contactProblem::correct()
{
contactPatchPairList& contacts = *this;
// Create fields for accumulation
volVectorField::GeometricBoundaryField& Upatches = U().boundaryField();
FieldField<Field, vector> curTraction(Upatches.size());
FieldField<Field, vector> newTraction(Upatches.size());
FieldField<Field, vector> refValue(Upatches.size());
FieldField<Field, scalar> valueFraction(Upatches.size());
forAll (Upatches, patchI)
{
curTraction.set
(
patchI,
new vectorField(Upatches[patchI].size(), vector::zero)
);
newTraction.set
(
patchI,
new vectorField(Upatches[patchI].size(), vector::zero)
);
refValue.set
(
patchI,
new vectorField(Upatches[patchI].size(), vector::zero)
);
valueFraction.set
(
patchI,
new scalarField(Upatches[patchI].size(), 0)
);
}
// Collect patches involved in contact
boolList contactPatches(Upatches.size(), false);
forAll (contacts, contactI)
{
contactPatches[contacts[contactI].masterPatch().index()] = true;
contactPatches[contacts[contactI].slavePatch().index()] = true;
}
// Calculate the traction for all involved patches
// Collect fields
const volTensorField::GeometricBoundaryField& gradUpatches =
gradU().boundaryField();
const surfaceVectorField::GeometricBoundaryField& Apatches =
mesh().Sf().boundaryField();
const surfaceScalarField::GeometricBoundaryField& magApatches =
mesh().magSf().boundaryField();
// Lookup mu and lambda form object registry
const volScalarField& mu =
mesh().objectRegistry::lookupObject<volScalarField>("mu");
const volScalarField::GeometricBoundaryField& muPatches =
mu.boundaryField();
const volScalarField& lambda =
mesh().objectRegistry::lookupObject<volScalarField>("lambda");
const volScalarField::GeometricBoundaryField& lambdaPatches =
lambda.boundaryField();
forAll (Upatches, patchI)
{
if (contactPatches[patchI])
{
vectorField nPatch = Apatches[patchI]/magApatches[patchI];
curTraction[patchI] =
nPatch &
(
muPatches[patchI]*
(
gradUpatches[patchI]
+ gradUpatches[patchI].T()
)
+ I*(lambdaPatches[patchI]*tr(gradUpatches[patchI]))
);
}
}
// Accumulate contact data and active patches
forAll (contacts, contactI)
{
contacts[contactI].correct
(
curTraction,
newTraction,
refValue,
valueFraction
);
}
// Enforce accumulated contact onto the patches
forAll (Upatches, patchI)
{
if (contactPatches[patchI])
{
// Cast the patch into direction mixed type
directionMixedFvPatchVectorField& curUPatch =
refCast<directionMixedFvPatchVectorField>(Upatches[patchI]);
// Set the values using under-relaxation
curUPatch.refValue() =
(1.0 - urfValue_)*curUPatch.refValue()
+ urfValue_*refValue[patchI];
// Calculate the gradient from under-relaxad accumulated traction
vectorField nPatch = Apatches[patchI]/magApatches[patchI];
curUPatch.refGrad() =
(
(1.0 - urfTraction_)*curTraction[patchI]
+ urfTraction_*newTraction[patchI]
- (nPatch &
(
muPatches[patchI]*gradUpatches[patchI].T()
- (
muPatches[patchI]
+ lambdaPatches[patchI]
)*gradUpatches[patchI]
)
)
- nPatch*
(
lambdaPatches[patchI]*tr(gradUpatches[patchI])
)
)/(2.0*muPatches[patchI] + lambdaPatches[patchI]);
// Set the value fractions
curUPatch.valueFraction() =
(1.0 - urfFraction_)*curUPatch.valueFraction()
+ I*urfFraction_*valueFraction[patchI];
}
}
}
tmp<volScalarField> contactProblem::contactArea() const
{
tmp<volScalarField> tca
(
new volScalarField
(
IOobject
(
"contactArea",
U().time().timeName(),
U().db(),
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh(),
dimensionedScalar(0)
)
);
volScalarField& ca = tca();
// Set contact area boundary
const contactPatchPairList& contacts = *this;
forAll (contacts, contactI)
{
// Get master contact
ca.boundaryField()[contacts[contactI].masterPatch().index()] +=
contacts[contactI].masterTouchFraction();
// Get slave contact
ca.boundaryField()[contacts[contactI].slavePatch().index()] +=
contacts[contactI].slaveTouchFraction();
}
return tca;
}
// Return a list of contactPatchPair names
wordList contactProblem::names() const
{
const contactPatchPairList& contacts = *this;
wordList t(contacts.size());
forAll (contacts, contactI)
{
t[contactI] = contacts[contactI].name();
}
return t;
}
bool contactProblem::read()
{
if (regIOobject::read())
{
urfValue_ = readScalar(lookup("urfValue"));
urfTraction_ = readScalar(lookup("urfTraction"));
urfFraction_ = readScalar(lookup("urfFraction"));
// Decided not to re-read contactPatchPairList. HJ, 10/Jul/2004
return true;
}
else
{
return false;
}
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -1,161 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
contactProblem
Description
Class describes a multiple body contact problem. Each individual contact
is described by a contactPatchPair. contactProblem handles
multiple contact updates and sets the boundary conditions on the
displacement field.
SourceFiles
contactProblem.C
\*---------------------------------------------------------------------------*/
#ifndef contactProblem_H
#define contactProblem_H
#include "contactPatchPairList.H"
#include "IOdictionary.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class fvMesh;
/*---------------------------------------------------------------------------*\
Class contactProblem Declaration
\*---------------------------------------------------------------------------*/
class contactProblem
:
public IOdictionary,
public contactPatchPairList
{
private:
// Private data
//- Reference to displacement field
volVectorField& U_;
//- Reference to displacement gradient field
const volTensorField& gradU_;
//- Value under-relaxation
scalar urfValue_;
//- Gradient under-relaxation
scalar urfTraction_;
//- Fraction under-relaxation
scalar urfFraction_;
// Private Member Functions
//- Disallow default bitwise copy construct
contactProblem(const contactProblem&);
//- Disallow default bitwise assignment
void operator=(const contactProblem&);
public:
//- Runtime type information
TypeName("contactProblem");
// Constructors
//- Read constructor
contactProblem
(
volVectorField& U,
const volTensorField& gradU
);
// Destructor
virtual ~contactProblem()
{}
// Member Functions
//- Return const reference to displacement field
const volVectorField& U() const
{
return U_;
}
//- Return reference to displacement field
volVectorField& U()
{
return U_;
}
//- Return const reference to displacement gradient field
const volTensorField& gradU() const
{
return gradU_;
}
//- Return reference to displacement field
const fvMesh& mesh() const
{
return U_.mesh();
}
//- Return contact area field
tmp<volScalarField> contactArea() const;
//- Return a list of contact patch pair names
wordList names() const;
//- Correct contact conditions
void correct();
//- Read rheologyProperties dictionary
virtual bool read();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -1,38 +0,0 @@
mesh.weights();
Info<< "Reading field U\n" << endl;
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
// Create gradient field
volTensorField gradU = fvc::grad(U);
volSymmTensorField sigma
(
IOobject
(
"sigma",
runTime.timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
mesh,
dimensionedSymmTensor("zero", dimForce/dimArea, symmTensor::zero)
);
// Create rheology model
rheologyModel rheology(sigma);
// Create contact problem
contactProblem contact(U, gradU);

View file

@ -1,120 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Application
stressedFoam
Description
Transient/steady-state solver for solid bodies in contact.
Solves for the displacement vector field U, also generating the
stress tensor field sigma.
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "rheologyModel.H"
#include "contactProblem.H"
#include "componentReferenceList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
# include "setRootCase.H"
# include "createTime.H"
# include "createMesh.H"
# include "createFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nCalculating displacement field\n" << endl;
volScalarField rho = rheology.rho();
// Force n-sqaured projection
// polyPatch::setNSquaredProjection(true);
while (runTime.loop())
{
Info<< "Iteration: " << runTime.timeName() << nl << endl;
# include "readStressedFoamControls.H"
volScalarField mu = rheology.mu();
volScalarField lambda = rheology.lambda();
int iCorr=0;
scalar initialResidual=0;
contact.correct();
do
{
fvVectorMatrix UEqn
(
fvm::d2dt2(rho, U)
==
fvm::laplacian(2*mu + lambda, U, "laplacian(DU,U)")
+ fvc::div
(
mu*gradU.T() + lambda*(I*tr(gradU)) - (mu + lambda)*gradU,
"div(sigma)"
)
);
# include "setComponentReference.H"
initialResidual = UEqn.solve().initialResidual();
gradU = fvc::grad(U);
# include "calculateSigma.H"
rheology.correct();
rho = rheology.rho();
mu = rheology.mu();
lambda = rheology.lambda();
} while (initialResidual > convergenceTolerance && ++iCorr < nCorr);
# include "calculateStress.H"
# include "calculateContactArea.H"
Info<< "ExecutionTime = "
<< runTime.elapsedCpuTime()
<< " s\n\n" << endl;
}
Info<< "End\n" << endl;
return(0);
}
// ************************************************************************* //

View file

@ -1,3 +0,0 @@
newStressedFoam.C
EXE = $(FOAM_APPBIN)/newStressedFoam

View file

@ -1,8 +0,0 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I../materialModels/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lmaterialModels \
-llduSolvers

View file

@ -1 +0,0 @@
sigma = 2*mu*symm(gradU) + lambda*(I*tr(gradU));

View file

@ -1,101 +0,0 @@
if (runTime.outputTime())
{
volScalarField sigmaEq
(
IOobject
(
"sigmaEq",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
sqrt((3.0/2.0)*magSqr(dev(sigma)))
);
Info<< "Max sigmaEq = " << max(sigmaEq).value()
<< endl;
volScalarField sigmaxx
(
IOobject
(
"sigmaxx",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
sigma.component(symmTensor::XX)
);
volScalarField sigmayy
(
IOobject
(
"sigmayy",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
sigma.component(symmTensor::YY)
);
volScalarField sigmazz
(
IOobject
(
"sigmazz",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
sigma.component(symmTensor::ZZ)
);
Info<< "Max sigmazz = " << max(sigmazz).value()
<< endl;
volScalarField sigmaxy
(
IOobject
(
"sigmaxy",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
sigma.component(symmTensor::XY)
);
volScalarField sigmaxz
(
IOobject
(
"sigmaxz",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
sigma.component(symmTensor::XZ)
);
volScalarField sigmayz
(
IOobject
(
"sigmayz",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
sigma.component(symmTensor::YZ)
);
runTime.write();
}

View file

@ -1,29 +0,0 @@
Info<< "Reading field U\n" << endl;
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
volSymmTensorField sigma
(
IOobject
(
"sigma",
runTime.timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
mesh,
dimensionedSymmTensor("zero", dimForce/dimArea, symmTensor::zero)
);
rheologyModel rheology(sigma);

View file

@ -1,115 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Application
stressedFoam
Description
Transient/steady-state segregated finite-volume solver for a solid
body.
Solves for the displacement vector field U, also generating the
stress tensor field sigma.
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "rheologyModel.H"
#include "componentReferenceList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
# include "setRootCase.H"
# include "createTime.H"
# include "createMesh.H"
# include "createFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nCalculating displacement field\n" << endl;
volTensorField gradU = fvc::grad(U);
volScalarField rho = rheology.rho();
while (runTime.loop())
{
Info<< "Iteration: " << runTime.timeName() << nl << endl;
# include "readStressedFoamControls.H"
volScalarField mu = rheology.mu();
volScalarField lambda = rheology.lambda();
int iCorr = 0;
scalar initialResidual = 0;
do
{
fvVectorMatrix UEqn
(
fvm::d2dt2(rho, U)
==
fvm::laplacian(2*mu + lambda, U, "laplacian(DU,U)")
+ fvc::div
(
mu*gradU.T() + lambda*(I*tr(gradU)) - (mu + lambda)*gradU,
"div(sigma)"
)
);
# include "setComponentReference.H"
initialResidual = UEqn.solve().initialResidual();
gradU = fvc::grad(U);
# include "calculateSigma.H"
rheology.correct();
rho = rheology.rho();
mu = rheology.mu();
lambda = rheology.lambda();
} while (initialResidual > convergenceTolerance && ++iCorr < nCorr);
# include "calculateStress.H"
Info<< "ExecutionTime = "
<< runTime.elapsedCpuTime()
<< " s\n\n" << endl;
}
Info<< "End\n" << endl;
return(0);
}
// ************************************************************************* //

View file

@ -1,11 +0,0 @@
const dictionary& stressControl =
mesh.solutionDict().subDict("stressedFoam");
int nCorr(readInt(stressControl.lookup("nCorrectors")));
scalar convergenceTolerance(readScalar(stressControl.lookup("U")));
componentReferenceList cr
(
stressControl.lookup("componentReference"),
componentReference::iNew(mesh)
);

View file

@ -0,0 +1,3 @@
elasticAcpSolidFoam.C
EXE = $(FOAM_APPBIN)/elasticAcpSolidFoam

View file

@ -0,0 +1,16 @@
EXE_INC = \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude \
-I$(LIB_SRC)/dynamicMesh/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/dynamicMesh/topoChangerFvMesh/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/solidModels/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lmeshTools \
-ldynamicFvMesh \
-ldynamicMesh \
-ltopoChangerFvMesh \
-lsolidModels

View file

@ -0,0 +1,35 @@
// aitken acceleration
aitkenDelta.storePrevIter();
// update delta
aitkenDelta = (U - U.prevIter()) / aitkenInitialRes;
// update relaxation factor
if(iCorr == 0)
{
aitkenTheta = 0.01;
if(mesh.relax(U.name()))
{
aitkenTheta = mesh.relaxationFactor(U.name());
}
}
else
{
vectorField b = aitkenDelta.internalField() - aitkenDelta.prevIter().internalField();
//scalar sumMagB = gSum(mag(b));
scalar sumMagB = gSum(magSqr(b));
if(sumMagB < SMALL)
{
//Warning << "Aitken under-relaxation: denominator less then SMALL"
// << endl;
sumMagB += SMALL;
}
aitkenTheta = -aitkenTheta*
gSum(aitkenDelta.prevIter().internalField() & b)
/
sumMagB;
}
// correction to the latest U
U += aitkenTheta*aitkenDelta*aitkenInitialRes;

View file

@ -0,0 +1,49 @@
if(divSigmaExpMethod == "standard")
{
divSigmaExp = fvc::div
(
mu*gradU.T() + lambda*(I*tr(gradU)) - (mu + lambda)*gradU,
"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")
{
snGradU = fvc::snGrad(U);
surfaceTensorField shearGradU =
((I - n*n)&fvc::interpolate(gradU));
divSigmaExp = fvc::div
(
mesh.magSf()
*(
- (muf + lambdaf)*(snGradU&(I - n*n))
+ lambdaf*tr(shearGradU&(I - n*n))*n
+ muf*(shearGradU&n)
)
);
}
else if(divSigmaExpMethod == "expLaplacian")
{
divSigmaExp =
- fvc::laplacian(mu + lambda, U, "laplacian(DU,U)")
+ fvc::div
(
mu*gradU.T()
+ lambda*(I*tr(gradU)),
"div(sigma)"
);
}
else
{
FatalError << "divSigmaExp method " << divSigmaExpMethod << " not found!" << endl;
}

View file

@ -0,0 +1,19 @@
{
// force residual is the net force on the model
// this should got to zero in a converged steady state model
// should be altered for parallel runs
vector netForce = vector::zero;
forAll(mesh.boundary(), patchi)
{
netForce +=
sum(
mesh.Sf().boundaryField()[patchi]
&
(
2*mu.boundaryField()[patchi]*symm(gradU.boundaryField()[patchi])
+ lambda*tr(gradU.boundaryField()[patchi])*I
)
);
}
forceResidual = mag(netForce);
}

View file

@ -0,0 +1,12 @@
{
scalar maxDU = gMax(mag(U.internalField() - U.oldTime().internalField()));
relativeResidual =
gMax
(
mag(U.internalField() - U.prevIter().internalField())
/(maxDU + SMALL)
);
resid = (U - U.prevIter())/(max(mag(U-U.oldTime()))+dimensionedScalar("SMALL", dimLength, SMALL));
}

View file

@ -0,0 +1,41 @@
{
surfaceVectorField n = mesh.Sf()/mesh.magSf();
// traction = (n&fvc::interpolate(sigma));
// surfaceTensorField sGradU =
// ((I - n*n)&fvc::interpolate(gradU));
// traction =
// (2*mu + lambda)*snGradU
// - (mu + lambda)*(snGradU&(I - n*n))
// + mu*(sGradU&n)
// + lambda*tr(sGradU&(I - n*n))*n;
// traction =
// (2*mu + lambda)*fvc::snGrad(U)
// - (mu + lambda)*(n&sGradU)
// + mu*(sGradU&n)
// + lambda*tr(sGradU)*n;
// philipc
// I am having trouble with back-calculation of interface tractions from solid interface
// procedure (in multiMaterial.C), the tractions have quite large differences from each
// side. Interpolating sigma is OK for now
// traction = rheology.law().interfaceTraction(n, U, gradU, rheology.mu(), rheology.lambda());
# include "calculateEpsilonSigma.H"
traction = (n&fvc::interpolate(sigma));
// forAll(traction.boundaryField(), patchi)
// {
// if (mesh.boundary()[patchi].type() == "cohesive")
// {
// forAll(traction.boundaryField()[patchi], facei)
// {
// Pout << "face " << facei << " with traction magnitude "
// << mag(traction.boundaryField()[patchi][facei])/1e6 << " MPa and traction "
// << traction.boundaryField()[patchi][facei]/1e6 << " MPa" << endl;
// }
// }
// }
}

View file

@ -0,0 +1,22 @@
{
label sizeByTwo = mesh.boundary()[cohesivePatchID].size()/2;
vectorField Cczm = mesh.boundary()[cohesivePatchID].Cf();
for(label i = 0; i < sizeByTwo; i++)
{
Cczm[i] -= Cczm[sizeByTwo + i];
Cczm[sizeByTwo + i] = Cczm[i];
}
scalar error = sum(mag(Cczm));
if(error < SMALL)
{
Info << "Cohesive patch face ordering: OK" << endl;
}
else
{
Info << "Cohesive patch face ordering: error (" << error << ")"
<< endl;
}
}

View file

@ -0,0 +1,226 @@
label cohesivePatchID = -1;
solidCohesiveFvPatchVectorField* cohesivePatchUPtr = NULL;
solidCohesiveFixedModeMixFvPatchVectorField* cohesivePatchUFixedModePtr = NULL;
forAll (U.boundaryField(), patchI)
{
if (isA<solidCohesiveFvPatchVectorField>(U.boundaryField()[patchI]))
{
cohesivePatchID = patchI;
cohesivePatchUPtr =
&refCast<solidCohesiveFvPatchVectorField>
(
U.boundaryField()[cohesivePatchID]
);
break;
}
else if (isA<solidCohesiveFixedModeMixFvPatchVectorField>(U.boundaryField()[patchI]))
{
cohesivePatchID = patchI;
cohesivePatchUFixedModePtr =
&refCast<solidCohesiveFixedModeMixFvPatchVectorField>
(
U.boundaryField()[cohesivePatchID]
);
break;
}
}
if(cohesivePatchID == -1)
{
FatalErrorIn(args.executable())
<< "Can't find cohesiveLawFvPatch" << nl
<< "One of the boundary patches in " << U.name() << ".boundaryField() "
<< "should be of type " << solidCohesiveFvPatchVectorField::typeName
<< "or " << solidCohesiveFixedModeMixFvPatchVectorField::typeName
<< abort(FatalError);
}
// solidCohesiveFvPatchVectorField& cohesivePatchU =
// refCast<solidCohesiveFvPatchVectorField>
// (
// U.boundaryField()[cohesivePatchID]
// );
// philipc: I have moved cohesive stuff to constitutiveModel
// cohesiveZone is an index field
// which allows the user to limit the crack to certain areas at runtime
// 1 for faces within cohesiveZone
// 0 for faces outside cohesiveZone
surfaceScalarField cohesiveZone
(
IOobject
(
"cohesiveZone",
runTime.timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
mesh,
dimensionedScalar("zero", dimless, 0.0)
);
// limit crack to specified boxes
{
const dictionary& stressControl =
mesh.solutionDict().subDict("stressedFoam");
List<boundBox> userBoxes(stressControl.lookup("crackLimitingBoxes"));
const surfaceVectorField& Cf = mesh.Cf();
forAll(cohesiveZone.internalField(), faceI)
{
bool faceInsideBox = false;
forAll(userBoxes, boxi)
{
if(userBoxes[boxi].contains(Cf.internalField()[faceI])) faceInsideBox = true;
}
if(faceInsideBox)
{
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(faceInsideBox)
{
cohesiveZone.boundaryField()[patchI][faceI] = 1.0;
}
}
}
}
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;
// 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.internalField()[facei])
{
cohesiveZoneVol.internalField()[mesh.owner()[facei]] = 1.0;
cohesiveZoneVol.internalField()[mesh.neighbour()[facei]] = 1.0;
}
}
forAll(cohesiveZone.boundaryField(), patchi)
{
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();
}
Switch initialiseSolution(false);
if
(
mesh.solutionDict().subDict("stressedFoam")
.found("initialiseSolution")
)
{
initialiseSolution =
Switch
(
mesh.solutionDict().subDict("stressedFoam").lookup
(
"initialiseSolution"
)
);
}
Switch breakOnlyOneFacePerTopologyChange(true);
if
(
mesh.solutionDict().subDict("stressedFoam")
.found("breakOnlyOneFacePerTopologyChange")
)
{
breakOnlyOneFacePerTopologyChange =
Switch
(
mesh.solutionDict().subDict("stressedFoam").lookup
(
"breakOnlyOneFacePerTopologyChange"
)
);
}
Switch crackPropagationFromSpecifiedPatches
(
mesh.solutionDict().subDict("stressedFoam").lookup
(
"crackPropagationFromSpecifiedPatches"
)
);
wordList crackPropagationPatchNames
(
mesh.solutionDict().subDict("stressedFoam").lookup
(
"crackPropagationPatches"
)
);
labelList crackPropagationPatches(crackPropagationPatchNames.size(), -1);
forAll(crackPropagationPatchNames, patchI)
{
crackPropagationPatches[patchI] =
mesh.boundaryMesh().findPatchID
(
crackPropagationPatchNames[patchI]
);
if(crackPropagationPatches[patchI] == -1)
{
FatalErrorIn(args.executable())
<< "Can't find " << crackPropagationPatchNames[patchI]
<< " patch" << abort(FatalError);
}
}
// Internal faces next to selected crack propagation patches
labelList crackPropagationPatchesInternalFaces;
# include "updateCrackPropagationPatchesInternalFaces.H"

View file

@ -1,13 +1,10 @@
fvMesh stressMesh
crackerFvMesh mesh
(
IOobject
(
"solid",
fvMesh::defaultRegion,
runTime.timeName(),
runTime,
IOobject::MUST_READ
)
);
const volPointInterpolation& cpi = volPointInterpolation::New(stressMesh);

View file

@ -0,0 +1,148 @@
Info<< "Reading field U\n" << endl;
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
volTensorField gradU //= fvc::grad(U);
(
IOobject
(
"grad(U)",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionedTensor("zero", dimless, tensor::zero)
);
surfaceVectorField snGradU // = fvc::snGrad(U);
(
IOobject
(
"snGrad(U)",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionedVector("zero", dimless, vector::zero)
);
volVectorField V
(
IOobject
(
"V",
runTime.timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
fvc::ddt(U)
);
volSymmTensorField epsilon
(
IOobject
(
"epsilon",
runTime.timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
mesh,
dimensionedSymmTensor("zero", dimless, symmTensor::zero)
);
volSymmTensorField sigma
(
IOobject
(
"sigma",
runTime.timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
mesh,
dimensionedSymmTensor("zero", dimForce/dimArea, symmTensor::zero)
);
volVectorField divSigmaExp
(
IOobject
(
"divSigmaExp",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionedVector("zero", dimForce/dimVolume, vector::zero)
);
constitutiveModel rheology(sigma, U);
surfaceVectorField traction
(
IOobject
(
"traction",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionedVector("zero", dimForce/dimArea, vector::zero)
);
// for aitken relaxation
volVectorField aitkenDelta
(
IOobject
(
"aitkenDelta",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionedVector("zero", dimLength, vector::zero)
);
// aitken relaxation factor
scalar aitkenInitialRes = 1.0;
scalar aitkenTheta = 0.1;
if(mesh.relax(U.name()))
{
aitkenTheta = mesh.relaxationFactor(U.name());
}
volVectorField resid
(
IOobject
(
"resid",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
dimensionedVector("zero", dimless, vector::zero)
);

View file

@ -0,0 +1,30 @@
OFstream * filePtr(NULL);
word historyPatchName(mesh.solutionDict().subDict("stressedFoam").lookup("historyPatch"));
label historyPatchID = mesh.boundaryMesh().findPatchID(historyPatchName);
if(historyPatchID == -1)
{
Warning << "history patch " << historyPatchName
<< " not found. Force-displacement will not be written"
<< endl;
}
else if(Pstream::master())
{
Info << "Force-displacement for patch " << historyPatchName
<< " will be written to forceDisp.dat"
<< endl;
word hisDirName("history");
mkDir(hisDirName);
filePtr = new OFstream(hisDirName/"forceDisp.dat");
OFstream& forceDispFile = *filePtr;
forceDispFile << "#Disp(mm)\tForce(N)" << endl;
}
clipGauge* clipGPtr = NULL;
if(mesh.solutionDict().subDict("stressedFoam").found("clipGauge"))
{
if(Switch(mesh.solutionDict().subDict("stressedFoam").lookup("clipGauge")))
{
clipGPtr = new clipGauge("clipGauge1", U);
}
}

View file

@ -0,0 +1,7 @@
boolList needRef(mesh.regions().nRegions(), true);
labelList refCells(mesh.regions().nRegions(), -1);
labelList deadCells;
# include "updateReference.H"

View file

@ -0,0 +1,257 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Application
elasticAcpSolidFoam
Description
Arbitrary crack propagation solver.
Cracks may propagate along any mesh internal face.
Please cite:
Carolan D, Tuković Z, Murphy N, Ivankovic A, Arbitrary crack propagation
in multi-phase materials using the finite volume method, Computational
Materials Science, 2013, http://dx.doi.org/10.1016/j.commatsci.2012.11.049.
Author
Zeljko Tukovic, FSB Zagreb
Declan Carolan UCD
Philip Cardiff UCD
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "constitutiveModel.H"
//#include "componentReferenceList.H"
#include "crackerFvMesh.H"
#include "processorPolyPatch.H"
#include "SortableList.H"
#include "solidInterface.H"
#include "solidCohesiveFvPatchVectorField.H"
#include "solidCohesiveFixedModeMixFvPatchVectorField.H"
#include "clipGauge.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
# include "setRootCase.H"
# include "createTime.H"
# include "createCrackerMesh.H"
# include "createFields.H"
# include "createCrack.H"
//# include "createReference.H"
# include "createHistory.H"
# include "readDivSigmaExpMethod.H"
# include "createSolidInterfaceNoModify.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nStarting time loop\n" << endl;
lduMatrix::debug = 0;
scalar maxEffTractionFraction = 0;
// time rates for predictor
volTensorField gradV = fvc::ddt(gradU);
surfaceVectorField snGradV =
(snGradU - snGradU.oldTime())/runTime.deltaT();
//# include "initialiseSolution.H"
while (runTime.run())
{
# include "readStressedFoamControls.H"
# include "setDeltaT.H"
runTime++;
Info<< "\nTime: " << runTime.timeName() << " s\n" << endl;
volScalarField rho = rheology.rho();
volScalarField mu = rheology.mu();
volScalarField lambda = rheology.lambda();
surfaceScalarField muf = fvc::interpolate(mu);
surfaceScalarField lambdaf = fvc::interpolate(lambda);
if(solidInterfaceCorr)
solidInterfacePtr->modifyProperties(muf, lambdaf);
//# include "waveCourantNo.H"
int iCorr = 0;
lduMatrix::solverPerformance solverPerf;
scalar initialResidual = 0;
scalar relativeResidual = 1;
//scalar forceResidual = 1;
label nFacesToBreak = 0;
label nCoupledFacesToBreak = 0;
bool topoChange = false;
//bool noMoreCracks = false;
// Predictor step using time rates
if (predictor)
{
Info << "Predicting U, gradU and snGradU using velocity"
<< endl;
U += V*runTime.deltaT();
gradU += gradV*runTime.deltaT();
snGradU += snGradV*runTime.deltaT();
}
do
{
surfaceVectorField n = mesh.Sf()/mesh.magSf();
do
{
U.storePrevIter();
# include "calculateDivSigmaExp.H"
fvVectorMatrix UEqn
(
rho*fvm::d2dt2(U)
==
fvm::laplacian(2*muf + lambdaf, U, "laplacian(DU,U)")
+ divSigmaExp
);
//# include "setReference.H"
if(solidInterfaceCorr)
solidInterfacePtr->correct(UEqn);
if(relaxEqn)
UEqn.relax();
solverPerf = UEqn.solve();
if(aitkenRelax)
{
# include "aitkenRelaxation.H"
}
else
{
U.relax();
}
if(iCorr == 0)
{
initialResidual = solverPerf.initialResidual();
aitkenInitialRes = gMax(mag(U.internalField()));
}
//gradU = solidInterfacePtr->grad(U);
gradU = fvc::grad(U); // use leastSquaresSolidInterface grad scheme
# include "calculateRelativeResidual.H"
//# include "calculateForceResidual.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++ < 2
||
(
solverPerf.initialResidual() > convergenceTolerance
//relativeResidual > convergenceTolerance
&&
iCorr < nCorr
)
);
Info << "Solving for " << U.name() << " using "
<< solverPerf.solverName()
<< ", Initial residual = " << initialResidual
<< ", Final residual = " << solverPerf.initialResidual()
<< ", No outer iterations " << iCorr
<< ", Relative residual " << relativeResidual << endl;
# include "calculateTraction.H"
# include "updateCrack.H"
Info << "Max effective traction fraction: " << maxEffTractionFraction << endl;
// reset counter if faces want to crack
if((nFacesToBreak > 0) || (nCoupledFacesToBreak > 0)) iCorr = 0;
}
while( (nFacesToBreak > 0) || (nCoupledFacesToBreak > 0));
if(cohesivePatchUPtr)
{
if(returnReduce(cohesivePatchUPtr->size(), sumOp<label>()))
{
cohesivePatchUPtr->cracking();
}
}
else
{
if ( returnReduce(cohesivePatchUFixedModePtr->size(), sumOp<label>()) )
{
Pout << "Number of faces in crack: " << cohesivePatchUFixedModePtr->size()
<< endl;
cohesivePatchUFixedModePtr->relativeSeparationDistance();
}
}
// update time rates for predictor
if(predictor)
{
V = fvc::ddt(U);
gradV = fvc::ddt(gradU);
snGradV = (snGradU - snGradU.oldTime())/runTime.deltaT();
}
# 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;
return(0);
}
// ************************************************************************* //

View file

@ -0,0 +1,136 @@
if (initialiseSolution)
{
Info << "Initialise solution" << endl;
const dictionary& stressControl =
mesh.solutionDict().subDict("stressedFoam");
int nCorr(readInt(stressControl.lookup("nCorrectors")));
scalar convergenceTolerance
(
readScalar(stressControl.lookup("U"))
);
volScalarField rho = rheology.rho();
surfaceScalarField mu = fvc::interpolate(rheology.mu());
surfaceScalarField lambda = fvc::interpolate(rheology.lambda());
//interface.modifyProperties(mu, lambda);
interfacePtr->modifyProperties(mu, lambda);
int iCorr = 0;
lduMatrix::solverPerformance solverPerf;
scalar initialResidual = 0;
scalar relRes = GREAT;
surfaceVectorField n = mesh.Sf()/mesh.magSf();
do
{
U.storePrevIter();
surfaceTensorField sGradU =
((I - n*n)&fvc::interpolate(gradU));
fvVectorMatrix UEqn
(
fvm::laplacian(2*mu + lambda, U, "laplacian(DU,U)")
+ fvc::div
(
mesh.magSf()
*(
- (mu + lambda)*(snGradU & (I - n*n))
+ mu*(sGradU & n)
+ lambda*tr(sGradU&(I - n*n))*n
)
)
);
# include "setReference.H"
interfacePtr->correct(UEqn);
solverPerf = UEqn.solve();
U.relax();
if(iCorr == 0)
{
initialResidual = solverPerf.initialResidual();
}
//gradU = fvc::grad(U);
//gradU = interface.grad(U);
gradU = interfacePtr->grad(U);
snGradU = fvc::snGrad(U);
relRes =
gMax
(
mag(U.internalField() - U.prevIter().internalField())
/(
mag
(
U.internalField()
- U.oldTime().internalField()
)
+ SMALL
)
);
}
while
(
relRes > convergenceTolerance
&& ++iCorr < nCorr
);
Info << "Solving for " << U.name() << " using "
<< solverPerf.solverName()
<< ", Initial residual = " << initialResidual
<< ", Final residual = " << solverPerf.initialResidual()
<< ", No outer iterations " << iCorr
<< ", Relative residual " << relRes << endl;
# include "calculateTraction.H"
scalarField effTraction =
mag(n.internalField() & traction.internalField());
// cohesivePatchU.effectiveTraction
// (
// traction.internalField(),
// n.internalField()
// );
scalar maxEffTraction = 0.0;
if
(
crackPropagationFromSpecifiedPatches
&& crackPropagationPatchesInternalFaces.size()
)
{
maxEffTraction =
gMax
(
scalarField
(
effTraction,
crackPropagationPatchesInternalFaces
)
);
}
else
{
maxEffTraction = gMax(cohesiveZone.internalField()*effTraction);
}
Info << "Max effTraction: " << maxEffTraction << endl;
// if (maxEffTraction >= CzLaw.sigmaMax().value())
// {
// FatalErrorIn(args.executable())
// << "Maximal effective traction is greater then critical traction"
// << abort(FatalError);
// }
U.oldTime() = U;
}

View file

@ -1,6 +1,6 @@
//- how explicit component of sigma is to be calculated
word divSigmaExpMethod(mesh.solutionDict().subDict("stressedFoam").lookup("divSigmaExp"));
Info << divSigmaExpMethod << " method chosen for calculation of sigmaExp" << endl;
Info << "Selecting divSigmaExp calculation method " << divSigmaExpMethod << endl;
if(divSigmaExpMethod != "standard" && divSigmaExpMethod != "surface" && divSigmaExpMethod != "decompose" && divSigmaExpMethod != "laplacian")
{
FatalError << "divSigmaExp method " << divSigmaExpMethod << " not found!" << nl

View file

@ -0,0 +1,19 @@
const dictionary& stressControl =
mesh.solutionDict().subDict("stressedFoam");
int nCorr(readInt(stressControl.lookup("nCorrectors")));
scalar convergenceTolerance(readScalar(stressControl.lookup("U")));
Switch predictor(stressControl.lookup("predictor"));
Switch dynamicTimeStep(stressControl.lookup("dynamicTimeStep"));
scalar deltaTmin(readScalar(stressControl.lookup("deltaTmin")));
scalar deltaTmax(readScalar(stressControl.lookup("deltaTmax")));
scalar dynamicTimeStepActivation(readScalar(stressControl.lookup("dynamicTimeStepActivation")));
int infoFrequency(readInt(stressControl.lookup("infoFrequency")));
Switch aitkenRelax(stressControl.lookup("aitkenRelaxation"));
Switch relaxEqn(stressControl.lookup("relaxEqn"));
if(relaxEqn && solidInterfaceCorr)
{
FatalError << "relaxEqn and solidInterface may not be used concurrently"
<< exit(FatalError);
}

View file

@ -0,0 +1,36 @@
if (dynamicTimeStep && runTime.value() > dynamicTimeStepActivation)
{
if
(
//(maxEffTraction < 0.999*CzLaw.sigmaMax().value())
(returnReduce(maxEffTractionFraction, maxOp<scalar>()) < 0.99)
//&& (cohesivePatchU.size() == 0)
&& (mag(runTime.deltaT().value() - deltaTmax) < SMALL)
)
{
runTime.setDeltaT(deltaTmax);
}
else
{
scalar newDeltaT = deltaTmin;
if (newDeltaT/runTime.deltaT().value() < 0.5)
{
newDeltaT = 0.5*runTime.deltaT().value();
Info << "Reducing time step" << nl;
}
runTime.setDeltaT(newDeltaT);
}
Pout << "Current time step size: "
<< runTime.deltaT().value() << " s" << endl;
scalar maxDT = runTime.deltaT().value();
if(mag(returnReduce(maxDT, maxOp<scalar>()) - runTime.deltaT().value()) > SMALL)
{
FatalError << "Processors have different time-steps!"
<< exit(FatalError);
}
}

View file

@ -0,0 +1,36 @@
{
// Set reference
for (label regI = 0; regI < mesh.regions().nRegions(); regI++)
{
if (needRef[regI])
{
UEqn.source()[refCells[regI]] +=
UEqn.diag()[refCells[regI]]*vector::zero;
UEqn.diag()[refCells[regI]] +=
UEqn.diag()[refCells[regI]];
}
}
// Set value for dead cells (small particles or regions)
// label size = mesh.nCells() - label(sum(gamma.internalField()));
if (deadCells.size())
{
labelList curRefCell(deadCells.size(), -1);
label index = 0;
forAll(deadCells, cellI)
{
curRefCell[index++] = deadCells[cellI];
// if (gamma.internalField()[cellI] < 1 - SMALL)
// {
// curRefCell[index++] = cellI;
// }
}
vectorField curRefValue(curRefCell.size(), vector::zero);
UEqn.setValues(curRefCell, curRefValue);
}
}

View file

@ -0,0 +1,564 @@
nFacesToBreak = 0;
nCoupledFacesToBreak = 0;
{
// Check internal faces
// scalarField effTraction =
// cohesiveZone.internalField() *
// mag(traction.internalField());
scalarField normalTraction =
cohesiveZone.internalField() *
( n.internalField() & traction.internalField() );
normalTraction = max(normalTraction, 0.0); // only consider tensile tractions
scalarField shearTraction =
cohesiveZone.internalField() *
mag( (I - Foam::sqr(n.internalField())) & traction.internalField() );
// the traction fraction is monitored to decide which faces to break:
// ie (tN/tNC)^2 + (tS/tSC)^2 >1 to crack a face
const surfaceScalarField sigmaMax = rheology.cohLaw().sigmaMax();
const surfaceScalarField tauMax = rheology.cohLaw().tauMax();
const scalarField& sigmaMaxI = sigmaMax.internalField();
const scalarField& tauMaxI = tauMax.internalField();
//scalarField effTractionFraction = effTraction/sigmaMax;
scalarField effTractionFraction(normalTraction.size(), 0.0);
if(cohesivePatchUPtr)
{
effTractionFraction =
(normalTraction/sigmaMaxI)*(normalTraction/sigmaMaxI) + (shearTraction/tauMaxI)*(shearTraction/tauMaxI);
}
else
{
// solidCohesiveFixedModeMix only uses sigmaMax
effTractionFraction =
(normalTraction/sigmaMaxI)*(normalTraction/sigmaMaxI) + (shearTraction/sigmaMaxI)*(shearTraction/sigmaMaxI);
}
maxEffTractionFraction = gMax(effTractionFraction);
SLList<label> facesToBreakList;
SLList<scalar> facesToBreakEffTractionFractionList;
forAll(effTractionFraction, faceI)
{
if (effTractionFraction[faceI] > 1.0)
{
facesToBreakList.insert(faceI);
facesToBreakEffTractionFractionList.insert(effTractionFraction[faceI]);
}
}
labelList facesToBreak(facesToBreakList);
List<scalar> facesToBreakEffTractionFraction(facesToBreakEffTractionFractionList);
nFacesToBreak = facesToBreak.size();
// Break only one face per topo change
if (nFacesToBreak > 1)
{
nFacesToBreak = 1;
}
// philipc - select face with maximum effective traction fraction
label faceToBreakIndex = -1;
scalar faceToBreakEffTractionFraction = 0;
forAll(facesToBreakEffTractionFraction, faceI)
{
if (facesToBreakEffTractionFraction[faceI] > faceToBreakEffTractionFraction)
{
faceToBreakEffTractionFraction = facesToBreakEffTractionFraction[faceI];
faceToBreakIndex = facesToBreak[faceI];
}
}
scalar gMaxEffTractionFraction =
returnReduce(faceToBreakEffTractionFraction, maxOp<scalar>());
if (Pstream::parRun())
{
bool procHasFaceToBreak = false;
if (nFacesToBreak > 0)
{
if ( mag(gMaxEffTractionFraction - faceToBreakEffTractionFraction) < SMALL )
{
// philipc - Maximum traction fraction is on this processor
procHasFaceToBreak = true;
}
}
// Check if maximum is present on more then one processors
label procID = Pstream::nProcs();
if (procHasFaceToBreak)
{
procID = Pstream::myProcNo();
}
label minProcID =
returnReduce<label>(procID, minOp<label>());
if (procID != minProcID)
{
nFacesToBreak = 0;
}
}
// Check coupled (processor) patches
SLList<label> coupledFacesToBreakList;
SLList<scalar> coupledFacesToBreakEffTractionFractionList;
forAll(mesh.boundary(), patchI)
{
if (mesh.boundary()[patchI].coupled())
{
// scalarField pEffTraction =
// cohesiveZone.boundaryField()[patchI] *
// mag(traction.boundaryField()[patchI]);
// scalarField pEffTractionFraction = pEffTraction/sigmaMax.boundaryField()[patchI];
scalarField pNormalTraction =
cohesiveZone.boundaryField()[patchI] *
( n.boundaryField()[patchI] & traction.boundaryField()[patchI] );
pNormalTraction = max(pNormalTraction, 0.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:
// ie (tN/tNC)^2 + (tS/tSC)^2 >1 to crack a face
const scalarField& pSigmaMax = sigmaMax.boundaryField()[patchI];
const scalarField& pTauMax = tauMax.boundaryField()[patchI];
scalarField pEffTractionFraction(pNormalTraction.size(), 0.0);
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();
forAll(pEffTractionFraction, faceI)
{
if (pEffTractionFraction[faceI] > maxEffTractionFraction)
{
maxEffTractionFraction = pEffTractionFraction[faceI];
}
if (pEffTractionFraction[faceI] > 1.0)
{
coupledFacesToBreakList.insert(start + faceI);
coupledFacesToBreakEffTractionFractionList.insert
(
pEffTractionFraction[faceI]
);
}
}
}
}
labelList coupledFacesToBreak(coupledFacesToBreakList);
List<scalar> coupledFacesToBreakEffTractionFraction
(
coupledFacesToBreakEffTractionFractionList
);
nCoupledFacesToBreak = coupledFacesToBreak.size();
// Break only one face per topo change
if (nCoupledFacesToBreak > 1)
{
nCoupledFacesToBreak = 1;
}
// Select coupled face with maximum effective traction fraction
label coupledFaceToBreakIndex = -1;
scalar coupledFaceToBreakEffTractionFraction = 0;
forAll(coupledFacesToBreakEffTractionFraction, faceI)
{
if
(
coupledFacesToBreakEffTractionFraction[faceI]
> coupledFaceToBreakEffTractionFraction
)
{
coupledFaceToBreakEffTractionFraction =
coupledFacesToBreakEffTractionFraction[faceI];
coupledFaceToBreakIndex = coupledFacesToBreak[faceI];
}
}
scalar gMaxCoupledEffTractionFraction =
returnReduce(coupledFaceToBreakEffTractionFraction, maxOp<scalar>());
if (Pstream::parRun())
{
bool procHasCoupledFaceToBreak = false;
if (nCoupledFacesToBreak > 0)
{
if
(
mag(gMaxCoupledEffTractionFraction - coupledFaceToBreakEffTractionFraction)
< SMALL
)
{
// Maximum traction fraction is on this processor
procHasCoupledFaceToBreak = true;
}
}
// Check if maximum is present on more then one processors
label procID = Pstream::nProcs();
if (procHasCoupledFaceToBreak)
{
procID = Pstream::myProcNo();
}
label minProcID =
returnReduce<label>(procID, minOp<label>());
if (procID != minProcID)
{
nCoupledFacesToBreak = 0;
}
}
if (gMaxCoupledEffTractionFraction > gMaxEffTractionFraction)
{
// Break coupled face
nFacesToBreak = 0;
}
else
{
// Break internal face
nCoupledFacesToBreak = 0;
}
// Make sure that coupled faces are broken in pairs
labelList ngbProc(Pstream::nProcs(), -1);
labelList index(Pstream::nProcs(), -1);
if (nCoupledFacesToBreak)
{
label patchID =
mesh.boundaryMesh().whichPatch(coupledFaceToBreakIndex);
label start = mesh.boundaryMesh()[patchID].start();
label localIndex = coupledFaceToBreakIndex - start;
const processorPolyPatch& procPatch =
refCast<const processorPolyPatch>(mesh.boundaryMesh()[patchID]);
label ngbProcNo = procPatch.neighbProcNo();
ngbProc[Pstream::myProcNo()] = ngbProcNo;
index[Pstream::myProcNo()] = localIndex;
}
if (returnReduce(nCoupledFacesToBreak, maxOp<label>()))
{
reduce(ngbProc, maxOp<labelList>());
reduce(index, maxOp<labelList>());
for (label procI = 0; procI < Pstream::nProcs(); procI++)
{
if (procI != Pstream::myProcNo())
{
if (ngbProc[procI] == Pstream::myProcNo())
{
forAll(mesh.boundaryMesh(), patchI)
{
if
(
mesh.boundaryMesh()[patchI].type()
== processorPolyPatch::typeName
)
{
const processorPolyPatch& procPatch =
refCast<const processorPolyPatch>
(
mesh.boundaryMesh()[patchI]
);
label ngbProcNo = procPatch.neighbProcNo();
if (ngbProcNo == procI)
{
label start =
mesh.boundaryMesh()[patchI].start();
coupledFaceToBreakIndex = start + index[procI];
nCoupledFacesToBreak = 1;
}
}
}
}
}
}
}
vector faceToBreakTraction = vector::zero;
vector faceToBreakNormal = vector::zero;
scalar faceToBreakSigmaMax = 0.0;
scalar faceToBreakTauMax = 0.0;
// Set faces to break
if (nFacesToBreak > 0)
{
faceToBreakTraction = traction.internalField()[faceToBreakIndex];
faceToBreakNormal = n.internalField()[faceToBreakIndex];
// Scale broken face traction
faceToBreakSigmaMax = sigmaMaxI[faceToBreakIndex];
faceToBreakTauMax = tauMaxI[faceToBreakIndex];
scalar normalTrac = faceToBreakNormal & faceToBreakTraction;
normalTrac = max(normalTrac, 0.0);
scalar shearTrac = mag( (I - sqr(faceToBreakNormal)) & faceToBreakTraction );
scalar scaleFactor = 1;
if(cohesivePatchUPtr)
{
scaleFactor =
::sqrt(1 / (
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
+ (shearTrac/faceToBreakTauMax)*(shearTrac/faceToBreakTauMax)
) );
}
else
{
// solidCohesiveFixedModeMix only uses sigmaMax
scaleFactor =
::sqrt(1 / (
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
+ (shearTrac/faceToBreakSigmaMax)*(shearTrac/faceToBreakSigmaMax)
) );
}
faceToBreakTraction *= scaleFactor;
topoChange = true;
}
else if (nCoupledFacesToBreak > 0)
{
label patchID =
mesh.boundaryMesh().whichPatch(coupledFaceToBreakIndex);
label start = mesh.boundaryMesh()[patchID].start();
label localIndex = coupledFaceToBreakIndex - start;
faceToBreakTraction = traction.boundaryField()[patchID][localIndex];
faceToBreakNormal = n.boundaryField()[patchID][localIndex];
// Scale broken face traction
faceToBreakSigmaMax = sigmaMax.boundaryField()[patchID][localIndex];
faceToBreakTauMax = tauMax.boundaryField()[patchID][localIndex];
scalar normalTrac = faceToBreakNormal & faceToBreakTraction;
normalTrac = max(normalTrac, 0.0);
scalar shearTrac = mag( (I - sqr(faceToBreakNormal)) & faceToBreakTraction );
scalar scaleFactor = 1;
if(cohesivePatchUPtr)
{
scaleFactor =
::sqrt(1 / (
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
+ (shearTrac/faceToBreakTauMax)*(shearTrac/faceToBreakTauMax)
) );
}
else
{
// solidCohesiveFixedModeMix only uses sigmaMax
scaleFactor =
::sqrt(1 / (
(normalTrac/faceToBreakSigmaMax)*(normalTrac/faceToBreakSigmaMax)
+ (shearTrac/faceToBreakSigmaMax)*(shearTrac/faceToBreakSigmaMax)
) );
}
faceToBreakTraction *= scaleFactor;
topoChange = true;
}
reduce(topoChange, orOp<bool>());
labelList faceToBreak(nFacesToBreak, faceToBreakIndex);
boolList faceToBreakFlip(nFacesToBreak, false);
labelList coupledFaceToBreak
(
nCoupledFacesToBreak,
coupledFaceToBreakIndex
);
reduce(nFacesToBreak, maxOp<label>());
reduce(nCoupledFacesToBreak, maxOp<label>());
if (nFacesToBreak || nCoupledFacesToBreak)
{
Pout << "Internal face to break: " << faceToBreak << endl;
Pout << "Coupled face to break: " << coupledFaceToBreak << endl;
mesh.setBreak(faceToBreak, faceToBreakFlip, coupledFaceToBreak);
mesh.update();
const labelList& faceMap = mesh.topoChangeMap().faceMap();
label start = mesh.boundaryMesh()[cohesivePatchID].start();
mu = rheology.mu();
lambda = rheology.lambda();
muf = fvc::interpolate(mu);
lambdaf = fvc::interpolate(lambda);
// we need to modify propertiess after cracking otherwise momentum equation is wrong
// but solidInterface seems to hold some information about old mesh
// so we will delete it and make another
// we could probably add a public clearout function
// create new solidInterface
//Pout << "Creating new solidInterface" << endl;
//delete solidInterfacePtr;
//solidInterfacePtr = new solidInterface(mesh, rheology);
// delete demand driven data as the mesh has changed
if(rheology.solidInterfaceActive())
{
rheology.solInterface().clearOut();
solidInterfacePtr->modifyProperties(muf, lambdaf);
}
// Local crack displacement
vectorField UpI =
U.boundaryField()[cohesivePatchID].patchInternalField();
vectorField oldUpI =
U.oldTime().boundaryField()[cohesivePatchID].patchInternalField();
// Global crack displacement
vectorField globalUpI = mesh.globalCrackField(UpI);
vectorField globalOldUpI = mesh.globalCrackField(oldUpI);
// mu and lambda field on new crack faces must be updated
scalarField muPI = mu.boundaryField()[cohesivePatchID].patchInternalField();
scalarField lambdaPI = lambda.boundaryField()[cohesivePatchID].patchInternalField();
scalarField globalMuPI = mesh.globalCrackField(muPI);
scalarField globalLambdaPI = mesh.globalCrackField(lambdaPI);
// cohesivePatchU.size()
int cohesivePatchSize(cohesivePatchUPtr ? cohesivePatchUPtr->size() : cohesivePatchUFixedModePtr->size());
// Initialise U for new cohesive face
const labelList& gcfa = mesh.globalCrackFaceAddressing();
label globalIndex = mesh.localCrackStart();
// for (label i=0; i<cohesivePatchU.size(); i++)
for (label i=0; i<cohesivePatchSize; i++)
{
label oldFaceIndex = faceMap[start+i];
// If new face
if (oldFaceIndex == faceToBreakIndex)
{
U.boundaryField()[cohesivePatchID][i] =
0.5
*(
globalUpI[globalIndex]
+ globalUpI[gcfa[globalIndex]]
);
U.oldTime().boundaryField()[cohesivePatchID][i] =
0.5
*(
globalOldUpI[globalIndex]
+ globalOldUpI[gcfa[globalIndex]]
);
// initialise mu and lambda on new faces
// set new face value to value of internal cell
muf.boundaryField()[cohesivePatchID][i] = globalMuPI[globalIndex];
lambdaf.boundaryField()[cohesivePatchID][i] = globalLambdaPI[globalIndex];
globalIndex++;
}
else
{
globalIndex++;
}
}
// we must calculate grad using interface
// U at the interface has not been calculated yet as interface.correct()
// has not been called yet
// 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.
// we should be able to calculate the interface displacements without
// having to call interface.correct()
// todo: add calculateInterfaceU() function
// interface grad uses Gauss, we need least squares
//gradU = solidInterfacePtr->grad(U);
gradU = fvc::grad(U); // leastSquaresSolidInterface grad scheme
//snGradU = fvc::snGrad(U);
# include "calculateTraction.H"
//if (nFacesToBreak || nCoupledFacesToBreak) mesh.write(); traction.write();
// Initialise initiation traction for new cohesive patch face
// for (label i=0; i<cohesivePatchU.size(); i++)
for (label i=0; i<cohesivePatchSize; i++)
{
label oldFaceIndex = faceMap[start+i];
// If new face
if
(
(oldFaceIndex == faceToBreakIndex)
|| (oldFaceIndex == coupledFaceToBreakIndex)
)
{
vector n0 =
mesh.Sf().boundaryField()[cohesivePatchID][i]
/mesh.magSf().boundaryField()[cohesivePatchID][i];
//vector n1 = -n0;
if ((n0&faceToBreakNormal) > SMALL)
{
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
{
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;
cohesivePatchUFixedModePtr->initiationTraction()[i] = -faceToBreakTraction;
}
}
}
}
// hmmnn we only need a reference for very small groups of cells
// turn off for now
//# include "updateReference.H"
}
}

View file

@ -0,0 +1,87 @@
{
labelHashSet selectedFaces;
const labelListList& edgeFaces = mesh.edgeFaces();
const scalarField& cohesiveZoneI = cohesiveZone.internalField();
forAll (crackPropagationPatches, patchI)
{
label curPatchID = crackPropagationPatches[patchI];
const labelList& patchEdges =
mesh.boundaryMesh()[curPatchID].meshEdges();
forAll(patchEdges, edgeI)
{
label curEdge = patchEdges[edgeI];
const labelList& curFaces = edgeFaces[curEdge];
forAll(curFaces, faceI)
{
if (curFaces[faceI] < mesh.nInternalFaces())
{
if (cohesiveZoneI[curFaces[faceI]] > (1.0 - SMALL))
{
if (!selectedFaces.found(curFaces[faceI]))
{
selectedFaces.insert(curFaces[faceI]);
}
}
}
}
}
}
// if (notchPatchID != -1)
// {
// const labelList& notchPatchEdges =
// mesh.boundaryMesh()[notchPatchID].meshEdges();
// forAll(notchPatchEdges, edgeI)
// {
// label curEdge = notchPatchEdges[edgeI];
// const labelList& curFaces = edgeFaces[curEdge];
// forAll(curFaces, faceI)
// {
// if (curFaces[faceI] < mesh.nInternalFaces())
// {
// if (cohesiveZoneI[curFaces[faceI]] > (1.0 - SMALL))
// {
// selectedFaces.insert(curFaces[faceI]);
// }
// }
// }
// }
// }
// if (mesh.boundary()[cohesivePatchID].size())
// {
// const labelList& cohesivePatchEdges =
// mesh.boundaryMesh()[cohesivePatchID].meshEdges();
// forAll(cohesivePatchEdges, edgeI)
// {
// label curEdge = cohesivePatchEdges[edgeI];
// const labelList& curFaces = edgeFaces[curEdge];
// forAll(curFaces, faceI)
// {
// if (curFaces[faceI] < mesh.nInternalFaces())
// {
// if (cohesiveZoneI[curFaces[faceI]] > (1.0 - SMALL))
// {
// selectedFaces.insert(curFaces[faceI]);
// }
// }
// }
// }
// }
crackPropagationPatchesInternalFaces = labelList(selectedFaces.toc());
}

View file

@ -0,0 +1,60 @@
{
// Check which region needs reference
needRef = boolList(mesh.regions().nRegions(), true);
forAll(U.boundaryField(), patchI)
{
// philipc - this used to set a reference on
// processors which did not have a patch that fixesValue
// so processor in the centre of the domain all had
// a referece set causing stress peaks and resulting
// in an incorrect solution
// so a quick fix is to not set a reference on regions
// with a processor boundary
//if (U.boundaryField()[patchI].fixesValue())
if (
U.boundaryField()[patchI].fixesValue()
||
mesh.boundaryMesh()[patchI].type()
== processorPolyPatch::typeName
)
{
const unallocLabelList& curFaceCells =
mesh.boundary()[patchI].faceCells();
forAll(curFaceCells, fI)
{
needRef[mesh.regions()[curFaceCells[fI]]] = false;
}
}
}
// Find reference cell for each region
refCells = labelList(mesh.regions().nRegions(), -1);
forAll(refCells, regI)
{
refCells[regI] = findIndex(mesh.regions(), regI);
if (refCells[regI] == -1)
{
FatalErrorIn(args.executable())
<< "Can't find reference cell for region: "
<< regI << abort(FatalError);
}
}
// Find dead cells
labelHashSet deadCellsSet;
const labelList& regs = mesh.regions();
forAll(regs, cellI)
{
if (mesh.nCellsInRegion(regs[cellI]) < 0.01*mesh.nCells())
{
deadCellsSet.insert(cellI);
}
}
deadCells = deadCellsSet.toc();
}

View file

@ -0,0 +1,17 @@
{
scalar E0 = rheology.law().E()().internalField()[0];
scalar nu0 = rheology.law().nu()().internalField()[0];
scalar rho0 = rho.internalField()[0];
scalar waveVelocity =
::sqrt(E0*(1 - nu0)/(rho0*(1 + nu0)*(1 - 2*nu0)));
// Courant number
scalarField Co =
waveVelocity*runTime.deltaT().value()
*mesh.surfaceInterpolation::deltaCoeffs().internalField();
Info<< "Courant Number mean: " << gAverage(Co)
<< " max: " << gMax(Co)
<< " wave velocity magnitude: " << waveVelocity << endl;
}

View file

@ -0,0 +1,149 @@
if (runTime.outputTime() || topoChange)
{
volScalarField sigmaEq
(
IOobject
(
"sigmaEq",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
sqrt((3.0/2.0)*magSqr(dev(sigma)))
);
Info<< "Max sigmaEq = " << max(sigmaEq).value()
<< endl;
volScalarField epsilonEq
(
IOobject
(
"epsilonEq",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
sqrt((2.0/3.0)*magSqr(dev(epsilon)))
);
Info<< "Max epsilonEq = " << max(epsilonEq).value()
<< endl;
// Info << "\nCalculate maximal principal stress ..." << flush;
// // Principal stresses
// volVectorField sigmaMax
// (
// IOobject
// (
// "sigmaMax",
// runTime.timeName(),
// mesh,
// IOobject::NO_READ,
// IOobject::AUTO_WRITE
// ),
// mesh,
// dimensionedVector("sigmaMax", dimPressure, vector::zero)
// );
// vectorField& sigmaMaxI = sigmaMax.internalField();
// forAll (sigmaMaxI, cellI)
// {
// vector eValues = eigenValues(sigma.internalField()[cellI]);
// tensor eVectors = eigenVectors(sigma.internalField()[cellI]);
// scalar maxEValue = 0;
// label iMax = -1;
// forAll(eValues, i)
// {
// if (eValues[i] > maxEValue)
// {
// maxEValue = eValues[i];
// iMax = i;
// }
// }
// if (iMax != -1)
// {
// if (iMax == 0)
// {
// sigmaMaxI[cellI] = eVectors.x()*eValues.x();
// }
// else if (iMax == 1)
// {
// sigmaMaxI[cellI] = eVectors.y()*eValues.y();
// }
// else if (iMax == 2)
// {
// sigmaMaxI[cellI] = eVectors.z()*eValues.z();
// }
// }
// }
//- cohesive damage and cracking, and GII and GII
volScalarField damageAndCracks
(
IOobject
(
"damageAndCracks",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
dimensionedScalar("zero", dimless, 0.0),
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();
GII.boundaryField()[patchi] = Upatch.GII();
damageAndCracks.boundaryField()[patchi] = Upatch.crackingAndDamage();
}
}
volScalarField GTotal("GTotal", GI + GII);
GTotal.write();
runTime.writeNow();
}

View file

@ -0,0 +1,40 @@
//- write force displacement to file
if(historyPatchID != -1)
{
Info << "Writing disp and force of patch "<<historyPatchName<<" to file"
<< endl;
//- for small strain or moving mesh
vector force = gSum(mesh.boundary()[historyPatchID].Sf() & sigma.boundaryField()[historyPatchID]);
//- for large strain total lagrangian
// tensorField F = I + gradU.boundaryField()[historyPatchID];
// vectorField totalForce = mesh.Sf().boundaryField()[historyPatchID] & (sigma.boundaryField()[historyPatchID] & F);
//vector force = sum( totalForce );
//scalar force = force[vector::Y];;
//- 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
//- you cannot just take the component of the sigma tensor
//scalar forcePatchIntegrateMethod = gSum(
// mesh.magSf().boundaryField()[historyPatchID]
// *sigma.boundaryField()[historyPatchID].component(symmTensor::XY)
// );
vector avDisp = gAverage(U.boundaryField()[historyPatchID]);
//- write to file
if(Pstream::master())
{
OFstream& forceDispFile = *filePtr;
forceDispFile << avDisp.x() << " " << avDisp.y() << " " << avDisp.z() << " "
<< force.x() << " " << force.y() << " " << force.z() << endl;
}
}
if(clipGPtr)
{
clipGPtr->write();
}

View file

@ -1,3 +0,0 @@
elasticContactIncrSolidFoam.C
EXE = $(FOAM_APPBIN)/elasticContactIncrSolidFoam

View file

@ -1,14 +0,0 @@
EXE_INC = \
-I$(FOAM_SRC)/finiteVolume/lnInclude \
-I$(FOAM_SRC)/meshTools/lnInclude \
-I$(FOAM_SRC)/lagrangian/basic/lnInclude \
-I../solidModels/lnInclude \
-I$(FOAM_SRC)/VectorN/lnInclude
EXE_LIBS = \
-lsolidModels \
-lfiniteVolume \
-llduSolvers \
-lmeshTools \
-llagrangian \
-lVectorN

View file

@ -1,15 +0,0 @@
EXE_INC = \
// -I../../../myLibraries/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I../materialModels/lnInclude \
-I./solidInterface
// -I./patchToPatchInterpolation
EXE_LIBS = \
-L$(FOAM_USER_LIBBIN) \
// -lfiniteVolume_philipc \
// -lfiniteVolume \
-lmaterialModels_philipc \
-llduSolvers \
-lmeshTools

View file

@ -1,9 +0,0 @@
EXE_INC = \
-I$(FOAM_SRC)/finiteVolume/lnInclude \
-I$(FOAM_SRC)/dynamicMesh/lnInclude \
-I../materialModels/lnInclude
EXE_LIBS = \
-L$(FOAM_USER_LIBBIN) \
-lfiniteVolume \
-lmaterialModels_philipc

View file

@ -1,47 +0,0 @@
if(divDSigmaExpMethod == "standard")
{
divDSigmaExp = fvc::div
(
mu*gradDU.T() + lambda*(I*tr(gradDU)) - (mu + lambda)*gradDU,
"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")
{
surfaceTensorField shearGradDU = ((I - n*n)&fvc::interpolate(gradDU));
divDSigmaExp = fvc::div
(
mesh.magSf()
*
(
- (muf + lambdaf)*(fvc::snGrad(DU)&(I - n*n))
+ lambdaf*tr(shearGradDU&(I - n*n))*n
+ muf*(shearGradDU&n)
)
);
}
else if(divDSigmaExpMethod == "laplacian")
{
divDSigmaExp =
- fvc::laplacian(mu + lambda, DU, "laplacian(DDU,DU)")
+ fvc::div
(
mu*gradDU.T()
+ lambda*(I*tr(gradDU)),
"div(sigma)"
);
}
else
{
FatalError << "divDSigmaExp method " << divDSigmaExpMethod << " not found!" << endl;
}

View file

@ -1,153 +0,0 @@
/*---------------------------------------------------------------------------*\
correctGlobalFaceZoneMesh.H
When there is a globalFaceZone and the mesh is moved by interpolating U to the
vertices with volPointInterpolation, then there are two problems:
-some points on the patch with the faceZone are moved incorrectly, I think
it is because the faceZone has no U and causes an incorrect interpolation,
-the faceZones points not on the proc cells are not moved at all because
they have no U.
So the points on the patch with the faceZone need to be fixed and also all the
faceZone points need to be moved and synchronised so each proc has the same
full faceZone mesh.
The mapping of procs faceZone order of points to the master procs faceZone point
order is kept in procToGlobalFZmap, which is calculated at the start of the run
in the createGlobalToLocalFaceZonePointMap.H header file.
Note: DU is used for updated Lagrangian solver instead of U
philipc
\*---------------------------------------------------------------------------*/
//- this is only needed in a parallel runs
if(Pstream::parRun())
{
//***** FIX INCORRECT POINT ON PATCHES WITH FACEZONE *****//
contactPatchPairList& contacts = contact;
forAll(contacts, contactI)
{
label masterID = contacts[contactI].masterPatch().index();
label slaveID = contacts[contactI].slavePatch().index();
primitivePatchInterpolation masterInterpolator
(
mesh.boundaryMesh()[masterID]
);
primitivePatchInterpolation slaveInterpolator
(
mesh.boundaryMesh()[slaveID]
);
//- U must be interpolated to the vertices, this ignores the faceZone
//- points with no U (unlike volPointInterpolation)
vectorField correctMasterPointU =
masterInterpolator.faceToPointInterpolate<vector>
(
U.boundaryField()[masterID]
);
vectorField correctSlavePointU =
slaveInterpolator.faceToPointInterpolate<vector>
(
U.boundaryField()[slaveID]
);
vectorField oldMasterPoints =
mesh.boundaryMesh()[masterID].localPoints();
vectorField oldSlavePoints =
mesh.boundaryMesh()[slaveID].localPoints();
labelList masterPointLabels =
mesh.boundaryMesh()[masterID].meshPoints();
labelList slavePointLabels =
mesh.boundaryMesh()[slaveID].meshPoints();
//- correct the patch newPoints
forAll(masterPointLabels, pointI)
{
label pointGlobalLabel = masterPointLabels[pointI];
newPoints[pointGlobalLabel] =
oldMasterPoints[pointI] + correctMasterPointU[pointI];
}
forAll(slavePointLabels, pointI)
{
label pointGlobalLabel = slavePointLabels[pointI];
newPoints[pointGlobalLabel] =
oldSlavePoints[pointI] + correctSlavePointU[pointI];
}
}
//***** NOW FIX AND SYNCHRONISE ALL THE FACEZONE POINTS *****//
forAll(mesh.faceZones(), faceZoneI)
{
//- find the patch corresponding to this faceZone
//- assuming that the FZ is called <patch_name>FaceZone
string faceZoneName = mesh.faceZones().names()[faceZoneI];
//- remove the string FaceZone from the end of the face zone name to get the patch name
string patchName = faceZoneName.substr(0, (faceZoneName.size()-8));
label patchID = mesh.boundaryMesh().findPatchID(patchName);
if(patchID == -1)
{
FatalError << "Patch " << patchName << " not found corresponding for faceZone"
<< faceZoneName << exit(FatalError);
}
vectorField globalFZpoints =
mesh.faceZones()[faceZoneI]().localPoints();
//- new points for the face zone
vectorField globalFZnewPoints(globalFZpoints.size(), vector::zero);
//- inter-proc points are shared by multiple procs
//- pointNumProc is the number of procs which a point lies on
scalarField pointNumProcs(globalFZpoints.size(), 0.0);
forAll(globalFZnewPoints, globalPointI)
{
label localPoint = procToGlobalFZmap[faceZoneI][globalPointI];
//if(localPoint < mesh.boundaryMesh()[patchID].localPoints().size())
if(pointOnLocalProcPatch[faceZoneI][localPoint])
{
label procPoint =
mesh.faceZones()[faceZoneI]().meshPoints()[localPoint];
globalFZnewPoints[globalPointI] = newPoints[procPoint];
pointNumProcs[globalPointI] = 1;
}
}
reduce(globalFZnewPoints, sumOp<vectorField>());
reduce(pointNumProcs, sumOp<scalarField>());
//- now average the newPoints between all procs
if(min(pointNumProcs) < 1)
{
FatalError << "pointNumProc has not been set for all points" << exit(FatalError);
}
globalFZnewPoints /= pointNumProcs;
//- the globalFZnewPoints now contains the correct FZ new points in
//- a global order, now convert them back into the local proc order
vectorField procFZnewPoints(globalFZpoints.size(), vector::zero);
forAll(globalFZnewPoints, globalPointI)
{
label localPoint = procToGlobalFZmap[faceZoneI][globalPointI];
procFZnewPoints[localPoint] = globalFZnewPoints[globalPointI];
}
//- now fix the newPoints points on the globalFaceZones
labelList procFZmeshPoints = mesh.faceZones()[faceZoneI]().meshPoints();
forAll(procFZmeshPoints, pointI)
{
label procPoint = procFZmeshPoints[pointI];
newPoints[procPoint] = procFZnewPoints[pointI];
}
}
}

View file

@ -1,138 +0,0 @@
/*---------------------------------------------------------------------------*\
createGlobalToLocalFaceZonePointMap.H
I could not figure out the order of the points on a globalFaceZone, they is a
different order for each processor where the processors own points come first.
So I decide that the master proc order is the global order and I find the map
from this order to each proc order here by just commparing actual point
coordinates.
This map is then used to correct and synchronise the globalFaceZone points on
all the procs when the mesh is moved, in header file correctGlobalFaceZoneMesh.H.
philipc
\*---------------------------------------------------------------------------*/
//- procToGlobalFZmap is a map from the current proc faceZone point order to the
//- master proc point order
//- these are read if present to allow restarting of contact cases
IOList<labelList> procToGlobalFZmap
(
IOobject
(
"procToGlobalFZmap",
runTime.timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
mesh.faceZones().size()
);
IOList<labelList> pointOnLocalProcPatch
(
IOobject
(
"pointOnLocalProcPatch",
runTime.timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
mesh.faceZones().size()
);
//- if they have been read then don't recalculate it
bool globalFaceZoneMappingSet = false;
if(gMax(procToGlobalFZmap[0]) > 0 && gMax(pointOnLocalProcPatch[0]) > 0)
{
Info << "Reading procToGlobalFZmap and pointOnLocalProcPatch allowing restart of contact cases"
<< endl;
globalFaceZoneMappingSet = true;
}
else
{
Info << "procToGlobalFZmap and pointOnLocalProcPatch will be calculated as it has not been found" << nl
<< "this message should only appear starting a new analysis" << endl;
}
//- this is only needed in a parallel runs
if(Pstream::parRun())
{
if(!globalFaceZoneMappingSet)
{
forAll(mesh.faceZones(), faceZoneI)
{
vectorField globalFZpoints = mesh.faceZones()[faceZoneI]().localPoints();
procToGlobalFZmap[faceZoneI].setSize(globalFZpoints.size(), 0);
//- set all slave points to zero because only the master order is used
if(!Pstream::master())
{
globalFZpoints *= 0.0;
}
//- pass points to all procs
reduce(globalFZpoints, sumOp<vectorField>());
//- now every proc has the master's list of FZ points
//- every proc must now find the mapping from their local FZpoints to
//- the globalFZpoints
vectorField procFZpoints = mesh.faceZones()[faceZoneI]().localPoints();
forAll(globalFZpoints, globalPointI)
{
forAll(procFZpoints, procPointI)
{
if(procFZpoints[procPointI] == globalFZpoints[globalPointI])
{
procToGlobalFZmap[faceZoneI][globalPointI] = procPointI;
break;
}
}
}
//- procToGlobalFZmap now contains the local FZpoint label for each
//- global FZ point label - for each faceZone
//- check what points are on the current proc patch
pointOnLocalProcPatch[faceZoneI].setSize(globalFZpoints.size(), 0);
//- find corresponding patch
string faceZoneName = mesh.faceZones().names()[faceZoneI];
//- remove the string FaceZone from the end of the face zone name to get the patch name
string patchName = faceZoneName.substr(0, (faceZoneName.size()-8));
label patchID = mesh.boundaryMesh().findPatchID(patchName);
if(patchID == -1)
{
FatalError << "Patch " << patchName << " not found corresponding for faceZone"
<< faceZoneName << exit(FatalError);
}
forAll(mesh.faceZones()[faceZoneI]().localPoints(), fzpi)
{
forAll(mesh.boundaryMesh()[patchID].localPoints(), pi)
{
if(mesh.faceZones()[faceZoneI]().localPoints()[fzpi] == mesh.boundaryMesh()[patchID].localPoints()[pi])
{
pointOnLocalProcPatch[faceZoneI][fzpi] = 1;
break;
}
}
}
}
} //- end if(!globalFaceZoneMappingSet)
}
//- write to disk to allow restart of cases
//- because it is not possible to calculate the
//- mapping after the meshes have moved
if(!globalFaceZoneMappingSet && Pstream::parRun())
{
procToGlobalFZmap.write();
pointOnLocalProcPatch.write();
}

View file

@ -1,25 +0,0 @@
Switch solidInterfaceCorr(false);
solidInterface* solidInterfacePtr(NULL);
{
const dictionary& stressControl =
mesh.solutionDict().subDict("stressedFoam");
solidInterfaceCorr = Switch(stressControl.lookup("solidInterface"));
if(solidInterfaceCorr)
{
Info << "Creating solid interface correction" << endl;
solidInterfacePtr = new solidInterface(mesh, rheology);
solidInterfacePtr->modifyProperties(muf, lambdaf);
gradDU = solidInterfacePtr->grad(DU);
//- solidInterface needs muf and lambdaf to be used for divDSigmaExp
if(divDSigmaExpMethod != "surface" && divDSigmaExpMethod != "decompose")
{
FatalError << "divDSigmaExp must be decompose or surface when solidInterface is on"
<< exit(FatalError);
}
}
}

View file

@ -1,220 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2007 Hrvoje Jasak
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Application
elasticContactIncrSolidFoam
Description
Transient/steady-state segregated finite-volume solver for small strain
elastic solid bodies in contact, using an incremental total Lagrangian
approach.
Works in parallel.
Solves for the displacement increment vector field DU, also generating the
stress tensor field sigma.
It is only for frictionless contact, friction not implemented yet.
Author
Philip Cardiff
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "rheologyModel.H"
#include "contactProblem.H"
#include "solidInterface.H"
#include "volPointInterpolation.H"
#include "pointPatchInterpolation.H"
#include "primitivePatchInterpolation.H"
#include "fixedValuePointPatchFields.H"
#include "pointFields.H"
#include "pointMesh.H"
#include "pointBoundaryMesh.H"
#include "primitivePatchInterpolation.H"
#include "twoDPointCorrector.H"
//#include "leastSquaresVolPointInterpolation.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
# include "setRootCase.H"
# include "createTime.H"
# include "createMesh.H"
# include "createFields.H"
# include "readDivDSigmaExpMethod.H"
# include "createGlobalToLocalFaceZonePointMap.H"
# include "createSolidInterface.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nStarting time loop\n" << endl;
for (runTime++; !runTime.end(); runTime++)
{
Info<< "Time: " << runTime.timeName() << endl;
# include "readContactControls.H"
# include "readStressedFoamControls.H"
//-- for moving the mesh and then back again
vectorField oldMeshPoints = mesh.allPoints();
int iCorr = 0;
lduMatrix::solverPerformance solverPerf;
word solverName;
lduMatrix::debug = 0;
scalar residual = GREAT;
scalar initialResidual = 0;
scalar relativeResidual = GREAT;
//- reset DU to zero at the start of the time-step if
//- a predictor is not required
if(!predictor)
{
DU = dimensionedVector("zero", dimLength, vector::zero);
}
do //- start of momentum loop
{
DU.storePrevIter();
//- correct the contact boundaries
if(iCorr % uEqnContactCorrFreq == 0)
{
Info << "\t\tCorrecting contact in the momentum loop "
<< "iteration: " << iCorr
<< ", residual: " << residual
<< endl;
//# include "moveMeshLeastSquares.H"
# include "moveSolidMesh.H"
contact.correct();
mesh.movePoints(oldMeshPoints);
}
# include "calculateDivDSigmaExp.H"
fvVectorMatrix DUEqn
(
fvm::d2dt2(rho, DU)
==
fvm::laplacian(2*mu + lambda, DU, "laplacian(DDU,DU)")
+ divDSigmaExp
);
if(solidInterfaceCorr)
{
solidInterfacePtr->correct(DUEqn);
}
solverPerf = DUEqn.solve();
DU.relax();
solverName = solverPerf.solverName();
if(solidInterfaceCorr)
{
gradDU = solidInterfacePtr->grad(DU);
}
else
{
gradDU = fvc::grad(DU);
}
U = U.oldTime() + DU;
residual = solverPerf.initialResidual();
//****************************************************//
// The contact residual is the initial residual for the
// first iteration of the momentum equation
//****************************************************//
if(iCorr == 0)
{
initialResidual = solverPerf.initialResidual();
}
# include "calculateRelativeResidual.H"
Info << "\tTime " << runTime.value()
<< ", Corrector " << iCorr
<< ", Solving for " << DU.name()
<< " using " << solverPerf.solverName()
<< ", residual = " << solverPerf.initialResidual()
<< ", relative residual = " << relativeResidual << endl;
} //- end of momentum loop
while
(
relativeResidual > convergenceTolerance
//residual > convergenceTolerance
&&
++iCorr < nCorr
);
// Print out info per contact iteration
Info << "\t\tSolving for " << DU.name()
<< " using " << solverName
<< ", Initial residual = " << initialResidual
<< ", Final residual = " << solverPerf.initialResidual()
<< ", No outer iterations " << iCorr << endl;
lduMatrix::debug = 1;
# include "calculateDEpsilonDSigma.H"
epsilon += DEpsilon;
sigma += DSigma;
# include "writeFields.H"
//# include "writeBoundaryNetForces.H"
//# include "moveMeshLeastSquares.H"
//# include "moveSolidMesh.H"
//# include "printContactResults.H"
//mesh.movePoints(oldMeshPoints);
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< endl << endl;
}
Info<< "End\n" << endl;
return(0);
}
// ************************************************************************* //

View file

@ -1,28 +0,0 @@
{
//- move mesh for the contact correction
// Create point interpolation
volPointInterpolation pointInterpolation(mesh);
// Calculate mesh points displacement
pointVectorField pointU = pointInterpolation.interpolate(U);
const vectorField& pointUI = pointU.internalField();
// Move mesh
vectorField newPoints = mesh.allPoints();
forAll (pointUI, pointI)
{
newPoints[pointI] += pointUI[pointI];
}
# include "correctGlobalFaceZoneMesh.H"
twoDPointCorrector twoDCorrector(mesh);
twoDCorrector.correctPoints(newPoints);
mesh.movePoints(newPoints);
mesh.V00();
mesh.moving(false);
}

View file

@ -1,55 +0,0 @@
if (runTime.outputTime())
{
// FAILS IN PARALLEL - FIX
// Info << "Print contact area" << endl;
//volScalarField ca = contact.contactArea();
//ca.write();
//-------------------------------------------------------------//
// I couldn't get tmp to return the pointScalarField correctly //
// so I had to make the pointScalarField here and pass it to //
// contactGapPoints and pointContactForce to populate //
//-------------------------------------------------------------//
//This is the point distance for each contact vertex
pointScalarField cGapPoints
(
IOobject
(
"pointContactGap",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
pMesh,
dimensionedScalar("scalar", dimLength, 0.0),
"calculated"
);
contact.contactGapPoints(cGapPoints);
cGapPoints.write();
//- This is the point distance for each contact vertex
pointVectorField cPointForce
(
IOobject
(
"pointContactForce",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
pMesh,
dimensionedVector("vector", dimForce, vector::zero),
"calculated"
);
contact.contactPointForce(cPointForce);
cPointForce.write();
//- this is the actual (sigma&n)&n) on the contact patches
//- SHOULD THIS BE A REF TO A TMP...?
volScalarField cPressure = contact.contactPressure();
cPressure.write();
}

View file

@ -1,16 +0,0 @@
//****************************************************//
// Read the contact tol and max contact correctors
//****************************************************//
const IOdictionary& contactControl =
IOobject
(
"contactProperties",
U.time().constant(),
U.db(),
IOobject::MUST_READ,
IOobject::NO_WRITE
);
//- The frequnecy the conatct is corrected inside the momentum loop
int uEqnContactCorrFreq(readInt(contactControl.lookup("innerContactCorrectFreq")));

View file

@ -1,15 +0,0 @@
//- how explicit component of sigma is to be calculated
word divDSigmaExpMethod(mesh.solutionDict().subDict("stressedFoam").lookup("divDSigmaExp"));
Info << divDSigmaExpMethod << " method chosen for calculation of sigmaExp" << endl;
if
(
divDSigmaExpMethod != "standard"
&& divDSigmaExpMethod != "surface"
&& divDSigmaExpMethod != "decompose"
&& divDSigmaExpMethod != "laplacian"
)
{
FatalError << "divDSigmaExp method " << divDSigmaExpMethod << " not found!" << nl
<< "valid methods are:\nstandard\nsurface\ndecompose\nlaplacian"
<< exit(FatalError);
}

View file

@ -1,7 +0,0 @@
const dictionary& stressControl =
mesh.solutionDict().subDict("stressedFoam");
int nCorr(readInt(stressControl.lookup("nCorrectors")));
scalar convergenceTolerance(readScalar(stressControl.lookup("DU")));
Switch predictor(stressControl.lookup("predictor"));

View file

@ -1,14 +0,0 @@
// * * * * * * * * * * * * * * * * NET FORCES * * * * * * * * * * * * * * * //
vectorField netForces(mesh.boundary().size(), vector::zero);
Info << nl;
forAll(netForces, patchI)
{
netForces[patchI] = gSum(mesh.Sf().boundaryField()[patchI] & sigma.boundaryField()[patchI]);
Info << "patch\t" << mesh.boundary()[patchI].name() << "\t\tnet force is\t"
<< netForces[patchI] << " N" << endl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View file

@ -1,78 +0,0 @@
if (runTime.outputTime())
{
volScalarField epsilonEq
(
IOobject
(
"epsilonEq",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
sqrt((2.0/3.0)*magSqr(dev(epsilon)))
);
Info<< "Max epsilonEq = " << max(epsilonEq).value()
<< endl;
volScalarField sigmaEq
(
IOobject
(
"sigmaEq",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
sqrt((3.0/2.0)*magSqr(dev(sigma)))
);
Info<< "Max sigmaEq = " << max(sigmaEq).value()
<< endl;
volScalarField pressure
(
IOobject
(
"pressure",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
tr(sigma)/3.0
);
//- boundary surface pressure
forAll(pressure.boundaryField(), patchi)
{
const vectorField& nb = n.boundaryField()[patchi];
pressure.boundaryField()[patchi] =
-(nb & ( nb & sigma.boundaryField()[patchi] ));
}
//- contact slave penetration
# include "moveSolidMesh.H"
pointMesh pMesh(mesh);
pointScalarField cGapPoints
(
IOobject
(
"pointContactGap",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
pMesh,
dimensionedScalar("scalar", dimLength, 0.0),
"calculated"
);
contact.contactGapPoints(cGapPoints);
cGapPoints.write();
mesh.movePoints(oldMeshPoints);
runTime.write();
}

View file

@ -1,3 +0,0 @@
elasticContactNonLinULSolidFoam.C
EXE = $(FOAM_APPBIN)/elasticContactNonLinULSolidFoam

View file

@ -1,14 +0,0 @@
EXE_INC = \
-I$(FOAM_SRC)/finiteVolume/lnInclude \
-I$(FOAM_SRC)/meshTools/lnInclude \
-I$(FOAM_SRC)/lagrangian/basic/lnInclude \
-I../solidModels/lnInclude \
-I$(FOAM_SRC)/VectorN/lnInclude
EXE_LIBS = \
-lsolidModels \
-lfiniteVolume \
-llduSolvers \
-lmeshTools \
-llagrangian \
-lVectorN

View file

@ -1,15 +0,0 @@
EXE_INC = \
// -I../../../myLibraries/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I../materialModels/lnInclude \
-I./solidInterface
// -I./patchToPatchInterpolation
EXE_LIBS = \
-L$(FOAM_USER_LIBBIN) \
// -lfiniteVolume_philipc \
// -lfiniteVolume \
-lmaterialModels_philipc \
-llduSolvers \
-lmeshTools

View file

@ -1,9 +0,0 @@
EXE_INC = \
-I$(FOAM_SRC)/finiteVolume/lnInclude \
-I$(FOAM_SRC)/dynamicMesh/lnInclude \
-I../materialModels/lnInclude
EXE_LIBS = \
-L$(FOAM_USER_LIBBIN) \
-lfiniteVolume \
-lmaterialModels_philipc

View file

@ -1,3 +0,0 @@
DEpsilon = symm(gradDU) + 0.5*symm(gradDU & gradDU.T());
DSigma = 2*mu*DEpsilon + lambda*(I*tr(DEpsilon));

View file

@ -1,47 +0,0 @@
if(divDSigmaExpMethod == "standard")
{
divDSigmaExp = fvc::div
(
mu*gradDU.T() + lambda*(I*tr(gradDU)) - (mu + lambda)*gradDU,
"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")
{
surfaceTensorField shearGradDU =
((I - n*n)&fvc::interpolate(gradDU));
divDSigmaExp = fvc::div
(
mesh.magSf()
*(
- (muf + lambdaf)*(fvc::snGrad(DU)&(I - n*n))
+ lambdaf*tr(shearGradDU&(I - n*n))*n
+ muf*(shearGradDU&n)
)
);
}
else if(divDSigmaExpMethod == "laplacian")
{
divDSigmaExp =
- fvc::laplacian(mu + lambda, DU, "laplacian(DDU,DU)")
+ fvc::div
(
mu*gradDU.T()
+ lambda*(I*tr(gradDU)),
"div(sigma)"
);
}
else
{
FatalError << "divDSigmaExp method " << divDSigmaExpMethod << " not found!" << endl;
}

View file

@ -1,34 +0,0 @@
//----------------------------------------------------//
//- sigma explicit large strain explicit terms
//----------------------------------------------------//
if(divDSigmaLargeStrainExpMethod == "standard")
{
divDSigmaLargeStrainExp =
fvc::div
(
mu*(gradDU & gradDU.T())
+ 0.5*lambda*(gradDU && gradDU)*I //- equivalent to 0.5*lambda*(I*tr(gradDU & gradDU.T()))
+ ((sigma + DSigma) & DF.T()),
"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 & DF.T() ))
+ (mesh.Sf() & fvc::interpolate(DSigma & DF.T() ))
);
}
else
{
FatalError
<< "divDSigmaLargeStrainExp not found!"
<< exit(FatalError);
}
//- relax large strain component
divDSigmaLargeStrainExp.relax();

View file

@ -1,72 +0,0 @@
//void Foam::edgeCorrectedVolPointInterpolation::makeExtrapolationWeights() const
//{
// Interpolation:
// For each point to be corrected calculate the extrapolated value
// for each face around it and combine them using the inverse
// distance weighting factors
//const labelList& ptc = boundaryPoints();
// Calculate the correction vectors
//extrapolationVectorsPtr_ =
// new FieldField<Field, vector>(ptc.size());
//FieldField<Field, vector>& extraVecs = *extrapolationVectorsPtr_;
FieldField<Field, vector> extraVecs(ptc.size());
{
const labelListList& pfaces = mesh.pointFaces();
const volVectorField& centres = mesh.C();
const fvBoundaryMesh& bm = mesh.boundary();
forAll (ptc, pointI)
{
const label curPoint = ptc[pointI];
const labelList& curFaces = pfaces[curPoint];
// extraVecs.hook(new vectorField(curFaces.size())); //- no hook function
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])
&& !bm[patchID].coupled()
)
{
// Found a face for extrapolation
curExtraVectors[nFacesAroundPoint] =
pointLoc
- centres.boundaryField()[patchID]
[bm[patchID].patch().whichFace(curFaces[faceI])];
nFacesAroundPoint++;
}
}
}
curExtraVectors.setSize(nFacesAroundPoint);
}
}

Some files were not shown because too many files have changed in this diff Show more