Separate the solid material representation form the integrand classes themselves, to better facilitate other material laws. Preparation to plasticity modeling.
git-svn-id: http://svn.sintef.no/trondheim/IFEM/trunk@863 e10b68d5-8a6e-419e-a041-bce267b0401d
This commit is contained in:
86
Apps/FiniteDefElasticity/LinearMaterial.C
Normal file
86
Apps/FiniteDefElasticity/LinearMaterial.C
Normal file
@@ -0,0 +1,86 @@
|
||||
// $Id$
|
||||
//==============================================================================
|
||||
//!
|
||||
//! \file LinearMaterial.C
|
||||
//!
|
||||
//! \date Mar 08 2011
|
||||
//!
|
||||
//! \author Knut Morten Okstad / SINTEF
|
||||
//!
|
||||
//! \brief General linear elastic material with push-forward transformations.
|
||||
//!
|
||||
//==============================================================================
|
||||
|
||||
#include "LinearMaterial.h"
|
||||
#include "Tensor.h"
|
||||
|
||||
|
||||
double LinearMaterial::getMassDensity (const Vec3& X) const
|
||||
{
|
||||
return material->getMassDensity(X);
|
||||
}
|
||||
|
||||
|
||||
bool LinearMaterial::evaluate (Matrix& C, SymmTensor& sigma, double& U,
|
||||
const Vec3& X, const Tensor& F,
|
||||
const SymmTensor& eps, char iop,
|
||||
const TimeDomain* prm) const
|
||||
{
|
||||
// Evaluate the constitutive matrix and the stress tensor at this point
|
||||
if (!material->evaluate(C,sigma,U,X,F,eps,iop,prm))
|
||||
return false;
|
||||
else if (iop == 2)
|
||||
return true;
|
||||
|
||||
double J = F.det();
|
||||
if (J == 0.0)
|
||||
{
|
||||
std::cerr <<" *** LinearMaterial::evaluate: "
|
||||
<<" Singular/zero deformation gradient\n"<< F;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Push-forward the constitutive matrix to current configuration
|
||||
|
||||
size_t i, j, k, l;
|
||||
size_t n = F.dim();
|
||||
size_t m = C.rows();
|
||||
Matrix T(m,m), Ctmp;
|
||||
|
||||
for (i = 1; i <= n; i++)
|
||||
{
|
||||
for (j = 1; j <= n; j++)
|
||||
T(i,j) = F(j,i)*F(j,i);
|
||||
for (j = n+1, k = 1; j <= m; j++, k++)
|
||||
T(i,j) = 0.5*(F(k,i)*F(k%3+1,i) + F(k%3+1,i)*F(k,i));
|
||||
}
|
||||
|
||||
for (i = n+1, k = 1; i <= m; i++, k++)
|
||||
{
|
||||
for (j = 1; j <= n; j++)
|
||||
T(i,j) = F(j,k)*F(j,k%3+1) + F(j,k%3+1)*F(j,k);
|
||||
for (j = n+1, l = 1; j <= m; j++, l++)
|
||||
T(i,j) = 0.5*(F(l,k)*F(l%3+1,k%3+1) + F(l%3+1,k)*F(l,k%3+1) +
|
||||
F(l,k%3+1)*F(l%3+1,k) + F(l%3+1,k%3+1)*F(l,k));
|
||||
}
|
||||
|
||||
// C = 1/J * T^t * C * T
|
||||
Ctmp.multiply(C,T);
|
||||
C.multiply(T,Ctmp,true);
|
||||
C *= 1.0/J;
|
||||
#if INT_DEBUG > 0
|
||||
std::cout <<"LinearMaterial::C ="<< C;
|
||||
#endif
|
||||
|
||||
if (iop == 1)
|
||||
{
|
||||
// Push-forward the stress tensor to current configuration
|
||||
sigma.transform(F); // sigma = F * sigma * F^t
|
||||
sigma *= 1.0/J;
|
||||
#if INT_DEBUG > 0
|
||||
std::cout <<"LinearMaterial::sigma =\n"<< sigma;
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
59
Apps/FiniteDefElasticity/LinearMaterial.h
Normal file
59
Apps/FiniteDefElasticity/LinearMaterial.h
Normal file
@@ -0,0 +1,59 @@
|
||||
// $Id$
|
||||
//==============================================================================
|
||||
//!
|
||||
//! \file LinearMaterial.h
|
||||
//!
|
||||
//! \date Mar 08 2011
|
||||
//!
|
||||
//! \author Knut Morten Okstad / SINTEF
|
||||
//!
|
||||
//! \brief General linear elastic material with push-forward transformations.
|
||||
//!
|
||||
//==============================================================================
|
||||
|
||||
#ifndef _LINEAR_MATERIAL_H
|
||||
#define _LINEAR_MATERIAL_H
|
||||
|
||||
#include "MaterialBase.h"
|
||||
|
||||
|
||||
/*!
|
||||
\brief Class representing a isotropic linear elastic material model.
|
||||
*/
|
||||
|
||||
class LinearMaterial : public Material
|
||||
{
|
||||
public:
|
||||
//! \brief The constructor initializes the material properties pointer.
|
||||
LinearMaterial(const Material* mat) : material(mat) {}
|
||||
//! \brief The destructor deletes the material properties object.
|
||||
virtual ~LinearMaterial() { delete material; }
|
||||
|
||||
//! \brief Prints out material parameters to the given output stream.
|
||||
virtual void print(std::ostream& os) const { material->print(os); }
|
||||
|
||||
//! \brief Evaluates the mass density at an integration point.
|
||||
virtual double getMassDensity(const Vec3& X) const;
|
||||
|
||||
//! \brief Evaluates the constitutive relation at an integration point.
|
||||
//! \param[out] C Constitutive matrix at current point
|
||||
//! \param[out] sigma Stress tensor at current point
|
||||
//! \param[out] U Strain energy density at current point
|
||||
//! \param[in] X Cartesian coordinates of current point
|
||||
//! \param[in] F Deformation gradient at current point
|
||||
//! \param[in] eps Strain tensor at current point
|
||||
//! \param[in] iop Calculation option;
|
||||
//! -1 : Calculate the inverse constitutive matrix only,
|
||||
//! 0 : Calculate the constitutive matrix only,
|
||||
//! 1 : Calculate Cauchy stresses and the constitutive matrix.
|
||||
//! 2 : 2nd Piola-Kirchhoff stresses and the tangent constitutive matrix.
|
||||
//! \param[in] prm Nonlinear solution algorithm parameters
|
||||
virtual bool evaluate(Matrix& C, SymmTensor& sigma, double& U,
|
||||
const Vec3& X, const Tensor& F, const SymmTensor& eps,
|
||||
char iop = 1, const TimeDomain* prm = 0) const;
|
||||
|
||||
private:
|
||||
const Material* material; //!< Pointer to actual material properties object
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
// $Id: NeoHookeElasticity.C,v 1.2 2011-02-08 09:06:02 kmo Exp $
|
||||
// $Id$
|
||||
//==============================================================================
|
||||
//!
|
||||
//! \file NeoHookeElasticity.C
|
||||
@@ -23,7 +23,7 @@ void NeoHookeElasticity::print (std::ostream& os) const
|
||||
|
||||
void NeoHookeElasticity::setMaterial (double Emod, double Poiss, double Density)
|
||||
{
|
||||
this->Elasticity::setMaterial(Emod,Poiss,Density);
|
||||
//this->Elasticity::setMaterial(Emod,Poiss,Density);
|
||||
|
||||
// Define the Lame elasticity parameters
|
||||
lambda = Emod*Poiss / ((1.0+Poiss)*(1.0-Poiss-Poiss));
|
||||
@@ -43,7 +43,8 @@ bool NeoHookeElasticity::formStressTensor (const Matrix& dNdX, const Vec3&,
|
||||
}
|
||||
|
||||
// Evaluate the kinematic quantities, F, E, Ci, and J at this point
|
||||
if (!this->kinematics(dNdX,E))
|
||||
Tensor _F(nsd);
|
||||
if (!this->kinematics(dNdX,_F,E))
|
||||
return false;
|
||||
|
||||
// Set up the 2nd Piola-Kirchhoff stress tensor, S
|
||||
@@ -65,17 +66,17 @@ bool NeoHookeElasticity::formTangent (Matrix& Ctan, SymmTensor& S,
|
||||
}
|
||||
|
||||
|
||||
bool NeoHookeElasticity::kinematics (const Matrix& dNdX, SymmTensor& _E) const
|
||||
bool NeoHookeElasticity::kinematics (const Matrix& dNdX,
|
||||
Tensor& _F, SymmTensor& _E) const
|
||||
{
|
||||
// Form the deformation gradient, F
|
||||
if (!this->NonlinearElasticity::kinematics(dNdX,_E))
|
||||
if (!this->NonlinearElasticity::kinematics(dNdX,_F,_E))
|
||||
return false;
|
||||
else
|
||||
J = F.det();
|
||||
J = _F.det();
|
||||
|
||||
// Form the right Cauchy-Green tensor, C = F^T*F
|
||||
static Tensor dUdX(nsd);
|
||||
C.rightCauchyGreen(dUdX=F);
|
||||
C.rightCauchyGreen(_F);
|
||||
|
||||
// Invert the right Cauchy-Green tensor, Ci = C^-1
|
||||
Ci = C;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// $Id: NeoHookeElasticity.h,v 1.1 2010-12-18 20:03:53 kmo Exp $
|
||||
// $Id$
|
||||
//==============================================================================
|
||||
//!
|
||||
//! \file NeoHookeElasticity.h
|
||||
@@ -45,13 +45,14 @@ public:
|
||||
protected:
|
||||
//! \brief Calculates some kinematic quantities at current point.
|
||||
//! \param[in] dNdX Basis function gradients at current point
|
||||
//! \param[out] _F Deformation gradient at current point
|
||||
//! \param[out] _E Green-Lagrange strain tensor at current point
|
||||
//!
|
||||
//! \details The deformation gradient \b F and the Green-Lagrange tensor \b E
|
||||
//! are established. In addition, the right Cauchy-Green tensor \b C and its
|
||||
//! inverse \b Ci are formed.
|
||||
//! All quantities are stored internally in mutable data members.
|
||||
virtual bool kinematics(const Matrix& dNdX, SymmTensor& _E) const;
|
||||
virtual bool kinematics(const Matrix& dNdX, Tensor& _F, SymmTensor& _E) const;
|
||||
|
||||
//! \brief Forms tangential tensorial quantities needed by the evalInt method.
|
||||
//! \param[in] X Cartesian coordinates of current integration point
|
||||
|
||||
118
Apps/FiniteDefElasticity/NeoHookeMaterial.C
Normal file
118
Apps/FiniteDefElasticity/NeoHookeMaterial.C
Normal file
@@ -0,0 +1,118 @@
|
||||
// $Id$
|
||||
//==============================================================================
|
||||
//!
|
||||
//! \file NeoHookeMaterial.C
|
||||
//!
|
||||
//! \date Mar 08 2011
|
||||
//!
|
||||
//! \author Knut Morten Okstad / SINTEF
|
||||
//!
|
||||
//! \brief Neo-Hookean hyperelastic material model.
|
||||
//!
|
||||
//==============================================================================
|
||||
|
||||
#include "NeoHookeMaterial.h"
|
||||
#include "Tensor.h"
|
||||
|
||||
#ifdef USE_FTNMAT
|
||||
extern "C" {
|
||||
//! \brief Interface to 2D nonlinear material routines (FORTRAN-77 code).
|
||||
void cons2d_(const int& ipsw, const int& iter, const int& iwr,
|
||||
const int& lfirst, const int& mTYP, const int& mVER,
|
||||
const int& nHV, const int& nTM, const double& detF,
|
||||
const double* F, const double* pMAT, double* HV, double& Engy,
|
||||
const double* Sig, double* Cst, int& ierr);
|
||||
//! \brief Interface to 3D nonlinear material routines (FORTRAN-77 code).
|
||||
void cons3d_(const int& ipsw, const int& iter, const int& iwr,
|
||||
const int& lfirst, const int& mTYP, const int& mVER,
|
||||
const int& nHV, const int& nTM, const double& detF,
|
||||
const double* F, const double* pMAT, double* HV, double& Engy,
|
||||
const double* Sig, double* Cst, int& ierr);
|
||||
}
|
||||
#ifndef INT_DEBUG
|
||||
#define INT_DEBUG 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
NeoHookeMaterial::NeoHookeMaterial () : LinIsotropic(false)
|
||||
{
|
||||
mTYP = 10;
|
||||
mVER = 0;
|
||||
pmat[0] = Emod;
|
||||
pmat[1] = nu;
|
||||
}
|
||||
|
||||
|
||||
NeoHookeMaterial::NeoHookeMaterial (double E, double v, double d, int ver)
|
||||
: LinIsotropic(E,v,d,false)
|
||||
{
|
||||
mTYP = 10;
|
||||
mVER = ver;
|
||||
pmat[0] = Emod;
|
||||
pmat[1] = nu;
|
||||
if (nu > 0.5)
|
||||
{
|
||||
mTYP = -10; // Assume Lame' parameters (kappa and mu are specified)
|
||||
double kappa = Emod;
|
||||
double mu = nu;
|
||||
// Calculate Young's modulus and Poisson's ratio
|
||||
Emod = 9.0*kappa*mu/(3.0*kappa + mu);
|
||||
nu = (1.5*kappa - mu)/(3.0*kappa + mu);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void NeoHookeMaterial::print (std::ostream& os) const
|
||||
{
|
||||
this->LinIsotropic::print(os);
|
||||
std::cout <<"NeoHookeMaterial: mVER = "<< mVER << std::endl;
|
||||
}
|
||||
|
||||
|
||||
bool NeoHookeMaterial::evaluate (Matrix& C, SymmTensor& sigma, double& U,
|
||||
const Vec3& X, const Tensor& F,
|
||||
const SymmTensor&, char iop,
|
||||
const TimeDomain*) const
|
||||
{
|
||||
double J = F.det();
|
||||
if (J == 0.0)
|
||||
{
|
||||
std::cerr <<" *** NeoHookeMaterial::evaluate: "
|
||||
<<" Singular/zero deformation gradient\n"<< F;
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t ndim = F.dim();
|
||||
size_t ncmp = ndim*(ndim+1)/2;
|
||||
C.resize(ncmp,ncmp);
|
||||
int ipsw = INT_DEBUG > 1 ? 9 : 0;
|
||||
int ierr = 0;
|
||||
#ifdef USE_FTNMAT
|
||||
// Invoke the FORTRAN routine for Neo-Hookean hyperelastic material models.
|
||||
if (ndim == 2)
|
||||
cons2d_(ipsw,0,6,0,mTYP,mVER,0,3,J,F.ptr(),pmat,
|
||||
&U,U,sigma.ptr(),C.ptr(),ierr);
|
||||
else
|
||||
cons3d_(ipsw,0,6,0,mTYP,mVER,0,6,J,F.ptr(),pmat,
|
||||
&U,U,sigma.ptr(),C.ptr(),ierr);
|
||||
#endif
|
||||
|
||||
if (iop == 2)
|
||||
{
|
||||
// Transform to 2nd Piola-Kirchhoff stresses,
|
||||
// via pull-back to reference configuration
|
||||
Tensor Fi(F);
|
||||
Fi.inverse();
|
||||
sigma.transform(Fi); // sigma = F^-1 * sigma * F^-t
|
||||
sigma *= J;
|
||||
}
|
||||
|
||||
#if INT_DEBUG > 0
|
||||
if (iop > 0)
|
||||
std::cout <<"NeoHookeMaterial::sigma =\n"<< sigma;
|
||||
std::cout <<"NeoHookeMaterial::C ="<< C;
|
||||
#endif
|
||||
|
||||
return ierr == 0;
|
||||
}
|
||||
56
Apps/FiniteDefElasticity/NeoHookeMaterial.h
Normal file
56
Apps/FiniteDefElasticity/NeoHookeMaterial.h
Normal file
@@ -0,0 +1,56 @@
|
||||
// $Id$
|
||||
//==============================================================================
|
||||
//!
|
||||
//! \file NeoHookeMaterial.h
|
||||
//!
|
||||
//! \date Mar 08 2011
|
||||
//!
|
||||
//! \author Knut Morten Okstad / SINTEF
|
||||
//!
|
||||
//! \brief Neo-Hookean hyperelastic material model.
|
||||
//!
|
||||
//==============================================================================
|
||||
|
||||
#ifndef _NEO_HOOKE_MATERIAL_H
|
||||
#define _NEO_HOOKE_MATERIAL_H
|
||||
|
||||
#include "LinIsotropic.h"
|
||||
|
||||
|
||||
/*!
|
||||
\brief Class representing a Neo-Hookean hyperelastic material model.
|
||||
*/
|
||||
|
||||
class NeoHookeMaterial : public LinIsotropic
|
||||
{
|
||||
public:
|
||||
//! \brief Default constructor.
|
||||
NeoHookeMaterial();
|
||||
//! \brief Constructor initializing the material parameters.
|
||||
NeoHookeMaterial(double E, double v = 0.0, double density = 0.0, int ver = 0);
|
||||
//! \brief Empty destructor.
|
||||
virtual ~NeoHookeMaterial() {}
|
||||
|
||||
//! \brief Prints out material parameters to the given output stream.
|
||||
virtual void print(std::ostream&) const;
|
||||
|
||||
//! \brief Evaluates the constitutive relation at an integration point.
|
||||
//! \param[out] C Constitutive matrix at current point
|
||||
//! \param[out] sigma Stress tensor at current point
|
||||
//! \param[out] U Strain energy density
|
||||
//! \param[in] F Deformation gradient at current point
|
||||
//! \param[in] iop Calculation option;
|
||||
//! 0 : Calculate the consitutive matrix only,
|
||||
//! 1 : Cauchy stresses and the tangent constitutive matrix,
|
||||
//! 2 : 2nd Piola-Kirchhoff stresses and the tangent constitutive matrix.
|
||||
virtual bool evaluate(Matrix& C, SymmTensor& sigma, double& U,
|
||||
const Vec3&, const Tensor& F, const SymmTensor&,
|
||||
char iop = 1, const TimeDomain* = 0) const;
|
||||
|
||||
private:
|
||||
int mTYP; //!< Material type
|
||||
int mVER; //!< Material version
|
||||
double pmat[2]; //!< Material properties
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -12,6 +12,7 @@
|
||||
//==============================================================================
|
||||
|
||||
#include "NonlinearElasticity.h"
|
||||
#include "MaterialBase.h"
|
||||
#include "Utilities.h"
|
||||
#include "Profiler.h"
|
||||
|
||||
@@ -51,8 +52,8 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
NonlinearElasticity::NonlinearElasticity (unsigned short int n, bool ps)
|
||||
: NonlinearElasticityTL(n,ps), E(n)
|
||||
NonlinearElasticity::NonlinearElasticity (unsigned short int n)
|
||||
: NonlinearElasticityTL(n), E(n)
|
||||
{
|
||||
fullCmat = false;
|
||||
}
|
||||
@@ -80,14 +81,15 @@ bool NonlinearElasticity::evalInt (LocalIntegral*& elmInt, double detJW,
|
||||
PROFILE3("NonlinearEl::evalInt");
|
||||
|
||||
// Evaluate the kinematic quantities, F and E, at this point
|
||||
if (!this->kinematics(dNdX,E))
|
||||
Tensor F(nsd);
|
||||
if (!this->kinematics(dNdX,F,E))
|
||||
return false;
|
||||
|
||||
// Evaluate current tangent at this point, that is
|
||||
// the incremental constitutive matrix, Cmat, and
|
||||
// the 2nd Piola-Kirchhoff stress tensor, S
|
||||
static SymmTensor S(nsd);
|
||||
if (!this->formTangent(Cmat,S,X))
|
||||
SymmTensor S(nsd);
|
||||
if (!this->formTangent(Cmat,S,X,F))
|
||||
return false;
|
||||
|
||||
bool haveStrains = !E.isZero(1.0e-16);
|
||||
@@ -189,7 +191,7 @@ bool NonlinearElasticity::evalSol (Vector& s, const Vector&,
|
||||
}
|
||||
|
||||
// Evaluate the stress state at this point
|
||||
static SymmTensor Sigma(nsd);
|
||||
SymmTensor Sigma(nsd);
|
||||
if (!this->formStressTensor(dNdX,X,Sigma))
|
||||
return false;
|
||||
|
||||
@@ -207,7 +209,7 @@ bool NonlinearElasticity::evalSol (Vector& s,
|
||||
{
|
||||
PROFILE3("NonlinearEl::evalSol");
|
||||
|
||||
static SymmTensor Sigma(nsd);
|
||||
SymmTensor Sigma(nsd);
|
||||
if (!this->formStressTensor(dNdX,X,Sigma))
|
||||
return false;
|
||||
|
||||
@@ -227,24 +229,19 @@ bool NonlinearElasticity::formStressTensor (const Matrix& dNdX, const Vec3& X,
|
||||
}
|
||||
|
||||
// Evaluate the kinematic quantities, F and E, at this point
|
||||
if (!this->kinematics(dNdX,E))
|
||||
Tensor F(nsd);
|
||||
if (!this->kinematics(dNdX,F,E))
|
||||
return false;
|
||||
|
||||
// Evaluate the constitutive matrix, C, at this point
|
||||
if (!this->formCmatrix(Cmat,X))
|
||||
return false;
|
||||
|
||||
return Cmat.multiply(E,S); // S = C*E
|
||||
// Evaluate the stress tensor, S, at this point
|
||||
double U;
|
||||
return material->evaluate(Cmat,S,U,X,F,E);
|
||||
}
|
||||
|
||||
|
||||
bool NonlinearElasticity::formTangent (Matrix& Ctan, SymmTensor& S,
|
||||
const Vec3& X) const
|
||||
const Vec3& X, const Tensor& F) const
|
||||
{
|
||||
if (!this->formCmatrix(Ctan,X))
|
||||
return false;
|
||||
else if (eV && !eV->empty())
|
||||
return Ctan.multiply(E,S); // S = C*E
|
||||
else
|
||||
return true; // Initial state (no stresses)
|
||||
double U;
|
||||
return material->evaluate(Ctan,S,U,X,F,E,!E.isZero());
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// $Id: NonlinearElasticity.h,v 1.2 2011-02-08 09:06:02 kmo Exp $
|
||||
// $Id$
|
||||
//==============================================================================
|
||||
//!
|
||||
//! \file NonlinearElasticity.h
|
||||
@@ -36,8 +36,7 @@ class NonlinearElasticity : public NonlinearElasticityTL
|
||||
public:
|
||||
//! \brief The default constructor invokes the parent class constructor only.
|
||||
//! \param[in] n Number of spatial dimensions
|
||||
//! \param[in] ps If \e true, assume plane stress in 2D
|
||||
NonlinearElasticity(unsigned short int n = 3, bool ps = true);
|
||||
NonlinearElasticity(unsigned short int n = 3);
|
||||
//! \brief Empty destructor.
|
||||
virtual ~NonlinearElasticity() {}
|
||||
|
||||
@@ -76,10 +75,12 @@ public:
|
||||
|
||||
protected:
|
||||
//! \brief Forms tangential tensorial quantities needed by the evalInt method.
|
||||
//! \param[in] X Cartesian coordinates of current integration point
|
||||
//! \param[out] Ctan Tangential constitutive tensor at current point
|
||||
//! \param[out] S 2nd Piola-Kirchhoff stress tensor at current point
|
||||
virtual bool formTangent(Matrix& Ctan, SymmTensor& S, const Vec3& X) const;
|
||||
//! \param[in] X Cartesian coordinates of current integration point
|
||||
//! \param[in] F Deformation gradient at current integration point
|
||||
virtual bool formTangent(Matrix& Ctan, SymmTensor& S,
|
||||
const Vec3& X, const Tensor& F) const;
|
||||
|
||||
//! \brief Forms the 2nd Piola-Kirchhoff stress tensor.
|
||||
//! \param[in] dNdX Basis function gradients at current integration point
|
||||
|
||||
@@ -12,13 +12,14 @@
|
||||
//==============================================================================
|
||||
|
||||
#include "NonlinearElasticity.h"
|
||||
#include "MaterialBase.h"
|
||||
#include "ElmMats.h"
|
||||
#include "Tensor.h"
|
||||
#include "Vec3Oper.h"
|
||||
|
||||
|
||||
NonlinearElasticityTL::NonlinearElasticityTL (unsigned short int n, bool ps)
|
||||
: Elasticity(n,ps)
|
||||
NonlinearElasticityTL::NonlinearElasticityTL (unsigned short int n)
|
||||
: Elasticity(n)
|
||||
{
|
||||
// Only the current solution is needed
|
||||
primsol.resize(1);
|
||||
@@ -85,17 +86,20 @@ bool NonlinearElasticityTL::evalInt (LocalIntegral*& elmInt, double detJW,
|
||||
const Vec3& X) const
|
||||
{
|
||||
// Evaluate the deformation gradient, F, and the Green-Lagrange strains, E,
|
||||
// and compute the nonlinear strain-displacement matrix B from dNdX and F
|
||||
// and compute the nonlinear strain-displacement matrix, B, from dNdX and F
|
||||
Tensor F(nsd);
|
||||
SymmTensor E(nsd), S(nsd);
|
||||
if (!this->kinematics(dNdX,E))
|
||||
if (!this->kinematics(dNdX,F,E))
|
||||
return false;
|
||||
|
||||
// Evaluate the constitutive relation
|
||||
double U = 0.0;
|
||||
bool lHaveStrains = !E.isZero();
|
||||
if (eKm || eKg || iS)
|
||||
if (!this->constitutive(Cmat,S,U,E,X, (eKg || iS) && lHaveStrains))
|
||||
{
|
||||
double U;
|
||||
if (!material->evaluate(Cmat,S,U,X,F,E, (eKg || iS) && lHaveStrains))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (eKm)
|
||||
{
|
||||
@@ -156,8 +160,9 @@ bool NonlinearElasticityTL::evalBou (LocalIntegral*& elmInt, double detJW,
|
||||
if (tracFld->isNormalPressure())
|
||||
{
|
||||
// Compute the deformation gradient, F
|
||||
Tensor F(nsd);
|
||||
SymmTensor dummy(0);
|
||||
if (!this->kinematics(dNdX,dummy)) return false;
|
||||
if (!this->kinematics(dNdX,F,dummy)) return false;
|
||||
|
||||
// Compute its inverse and determinant, J
|
||||
double J = F.inverse();
|
||||
@@ -182,13 +187,14 @@ bool NonlinearElasticityTL::evalBou (LocalIntegral*& elmInt, double detJW,
|
||||
}
|
||||
|
||||
|
||||
bool NonlinearElasticityTL::kinematics (const Matrix& dNdX, SymmTensor& E) const
|
||||
bool NonlinearElasticityTL::kinematics (const Matrix& dNdX,
|
||||
Tensor& F, SymmTensor& E) const
|
||||
{
|
||||
if (!eV || eV->empty())
|
||||
{
|
||||
// Initial state, unit deformation gradient and linear B-matrix
|
||||
F.diag(1.0,nsd);
|
||||
return this->Elasticity::kinematics(dNdX,E);
|
||||
F = 1.0;
|
||||
return this->Elasticity::kinematics(dNdX,F,E);
|
||||
}
|
||||
|
||||
const size_t nenod = dNdX.rows();
|
||||
@@ -206,7 +212,10 @@ bool NonlinearElasticityTL::kinematics (const Matrix& dNdX, SymmTensor& E) const
|
||||
// Notice that the matrix multiplication method used here treats the
|
||||
// element displacement vector, *eV, as a matrix whose number of columns
|
||||
// equals the number of rows in the matrix dNdX.
|
||||
if (!F.multiplyMat(*eV,dNdX)) // F = Grad{u} = eV*dNdX
|
||||
Matrix dUdX;
|
||||
if (dUdX.multiplyMat(*eV,dNdX)) // dUdX = Grad{u} = eV*dNd
|
||||
F = dUdX;
|
||||
else
|
||||
return false;
|
||||
|
||||
unsigned short int i, j, k;
|
||||
@@ -224,11 +233,10 @@ bool NonlinearElasticityTL::kinematics (const Matrix& dNdX, SymmTensor& E) const
|
||||
}
|
||||
|
||||
// Add the unit tensor to F to form the deformation gradient
|
||||
for (i = 1; i <= nsd; i++)
|
||||
F(i,i) += 1.0;
|
||||
F += 1.0;
|
||||
|
||||
#ifdef INT_DEBUG
|
||||
std::cout <<"NonlinearElasticityTL::F ="<< F;
|
||||
std::cout <<"NonlinearElasticityTL::F =\n"<< F;
|
||||
#endif
|
||||
|
||||
if (!formB || E.dim() < nsd) return true;
|
||||
|
||||
@@ -31,8 +31,7 @@ class NonlinearElasticityTL : public Elasticity
|
||||
public:
|
||||
//! \brief The default constructor invokes the parent class constructor only.
|
||||
//! \param[in] n Number of spatial dimensions
|
||||
//! \param[in] ps If \e true, assume plane stress in 2D
|
||||
NonlinearElasticityTL(unsigned short int n = 3, bool ps = true);
|
||||
NonlinearElasticityTL(unsigned short int n = 3);
|
||||
//! \brief Empty destructor.
|
||||
virtual ~NonlinearElasticityTL() {}
|
||||
|
||||
@@ -70,17 +69,17 @@ public:
|
||||
protected:
|
||||
//! \brief Calculates some kinematic quantities at current point.
|
||||
//! \param[in] dNdX Basis function gradients at current point
|
||||
//! \param[in] F Deformation gradient at current point
|
||||
//! \param[out] E Green-Lagrange strain tensor at current point
|
||||
//!
|
||||
//! \details The deformation gradient \b F and the nonlinear
|
||||
//! strain-displacement matrix \b B are established. The latter matrix
|
||||
//! is stored in the mutable class member \a Bmat of the parent class.
|
||||
//! The B-matrix is formed only when the variable \a formB is true.
|
||||
virtual bool kinematics(const Matrix& dNdX, SymmTensor& E) const;
|
||||
virtual bool kinematics(const Matrix& dNdX, Tensor& F, SymmTensor& E) const;
|
||||
|
||||
protected:
|
||||
bool formB; //!< Flag determining whether we need to form the B-matrix
|
||||
mutable Matrix F; //!< Deformation gradient
|
||||
bool formB; //!< Flag determining whether we need to form the B-matrix
|
||||
mutable Matrix CB; //!< Result of the matrix-matrix product C*B
|
||||
};
|
||||
|
||||
|
||||
@@ -12,40 +12,16 @@
|
||||
//==============================================================================
|
||||
|
||||
#include "NonlinearElasticityUL.h"
|
||||
#include "MaterialBase.h"
|
||||
#include "ElmMats.h"
|
||||
#include "ElmNorm.h"
|
||||
#include "Tensor.h"
|
||||
#include "Vec3Oper.h"
|
||||
|
||||
#ifdef USE_FTNMAT
|
||||
extern "C" {
|
||||
//! \brief Interface to 2D nonlinear material routines (FORTRAN-77 code).
|
||||
void cons2d_(const int& ipsw, const int& iter, const int& iwr,
|
||||
const int& lfirst, const int& mTYP, const int& mVER,
|
||||
const int& nHV, const int& nTM, const double& detF,
|
||||
const double* F, const double* pMAT, double* HV, double& Engy,
|
||||
const double* Sig, double* Cst, int& ierr);
|
||||
//! \brief Interface to 3D nonlinear material routines (FORTRAN-77 code).
|
||||
void cons3d_(const int& ipsw, const int& iter, const int& iwr,
|
||||
const int& lfirst, const int& mTYP, const int& mVER,
|
||||
const int& nHV, const int& nTM, const double& detF,
|
||||
const double* F, const double* pMAT, double* HV, double& Engy,
|
||||
const double* Sig, double* Cst, int& ierr);
|
||||
}
|
||||
#ifndef INT_DEBUG
|
||||
#define INT_DEBUG 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
NonlinearElasticityUL::NonlinearElasticityUL (unsigned short int n,
|
||||
bool ps, int mver, char lop)
|
||||
: Elasticity(n,ps)
|
||||
NonlinearElasticityUL::NonlinearElasticityUL (unsigned short int n, char lop)
|
||||
: Elasticity(n)
|
||||
{
|
||||
mVER = -1;
|
||||
#ifdef USE_FTNMAT
|
||||
if (n == 3 || (n == 2 && !ps)) mVER = mver;
|
||||
#endif
|
||||
loadOp = lop;
|
||||
|
||||
// Only the current solution is needed
|
||||
@@ -55,30 +31,9 @@ NonlinearElasticityUL::NonlinearElasticityUL (unsigned short int n,
|
||||
|
||||
void NonlinearElasticityUL::print (std::ostream& os) const
|
||||
{
|
||||
this->Elasticity::print(os);
|
||||
std::cout <<"NonlinearElasticityUL: Updated Lagrangian formulation";
|
||||
if (mVER >= 0) std::cout <<", mVER="<< mVER;
|
||||
if (mVER >= 1) std::cout <<" (Neo-Hooke)";
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
|
||||
void NonlinearElasticityUL::setMaterial (double Young, double Poiss,
|
||||
double Density)
|
||||
{
|
||||
mTYP = 10;
|
||||
pmat[0] = Young;
|
||||
pmat[1] = Poiss;
|
||||
if (Poiss > 0.5)
|
||||
{
|
||||
mTYP *= -1; // Assume Lame' parameters (kappa and mu are specified)
|
||||
double kappa = Young;
|
||||
double mu = Poiss;
|
||||
// Calculate Young's modulus and Poisson's ratio
|
||||
Young = 9.0*kappa*mu/(3.0*kappa + mu);
|
||||
Poiss = (1.5*kappa - mu)/(3.0*kappa + mu);
|
||||
}
|
||||
this->Elasticity::setMaterial(Young,Poiss,Density);
|
||||
material->print(os);
|
||||
std::cout <<"NonlinearElasticityUL: Updated Lagrangian formulation"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,6 +41,7 @@ void NonlinearElasticityUL::setMode (SIM::SolutionMode mode)
|
||||
{
|
||||
if (!myMats) return;
|
||||
|
||||
size_t nvec = 1 + primsol.size();
|
||||
myMats->rhsOnly = false;
|
||||
eM = eKm = eKg = 0;
|
||||
iS = eS = eV = 0;
|
||||
@@ -93,13 +49,13 @@ void NonlinearElasticityUL::setMode (SIM::SolutionMode mode)
|
||||
switch (mode)
|
||||
{
|
||||
case SIM::STATIC:
|
||||
myMats->resize(1,2);
|
||||
myMats->resize(1,nvec);
|
||||
eKm = &myMats->A[0];
|
||||
eKg = &myMats->A[0];
|
||||
break;
|
||||
|
||||
case SIM::DYNAMIC:
|
||||
myMats->resize(2,2);
|
||||
myMats->resize(2,nvec);
|
||||
eKm = &myMats->A[0];
|
||||
eKg = &myMats->A[0];
|
||||
eM = &myMats->A[1];
|
||||
@@ -107,9 +63,9 @@ void NonlinearElasticityUL::setMode (SIM::SolutionMode mode)
|
||||
|
||||
case SIM::RHS_ONLY:
|
||||
if (myMats->A.empty())
|
||||
myMats->resize(1,2);
|
||||
myMats->resize(1,nvec);
|
||||
else
|
||||
myMats->b.resize(2);
|
||||
myMats->b.resize(nvec);
|
||||
eKm = &myMats->A[0];
|
||||
eKg = &myMats->A[0];
|
||||
myMats->rhsOnly = true;
|
||||
@@ -132,18 +88,18 @@ bool NonlinearElasticityUL::evalInt (LocalIntegral*& elmInt, double detJW,
|
||||
const Vector& N, const Matrix& dNdX,
|
||||
const Vec3& X) const
|
||||
{
|
||||
elmInt = myMats;
|
||||
|
||||
// Evaluate the deformation gradient, F, and the Green-Lagrange strains, E
|
||||
Tensor F(nsd);
|
||||
SymmTensor E(nsd);
|
||||
if (!this->kinematics(dNdX,E))
|
||||
if (!this->kinematics(dNdX,F,E))
|
||||
return false;
|
||||
|
||||
bool lHaveStrains = !E.isZero();
|
||||
if (lHaveStrains)
|
||||
{
|
||||
// Invert the deformation gradient ==> Fi
|
||||
Matrix Fi(F);
|
||||
Matrix Fi(nsd,nsd);
|
||||
Fi.fill(F.ptr());
|
||||
double J = Fi.inverse();
|
||||
if (J == 0.0) return false;
|
||||
|
||||
@@ -156,7 +112,7 @@ bool NonlinearElasticityUL::evalInt (LocalIntegral*& elmInt, double detJW,
|
||||
dNdx.multiply(dNdX,Fi); // dNdx = dNdX * F^-1
|
||||
// Compute the small-deformation strain-displacement matrix B from dNdx
|
||||
if (!this->formBmatrix(dNdx)) return false;
|
||||
#if INT_DEBUG > 0
|
||||
#ifdef INT_DEBUG
|
||||
std::cout <<"NonlinearElasticityUL::dNdx ="<< dNdx;
|
||||
std::cout <<"NonlinearElasticityUL::B ="<< Bmat;
|
||||
#endif
|
||||
@@ -168,10 +124,12 @@ bool NonlinearElasticityUL::evalInt (LocalIntegral*& elmInt, double detJW,
|
||||
|
||||
// Evaluate the constitutive relation
|
||||
SymmTensor sigma(nsd);
|
||||
double U = 0.0;
|
||||
if (eKm || eKg || iS)
|
||||
if (!this->constitutive(Cmat,sigma,U,E,X, (eKg || iS) && lHaveStrains))
|
||||
{
|
||||
double U = 0.0;
|
||||
if (!material->evaluate(Cmat,sigma,U,X,F,E, (eKg || iS) && lHaveStrains))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (eKm)
|
||||
{
|
||||
@@ -200,7 +158,7 @@ bool NonlinearElasticityUL::evalInt (LocalIntegral*& elmInt, double detJW,
|
||||
// Integrate the load vector due to gravitation and other body forces
|
||||
this->formBodyForce(*eS,N,X,detJW);
|
||||
|
||||
return true;
|
||||
return this->getIntegralResult(elmInt);
|
||||
}
|
||||
|
||||
|
||||
@@ -208,7 +166,6 @@ bool NonlinearElasticityUL::evalBou (LocalIntegral*& elmInt, double detJW,
|
||||
const Vector& N, const Matrix& dNdX,
|
||||
const Vec3& X, const Vec3& normal) const
|
||||
{
|
||||
elmInt = myMats;
|
||||
if (!tracFld)
|
||||
{
|
||||
std::cerr <<" *** NonlinearElasticityUL::evalBou: No tractions."
|
||||
@@ -232,7 +189,8 @@ bool NonlinearElasticityUL::evalBou (LocalIntegral*& elmInt, double detJW,
|
||||
if (loadOp == 1)
|
||||
{
|
||||
// Compute the deformation gradient, F
|
||||
if (!this->formDefGradient(dNdX)) return false;
|
||||
Tensor F(nsd);
|
||||
if (!this->formDefGradient(dNdX,F)) return false;
|
||||
|
||||
// Check for with-rotated pressure load
|
||||
if (tracFld->isNormalPressure())
|
||||
@@ -260,23 +218,25 @@ bool NonlinearElasticityUL::evalBou (LocalIntegral*& elmInt, double detJW,
|
||||
for (i = 1; i <= nsd; i++)
|
||||
ES(nsd*(a-1)+i) += T[i-1]*N(a)*detJW;
|
||||
|
||||
return true;
|
||||
return this->getIntegralResult(elmInt);
|
||||
}
|
||||
|
||||
|
||||
bool NonlinearElasticityUL::formDefGradient (const Matrix& dNdX) const
|
||||
bool NonlinearElasticityUL::formDefGradient (const Matrix& dNdX,
|
||||
Tensor& F) const
|
||||
{
|
||||
static SymmTensor dummy(0);
|
||||
return this->kinematics(dNdX,dummy);
|
||||
SymmTensor dummy(0);
|
||||
return this->kinematics(dNdX,F,dummy);
|
||||
}
|
||||
|
||||
|
||||
bool NonlinearElasticityUL::kinematics (const Matrix& dNdX, SymmTensor& E) const
|
||||
bool NonlinearElasticityUL::kinematics (const Matrix& dNdX,
|
||||
Tensor& F, SymmTensor& E) const
|
||||
{
|
||||
if (!eV || eV->empty())
|
||||
{
|
||||
// Initial state, unit deformation gradient and zero strains
|
||||
F.diag(1.0,nsd);
|
||||
F = 1.0;
|
||||
E.zero();
|
||||
return true;
|
||||
}
|
||||
@@ -295,7 +255,10 @@ bool NonlinearElasticityUL::kinematics (const Matrix& dNdX, SymmTensor& E) const
|
||||
// Notice that the matrix multiplication method used here treats the
|
||||
// element displacement vector, *eV, as a matrix whose number of columns
|
||||
// equals the number of rows in the matrix dNdX.
|
||||
if (!F.multiplyMat(*eV,dNdX)) // F = Grad{u} = eV*dNdX
|
||||
Matrix dUdX;
|
||||
if (dUdX.multiplyMat(*eV,dNdX)) // dUdX = Grad{u} = eV*dNdX
|
||||
F = dUdX;
|
||||
else
|
||||
return false;
|
||||
|
||||
unsigned short int i, j, k;
|
||||
@@ -313,118 +276,11 @@ bool NonlinearElasticityUL::kinematics (const Matrix& dNdX, SymmTensor& E) const
|
||||
}
|
||||
|
||||
// Add the unit tensor to F to form the deformation gradient
|
||||
for (i = 1; i <= nsd; i++)
|
||||
F(i,i) += 1.0;
|
||||
F += 1.0;
|
||||
|
||||
#if INT_DEBUG > 0
|
||||
#ifdef INT_DEBUG
|
||||
std::cout <<"NonlinearElasticityUL::eV ="<< *eV;
|
||||
std::cout <<"NonlinearElasticityUL::F ="<< F;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NonlinearElasticityUL::constitutive (Matrix& C, SymmTensor& sigma,
|
||||
double& U, const SymmTensor& eps,
|
||||
const Vec3& X,
|
||||
char calcStress) const
|
||||
{
|
||||
double J = F.det();
|
||||
if (J == 0.0)
|
||||
{
|
||||
std::cerr <<" *** NonlinearElasticityUL::constitutive: "
|
||||
<<" Singular/zero deformation gradient"<< F;
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t ndim = F.rows();
|
||||
#ifdef USE_FTNMAT
|
||||
if (mVER >= 0)
|
||||
{
|
||||
// Invoke the FORTRAN routine for constitutive relations.
|
||||
// This also includes the Neo-Hookean hyperelastic material models.
|
||||
size_t ncmp = ndim*(ndim+1)/2;
|
||||
C.resize(ncmp,ncmp);
|
||||
int ipsw = INT_DEBUG > 1 ? 9 : 0;
|
||||
int ierr = 0;
|
||||
if (ndim == 2)
|
||||
cons2d_(ipsw,0,6,0,mTYP,mVER,0,3,J,F.ptr(),pmat,
|
||||
&U,U,sigma.ptr(),C.ptr(),ierr);
|
||||
else
|
||||
cons3d_(ipsw,0,6,0,mTYP,mVER,0,6,J,F.ptr(),pmat,
|
||||
&U,U,sigma.ptr(),C.ptr(),ierr);
|
||||
if (calcStress == 2)
|
||||
{
|
||||
// Transform to 2nd Piola-Kirchhoff stresses,
|
||||
// via pull-back to reference configuration
|
||||
F.inverse();
|
||||
Tensor Fi(ndim);
|
||||
sigma.transform(Fi=F); // sigma = F^-1 * sigma * F^-t
|
||||
sigma *= J;
|
||||
}
|
||||
#if INT_DEBUG > 0
|
||||
if (calcStress)
|
||||
std::cout <<"NonlinearElasticityUL::sigma =\n"<< sigma;
|
||||
std::cout <<"NonlinearElasticityUL::C ="<< C;
|
||||
#endif
|
||||
return ierr == 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// We are only doing pure isotrophic linear elastic material in this method.
|
||||
// Evaluate the constitutive matrix at this point, but first reset nsd to ndim
|
||||
// since it is used to set the dimension on C.
|
||||
unsigned short int tmp = nsd;
|
||||
const_cast<NonlinearElasticityUL*>(this)->nsd = ndim;
|
||||
if (!this->formCmatrix(C,X)) return false;
|
||||
const_cast<NonlinearElasticityUL*>(this)->nsd = tmp;
|
||||
|
||||
if (calcStress)
|
||||
// Evaluate the symmetric stress tensor
|
||||
C.multiply(eps,sigma); // sigma = C*eps
|
||||
|
||||
if (calcStress == 1)
|
||||
{
|
||||
// Push-forward the stress tensor to current configuration
|
||||
Tensor dUdX(ndim);
|
||||
sigma.transform(dUdX=F); // sigma = F * sigma * F^t
|
||||
sigma *= 1.0/J;
|
||||
#if INT_DEBUG > 0
|
||||
std::cout <<"NonlinearElasticityUL::sigma =\n"<< sigma;
|
||||
#endif
|
||||
}
|
||||
else if (calcStress == 2)
|
||||
return true;
|
||||
|
||||
// Push-forward the constitutive matrix to current configuration
|
||||
|
||||
size_t i, j, k, l, m = C.rows();
|
||||
Matrix T(m,m), Ctmp;
|
||||
|
||||
for (i = 1; i <= ndim; i++)
|
||||
{
|
||||
for (j = 1; j <= ndim; j++)
|
||||
T(i,j) = F(j,i)*F(j,i);
|
||||
for (j = ndim+1, k = 1; j <= m; j++, k++)
|
||||
T(i,j) = 0.5*(F(k,i)*F(k%3+1,i) + F(k%3+1,i)*F(k,i));
|
||||
}
|
||||
|
||||
for (i = ndim+1, k = 1; i <= m; i++, k++)
|
||||
{
|
||||
for (j = 1; j <= ndim; j++)
|
||||
T(i,j) = F(j,k)*F(j,k%3+1) + F(j,k%3+1)*F(j,k);
|
||||
for (j = ndim+1, l = 1; j <= m; j++, l++)
|
||||
T(i,j) = 0.5*(F(l,k)*F(l%3+1,k%3+1) + F(l%3+1,k)*F(l,k%3+1) +
|
||||
F(l,k%3+1)*F(l%3+1,k) + F(l%3+1,k%3+1)*F(l,k));
|
||||
}
|
||||
|
||||
// C = 1/J * T^t * C * T
|
||||
Ctmp.multiply(C,T);
|
||||
C.multiply(T,Ctmp,true);
|
||||
C *= 1.0/J;
|
||||
#if INT_DEBUG > 0
|
||||
std::cout <<"NonlinearElasticityUL::C ="<< C;
|
||||
std::cout <<"NonlinearElasticityUL::F =\n"<< F;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
@@ -446,15 +302,16 @@ bool ElasticityNormUL::evalInt (LocalIntegral*& elmInt, double detJW,
|
||||
NonlinearElasticityUL* ulp = static_cast<NonlinearElasticityUL*>(&problem);
|
||||
|
||||
// Evaluate the deformation gradient, F, and the Green-Lagrange strains, E
|
||||
Tensor F(dNdX.cols());
|
||||
SymmTensor E(dNdX.cols());
|
||||
if (!ulp->kinematics(dNdX,E))
|
||||
if (!ulp->kinematics(dNdX,F,E))
|
||||
return false;
|
||||
|
||||
// Evaluate the 2nd Piola Kirchhoff stresses, S
|
||||
Matrix C;
|
||||
SymmTensor S(E.dim());
|
||||
double U = 0.0;
|
||||
if (!ulp->constitutive(C,S,U,E,X,2))
|
||||
if (!ulp->material->evaluate(C,S,U,X,F,E,2))
|
||||
return false;
|
||||
|
||||
if (U == 0.0)
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
#include "Elasticity.h"
|
||||
|
||||
struct TimeDomain;
|
||||
|
||||
|
||||
/*!
|
||||
\brief Class representing the integrand of the nonlinear elasticity problem.
|
||||
@@ -25,9 +27,6 @@
|
||||
strain tensor, and the method \a constitutive for calculating the tangent
|
||||
constitutive matrix and the associated stress tensor. The \a evalInt and
|
||||
\a evalBou methods are also reimplemented to account for the updated geometry.
|
||||
|
||||
This class supports isotrophic linear-elastic and neo-Hookean hyperelastic
|
||||
material laws. The material properties are assumed constant in space.
|
||||
*/
|
||||
|
||||
class NonlinearElasticityUL : public Elasticity
|
||||
@@ -35,26 +34,14 @@ class NonlinearElasticityUL : public Elasticity
|
||||
public:
|
||||
//! \brief The default constructor invokes the parent class constructor.
|
||||
//! \param[in] n Number of spatial dimensions
|
||||
//! \param[in] ps If \e true, assume plane stress in 2D
|
||||
//! \param[in] mver Material version parameter
|
||||
//! \param[in] lop Load option (0=on initial length, 1=on updated length)
|
||||
NonlinearElasticityUL(unsigned short int n = 3,
|
||||
bool ps = false, int mver = 0, char lop = 0);
|
||||
NonlinearElasticityUL(unsigned short int n = 3, char lop = 0);
|
||||
//! \brief Empty destructor.
|
||||
virtual ~NonlinearElasticityUL() {}
|
||||
|
||||
//! \brief Prints out problem definition to the given output stream.
|
||||
virtual void print(std::ostream& os) const;
|
||||
|
||||
//! \brief Defines the material properties to use.
|
||||
//! \param[in] Young Young's modulus
|
||||
//! \param[in] Poiss Poisson's ratio
|
||||
//! \param[in] Density Mass density
|
||||
//!
|
||||
//! \details If \a Poiss > 0.5, it is assumed that \a Young and \a Poiss
|
||||
//! are the Lame's parameters instead (bulk and shear moduli).
|
||||
virtual void setMaterial(double Young, double Poiss, double Density);
|
||||
|
||||
//! \brief Defines the solution mode before the element assembly is started.
|
||||
//! \param[in] mode The solution mode to use
|
||||
virtual void setMode(SIM::SolutionMode mode);
|
||||
@@ -93,40 +80,24 @@ public:
|
||||
|
||||
//! \brief Calculates some kinematic quantities at current point.
|
||||
//! \param[in] dNdX Basis function gradients at current point
|
||||
//! \param[out] F Deformation gradient at current point
|
||||
//! \param[out] E Green-Lagrange strain tensor at current point
|
||||
//!
|
||||
//! \details The deformation gradient is established and stored in
|
||||
//! the mutable class member \a F.
|
||||
virtual bool kinematics(const Matrix& dNdX, SymmTensor& E) const;
|
||||
|
||||
//! \brief Calculates the deformation gradient at current point.
|
||||
//! \param[in] dNdX Basis function gradients at current point
|
||||
bool formDefGradient(const Matrix& dNdX) const;
|
||||
|
||||
//! \brief Evaluates the constitutive relation at current point.
|
||||
//! \param[out] C Constitutive matrix at current point
|
||||
//! \param[out] sigma Stress tensor at current point
|
||||
//! \param[out] U Strain energy density
|
||||
//! \param[in] eps Strain tensor at current point
|
||||
//! \param[in] X Cartesian coordinates of current point
|
||||
//! \param[in] calcStress Stress calculation option.
|
||||
//! 0: No stress calculation, only output the C-matrix,
|
||||
//! 1: Calculate Cauchy stresses,
|
||||
//! 2: Calculate Second Piola Kirchhoff stresses.
|
||||
virtual bool constitutive(Matrix& C, SymmTensor& sigma, double& U,
|
||||
const SymmTensor& eps, const Vec3& X,
|
||||
char calcStress = 1) const;
|
||||
virtual bool kinematics(const Matrix& dNdX, Tensor& F, SymmTensor& E) const;
|
||||
|
||||
protected:
|
||||
//! \brief Calculates the deformation gradient at current point.
|
||||
//! \param[in] dNdX Basis function gradients at current point
|
||||
//! \param[out] F Deformation gradient at current point
|
||||
bool formDefGradient(const Matrix& dNdX, Tensor& F) const;
|
||||
|
||||
protected:
|
||||
mutable Matrix F; //!< Deformation gradient
|
||||
mutable Matrix dNdx; //!< Basis function gradients in current configuration
|
||||
mutable Matrix CB; //!< Result of the matrix-matrix product C*B
|
||||
|
||||
private:
|
||||
char loadOp; //!< Load option
|
||||
int mTYP; //!< Material type
|
||||
int mVER; //!< Material version
|
||||
double pmat[2]; //!< Material properties
|
||||
char loadOp; //!< Load option
|
||||
|
||||
friend class ElasticityNormUL;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
//==============================================================================
|
||||
|
||||
#include "NonlinearElasticityULMX.h"
|
||||
#include "MaterialBase.h"
|
||||
#include "ElmMats.h"
|
||||
#include "ElmNorm.h"
|
||||
#include "Utilities.h"
|
||||
@@ -39,9 +40,8 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
NonlinearElasticityULMX::NonlinearElasticityULMX (unsigned short int n,
|
||||
int mver, int pp)
|
||||
: NonlinearElasticityUL(n, false, mver < 0 ? 0 : mver)
|
||||
NonlinearElasticityULMX::NonlinearElasticityULMX (unsigned short int n, int pp)
|
||||
: NonlinearElasticityUL(n)
|
||||
{
|
||||
p = pp;
|
||||
iP = 0;
|
||||
@@ -151,7 +151,6 @@ bool NonlinearElasticityULMX::evalInt (LocalIntegral*& elmInt, double detJW,
|
||||
if (myMats->b.size() < 3) return false;
|
||||
|
||||
ItgPtData& ptData = myData[iP++];
|
||||
unsigned short int i, j;
|
||||
|
||||
#if INT_DEBUG > 0
|
||||
std::cout <<"NonlinearElasticityUL::dNdX ="<< dNdX;
|
||||
@@ -159,31 +158,25 @@ bool NonlinearElasticityULMX::evalInt (LocalIntegral*& elmInt, double detJW,
|
||||
|
||||
// Evaluate the deformation gradient, Fp, at previous configuration
|
||||
const_cast<NonlinearElasticityULMX*>(this)->eV = &myMats->b[2];
|
||||
if (this->formDefGradient(dNdX))
|
||||
for (i = 1; i <= nsd; i++)
|
||||
for (j = 1; j <= nsd; j++)
|
||||
ptData.Fp(i,j) = F(i,j);
|
||||
else
|
||||
if (!this->formDefGradient(dNdX,ptData.Fp))
|
||||
return false;
|
||||
|
||||
// Evaluate the deformation gradient, F, at current configuration
|
||||
const_cast<NonlinearElasticityULMX*>(this)->eV = &myMats->b[1];
|
||||
if (this->formDefGradient(dNdX))
|
||||
for (i = 1; i <= nsd; i++)
|
||||
for (j = 1; j <= nsd; j++)
|
||||
ptData.F(i,j) = F(i,j);
|
||||
else
|
||||
if (!this->formDefGradient(dNdX,ptData.F))
|
||||
return false;
|
||||
|
||||
if (nsd == 2) // In 2D we always assume plane strain so set F(3,3)=1
|
||||
ptData.F(3,3) = ptData.Fp(3,3) = 1.0;
|
||||
|
||||
// Invert the deformation gradient ==> Fi
|
||||
double J = F.inverse();
|
||||
Tensor Fi(nsd);
|
||||
Fi = ptData.F;
|
||||
double J = Fi.inverse();
|
||||
if (J == 0.0) return false;
|
||||
|
||||
// Push-forward the basis function gradients to current configuration
|
||||
ptData.dNdx.multiply(dNdX,F); // dNdx = dNdX * F^-1
|
||||
ptData.dNdx.multiply(dNdX,Fi); // dNdx = dNdX * F^-1
|
||||
|
||||
ptData.X.assign(X);
|
||||
ptData.detJW = detJW;
|
||||
@@ -359,7 +352,6 @@ bool NonlinearElasticityULMX::finalizeElement (LocalIntegral*& elmInt)
|
||||
Vector Sigm(nPM), Hsig;
|
||||
std::vector<SymmTensor> Sig;
|
||||
Sig.reserve(nGP);
|
||||
F.resize(3,3);
|
||||
|
||||
bool lHaveStress = false;
|
||||
for (iP = 0; iP < nGP; iP++)
|
||||
@@ -371,9 +363,8 @@ bool NonlinearElasticityULMX::finalizeElement (LocalIntegral*& elmInt)
|
||||
|
||||
// Evaluate the constitutive relation
|
||||
double U = 0.0;
|
||||
F.fill(pt.F.ptr());
|
||||
Sig.push_back(SymmTensor(3));
|
||||
if (!this->constitutive(Cmat,Sig.back(),U,Sig.back(),pt.X))
|
||||
if (!material->evaluate(Cmat,Sig.back(),U,pt.X,pt.F,Sig.back()))
|
||||
return false;
|
||||
|
||||
#ifdef USE_FTNMAT
|
||||
@@ -569,7 +560,6 @@ bool ElasticityNormULMX::finalizeElement (LocalIntegral*& elmInt)
|
||||
|
||||
Matrix C;
|
||||
SymmTensor Sig(3);
|
||||
elp.F.resize(3,3);
|
||||
|
||||
for (iP = 0; iP < nGP; iP++)
|
||||
{
|
||||
@@ -583,8 +573,7 @@ bool ElasticityNormULMX::finalizeElement (LocalIntegral*& elmInt)
|
||||
|
||||
// Compute the strain energy density
|
||||
double U = 0.0;
|
||||
elp.F.fill(pt.F.ptr());
|
||||
if (!elp.constitutive(C,Sig,U,Sig,pt.X,false))
|
||||
if (!elp.material->evaluate(C,Sig,U,pt.X,pt.F,Sig,false))
|
||||
return false;
|
||||
|
||||
// Integrate strain energy
|
||||
|
||||
@@ -42,9 +42,8 @@ class NonlinearElasticityULMX : public NonlinearElasticityUL
|
||||
public:
|
||||
//! \brief The default constructor invokes the parent class constructor.
|
||||
//! \param[in] n Number of spatial dimensions
|
||||
//! \param[in] mver Material version parameter
|
||||
//! \param[in] pp Polynomial order of the pressure/volumetric-change field
|
||||
NonlinearElasticityULMX(unsigned short int n = 3, int mver = 0, int pp = 1);
|
||||
NonlinearElasticityULMX(unsigned short int n = 3, int pp = 1);
|
||||
//! \brief Empty destructor.
|
||||
virtual ~NonlinearElasticityULMX() {}
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
//==============================================================================
|
||||
|
||||
#include "NonlinearElasticityULMixed.h"
|
||||
#include "MaterialBase.h"
|
||||
#include "ElmMats.h"
|
||||
#include "Utilities.h"
|
||||
#include "Tensor.h"
|
||||
|
||||
#ifdef USE_FTNMAT
|
||||
extern "C" {
|
||||
@@ -189,13 +189,9 @@ const Vector& NonlinearElasticityULMixed::MixedElmMats::getRHSVector () const
|
||||
}
|
||||
|
||||
|
||||
NonlinearElasticityULMixed::NonlinearElasticityULMixed (unsigned short int n,
|
||||
int mver)
|
||||
: NonlinearElasticityUL(n,false,mver)
|
||||
NonlinearElasticityULMixed::NonlinearElasticityULMixed (unsigned short int n)
|
||||
: NonlinearElasticityUL(n), Fbar(n), Dmat(7,7)
|
||||
{
|
||||
Fbar.resize(3,3);
|
||||
Dmat.resize(7,7);
|
||||
|
||||
if (myMats) delete myMats;
|
||||
myMats = new MixedElmMats();
|
||||
|
||||
@@ -302,8 +298,9 @@ bool NonlinearElasticityULMixed::evalInt (LocalIntegral*& elmInt, double detJW,
|
||||
const Vec3& X) const
|
||||
{
|
||||
// Evaluate the deformation gradient, F, and the Green-Lagrange strains, E
|
||||
Tensor F(nsd);
|
||||
SymmTensor E(nsd);
|
||||
if (!this->kinematics(dNdX1,E))
|
||||
if (!this->kinematics(dNdX1,F,E))
|
||||
return false;
|
||||
|
||||
bool lHaveStrains = !E.isZero();
|
||||
@@ -354,10 +351,9 @@ bool NonlinearElasticityULMixed::evalInt (LocalIntegral*& elmInt, double detJW,
|
||||
this->formBodyForce(*eS,N1,X,J*detJW);
|
||||
|
||||
// Evaluate the constitutive relation
|
||||
F = Fbar;
|
||||
SymmTensor Eps(3), Sig(3), Sigma(nsd);
|
||||
double U, Bpres = 0.0, Mpres = 0.0;
|
||||
if (!this->constitutive(Cmat,Sig,U,Eps=E,X,lHaveStrains))
|
||||
if (!material->evaluate(Cmat,Sig,U,X,Fbar,Eps=E,lHaveStrains))
|
||||
return false;
|
||||
|
||||
#ifdef USE_FTNMAT
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// $Id: NonlinearElasticityULMixed.h,v 1.2 2010-12-30 15:25:14 kmo Exp $
|
||||
// $Id$
|
||||
//==============================================================================
|
||||
//!
|
||||
//! \file NonlinearElasticityULMixed.h
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "NonlinearElasticityUL.h"
|
||||
#include "ElmMats.h"
|
||||
#include "Tensor.h"
|
||||
|
||||
|
||||
/*!
|
||||
@@ -44,8 +45,7 @@ class NonlinearElasticityULMixed : public NonlinearElasticityUL
|
||||
public:
|
||||
//! \brief The default constructor invokes the parent class constructor.
|
||||
//! \param[in] n Number of spatial dimensions
|
||||
//! \param[in] mver Material version parameter
|
||||
NonlinearElasticityULMixed(unsigned short int n = 3, int mver = 0);
|
||||
NonlinearElasticityULMixed(unsigned short int n = 3);
|
||||
//! \brief Empty destructor.
|
||||
virtual ~NonlinearElasticityULMixed() {}
|
||||
|
||||
@@ -101,7 +101,7 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
mutable Matrix Fbar; //!< Mixed model deformation gradient
|
||||
mutable Tensor Fbar; //!< Mixed model deformation gradient
|
||||
mutable Matrix Dmat; //!< Projected mixed constitutive matrix
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// $Id: SIMFiniteDefEl.C,v 1.3 2010-12-29 18:51:53 kmo Exp $
|
||||
// $Id$
|
||||
//==============================================================================
|
||||
//!
|
||||
//! \file SIMFiniteDefEl.C
|
||||
@@ -12,36 +12,40 @@
|
||||
//==============================================================================
|
||||
|
||||
#include "SIMFiniteDefEl.h"
|
||||
#include "LinIsotropic.h"
|
||||
#include "LinearMaterial.h"
|
||||
#include "NeoHookeMaterial.h"
|
||||
#include "NonlinearElasticityULMixed.h"
|
||||
#include "NonlinearElasticityULMX.h"
|
||||
#include "NeoHookeElasticity.h"
|
||||
#include "Utilities.h"
|
||||
#include "Property.h"
|
||||
|
||||
|
||||
SIMFiniteDefEl2D::SIMFiniteDefEl2D (int form, bool planeStress,
|
||||
const std::vector<int>& options)
|
||||
SIMFiniteDefEl2D::SIMFiniteDefEl2D (const std::vector<int>& options)
|
||||
: SIMLinEl2D(SIM::NONE)
|
||||
{
|
||||
int mVER = options.size() > 0 ? options[0] : -1; // material version
|
||||
int pOrd = options.size() > 1 ? options[1] : 0; // pressure field order
|
||||
int form = options.size() > 0 ? options[0] : 0; // problem formulation
|
||||
int pOrd = options.size() > 1 ? options[1] : 0; // pressure field order
|
||||
|
||||
switch (form)
|
||||
{
|
||||
case SIM::MIXED_QnQn1:
|
||||
nf[1] = 2; // continuous volumetric change and pressure fields
|
||||
myProblem = new NonlinearElasticityULMixed(2,mVER);
|
||||
myProblem = new NonlinearElasticityULMixed(2);
|
||||
break;
|
||||
case SIM::MIXED_QnPn1:
|
||||
// Local discontinuous volumetric change and pressure fields
|
||||
myProblem = new NonlinearElasticityULMX(2,mVER,pOrd);
|
||||
myProblem = new NonlinearElasticityULMX(2,pOrd);
|
||||
break;
|
||||
case SIM::UPDATED_LAGRANGE:
|
||||
myProblem = new NonlinearElasticityUL(2,planeStress,mVER);
|
||||
myProblem = new NonlinearElasticityUL(2);
|
||||
break;
|
||||
case SIM::TOTAL_LAGRANGE:
|
||||
myProblem = new NonlinearElasticityTL(2,planeStress);
|
||||
myProblem = new NonlinearElasticityTL(2);
|
||||
break;
|
||||
case SIM::NONLINEAR: // Old tensor-based TL-formulation
|
||||
myProblem = new NonlinearElasticity(2,planeStress);
|
||||
myProblem = new NonlinearElasticity(2);
|
||||
break;
|
||||
default:
|
||||
std::cerr <<" *** SIMFiniteDefEl2D: Unknown problem formulation "
|
||||
@@ -50,25 +54,65 @@ SIMFiniteDefEl2D::SIMFiniteDefEl2D (int form, bool planeStress,
|
||||
}
|
||||
|
||||
|
||||
SIMFiniteDefEl3D::SIMFiniteDefEl3D (bool checkRHS, int form,
|
||||
bool SIMFiniteDefEl2D::parse (char* keyWord, std::istream& is)
|
||||
{
|
||||
if (!strncasecmp(keyWord,"ISOTROPIC",9))
|
||||
{
|
||||
int nmat = atoi(keyWord+10);
|
||||
if (myPid == 0)
|
||||
std::cout <<"\nNumber of isotropic materials: "<< nmat << std::endl;
|
||||
|
||||
char* cline = 0;
|
||||
for (int i = 0; i < nmat && (cline = utl::readLine(is)); i++)
|
||||
{
|
||||
int code = atoi(strtok(cline," "));
|
||||
if (code > 0)
|
||||
this->setPropertyType(code,Property::MATERIAL,mVec.size());
|
||||
double E = atof(strtok(NULL," "));
|
||||
double nu = atof(strtok(NULL," "));
|
||||
double rho = atof(strtok(NULL," "));
|
||||
int matVer = (cline = strtok(NULL," ")) ? atoi(cline) : -1;
|
||||
if (matVer >= 0)
|
||||
mVec.push_back(new NeoHookeMaterial(E,nu,rho,matVer));
|
||||
else
|
||||
mVec.push_back(new LinearMaterial(new LinIsotropic(E,nu,rho)));
|
||||
if (myPid == 0)
|
||||
std::cout <<"\tMaterial code "<< code <<": "
|
||||
<< E <<" "<< nu <<" "<< rho <<" ("<< matVer <<")"<< std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
return this->SIMLinEl2D::parse(keyWord,is);
|
||||
|
||||
if (!mVec.empty())
|
||||
{
|
||||
Elasticity* elp = dynamic_cast<Elasticity*>(myProblem);
|
||||
if (elp) elp->setMaterial(mVec.front());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
SIMFiniteDefEl3D::SIMFiniteDefEl3D (bool checkRHS,
|
||||
const std::vector<int>& options)
|
||||
: SIMLinEl3D(checkRHS,SIM::NONE)
|
||||
{
|
||||
int mVER = options.size() > 0 ? options[0] : -1; // material version
|
||||
int pOrd = options.size() > 1 ? options[1] : 0; // pressure field order
|
||||
int form = options.size() > 0 ? options[0] : 0; // problem formulation
|
||||
int pOrd = options.size() > 1 ? options[1] : 0; // pressure field order
|
||||
|
||||
switch (form)
|
||||
{
|
||||
case SIM::MIXED_QnQn1:
|
||||
nf[1] = 2; // continuous volumetric change and pressure fields
|
||||
myProblem = new NonlinearElasticityULMixed(3,mVER);
|
||||
myProblem = new NonlinearElasticityULMixed();
|
||||
break;
|
||||
case SIM::MIXED_QnPn1:
|
||||
// Local discontinuous volumetric change and pressure fields
|
||||
myProblem = new NonlinearElasticityULMX(3,mVER,pOrd);
|
||||
myProblem = new NonlinearElasticityULMX(3,pOrd);
|
||||
break;
|
||||
case SIM::UPDATED_LAGRANGE:
|
||||
myProblem = new NonlinearElasticityUL(3,false,mVER);
|
||||
myProblem = new NonlinearElasticityUL();
|
||||
break;
|
||||
case SIM::TOTAL_LAGRANGE:
|
||||
myProblem = new NonlinearElasticityTL();
|
||||
@@ -87,3 +131,43 @@ SIMFiniteDefEl3D::SIMFiniteDefEl3D (bool checkRHS, int form,
|
||||
<< form << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool SIMFiniteDefEl3D::parse (char* keyWord, std::istream& is)
|
||||
{
|
||||
if (!strncasecmp(keyWord,"ISOTROPIC",9))
|
||||
{
|
||||
int nmat = atoi(keyWord+10);
|
||||
if (myPid == 0)
|
||||
std::cout <<"\nNumber of isotropic materials: "<< nmat << std::endl;
|
||||
|
||||
char* cline = 0;
|
||||
for (int i = 0; i < nmat && (cline = utl::readLine(is)); i++)
|
||||
{
|
||||
int code = atoi(strtok(cline," "));
|
||||
if (code > 0)
|
||||
this->setPropertyType(code,Property::MATERIAL,mVec.size());
|
||||
double E = atof(strtok(NULL," "));
|
||||
double nu = atof(strtok(NULL," "));
|
||||
double rho = atof(strtok(NULL," "));
|
||||
int matVer = (cline = strtok(NULL," ")) ? atoi(cline) : -1;
|
||||
if (matVer >= 0)
|
||||
mVec.push_back(new NeoHookeMaterial(E,nu,rho,matVer));
|
||||
else
|
||||
mVec.push_back(new LinearMaterial(new LinIsotropic(E,nu,rho)));
|
||||
if (myPid == 0)
|
||||
std::cout <<"\tMaterial code "<< code <<": "
|
||||
<< E <<" "<< nu <<" "<< rho <<" ("<< matVer <<")"<< std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
return this->SIMLinEl3D::parse(keyWord,is);
|
||||
|
||||
if (!mVec.empty())
|
||||
{
|
||||
Elasticity* elp = dynamic_cast<Elasticity*>(myProblem);
|
||||
if (elp) elp->setMaterial(mVec.front());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// $Id: SIMFiniteDefEl.h,v 1.2 2010-12-29 18:51:53 kmo Exp $
|
||||
// $Id$
|
||||
//==============================================================================
|
||||
//!
|
||||
//! \file SIMFiniteDefEl.h
|
||||
@@ -41,13 +41,16 @@ class SIMFiniteDefEl2D : public SIMLinEl2D
|
||||
{
|
||||
public:
|
||||
//! \brief Default constructor.
|
||||
//! \param[in] form Problem formulation option
|
||||
//! \param[in] planeStress Plane stress/plane strain option
|
||||
//! \param[in] options Additional solution formulation options
|
||||
SIMFiniteDefEl2D(int form = SIM::TOTAL_LAGRANGE, bool planeStress = false,
|
||||
const std::vector<int>& options = std::vector<int>());
|
||||
SIMFiniteDefEl2D(const std::vector<int>& options = std::vector<int>());
|
||||
//! \brief Empty destructor.
|
||||
virtual ~SIMFiniteDefEl2D() {}
|
||||
|
||||
protected:
|
||||
//! \brief Parses a data section from the input stream.
|
||||
//! \param[in] keyWord Keyword of current data section to read
|
||||
//! \param is The file stream to read from
|
||||
virtual bool parse(char* keyWord, std::istream& is);
|
||||
};
|
||||
|
||||
|
||||
@@ -60,12 +63,17 @@ class SIMFiniteDefEl3D : public SIMLinEl3D
|
||||
public:
|
||||
//! \brief Default constructor.
|
||||
//! \param[in] checkRHS If \e true, ensure the model is in a right-hand system
|
||||
//! \param[in] form Problem formulation option
|
||||
//! \param[in] options Additional solution formulation options
|
||||
SIMFiniteDefEl3D(bool checkRHS = false, int form = SIM::TOTAL_LAGRANGE,
|
||||
SIMFiniteDefEl3D(bool checkRHS = false,
|
||||
const std::vector<int>& options = std::vector<int>());
|
||||
//! \brief Empty destructor.
|
||||
virtual ~SIMFiniteDefEl3D() {}
|
||||
|
||||
protected:
|
||||
//! \brief Parses a data section from the input stream.
|
||||
//! \param[in] keyWord Keyword of current data section to read
|
||||
//! \param is The file stream to read from
|
||||
virtual bool parse(char* keyWord, std::istream& is);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// $Id: main_NonLinEl.C,v 1.6 2011-02-08 09:32:18 kmo Exp $
|
||||
// $Id$
|
||||
//==============================================================================
|
||||
//!
|
||||
//! \file main_NonLinEl.C
|
||||
@@ -47,9 +47,10 @@
|
||||
\arg -check : Data check only, read model and output to VTF (no solution)
|
||||
\arg -checkRHS : Check that the patches are modelled in a right-hand system
|
||||
\arg -fixDup : Resolve co-located nodes by merging them into a single node
|
||||
\arg -2D : Use two-parametric simulation driver
|
||||
\arg -2D : Use two-parametric simulation driver (plane stress)
|
||||
\arg -2Dpstrain : Use two-parametric simulation driver (plane strain)
|
||||
\arg -Tensor : Use tensorial total Lagrangian formulation (slow...)
|
||||
\arg -UL \a mver : Use updated Lagrangian formulation with nonlinear material
|
||||
\arg -UL : Use updated Lagrangian formulation with nonlinear material
|
||||
\arg -MX \a pord : Mixed formulation with internal discontinuous pressure
|
||||
\arg -mixed : Mixed formulation with continuous pressure and volumetric change
|
||||
\arg -lag : Use Lagrangian basis functions instead of splines/NURBS
|
||||
@@ -72,7 +73,7 @@ int main (int argc, char** argv)
|
||||
bool skip2nd = false;
|
||||
bool checkRHS = false;
|
||||
bool fixDup = false;
|
||||
char twoD = false;
|
||||
bool twoD = false;
|
||||
char* infile = 0;
|
||||
|
||||
LinAlgInit linalg(argc,argv);
|
||||
@@ -140,14 +141,14 @@ int main (int argc, char** argv)
|
||||
checkRHS = true;
|
||||
else if (!strcmp(argv[i],"-fixDup"))
|
||||
fixDup = true;
|
||||
else if (!strcmp(argv[i],"-2Dpstrain"))
|
||||
twoD = SIMLinEl2D::planeStrain = true;
|
||||
else if (!strncmp(argv[i],"-2D",3))
|
||||
twoD = strcmp(argv[i],"-2Dpstrain") ? 1 : 2;
|
||||
twoD = true;
|
||||
else if (!strcmp(argv[i],"-UL"))
|
||||
{
|
||||
if (form < SIM::UPDATED_LAGRANGE)
|
||||
form = SIM::UPDATED_LAGRANGE;
|
||||
if (i < argc-1 && isdigit(argv[i+1][0]))
|
||||
options[0] = atoi(argv[++i]);
|
||||
}
|
||||
else if (!strcmp(argv[i],"-MX"))
|
||||
{
|
||||
@@ -178,8 +179,8 @@ int main (int argc, char** argv)
|
||||
{
|
||||
std::cout <<"usage: "<< argv[0]
|
||||
<<" <inputfile> [-dense|-spr|-superlu[<nt>]|-samg|-petsc]\n "
|
||||
<<" [-lag] [-spec] [-2D[pstrain]] [-UL [<mVER>]] [-MX [<p>]|-mixe"
|
||||
<<"d] [-nGauss <n>]\n [-vtf <format>] [-nviz <nviz>]"
|
||||
<<" [-lag] [-spec] [-2D[pstrain]] [-UL] [-MX [<p>]|-mixed]"
|
||||
<<" [-nGauss <n>]\n [-vtf <format>] [-nviz <nviz>]"
|
||||
<<" [-nu <nu>] [-nv <nv>] [-nw <nw>]\n "
|
||||
<<" [-saveInc <dtSave>] [-dumpInc <dtDump> [raw]]\n "
|
||||
<<" [-ignore <p1> <p2> ...] [-fixDup] [-checkRHS] [-check]\n";
|
||||
@@ -225,11 +226,12 @@ int main (int argc, char** argv)
|
||||
utl::profiler->start("Model input");
|
||||
|
||||
// Create the finite deformation elasticity model
|
||||
options[0] = form%100;
|
||||
SIMbase* model;
|
||||
if (twoD)
|
||||
model = new SIMFiniteDefEl2D(form%100,twoD==1,options);
|
||||
model = new SIMFiniteDefEl2D(options);
|
||||
else
|
||||
model = new SIMFiniteDefEl3D(checkRHS,form%100,options);
|
||||
model = new SIMFiniteDefEl3D(checkRHS,options);
|
||||
|
||||
// Read in solver and model definitions
|
||||
NonLinSIM simulator(model);
|
||||
@@ -255,6 +257,7 @@ int main (int argc, char** argv)
|
||||
std::cout <<"\nWriting updated g2-file "<< infile << std::endl;
|
||||
std::ofstream osg(infile);
|
||||
model->dumpGeometry(osg);
|
||||
|
||||
// Open ASCII file for solution dump
|
||||
strcat(strtok(infile,"."),".sol");
|
||||
oss = new std::ofstream(infile);
|
||||
@@ -290,22 +293,25 @@ int main (int argc, char** argv)
|
||||
if (!simulator.solveStep(params,SIM::STATIC))
|
||||
return 5;
|
||||
|
||||
// Dump primary solution for inspection or external processing
|
||||
if (params.time.t + epsT*params.time.dt > nextDump)
|
||||
{
|
||||
// Dump primary solution for inspection or external processing
|
||||
if (dumpWithID)
|
||||
simulator.dumpStep(params.step,params.time.t,std::cout);
|
||||
else
|
||||
simulator.dumpStep(params.step,params.time.t,*oss,false);
|
||||
|
||||
nextDump = params.time.t + dtDump;
|
||||
}
|
||||
|
||||
// Save solution variables to VTF for visualization
|
||||
if (params.time.t + epsT*params.time.dt > nextSave)
|
||||
if (simulator.saveStep(++iStep,params.time.t,n,skip2nd))
|
||||
nextSave = params.time.t + dtSave;
|
||||
else
|
||||
{
|
||||
// Save solution variables to VTF for visualization
|
||||
if (!simulator.saveStep(++iStep,params.time.t,n,skip2nd))
|
||||
return 6;
|
||||
|
||||
nextSave = params.time.t + dtSave;
|
||||
}
|
||||
}
|
||||
|
||||
if (oss) delete oss;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
//==============================================================================
|
||||
|
||||
#include "SIMLinEl2D.h"
|
||||
#include "LinIsotropic.h"
|
||||
#include "LinearElasticity.h"
|
||||
#include "AnalyticSolutions.h"
|
||||
#include "Functions.h"
|
||||
@@ -23,11 +24,19 @@
|
||||
#include <string.h>
|
||||
|
||||
|
||||
SIMLinEl2D::SIMLinEl2D (int, bool planeStress)
|
||||
bool SIMLinEl2D::planeStrain = false;
|
||||
|
||||
|
||||
SIMLinEl2D::SIMLinEl2D (int)
|
||||
{
|
||||
myProblem = new LinearElasticity(2,planeStress);
|
||||
myProblem = new LinearElasticity(2);
|
||||
}
|
||||
|
||||
SIMLinEl2D::~SIMLinEl2D ()
|
||||
{
|
||||
for (size_t i = 0; i < mVec.size(); i++)
|
||||
delete mVec[i];
|
||||
}
|
||||
|
||||
bool SIMLinEl2D::parse (char* keyWord, std::istream& is)
|
||||
{
|
||||
@@ -45,33 +54,28 @@ bool SIMLinEl2D::parse (char* keyWord, std::istream& is)
|
||||
<< gx <<" "<< gy << std::endl;
|
||||
}
|
||||
|
||||
else if (!strncasecmp(keyWord,"ISOTROPHIC",10))
|
||||
else if (!strncasecmp(keyWord,"ISOTROPIC",9))
|
||||
{
|
||||
int nmat = atoi(keyWord+10);
|
||||
if (myPid == 0)
|
||||
std::cout <<"\nNumber of isotrophic materials: "<< nmat << std::endl;
|
||||
std::cout <<"\nNumber of isotropic materials: "<< nmat << std::endl;
|
||||
|
||||
for (int i = 0; i < nmat && (cline = utl::readLine(is)); i++)
|
||||
{
|
||||
int code = atoi(strtok(cline," "));
|
||||
int code = atoi(strtok(cline," "));
|
||||
if (code > 0)
|
||||
this->setPropertyType(code,Property::MATERIAL,mVec.size());
|
||||
|
||||
double E = atof(strtok(NULL," "));
|
||||
double nu = atof(strtok(NULL," "));
|
||||
double rho = atof(strtok(NULL," "));
|
||||
mVec.push_back(new LinIsotropic(E,nu,rho,!planeStrain));
|
||||
if (myPid == 0)
|
||||
std::cout <<"\tMaterial code "<< code <<": "
|
||||
<< E <<" "<< nu <<" "<< rho << std::endl;
|
||||
if (code == 0 || i == 0)
|
||||
elp->setMaterial(E,nu,rho);
|
||||
for (size_t j = 0; j < myProps.size() && code > 0; j++)
|
||||
if (myProps[j].pindx == (size_t)code &&
|
||||
myProps[j].pcode == Property::UNDEFINED)
|
||||
{
|
||||
myProps[j].pindx = mVec.size();
|
||||
myProps[j].pcode = Property::MATERIAL;
|
||||
}
|
||||
if (code > 0)
|
||||
mVec.push_back(IsoMat(E,nu,rho));
|
||||
}
|
||||
if (!mVec.empty())
|
||||
elp->setMaterial(mVec.front());
|
||||
}
|
||||
|
||||
else if (!strncasecmp(keyWord,"CONSTANT_PRESSURE",17))
|
||||
@@ -229,7 +233,7 @@ bool SIMLinEl2D::parse (char* keyWord, std::istream& is)
|
||||
{
|
||||
std::cout <<"\tMaterial for all patches: "
|
||||
<< E <<" "<< nu <<" "<< rho << std::endl;
|
||||
elp->setMaterial(E,nu,rho);
|
||||
mVec.push_back(new LinIsotropic(E,nu,rho,!planeStrain));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -241,11 +245,12 @@ bool SIMLinEl2D::parse (char* keyWord, std::istream& is)
|
||||
std::cout <<"\tMaterial for P"<< patch
|
||||
<<": "<< E <<" "<< nu <<" "<< rho << std::endl;
|
||||
myProps.push_back(Property(Property::MATERIAL,mVec.size(),pid,3));
|
||||
mVec.push_back(IsoMat(E,nu,rho));
|
||||
if (i == 0)
|
||||
elp->setMaterial(E,nu,rho);
|
||||
mVec.push_back(new LinIsotropic(E,nu,rho,!planeStrain));
|
||||
}
|
||||
}
|
||||
|
||||
if (!mVec.empty())
|
||||
elp->setMaterial(mVec.front());
|
||||
}
|
||||
|
||||
else
|
||||
@@ -262,7 +267,7 @@ bool SIMLinEl2D::initMaterial (size_t propInd)
|
||||
|
||||
if (propInd >= mVec.size()) propInd = mVec.size()-1;
|
||||
|
||||
elp->setMaterial(mVec[propInd].E,mVec[propInd].nu,mVec[propInd].rho);
|
||||
elp->setMaterial(mVec[propInd]);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include "SIM2D.h"
|
||||
#include "SIMenums.h"
|
||||
|
||||
class Material;
|
||||
|
||||
|
||||
/*!
|
||||
\brief Driver class for 2D isogeometric FEM analysis of elasticity problems.
|
||||
@@ -27,27 +29,12 @@
|
||||
|
||||
class SIMLinEl2D : public SIM2D
|
||||
{
|
||||
//! \brief Struct for storage of physical material property parameters.
|
||||
struct IsoMat
|
||||
{
|
||||
double E; //!< Young's modulus
|
||||
double nu; //!< Poisson's ratio
|
||||
double rho; //!< Mass density
|
||||
//! \brief Default constructor.
|
||||
IsoMat() { E = nu = rho = 0.0; }
|
||||
//! \brief Constructor initializing a material instance.
|
||||
IsoMat(double Emod, double Poiss, double D) : E(Emod), nu(Poiss), rho(D) {}
|
||||
};
|
||||
|
||||
typedef std::vector<IsoMat> MaterialVec; //!< Vector of material data sets
|
||||
|
||||
public:
|
||||
//! \brief Default constructor.
|
||||
//! \param[in] form Problem formulation option
|
||||
//! \param[in] planeStress Plane stress/plane strain option
|
||||
SIMLinEl2D(int form = SIM::LINEAR, bool planeStress = true);
|
||||
//! \brief Empty destructor.
|
||||
virtual ~SIMLinEl2D() {}
|
||||
SIMLinEl2D(int form = SIM::LINEAR);
|
||||
//! \brief The destructor frees the dynamically allocated material properties.
|
||||
virtual ~SIMLinEl2D();
|
||||
|
||||
protected:
|
||||
//! \brief Parses a data section from the input stream.
|
||||
@@ -63,8 +50,11 @@ protected:
|
||||
//! \param[in] propInd Physical property index
|
||||
virtual bool initNeumann(size_t propInd);
|
||||
|
||||
private:
|
||||
MaterialVec mVec; //!< Material data
|
||||
public:
|
||||
static bool planeStrain; //!< Plane strain/stress option
|
||||
|
||||
protected:
|
||||
std::vector<Material*> mVec; //!< Material data
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
//==============================================================================
|
||||
|
||||
#include "SIMLinEl3D.h"
|
||||
#include "LinIsotropic.h"
|
||||
#include "LinearElasticity.h"
|
||||
#include "AnalyticSolutions.h"
|
||||
#include "Functions.h"
|
||||
@@ -156,6 +157,13 @@ SIMLinEl3D::SIMLinEl3D (bool checkRHS, int) : SIM3D(checkRHS)
|
||||
}
|
||||
|
||||
|
||||
SIMLinEl3D::~SIMLinEl3D ()
|
||||
{
|
||||
for (size_t i = 0; i < mVec.size(); i++)
|
||||
delete mVec[i];
|
||||
}
|
||||
|
||||
|
||||
bool SIMLinEl3D::parse (char* keyWord, std::istream& is)
|
||||
{
|
||||
char* cline = 0;
|
||||
@@ -175,33 +183,27 @@ bool SIMLinEl3D::parse (char* keyWord, std::istream& is)
|
||||
<< gx <<" "<< gy <<" "<< gz << std::endl;
|
||||
}
|
||||
|
||||
else if (!strncasecmp(keyWord,"ISOTROPHIC",10))
|
||||
else if (!strncasecmp(keyWord,"ISOTROPIC",9))
|
||||
{
|
||||
int nmat = atoi(keyWord+10);
|
||||
if (myPid == 0)
|
||||
std::cout <<"\nNumber of isotrophic materials: "<< nmat << std::endl;
|
||||
std::cout <<"\nNumber of isotropic materials: "<< nmat << std::endl;
|
||||
|
||||
for (int i = 0; i < nmat && (cline = utl::readLine(is)); i++)
|
||||
{
|
||||
int code = atoi(strtok(cline," "));
|
||||
int code = atoi(strtok(cline," "));
|
||||
if (code > 0)
|
||||
this->setPropertyType(code,Property::MATERIAL,mVec.size());
|
||||
double E = atof(strtok(NULL," "));
|
||||
double nu = atof(strtok(NULL," "));
|
||||
double rho = atof(strtok(NULL," "));
|
||||
mVec.push_back(new LinIsotropic(E,nu,rho));
|
||||
if (myPid == 0)
|
||||
std::cout <<"\tMaterial code "<< code <<": "
|
||||
<< E <<" "<< nu <<" "<< rho << std::endl;
|
||||
if (code == 0 || i == 0)
|
||||
elp->setMaterial(E,nu,rho);
|
||||
for (size_t j = 0; j < myProps.size() && code > 0; j++)
|
||||
if (myProps[j].pindx == (size_t)code &&
|
||||
myProps[j].pcode == Property::UNDEFINED)
|
||||
{
|
||||
myProps[j].pindx = mVec.size();
|
||||
myProps[j].pcode = Property::MATERIAL;
|
||||
}
|
||||
if (code > 0)
|
||||
mVec.push_back(IsoMat(E,nu,rho));
|
||||
}
|
||||
if (!mVec.empty())
|
||||
elp->setMaterial(mVec.front());
|
||||
}
|
||||
|
||||
else if (!strncasecmp(keyWord,"CONSTANT_PRESSURE",17))
|
||||
@@ -326,7 +328,7 @@ bool SIMLinEl3D::parse (char* keyWord, std::istream& is)
|
||||
{
|
||||
std::cout <<"\tMaterial for all patches: "
|
||||
<< E <<" "<< nu <<" "<< rho << std::endl;
|
||||
elp->setMaterial(E,nu,rho);
|
||||
mVec.push_back(new LinIsotropic(E,nu,rho));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -338,10 +340,11 @@ bool SIMLinEl3D::parse (char* keyWord, std::istream& is)
|
||||
std::cout <<"\tMaterial for P"<< patch
|
||||
<<": "<< E <<" "<< nu <<" "<< rho << std::endl;
|
||||
myProps.push_back(Property(Property::MATERIAL,mVec.size(),pid,3));
|
||||
mVec.push_back(IsoMat(E,nu,rho));
|
||||
if (i == 0)
|
||||
elp->setMaterial(E,nu,rho);
|
||||
mVec.push_back(new LinIsotropic(E,nu,rho));
|
||||
}
|
||||
|
||||
if (!mVec.empty())
|
||||
elp->setMaterial(mVec.front());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -398,7 +401,7 @@ bool SIMLinEl3D::initMaterial (size_t propInd)
|
||||
|
||||
if (propInd >= mVec.size()) propInd = mVec.size()-1;
|
||||
|
||||
elp->setMaterial(mVec[propInd].E,mVec[propInd].nu,mVec[propInd].rho);
|
||||
elp->setMaterial(mVec[propInd]);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include "SIM3D.h"
|
||||
#include "SIMenums.h"
|
||||
|
||||
class Material;
|
||||
|
||||
|
||||
/*!
|
||||
\brief Driver class for 3D isogeometric FEM analysis of elasticity problems.
|
||||
@@ -27,27 +29,13 @@
|
||||
|
||||
class SIMLinEl3D : public SIM3D
|
||||
{
|
||||
//! \brief Struct for storage of physical material property parameters.
|
||||
struct IsoMat
|
||||
{
|
||||
double E; //!< Young's modulus
|
||||
double nu; //!< Poisson's ratio
|
||||
double rho; //!< Mass density
|
||||
//! \brief Default constructor.
|
||||
IsoMat() { E = nu = rho = 0.0; }
|
||||
//! \brief Constructor initializing a material instance.
|
||||
IsoMat(double Emod, double Poiss, double D) : E(Emod), nu(Poiss), rho(D) {}
|
||||
};
|
||||
|
||||
typedef std::vector<IsoMat> MaterialVec; //!< Vector of material data sets
|
||||
|
||||
public:
|
||||
//! \brief Default constructor.
|
||||
//! \param[in] checkRHS If \e true, ensure the model is in a right-hand system
|
||||
//! \param[in] form Problem formulation option
|
||||
SIMLinEl3D(bool checkRHS = false, int form = SIM::LINEAR);
|
||||
//! \brief Empty destructor.
|
||||
virtual ~SIMLinEl3D() {}
|
||||
//! \brief The destructor frees the dynamically allocated material properties.
|
||||
virtual ~SIMLinEl3D();
|
||||
|
||||
protected:
|
||||
//! \brief Parses a data section from the input stream.
|
||||
@@ -63,8 +51,8 @@ protected:
|
||||
//! \param[in] propInd Physical property index
|
||||
virtual bool initNeumann(size_t propInd);
|
||||
|
||||
private:
|
||||
MaterialVec mVec; //!< Material data
|
||||
protected:
|
||||
std::vector<Material*> mVec; //!< Material data
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -74,7 +74,7 @@ int main (int argc, char** argv)
|
||||
bool vizRHS = false;
|
||||
bool fixDup = false;
|
||||
bool dumpASCII = false;
|
||||
char twoD = false;
|
||||
bool twoD = false;
|
||||
char* infile = 0;
|
||||
|
||||
LinAlgInit linalg(argc,argv);
|
||||
@@ -137,8 +137,10 @@ int main (int argc, char** argv)
|
||||
vizRHS = true;
|
||||
else if (!strcmp(argv[i],"-fixDup"))
|
||||
fixDup = true;
|
||||
else if (!strcmp(argv[i],"-2Dpstrain"))
|
||||
twoD = SIMLinEl2D::planeStrain = true;
|
||||
else if (!strncmp(argv[i],"-2D",3))
|
||||
twoD = strcmp(argv[i],"-2Dpstrain") ? 1 : 2;
|
||||
twoD = true;
|
||||
else if (!strncmp(argv[i],"-lag",4))
|
||||
SIMbase::discretization = SIMbase::Lagrange;
|
||||
else if (!strncmp(argv[i],"-spec",5))
|
||||
@@ -212,7 +214,7 @@ int main (int argc, char** argv)
|
||||
// Read in model definitions and establish the FE data structures
|
||||
SIMbase* model;
|
||||
if (twoD)
|
||||
model = new SIMLinEl2D(SIM::LINEAR,twoD==1);
|
||||
model = new SIMLinEl2D();
|
||||
else
|
||||
model = new SIMLinEl3D(checkRHS);
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
//==============================================================================
|
||||
|
||||
#include "Elasticity.h"
|
||||
#include "MaterialBase.h"
|
||||
#include "Utilities.h"
|
||||
#include "ElmMats.h"
|
||||
#include "ElmNorm.h"
|
||||
@@ -21,18 +22,14 @@
|
||||
#include "VTF.h"
|
||||
|
||||
|
||||
Elasticity::Elasticity (unsigned short int n, bool ps) : nsd(n), planeStress(ps)
|
||||
Elasticity::Elasticity (unsigned short int n) : nsd(n)
|
||||
{
|
||||
// Default material properties - typical values for steel (SI units)
|
||||
Emod = 2.05e11;
|
||||
nu = 0.29;
|
||||
rho = 7.85e3;
|
||||
|
||||
// Default is zero gravity
|
||||
g[0] = g[1] = g[2] = 0.0;
|
||||
grav[0] = grav[1] = grav[2] = 0.0;
|
||||
|
||||
myMats = new ElmMats();
|
||||
|
||||
material = 0;
|
||||
locSys = 0;
|
||||
tracFld = 0;
|
||||
bodyFld = 0;
|
||||
@@ -50,14 +47,11 @@ Elasticity::~Elasticity ()
|
||||
|
||||
void Elasticity::print (std::ostream& os) const
|
||||
{
|
||||
std::cout <<"Elasticity: "<< nsd <<"D";
|
||||
if (nsd == 2)
|
||||
std::cout <<" plane "<< (planeStress ? "stress" : "strain");
|
||||
std::cout <<", E = "<< Emod <<", nu = "<< nu <<", rho = "<< rho
|
||||
<<", gravity =";
|
||||
std::cout <<"Elasticity: "<< nsd <<"D, gravity =";
|
||||
for (unsigned short int d = 0; d < nsd; d++)
|
||||
std::cout <<" "<< g[d];
|
||||
std::cout <<" "<< grav[d];
|
||||
std::cout << std::endl;
|
||||
if (material) material->print(os);
|
||||
}
|
||||
|
||||
|
||||
@@ -162,6 +156,10 @@ bool Elasticity::initElement (const std::vector<int>& MNPC)
|
||||
std::cerr <<" *** Elasticity::initElement: Detected "
|
||||
<< ierr <<" node numbers out of range."<< std::endl;
|
||||
|
||||
int j = 1+myMats->b.size()-primsol.size();
|
||||
for (size_t i = 1; i < primsol.size() && ierr == 0; i++, j++)
|
||||
ierr = utl::gather(MNPC,nsd,primsol[j],myMats->b[j]);
|
||||
|
||||
if (myMats)
|
||||
myMats->withLHS = true;
|
||||
|
||||
@@ -199,8 +197,8 @@ Vec3 Elasticity::getTraction (const Vec3& X, const Vec3& n) const
|
||||
|
||||
Vec3 Elasticity::getBodyforce (const Vec3& X) const
|
||||
{
|
||||
Vec3 f(g[0],g[1],g[2]);
|
||||
f *= this->getMassDensity(X);
|
||||
Vec3 f(grav[0],grav[1],grav[2]);
|
||||
f *= material->getMassDensity(X);
|
||||
|
||||
if (bodyFld)
|
||||
f += (*bodyFld)(X);
|
||||
@@ -214,10 +212,10 @@ bool Elasticity::haveLoads () const
|
||||
if (tracFld) return true;
|
||||
if (bodyFld) return true;
|
||||
|
||||
if (rho != 0.0)
|
||||
for (unsigned short int i = 0; i < nsd; i++)
|
||||
if (g[i] != 0.0)
|
||||
return true;
|
||||
for (unsigned short int i = 0; i < nsd; i++)
|
||||
if (grav[i] != 0.0)
|
||||
if (material)
|
||||
return material->getMassDensity(Vec3()) != 0.0;
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -259,7 +257,7 @@ bool Elasticity::writeGlvT (VTF* vtf, int iStep, int& nBlock) const
|
||||
[\a N ] is the element basis functions arranged in a [nsd][nsd*NENOD] matrix.
|
||||
*/
|
||||
|
||||
bool Elasticity::kinematics (const Matrix& dNdX, SymmTensor& eps) const
|
||||
bool Elasticity::kinematics (const Matrix& dNdX, Tensor&, SymmTensor& eps) const
|
||||
{
|
||||
const size_t nenod = dNdX.rows();
|
||||
const size_t nstrc = nsd*(nsd+1)/2;
|
||||
@@ -348,115 +346,7 @@ bool Elasticity::kinematics (const Matrix& dNdX, SymmTensor& eps) const
|
||||
bool Elasticity::formBmatrix (const Matrix& dNdX) const
|
||||
{
|
||||
static SymmTensor dummy(0);
|
||||
return this->Elasticity::kinematics(dNdX,dummy);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
The consitutive matrix for Isotrophic linear elastic problems
|
||||
is defined as follows:
|
||||
|
||||
For 2D plain stress: \f[
|
||||
[C] = \frac{E}{(1-\nu^2)} \left[\begin{array}{ccc}
|
||||
1 & \ \ \nu & 0 \\
|
||||
\nu & \ \ 1 & 0 \\
|
||||
0 & \ \ 0 & \frac{1}{2}(1-\nu)
|
||||
\end{array}\right] \f]
|
||||
|
||||
For 2D plain strain: \f[
|
||||
[C] = \frac{E}{(1+\nu)(1-2\nu)} \left[\begin{array}{ccc}
|
||||
1-\nu & \nu & 0 \\
|
||||
\nu & 1-\nu & 0 \\
|
||||
0 & 0 & \frac{1}{2}-\nu
|
||||
\end{array}\right] \f]
|
||||
|
||||
For 3D: \f[
|
||||
[C] = \frac{E}{(1+\nu)(1-2\nu)} \left[\begin{array}{cccccc}
|
||||
1-\nu & \nu & \nu & 0 & 0 & 0 \\
|
||||
\nu & 1-\nu & \nu & 0 & 0 & 0 \\
|
||||
\nu & \nu & 1-\nu & 0 & 0 & 0 \\
|
||||
0 & 0 & 0 & \frac{1}{2}-\nu & 0 & 0 \\
|
||||
0 & 0 & 0 & 0 & \frac{1}{2}-\nu & 0 \\
|
||||
0 & 0 & 0 & 0 & 0 & \frac{1}{2}-\nu
|
||||
\end{array}\right] \f]
|
||||
*/
|
||||
|
||||
bool Elasticity::formCmatrix (Matrix& C, const Vec3&, bool invers) const
|
||||
{
|
||||
const double one = 1.0;
|
||||
const size_t nst = nsd*(nsd+1)/2;
|
||||
C.resize(nst,nst,true);
|
||||
if (nsd == 1)
|
||||
{
|
||||
// Special for 1D problems
|
||||
C(1,1) = invers ? one/Emod : Emod;
|
||||
return true;
|
||||
}
|
||||
else if (nu < 0.0 || nu >= 0.5)
|
||||
{
|
||||
std::cerr <<" *** Elasticity::formCmatrix: Poisson's ratio "<< nu
|
||||
<<" out of range [0,0.5>."<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (invers)
|
||||
if (nsd == 3 || (nsd == 2 && planeStress))
|
||||
{
|
||||
C(1,1) = one / Emod;
|
||||
C(2,1) = -nu / Emod;
|
||||
}
|
||||
else // 2D plain strain
|
||||
{
|
||||
C(1,1) = (one - nu*nu) / Emod;
|
||||
C(2,1) = (-nu - nu*nu) / Emod;
|
||||
}
|
||||
|
||||
else
|
||||
if (nsd == 2 && planeStress)
|
||||
{
|
||||
C(1,1) = Emod / (one - nu*nu);
|
||||
C(2,1) = C(1,1) * nu;
|
||||
}
|
||||
else // 2D plain strain or 3D
|
||||
{
|
||||
double fact = Emod / ((one + nu) * (one - nu - nu));
|
||||
C(1,1) = fact * (one - nu);
|
||||
C(2,1) = fact * nu;
|
||||
}
|
||||
|
||||
C(1,2) = C(2,1);
|
||||
C(2,2) = C(1,1);
|
||||
|
||||
const double G = Emod / (2.0 + nu + nu);
|
||||
C(nsd+1,nsd+1) = invers ? one / G : G;
|
||||
|
||||
if (nsd > 2)
|
||||
{
|
||||
C(3,1) = C(2,1);
|
||||
C(3,2) = C(2,1);
|
||||
C(1,3) = C(2,1);
|
||||
C(2,3) = C(2,1);
|
||||
C(3,3) = C(1,1);
|
||||
C(5,5) = C(4,4);
|
||||
C(6,6) = C(4,4);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Elasticity::constitutive (Matrix& C, SymmTensor& sigma, double&,
|
||||
const SymmTensor& eps, const Vec3& X,
|
||||
char calcStress) const
|
||||
{
|
||||
// Set up the constitutive matrix, C, at this point
|
||||
if (!this->formCmatrix(C,X))
|
||||
return false;
|
||||
else if (!calcStress)
|
||||
return true;
|
||||
|
||||
// Calculate the stress vector, sigma = C*eps
|
||||
return C.multiply(eps,sigma);
|
||||
return this->Elasticity::kinematics(dNdX,dummy,dummy);
|
||||
}
|
||||
|
||||
|
||||
@@ -493,7 +383,7 @@ void Elasticity::formKG (Matrix& EM, const Matrix& dNdX,
|
||||
void Elasticity::formMassMatrix (Matrix& EM, const Vector& N,
|
||||
const Vec3& X, double detJW) const
|
||||
{
|
||||
double rhow = this->getMassDensity(X)*detJW;
|
||||
double rhow = material->getMassDensity(X)*detJW;
|
||||
if (rhow == 0.0) return;
|
||||
|
||||
for (size_t a = 1; a <= N.size(); a++)
|
||||
@@ -527,6 +417,13 @@ Vec3 Elasticity::evalSol (const Vector& N) const
|
||||
}
|
||||
|
||||
|
||||
bool Elasticity::formCinverse (Matrix& Cinv, const Vec3& X) const
|
||||
{
|
||||
SymmTensor dummy(nsd); double U;
|
||||
return material->evaluate(Cinv,dummy,U,X,dummy,dummy,-1);
|
||||
}
|
||||
|
||||
|
||||
bool Elasticity::evalSol (Vector& s, const Vector&,
|
||||
const Matrix& dNdX, const Vec3& X,
|
||||
const std::vector<int>& MNPC) const
|
||||
@@ -540,14 +437,15 @@ bool Elasticity::evalSol (Vector& s, const Vector&,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Evaluate the strain tensor, eps
|
||||
// Evaluate the deformation gradient, dUdX, and/or the strain tensor, eps
|
||||
Tensor dUdX(nsd);
|
||||
SymmTensor eps(nsd);
|
||||
if (!this->kinematics(dNdX,eps))
|
||||
if (!this->kinematics(dNdX,dUdX,eps))
|
||||
return false;
|
||||
|
||||
// Calculate the stress tensor through the constitutive relation
|
||||
SymmTensor sigma(nsd); double U = 0.0;
|
||||
if (!this->constitutive(Cmat,sigma,U,eps,X))
|
||||
SymmTensor sigma(nsd); double U;
|
||||
if (!material->evaluate(Cmat,sigma,U,X,dUdX,eps))
|
||||
return false;
|
||||
|
||||
// Congruence transformation to local coordinate system at current point
|
||||
@@ -575,14 +473,15 @@ bool Elasticity::evalSol (Vector& s, const Matrix& dNdX, const Vec3& X) const
|
||||
return false;
|
||||
}
|
||||
|
||||
// Evaluate the strain tensor, eps
|
||||
// Evaluate the deformation gradient, dUdX, and/or the strain tensor, eps
|
||||
Tensor dUdX(nsd);
|
||||
SymmTensor eps(nsd);
|
||||
if (!this->kinematics(dNdX,eps))
|
||||
if (!this->kinematics(dNdX,dUdX,eps))
|
||||
return false;
|
||||
|
||||
// Calculate the stress tensor through the constitutive relation
|
||||
SymmTensor sigma(nsd); double U = 0.0;
|
||||
if (!this->constitutive(Cmat,sigma,U,eps,X))
|
||||
SymmTensor sigma(nsd); double U;
|
||||
if (!material->evaluate(Cmat,sigma,U,X,dUdX,eps))
|
||||
return false;
|
||||
|
||||
s = sigma;
|
||||
@@ -613,7 +512,7 @@ const char* Elasticity::getFieldLabel (size_t i, const char* prefix) const
|
||||
|
||||
static std::string label;
|
||||
if (prefix)
|
||||
label = prefix + std::string(" ");
|
||||
label = std::string(prefix) + " ";
|
||||
else
|
||||
label.clear();
|
||||
|
||||
@@ -678,7 +577,7 @@ bool ElasticityNorm::evalInt (LocalIntegral*& elmInt, double detJW,
|
||||
|
||||
// Evaluate the inverse constitutive matrix at this point
|
||||
Matrix Cinv;
|
||||
if (!problem.formCmatrix(Cinv,X,true)) return false;
|
||||
if (!problem.formCinverse(Cinv,X)) return false;
|
||||
|
||||
// Evaluate the finite element stress field
|
||||
Vector sigmah, sigma;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <map>
|
||||
|
||||
class LocalSystem;
|
||||
class Material;
|
||||
class ElmMats;
|
||||
class ElmNorm;
|
||||
class VTF;
|
||||
@@ -36,8 +37,7 @@ class Elasticity : public Integrand
|
||||
protected:
|
||||
//! \brief The default constructor initializes all pointers to zero.
|
||||
//! \param[in] n Number of spatial dimensions
|
||||
//! \param[in] ps If \e true, assume plane stress in 2D
|
||||
Elasticity(unsigned short int n = 3, bool ps = true);
|
||||
Elasticity(unsigned short int n = 3);
|
||||
|
||||
public:
|
||||
//! \brief The destructor frees the dynamically allocated data objects.
|
||||
@@ -57,17 +57,13 @@ public:
|
||||
|
||||
//! \brief Defines the gravitation vector.
|
||||
void setGravity(double gx, double gy = 0.0, double gz = 0.0)
|
||||
{ g[0] = gx; g[1] = gy; g[2] = gz; }
|
||||
{ grav[0] = gx; grav[1] = gy; grav[2] = gz; }
|
||||
|
||||
//! \brief Defines the body force field.
|
||||
void setBodyForce(VecFunc* bf) { bodyFld = bf; }
|
||||
|
||||
//! \brief Defines material properties for current volume patch.
|
||||
//! \param[in] Young Young's modulus
|
||||
//! \param[in] Poiss Poisson's ratio
|
||||
//! \param[in] Density Mass density
|
||||
virtual void setMaterial(double Young, double Poiss, double Density)
|
||||
{ Emod = Young; nu = Poiss; rho = Density; }
|
||||
//! \brief Defines the material properties.
|
||||
virtual void setMaterial(Material* mat) { material = mat; }
|
||||
|
||||
//! \brief Defines the local coordinate system for stress output.
|
||||
void setLocalSystem(LocalSystem* cs) { locSys = cs; }
|
||||
@@ -138,27 +134,13 @@ public:
|
||||
virtual const char* getFieldLabel(size_t i, const char* prefix = 0) const;
|
||||
|
||||
protected:
|
||||
//! \brief Evaluates the mass density at current point.
|
||||
virtual double getMassDensity(const Vec3&) const { return rho; }
|
||||
|
||||
//! \brief Calculates some kinematic quantities at current point.
|
||||
//! \param[in] dNdX Basis function gradients at current point
|
||||
//! \param[out] eps Strain tensor at current point
|
||||
//!
|
||||
//! \details The strain displacement matrix \b B is established
|
||||
//! and stored in the mutable class member \a Bmat.
|
||||
virtual bool kinematics(const Matrix& dNdX, SymmTensor& eps) const;
|
||||
|
||||
//! \brief Evaluates the constitutive relation at current point.
|
||||
//! \param[out] C Constitutive matrix at current point
|
||||
//! \param[out] sigma Stress tensor at current point
|
||||
//! \param[out] U Strain energy density
|
||||
//! \param[in] eps Strain tensor at current point
|
||||
//! \param[in] X Cartesian coordinates of current point
|
||||
//! \param[in] calcStress If \e false, claculate the C-matrix only
|
||||
virtual bool constitutive(Matrix& C, SymmTensor& sigma, double& U,
|
||||
const SymmTensor& eps, const Vec3& X,
|
||||
char calcStress = true) const;
|
||||
virtual bool kinematics(const Matrix& dNdX, Tensor&, SymmTensor& eps) const;
|
||||
|
||||
//! \brief Calculates integration point geometric stiffness contributions.
|
||||
//! \param EM Element matrix to receive the stiffness contributions
|
||||
@@ -194,19 +176,11 @@ protected:
|
||||
bool getIntegralResult(LocalIntegral*& elmInt) const;
|
||||
|
||||
public:
|
||||
//! \brief Sets up the tangential constitutive matrix at current point.
|
||||
//! \param[out] C \f$6\times6\f$-matrix (in 3D) or \f$3\times3\f$-matrix
|
||||
//! (in 2D), representing the constitutive tensor
|
||||
//! \brief Sets up the inverse constitutive matrix at current point.
|
||||
//! \param[out] Cinv \f$6\times6\f$-matrix (in 3D) or \f$3\times3\f$-matrix
|
||||
//! (in 2D), representing the inverse constitutive tensor
|
||||
//! \param[in] X Cartesian coordinates of current point
|
||||
//! \param[in] invers If \e true, set up the inverse matrix instead
|
||||
virtual bool formCmatrix(Matrix& C, const Vec3& X, bool invers = false) const;
|
||||
|
||||
private:
|
||||
// Physical properties (constant)
|
||||
double Emod; //!< Young's modulus
|
||||
double nu; //!< Poisson's ratio
|
||||
double rho; //!< Mass density
|
||||
double g[3]; //!< Gravitation vector
|
||||
bool formCinverse(Matrix& Cinv, const Vec3& X) const;
|
||||
|
||||
protected:
|
||||
// Finite element quantities
|
||||
@@ -219,6 +193,10 @@ protected:
|
||||
|
||||
ElmMats* myMats; //!< Local element matrices, result of numerical integration
|
||||
|
||||
// Physical properties
|
||||
Material* material; //!< Material data and constitutive relation
|
||||
double grav[3]; //!< Gravitation vector
|
||||
|
||||
LocalSystem* locSys; //!< Local coordinate system for result output
|
||||
TractionFunc* tracFld; //!< Pointer to boundary traction field
|
||||
VecFunc* bodyFld; //!< Pointer to body force field
|
||||
@@ -226,7 +204,6 @@ protected:
|
||||
mutable std::map<Vec3,Vec3> tracVal; //!< Traction field point values
|
||||
|
||||
unsigned short int nsd; //!< Number of space dimensions (1, 2 or, 3)
|
||||
bool planeStress; //!< Plane stress/strain option for 2D problems
|
||||
|
||||
// Work arrays declared as members to avoid frequent re-allocation
|
||||
// within the numerical integration loop (for reduced overhead)
|
||||
|
||||
141
src/Integrands/LinIsotropic.C
Normal file
141
src/Integrands/LinIsotropic.C
Normal file
@@ -0,0 +1,141 @@
|
||||
// $Id$
|
||||
//==============================================================================
|
||||
//!
|
||||
//! \file LinIsotropic.C
|
||||
//!
|
||||
//! \date Mar 01 2011
|
||||
//!
|
||||
//! \author Knut Morten Okstad / SINTEF
|
||||
//!
|
||||
//! \brief Isotropic linear elastic material model.
|
||||
//!
|
||||
//==============================================================================
|
||||
|
||||
#include "LinIsotropic.h"
|
||||
#include "Tensor.h"
|
||||
|
||||
|
||||
LinIsotropic::LinIsotropic (bool ps) : planeStress(ps)
|
||||
{
|
||||
// Default material properties - typical values for steel (SI units)
|
||||
Emod = 2.05e11;
|
||||
nu = 0.29;
|
||||
rho = 7.85e3;
|
||||
}
|
||||
|
||||
|
||||
void LinIsotropic::print (std::ostream& os) const
|
||||
{
|
||||
std::cout <<"LinIsotropic: ";
|
||||
if (planeStress)
|
||||
std::cout <<"plane stress, ";
|
||||
std::cout <<"E = "<< Emod <<", nu = "<< nu <<", rho = "<< rho << std::endl;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
The consitutive matrix for Isotropic linear elastic problems
|
||||
is defined as follows:
|
||||
|
||||
For 2D plain stress: \f[
|
||||
[C] = \frac{E}{(1-\nu^2)} \left[\begin{array}{ccc}
|
||||
1 & \ \ \nu & 0 \\
|
||||
\nu & \ \ 1 & 0 \\
|
||||
0 & \ \ 0 & \frac{1}{2}(1-\nu)
|
||||
\end{array}\right] \f]
|
||||
|
||||
For 2D plain strain: \f[
|
||||
[C] = \frac{E}{(1+\nu)(1-2\nu)} \left[\begin{array}{ccc}
|
||||
1-\nu & \nu & 0 \\
|
||||
\nu & 1-\nu & 0 \\
|
||||
0 & 0 & \frac{1}{2}-\nu
|
||||
\end{array}\right] \f]
|
||||
|
||||
For 3D: \f[
|
||||
[C] = \frac{E}{(1+\nu)(1-2\nu)} \left[\begin{array}{cccccc}
|
||||
1-\nu & \nu & \nu & 0 & 0 & 0 \\
|
||||
\nu & 1-\nu & \nu & 0 & 0 & 0 \\
|
||||
\nu & \nu & 1-\nu & 0 & 0 & 0 \\
|
||||
0 & 0 & 0 & \frac{1}{2}-\nu & 0 & 0 \\
|
||||
0 & 0 & 0 & 0 & \frac{1}{2}-\nu & 0 \\
|
||||
0 & 0 & 0 & 0 & 0 & \frac{1}{2}-\nu
|
||||
\end{array}\right] \f]
|
||||
*/
|
||||
|
||||
bool LinIsotropic::evaluate (Matrix& C, SymmTensor& sigma, double& U,
|
||||
const Vec3&, const Tensor&, const SymmTensor& eps,
|
||||
char iop, const TimeDomain*) const
|
||||
{
|
||||
const size_t nsd = eps.dim();
|
||||
const size_t nst = nsd*(nsd+1)/2;
|
||||
C.resize(nst,nst,true);
|
||||
|
||||
if (nsd == 1)
|
||||
{
|
||||
// Special for 1D problems
|
||||
C(1,1) = iop < 0 ? 1.0/Emod : Emod;
|
||||
if (iop > 0)
|
||||
{
|
||||
sigma = eps; sigma *= Emod;
|
||||
U = 0.5*sigma(1,1)*eps(1,1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (nu < 0.0 || nu >= 0.5)
|
||||
{
|
||||
std::cerr <<" *** LinIsotropic::evaluate: Poisson's ratio "<< nu
|
||||
<<" out of range [0,0.5>."<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (iop < 0) // The inverse C-matrix is wanted
|
||||
if (nsd == 3 || (nsd == 2 && planeStress))
|
||||
{
|
||||
C(1,1) = 1.0 / Emod;
|
||||
C(2,1) = -nu / Emod;
|
||||
}
|
||||
else // 2D plain strain
|
||||
{
|
||||
C(1,1) = (1.0 - nu*nu) / Emod;
|
||||
C(2,1) = (-nu - nu*nu) / Emod;
|
||||
}
|
||||
|
||||
else
|
||||
if (nsd == 2 && planeStress)
|
||||
{
|
||||
C(1,1) = Emod / (1.0 - nu*nu);
|
||||
C(2,1) = C(1,1) * nu;
|
||||
}
|
||||
else // 2D plain strain or 3D
|
||||
{
|
||||
double fact = Emod / ((1.0 + nu) * (1.0 - nu - nu));
|
||||
C(1,1) = fact * (1.0 - nu);
|
||||
C(2,1) = fact * nu;
|
||||
}
|
||||
|
||||
C(1,2) = C(2,1);
|
||||
C(2,2) = C(1,1);
|
||||
|
||||
const double G = Emod / (2.0 + nu + nu);
|
||||
C(nsd+1,nsd+1) = iop < 0 ? 1.0 / G : G;
|
||||
|
||||
if (nsd > 2)
|
||||
{
|
||||
C(3,1) = C(2,1);
|
||||
C(3,2) = C(2,1);
|
||||
C(1,3) = C(2,1);
|
||||
C(2,3) = C(2,1);
|
||||
C(3,3) = C(1,1);
|
||||
C(5,5) = C(4,4);
|
||||
C(6,6) = C(4,4);
|
||||
}
|
||||
|
||||
if (iop > 0)
|
||||
// Calculate the stress tensor, sigma = C*eps, and strain energy density, U
|
||||
if (C.multiply(eps,sigma))
|
||||
U = 0.5*sigma.innerProd(eps); // U = 0.5*sigma:eps
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
63
src/Integrands/LinIsotropic.h
Normal file
63
src/Integrands/LinIsotropic.h
Normal file
@@ -0,0 +1,63 @@
|
||||
// $Id$
|
||||
//==============================================================================
|
||||
//!
|
||||
//! \file LinIsotropic.h
|
||||
//!
|
||||
//! \date Mar 01 2011
|
||||
//!
|
||||
//! \author Knut Morten Okstad / SINTEF
|
||||
//!
|
||||
//! \brief Isotropic linear elastic material model.
|
||||
//!
|
||||
//==============================================================================
|
||||
|
||||
#ifndef _LIN_ISOTROPIC_H
|
||||
#define _LIN_ISOTROPIC_H
|
||||
|
||||
#include "MaterialBase.h"
|
||||
|
||||
|
||||
/*!
|
||||
\brief Class representing a isotropic linear elastic material model.
|
||||
*/
|
||||
|
||||
class LinIsotropic : public Material
|
||||
{
|
||||
public:
|
||||
//! \brief Default constructor.
|
||||
//! \param[in] ps If \e true, assume plane stress in 2D
|
||||
LinIsotropic(bool ps = false);
|
||||
//! \brief Constructor initializing the material parameters.
|
||||
LinIsotropic(double E, double v = 0.0, double density = 0.0, bool ps = false)
|
||||
: Emod(E), nu(v), rho(density), planeStress(ps) {}
|
||||
//! \brief Empty destructor.
|
||||
virtual ~LinIsotropic() {}
|
||||
|
||||
//! \brief Prints out material parameters to the given output stream.
|
||||
virtual void print(std::ostream&) const;
|
||||
|
||||
//! \brief Evaluates the mass density at current point.
|
||||
virtual double getMassDensity(const Vec3&) const { return rho; }
|
||||
|
||||
//! \brief Evaluates the constitutive relation at an integration point.
|
||||
//! \param[out] C Constitutive matrix at current point
|
||||
//! \param[out] sigma Stress tensor at current point
|
||||
//! \param[out] U Strain energy density at current point
|
||||
//! \param[in] eps Strain tensor at current point
|
||||
//! \param[in] iop Calculation option;
|
||||
//! -1 : Calculate the inverse constitutive matrix only,
|
||||
//! 0 : Calculate the constitutive matrix only,
|
||||
//! 1 : Calculate Cauchy stresses and the constitutive matrix.
|
||||
virtual bool evaluate(Matrix& C, SymmTensor& sigma, double& U,
|
||||
const Vec3&, const Tensor&, const SymmTensor& eps,
|
||||
char iop = 1, const TimeDomain* = 0) const;
|
||||
|
||||
protected:
|
||||
// Material properties (constant)
|
||||
double Emod; //!< Young's modulus
|
||||
double nu; //!< Poisson's ratio
|
||||
double rho; //!< Mass density
|
||||
bool planeStress; //!< Plane stress/strain option for 2D problems
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -12,12 +12,12 @@
|
||||
//==============================================================================
|
||||
|
||||
#include "LinearElasticity.h"
|
||||
#include "MaterialBase.h"
|
||||
#include "Tensor.h"
|
||||
#include "Vec3Oper.h"
|
||||
|
||||
|
||||
LinearElasticity::LinearElasticity (unsigned short int n, bool ps)
|
||||
: Elasticity(n,ps)
|
||||
LinearElasticity::LinearElasticity (unsigned short int n) : Elasticity(n)
|
||||
{
|
||||
// Only the current solution is needed
|
||||
primsol.resize(1);
|
||||
@@ -29,17 +29,19 @@ bool LinearElasticity::evalInt (LocalIntegral*& elmInt, double detJW,
|
||||
const Vec3& X) const
|
||||
{
|
||||
bool lHaveStrains = false;
|
||||
SymmTensor eps(nsd), sigma(nsd);
|
||||
|
||||
SymmTensor eps(nsd);
|
||||
if (eKm || eKg || iS)
|
||||
{
|
||||
// Compute the strain-displacement matrix B from dNdX
|
||||
// and evaluate the symmetric strain tensor if displacements are available
|
||||
if (!this->kinematics(dNdX,eps)) return false;
|
||||
if (!this->kinematics(dNdX,eps,sigma)) return false;
|
||||
if (!eps.isZero(1.0e-16)) lHaveStrains = true;
|
||||
|
||||
// Evaluate the constitutive matrix at this point
|
||||
if (!this->formCmatrix(Cmat,X)) return false;
|
||||
// Evaluate the constitutive matrix and the stress tensor at this point
|
||||
double U;
|
||||
if (!material->evaluate(Cmat,sigma,U,X,eps,eps))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (eKm)
|
||||
@@ -49,11 +51,6 @@ bool LinearElasticity::evalInt (LocalIntegral*& elmInt, double detJW,
|
||||
eKm->multiply(Bmat,CB,true,false,true); // EK += B^T * CB
|
||||
}
|
||||
|
||||
SymmTensor sigma(nsd);
|
||||
if ((eKg || iS) && lHaveStrains)
|
||||
// Evaluate the symmetric stress tensor
|
||||
Cmat.multiply(eps,sigma); // sigma = C*eps
|
||||
|
||||
if (eKg && lHaveStrains)
|
||||
// Integrate the geometric stiffness matrix
|
||||
this->formKG(*eKg,dNdX,sigma,detJW);
|
||||
|
||||
@@ -19,17 +19,14 @@
|
||||
|
||||
/*!
|
||||
\brief Class representing the integrand of the linear elasticity problem.
|
||||
\details This class supports constant isotrophic material properties only.
|
||||
Properties with spatial variation has to be implemented as sub-classes.
|
||||
*/
|
||||
|
||||
class LinearElasticity : public Elasticity
|
||||
{
|
||||
public:
|
||||
//! \brief The default constructor initializes all pointers to zero.
|
||||
//! \brief Default constructor.
|
||||
//! \param[in] n Number of spatial dimensions
|
||||
//! \param[in] ps If \e true, assume plane stress in 2D
|
||||
LinearElasticity(unsigned short int n = 3, bool ps = true);
|
||||
LinearElasticity(unsigned short int n = 3);
|
||||
//! \brief Empty destructor.
|
||||
virtual ~LinearElasticity() {}
|
||||
|
||||
|
||||
63
src/Integrands/MaterialBase.h
Normal file
63
src/Integrands/MaterialBase.h
Normal file
@@ -0,0 +1,63 @@
|
||||
// $Id$
|
||||
//==============================================================================
|
||||
//!
|
||||
//! \file MaterialBase.h
|
||||
//!
|
||||
//! \date Mar 01 2011
|
||||
//!
|
||||
//! \author Knut Morten Okstad / SINTEF
|
||||
//!
|
||||
//! \brief Base class for material models.
|
||||
//!
|
||||
//==============================================================================
|
||||
|
||||
#ifndef _MATERIAL_BASE_H
|
||||
#define _MATERIAL_BASE_H
|
||||
|
||||
#include "MatVec.h"
|
||||
|
||||
class Vec3;
|
||||
class Tensor;
|
||||
class SymmTensor;
|
||||
struct TimeDomain;
|
||||
|
||||
|
||||
/*!
|
||||
\brief Base class representing a material model of a PDE problem.
|
||||
*/
|
||||
|
||||
class Material
|
||||
{
|
||||
protected:
|
||||
//! \brief The default constructor is protected to allow sub-classes only.
|
||||
Material() {}
|
||||
|
||||
public:
|
||||
//! \brief Empty destructor.
|
||||
virtual ~Material() {}
|
||||
|
||||
//! \brief Prints out material parameters to the given output stream.
|
||||
virtual void print(std::ostream&) const {}
|
||||
|
||||
//! \brief Evaluates the mass density at current point.
|
||||
virtual double getMassDensity(const Vec3&) const { return 0.0; }
|
||||
|
||||
//! \brief Evaluates the constitutive relation at an integration point.
|
||||
//! \param[out] C Constitutive matrix at current point
|
||||
//! \param[out] sigma Stress tensor at current point
|
||||
//! \param[out] U Strain energy density at current point
|
||||
//! \param[in] X Cartesian coordinates of current point
|
||||
//! \param[in] F Deformation gradient at current point
|
||||
//! \param[in] eps Strain tensor at current point
|
||||
//! \param[in] iop Calculation option;
|
||||
//! -1 : Calculate the inverse constitutive matrix only,
|
||||
//! 0 : Calculate the consitutive matrix only,
|
||||
//! 1 : Cauchy stresses and the tangent constitutive matrix,
|
||||
//! 2 : 2nd Piola-Kirchhoff stresses and the tangent constitutive matrix.
|
||||
//! \param[in] prm Nonlinear solution algorithm parameters
|
||||
virtual bool evaluate(Matrix& C, SymmTensor& sigma, double& U,
|
||||
const Vec3& X, const Tensor& F, const SymmTensor& eps,
|
||||
char iop = 1, const TimeDomain* prm = 0) const = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -255,7 +255,7 @@ const char* Poisson::getFieldLabel (size_t i, const char* prefix) const
|
||||
|
||||
static std::string label;
|
||||
if (prefix)
|
||||
label = prefix + std::string(" ");
|
||||
label = std::string(prefix) + " ";
|
||||
else
|
||||
label.clear();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user