コード例 #1
0
void
CosseratLinearElasticMaterial::computeQpStrain()
{
    RankTwoTensor strain(_grad_disp_x[_qp], _grad_disp_y[_qp], _grad_disp_z[_qp]);
    RealVectorValue wc_vector((*_wc[0])[_qp], (*_wc[1])[_qp], (*_wc[2])[_qp]);

    for (unsigned i = 0; i < LIBMESH_DIM; ++i)
        for (unsigned j = 0; j < LIBMESH_DIM; ++j)
            for (unsigned k = 0; k < LIBMESH_DIM; ++k)
                strain(i, j) += PermutationTensor::eps(i, j, k) * wc_vector(k);

    _elastic_strain[_qp] = strain;

    _curvature[_qp] = RankTwoTensor((*_grad_wc[0])[_qp], (*_grad_wc[1])[_qp], (*_grad_wc[2])[_qp]);
}
コード例 #2
0
ファイル: SSPquad.cpp プロジェクト: fmckenna/OpenSees
int
SSPquad::update(void)
// this function updates variables for an incremental step n to n+1
{
	// get trial displacement
	const Vector &mDisp_1 = theNodes[0]->getTrialDisp();
	const Vector &mDisp_2 = theNodes[1]->getTrialDisp();
	const Vector &mDisp_3 = theNodes[2]->getTrialDisp();
	const Vector &mDisp_4 = theNodes[3]->getTrialDisp();
	
	// assemble displacement vector
	Vector u(8);
	u(0) = mDisp_1(0);
	u(1) = mDisp_1(1);
	u(2) = mDisp_2(0);
	u(3) = mDisp_2(1);
	u(4) = mDisp_3(0);
	u(5) = mDisp_3(1);
	u(6) = mDisp_4(0);
	u(7) = mDisp_4(1);

	Vector strain(3);
	strain = Mmem*u;
	theMaterial->setTrialStrain(strain);

	return 0;
}
コード例 #3
0
void
LinearIsotropicMaterial::computeProperties()
{
  for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
  {
    Real alpha = computeAlpha();

    _local_elasticity_tensor->calculate(_qp);

    _elasticity_tensor[_qp] = *_local_elasticity_tensor;

    SymmTensor strn(_grad_disp_x[_qp](0),
                    _grad_disp_y[_qp](1),
                    _grad_disp_z[_qp](2),
                    0.5 * (_grad_disp_x[_qp](1) + _grad_disp_y[_qp](0)),
                    0.5 * (_grad_disp_y[_qp](2) + _grad_disp_z[_qp](1)),
                    0.5 * (_grad_disp_z[_qp](0) + _grad_disp_x[_qp](2)));

    // Add in Isotropic Thermal Strain
    if (_has_temp)
    {
      Real isotropic_strain = alpha * (_temp[_qp] - _t_ref);

      strn.addDiag(-isotropic_strain);

      _d_strain_dT.zero();
      _d_strain_dT.addDiag(-alpha);
    }

    SymmTensor strain(strn);

    computeStress(strain, _stress[_qp]);
  }
}
コード例 #4
0
void FE2FluidMaterial :: giveVolumetricPressureStiffness(double &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)
{
    FE2FluidMaterialStatus *ms = static_cast<FE2FluidMaterialStatus*> (this->giveStatus(gp));
    ms->computeTangents(tStep);
    if ( mode == TangentStiffness ) {
        answer = ms->giveVolumetricPressureTangent();
#ifdef DEBUG_TANGENT
        // Numerical ATS for debugging
        FloatArray strain(3); strain.zero();
        FloatArray sig;
        double epspvol, epspvolh, pressure = 0.0;
        double h = 1.0; // Linear problem, size of this doesn't matter.

        computeDeviatoricStressVector(sig, epspvol, gp, strain, pressure, tStep);
        computeDeviatoricStressVector(sig, epspvolh, gp, strain, pressure+h, tStep);

        double dvol = (epspvolh - epspvol)/h;

        printf("Analytical volumetric pressure tangent = %e\n", answer);
        printf("Numerical volumetric pressure tangent = %e\n", dvol);

        double norm = fabs(dvol - answer);
        if (norm > fabs(answer)*DEBUG_ERR && norm > 0.0) {
            OOFEM_ERROR("Error in volumetric pressure tangent");
        }
#endif
    } else {
        OOFEM_ERROR("Mode not implemented");
    }
}
コード例 #5
0
void FE2FluidMaterial :: giveDeviatoricPressureStiffness(FloatArray &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)
{
    FE2FluidMaterialStatus *ms = static_cast<FE2FluidMaterialStatus*> (this->giveStatus(gp));
    ms->computeTangents(tStep);
    if ( mode == TangentStiffness ) {
        answer = ms->giveDeviatoricPressureTangent();
#ifdef DEBUG_TANGENT
        // Numerical ATS for debugging
        FloatArray strain(3); strain.zero();
        FloatArray sig, sigh;
        double epspvol, pressure = 0.0;
        double h = 1.00; // Linear problem, size of this doesn't matter.
        computeDeviatoricStressVector (sig, epspvol, gp, strain, pressure, tStep);
        computeDeviatoricStressVector (sigh, epspvol, gp, strain, pressure+h, tStep);

        FloatArray dsigh; dsigh.beDifferenceOf(sigh,sig); dsigh.times(1/h);

        printf("Analytical deviatoric pressure tangent = "); answer.printYourself();
        printf("Numerical deviatoric pressure tangent = "); dsigh.printYourself();
        dsigh.subtract(answer);
        double norm = dsigh.computeNorm();
        if (norm > answer.computeNorm()*DEBUG_ERR && norm > 0.0) {
            OOFEM_ERROR("Error in deviatoric pressure tangent");
        }
#endif
    } else {
        OOFEM_ERROR("Mode not implemented");
    }
}
コード例 #6
0
//get the strain and integrate plasticity equations
int MultiaxialCyclicPlasticityPlaneStrain :: setTrialStrain( const Vector &strain_from_element) 
{
  strain.Zero( ) ;

  strain(0,0) =        strain_from_element(0) ;
  strain(1,1) =        strain_from_element(1) ;
  strain(0,1) = 0.50 * strain_from_element(2) ;
  strain(1,0) =        strain(0,1) ;

  if (this->MaterialStageID ==1) { 
	  this->elastic_integrator( ) ;
  } else if (this->MaterialStageID ==2) {	  
	  this->plastic_integrator( ) ;
  }
  return 0 ;
}
コード例 #7
0
ファイル: abaqususermaterial.C プロジェクト: aishugang/oofem
void AbaqusUserMaterial :: give3dMaterialStiffnessMatrix(FloatMatrix &answer,
                                                         MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)
{
    AbaqusUserMaterialStatus *ms = dynamic_cast< AbaqusUserMaterialStatus * >( this->giveStatus(gp) );
    if ( !ms->hasTangent() ) { ///@todo Make this hack fit more nicely into OOFEM in general;
        // Evaluating the function once, so that the tangent can be obtained.
        FloatArray stress(6), strain(6);
        strain.zero();
        this->giveRealStressVector_3d(stress, gp, strain, tStep);
    }

    answer = ms->giveTempTangent();

#if 0
    double h = 1e-7;
    FloatArray strain, strainh, stress, stressh;
    strain = static_cast< StructuralMaterialStatus * >( gp->giveMaterialStatus() )->giveTempStrainVector();
    stress = static_cast< StructuralMaterialStatus * >( gp->giveMaterialStatus() )->giveTempStressVector();
    FloatMatrix En( strain.giveSize(), strain.giveSize() );
    for ( int i = 1; i <= strain.giveSize(); ++i ) {
        strainh = strain;
        strainh.at(i) += h;
        this->giveRealStressVector_3d(stressh, form, gp, strainh, tStep);
        stressh.subtract(stress);
        stressh.times(1.0 / h);
        En.setColumn(stressh, i);
    }
    this->giveRealStressVector_3d(stress, form, gp, strain, tStep);

    printf("En = ");
    En.printYourself();
    printf("Tangent = ");
    answer.printYourself();
#endif
}
コード例 #8
0
Vec3D<> CVX_Voxel::poissonsStrain() const
{
	vfloat mu = mat->poissonsRatio();
	Vec3D<> tensileStrain = strain(true);
	return Vec3D<>(	tensileStrain.x + pow(1+tensileStrain.y + tensileStrain.z, -mu)-1, 
					tensileStrain.y + pow(1+tensileStrain.x + tensileStrain.z, -mu)-1, 
					tensileStrain.z + pow(1+tensileStrain.x + tensileStrain.y, -mu)-1);
}
コード例 #9
0
void
ComputeCosseratSmallStrain::computeQpProperties()
{
  RankTwoTensor strain((*_grad_disp[0])[_qp], (*_grad_disp[1])[_qp], (*_grad_disp[2])[_qp]);
  RealVectorValue wc_vector((*_wc[0])[_qp], (*_wc[1])[_qp], (*_wc[2])[_qp]);

  for (unsigned i = 0; i < LIBMESH_DIM; ++i)
    for (unsigned j = 0; j < LIBMESH_DIM; ++j)
      for (unsigned k = 0; k < LIBMESH_DIM; ++k)
        strain(i, j) += PermutationTensor::eps(i, j, k) * wc_vector(k);

  _total_strain[_qp] = strain;

  _mechanical_strain[_qp] = strain;
  for (auto es : _eigenstrains)
    _mechanical_strain[_qp] -= (*es)[_qp];

  _curvature[_qp] = RankTwoTensor((*_grad_wc[0])[_qp], (*_grad_wc[1])[_qp], (*_grad_wc[2])[_qp]);
}
コード例 #10
0
//receive the strain
int
PlateRebarMaterial::setTrialStrain( const Vector &strainFromElement )
{
    strain(0) = strainFromElement(0) ;
    strain(1) = strainFromElement(1) ;
    strain(2) = strainFromElement(2) ;
    strain(3) = strainFromElement(3) ;
    strain(4) = strainFromElement(4) ;

    return theMat->setTrialStrain(   strain(0) * c * c
                                     + strain(1) * s * s
                                     + strain(2) * c * s,
                                     0) ;
}
コード例 #11
0
ファイル: CHak3DCont8.cpp プロジェクト: jiamingkang/bles
// compute C8 stress tensor at a point in the element
void CHak3DCont_8::stress(Coord3D p, double *elDisp, double *strs)
{
	double stn[6];

	// compute strain tensor (vector)
	strain(p, elDisp, stn); // NB: p should be in non-dim coordinates (i.e center = 0,0,0)

	// gwt material property matrix
    double *Em = Mat->getD();

	// multiply: stress = material matrix x strain
	cblas_dgemv(CblasRowMajor, CblasNoTrans, 6, 6, 1.0, Em, 6, stn, 1, 0.0, strs, 1);
}
コード例 #12
0
void AbaqusUserMaterial :: giveCharacteristicMatrix(FloatMatrix &answer,
                                                    MatResponseForm form, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)
{
    AbaqusUserMaterialStatus *ms = dynamic_cast< AbaqusUserMaterialStatus * >( this->giveStatus(gp) );
    if ( ~ms->hasTangent() ) { ///@todo Make this hack fit more nicely into OOFEM in general;
        // Evaluating the function once, so that the tangent can be obtained.
        MaterialMode mMode = gp->giveMaterialMode();
        int ncomp = 0;
        if ( mMode == _3dMat ) {
            ncomp = 6;
        } else if ( mMode == _PlaneStress ) {
            ncomp = 3;
        } else if ( mMode == _PlaneStrain ) {
            ncomp = 4;
        } /*else if ( mMode == _3dMat_F ) {
           * ncomp = 9;
           * } */
        else if ( mMode == _1dMat ) {
            ncomp = 1;
        }

        FloatArray stress(ncomp), strain(ncomp);
        strain.zero();
        this->giveRealStressVector(stress, form, gp, strain, tStep);
    }

    answer = ms->giveTempTangent();

#if 0
    double h = 1e-7;
    FloatArray strain, strainh, stress, stressh;
    strain = ( ( StructuralMaterialStatus * ) gp->giveMaterialStatus(AbaqusUserMaterialClass) )->giveTempStrainVector();
    stress = ( ( StructuralMaterialStatus * ) gp->giveMaterialStatus(AbaqusUserMaterialClass) )->giveTempStressVector();
    FloatMatrix En( strain.giveSize(), strain.giveSize() );
    for ( int i = 1; i <= strain.giveSize(); ++i ) {
        strainh = strain;
        strainh.at(i) += h;
        this->giveRealStressVector(stressh, form, gp, strainh, tStep);
        stressh.subtract(stress);
        stressh.times(1.0 / h);
        En.setColumn(stressh, i);
    }

    printf("En = ");
    En.printYourself();
    printf("Tangent = ");
    answer.printYourself();
#endif
}
コード例 #13
0
  // Second Piola-Kirchhoff stress (mechanical)
   const dSymMatrixT&
  FSDEMatIsotropicSurfaceT::S_IJ()
  {
	dSymMatrixT strain(NumSD());
	
	/* get mechanical part of the deformation gradient */
	const dMatrixT& F_mech = F_mechanical();

	/* strain */
	Compute_E(F_mech, strain);

	/* compute stress */
	fIsotropicStress.A_ijkl_B_kl(fModulusKStV, strain);
	return fIsotropicStress;
  }
コード例 #14
0
//receive the strain
int 
PlateFromPlaneStressMaterialThermal::setTrialStrain( const Vector &strainFromElement )
{
  strain(0) = strainFromElement(0) ;
  strain(1) = strainFromElement(1) ;
  strain(2) = strainFromElement(2) ;
  strain(3) = strainFromElement(3) ;
  strain(4) = strainFromElement(4) ;

  static Vector PSStrain(3) ;
  
  PSStrain(0) = strain(0);
  PSStrain(1) = strain(1);
  PSStrain(2) = strain(2);
  
  return theMat->setTrialStrain(PSStrain);
}
コード例 #15
0
void
LinearIsotropicMaterial::computeProperties()
{
  for (_qp=0; _qp < _qrule->n_points(); ++_qp)
  {
      Real alpha = computeAlpha();

    _local_elasticity_tensor->calculate(_qp);

    _elasticity_tensor[_qp] = *_local_elasticity_tensor;


    SymmTensor strn( _grad_disp_x[_qp](0),
                     _grad_disp_y[_qp](1),
                     _grad_disp_z[_qp](2),
                     0.5*(_grad_disp_x[_qp](1)+_grad_disp_y[_qp](0)),
                     0.5*(_grad_disp_y[_qp](2)+_grad_disp_z[_qp](1)),
                     0.5*(_grad_disp_z[_qp](0)+_grad_disp_x[_qp](2)) );

    // Add in Isotropic Thermal Strain
    if (_has_temp)
    {
      Real isotropic_strain = alpha * (_temp[_qp] - _t_ref);

      strn.addDiag( -isotropic_strain );

      _d_strain_dT.zero();
      _d_strain_dT.addDiag( -alpha );

    }

    SymmTensor v_strain(0);
    SymmTensor dv_strain_dT(0);
    for (unsigned int i(0); i < _volumetric_models.size(); ++i)
    {
      _volumetric_models[i]->modifyStrain(_qp, 1, v_strain, dv_strain_dT);
    }
    SymmTensor strain( v_strain );
    strain *= _dt;
    strain += strn;

    dv_strain_dT *= _dt;
    _d_strain_dT += dv_strain_dT;

    computeStress(strain, _stress[_qp]);

  }
}
コード例 #16
0
int J2ThreeDimensional :: setTrialStrainIncr( const Vector &v ) 
{
  static Vector newStrain(6);
  newStrain(0) = strain(0,0) + v(0);
  newStrain(1) = strain(1,1) + v(1);
  newStrain(2) = strain(2,2) + v(2);
  newStrain(3) = 2.0*strain(0,1) + v(3);
  newStrain(4) = 2.0*strain(1,2) + v(4);
  newStrain(5) = 2.0*strain(2,0) + v(5);
  
  return this->setTrialStrain(newStrain);
}
コード例 #17
0
//send back the strain
const Vector& J2ThreeDimensional :: getStrain( ) 
{
  strain_vec(0) =       strain(0,0) ;
  strain_vec(1) =       strain(1,1) ;
  strain_vec(2) =       strain(2,2) ;

  strain_vec(3) = 2.0 * strain(0,1) ;

  strain_vec(4) = 2.0 * strain(1,2) ;

  strain_vec(5) = 2.0 * strain(2,0) ;

  return strain_vec ;
} 
コード例 #18
0
void
TrabBoneNLEmbed :: updateBeforeNonlocAverage(const FloatArray &strainVector, GaussPoint *gp, TimeStep *atTime)
{
    FloatArray SDstrainVector, fullSDStrainVector;
    double cumPlastStrain;
    TrabBoneNLEmbedStatus *nlstatus = ( TrabBoneNLEmbedStatus * ) this->giveStatus(gp);

    this->initTempStatus(gp);
    this->initGpForNewStep(gp);
    this->giveStressDependentPartOfStrainVector(SDstrainVector, gp, strainVector, atTime, VM_Total);

    nlstatus->letTempStrainVectorBe(strainVector);

    StrainVector strain( strainVector, gp->giveMaterialMode() );

    this->performPlasticityReturn(gp, strain);
    this->computeLocalCumPlastStrain(cumPlastStrain, strain, gp, atTime);

    nlstatus->setLocalCumPlastStrainForAverage(cumPlastStrain);
}
コード例 #19
0
Real
ACGrGrElasticDrivingForce::computeDFDOP(PFFunctionType type)
{
    // Access the heterogeneous strain calculated by the Solid Mechanics kernels
    RankTwoTensor strain(_elastic_strain[_qp]);

    // Compute the partial derivative of the stress wrt the order parameter
    RankTwoTensor D_stress = _D_elastic_tensor[_qp] * strain;

    switch (type)
    {
    case Residual:
        return 0.5 * D_stress.doubleContraction(strain); // Compute the deformation energy driving force

    case Jacobian:
        return 0.0;
    }

    mooseError("Invalid type passed in");
}
コード例 #20
0
ファイル: J2AxiSymm.cpp プロジェクト: aceskpark/osfeo
//get the strain and integrate plasticity equations
int J2AxiSymm :: setTrialStrain( const Vector &strain_from_element) 
{
  strain.Zero( ) ;

  strain(0,0) =        strain_from_element(0) ;
  strain(1,1) =        strain_from_element(1) ;
  strain(2,2) =        strain_from_element(2) ;

  strain(0,1) = 0.50 * strain_from_element(3) ;
  strain(1,0) =        strain(0,1) ;

  this->plastic_integrator( ) ;

  return 0 ;
}
コード例 #21
0
ファイル: fe2fluidmaterial.C プロジェクト: vivianyw/oofem
int FE2FluidMaterial :: giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
{
    FE2FluidMaterialStatus *status = static_cast< FE2FluidMaterialStatus * >( this->giveStatus(gp) );
    if ( type == IST_VOFFraction ) {
        answer = FloatArray{status->giveVOFFraction()};
        return true;
    } else if ( type == IST_Pressure ) {
        answer = FloatArray{status->givePressure()};
        return true;
    } else if ( type == IST_Undefined ) { ///@todo What should one call this value? Relation between pressure and volumetric strain-rate.
#if 0
        // Numerical ATS for debugging
        FloatArray strain(3);
        strain.zero();
        FloatArray sig;
        double epspvol, epspvolh, pressure = 0.0;
        double h = 1.0; // Linear problem, size of this doesn't matter.

        computeDeviatoricStressVector(sig, epspvol, gp, strain, pressure, tStep);
        computeDeviatoricStressVector(sig, epspvolh, gp, strain, pressure + h, tStep);

        double dvol = - ( epspvolh - epspvol ) / h;

        
        printf("Analytical volumetric pressure tangent = %f\n", status->giveVolumetricPressureTangent());
        printf("Numerical volumetric pressure tangent = %f\n", dvol);

        double norm = fabs(dvol - status->giveVolumetricPressureTangent());
        if ( norm > fabs(status->giveVolumetricPressureTangent()) * DEBUG_ERR && norm > 0.0 ) {
            OOFEM_ERROR("Error in volumetric pressure tangent");
        }
#endif
        answer = FloatArray{status->giveVolumetricPressureTangent()};
        return true;
    } else {
        return FluidDynamicMaterial :: giveIPValue(answer, gp, type, tStep);
    }
}
コード例 #22
0
//send back the stress 
const Vector& ElasticPlateSection::getStressResultant( )
{
  double D  =  E * (h*h*h) / 12.0 / ( 1.0 - nu*nu ) ; //bending modulus

  double G  =  0.5 * E / ( 1.0 + nu ) ; //shear modulus
 
  G *= five6 ;
  G *= h ;


  stress(0) = -( D*strain(0) + nu*D*strain(1) ) ;
 
  stress(1) = -( nu*D*strain(0) + D*strain(1) ) ;

  stress(2) = -0.5*D*( 1.0 - nu )*strain(2) ;

  stress(3) = G*strain(3) ;

  stress(4) = G*strain(4) ;

 
  return this->stress ;
}
コード例 #23
0
//receive the strain
int 
BeamFiberMaterial::setTrialStrain(const Vector &strainFromElement)
{
  static const double tolerance = 1.0e-08;

  strain(0) = strainFromElement(0);
  strain(1) = strainFromElement(1);
  strain(2) = strainFromElement(2);

  //newton loop to solve for out-of-plane strains

  double norm;
  static Vector condensedStress(3);
  static Vector strainIncrement(3);
  static Vector threeDstrain(6);
  static Matrix dd22(3,3);

  int count = 0;
  const int maxCount = 20;
  double norm0;

  do {

    //set three dimensional strain
    threeDstrain(0) = this->strain(0);
    threeDstrain(1) = this->Tstrain22;
    threeDstrain(2) = this->Tstrain33;
    threeDstrain(3) = this->strain(1); 
    threeDstrain(4) = this->Tgamma23;
    threeDstrain(5) = this->strain(2);

    if (theMaterial->setTrialStrain(threeDstrain) < 0) {
      opserr << "BeamFiberMaterial::setTrialStrain - setStrain failed in material with strain " << threeDstrain;
      return -1;   
    }

    //three dimensional stress
    const Vector &threeDstress = theMaterial->getStress();

    //three dimensional tangent 
    const Matrix &threeDtangent = theMaterial->getTangent();

    //NDmaterial strain order        = 11, 22, 33, 12, 23, 31  
    //BeamFiberMaterial strain order = 11, 12, 31, 22, 33, 23

    condensedStress(0) = threeDstress(1);
    condensedStress(1) = threeDstress(2);
    condensedStress(2) = threeDstress(4);

    dd22(0,0) = threeDtangent(1,1);
    dd22(1,0) = threeDtangent(2,1);
    dd22(2,0) = threeDtangent(4,1);

    dd22(0,1) = threeDtangent(1,2);
    dd22(1,1) = threeDtangent(2,2);
    dd22(2,1) = threeDtangent(4,2);

    dd22(0,2) = threeDtangent(1,4);
    dd22(1,2) = threeDtangent(2,4);
    dd22(2,2) = threeDtangent(4,4);

    //set norm
    norm = condensedStress.Norm();
    if (count == 0)
      norm0 = norm;

    //condensation 
    dd22.Solve(condensedStress, strainIncrement);

    //update out of plane strains
    this->Tstrain22 -= strainIncrement(0);
    this->Tstrain33 -= strainIncrement(1);
    this->Tgamma23  -= strainIncrement(2);

  } while (count++ < maxCount && norm > tolerance);

  return 0;
}
コード例 #24
0
bool CVX_MaterialLink::updateAll()
{
	nomSize = 0.5*(vox1Mat->nomSize + vox2Mat->nomSize); //these should be the same...

	r=(int)(0.5*(vox1Mat->r + vox2Mat->r));
	g=(int)(0.5*(vox1Mat->g + vox2Mat->g));
	b=(int)(0.5*(vox1Mat->b + vox2Mat->b));
	a=(int)(0.5*(vox1Mat->a + vox2Mat->a));

	rho = 0.5f*(vox1Mat->rho + vox2Mat->rho);
	alphaCTE = 0.5f*(vox1Mat->alphaCTE + vox2Mat->alphaCTE);
	muStatic = 0.5f*(vox1Mat->muStatic + vox2Mat->muStatic);
	muKinetic = 0.5f*(vox1Mat->muKinetic + vox2Mat->muKinetic);
	zetaInternal = 0.5f*(vox1Mat->zetaInternal + vox2Mat->zetaInternal);
	zetaGlobal = 0.5f*(vox1Mat->zetaGlobal + vox2Mat->zetaGlobal);
	zetaCollision= 0.5f*(vox1Mat->zetaCollision + vox2Mat->zetaCollision);

	extScale=Vec3D<>(1.0, 1.0, 1.0);

	//failure stress (f) is the minimum of the two failure stresses, or if both are -1.0f it should also be -1.0f to denote no failure specified
	float stressFail=-1.0f, /*strainFail=-1.0f,*/ f1=vox1Mat->sigmaFail, f2=vox2Mat->sigmaFail;
	if (f1 == -1.0f) stressFail = f2; //-1.0f or vox2Mat fail
	else if (f2 == -1.0f) stressFail = f1; //vox1Mat fail
	else stressFail = f1 < f2 ? f1 : f2; //the lesser stress denotes failure

	if (vox1Mat->linear && vox2Mat->linear) setModelLinear(2.0f*vox1Mat->E*vox2Mat->E/(vox1Mat->E+vox2Mat->E), stressFail);
	else { //at least 1 bilinear or data-based, so build up data points and apply it.
		std::vector<float> newStressValues, newStrainValues;
		newStressValues.push_back(0.0f);
		newStrainValues.push_back(0.0f);

		//step up through ascending strains data points (could alternate randomly between vox1Mat and vox2Mat points
		int dataIt1 = 1, dataIt2 = 1; //iterators through each data point of the model
		while (dataIt1 < (int)vox1Mat->strainData.size() && dataIt2 < (int)vox2Mat->strainData.size()){
			float strain = FLT_MAX; //strain for the next data point is the smaller of the two possible next strain points (but we have to make sure we don't access off the end of one of the arrays)
			if (dataIt1 < (int)vox1Mat->strainData.size()) strain = vox1Mat->strainData[dataIt1];
			if (dataIt2 < (int)vox2Mat->strainData.size() && vox2Mat->strainData[dataIt2]<strain) strain = vox2Mat->strainData[dataIt2];
			else assert(strain != FLT_MAX); //this should never happen

			if (strain == vox1Mat->strainData[dataIt1]) dataIt1++;
			if (strain == vox2Mat->strainData[dataIt2]) dataIt2++;


			float modulus1 = vox1Mat->modulus(strain-FLT_EPSILON);
			float modulus2 = vox2Mat->modulus(strain-FLT_EPSILON);
			float thisModulus = 2.0f*modulus1*modulus2/(modulus1+modulus2);

			//add to the new strain/stress values
			int lastDataIndex = newStrainValues.size()-1;

			newStrainValues.push_back(strain);
			newStressValues.push_back(newStressValues[lastDataIndex] + thisModulus*(strain - newStrainValues[lastDataIndex])); //springs in series equation
		}

		setModel(newStrainValues.size(), &newStrainValues[0], &newStressValues[0]);

		//override failure points in case no failure was specified before (as possible in combos of linear and bilinear materials)
		//yield point is handled correctly in setModel.
		sigmaFail = stressFail;
		epsilonFail = stressFail==-1.0f ? -1.0f : strain(stressFail);
	}

	//poissons ratio: choose such that Ehat ends up according to spring in series of Ehat1 and EHat2
	if (vox1Mat->nu==0 && vox2Mat->nu==0) nu = 0;
	else { //poissons ratio: choose such that Ehat ends up according to spring in series of Ehat1 and EHat2
		float tmpEHat = 2*vox1Mat->_eHat*vox2Mat->_eHat/(vox1Mat->_eHat+vox2Mat->_eHat);
		float tmpE = youngsModulus();
		//completing the square algorithm to solve for nu.
		//eHat = E/((1-2nu)(1+nu)) -> E/EHat = -2nu^2-nu+1 -> nu^2+0.5nu = (EHat+E)/(2EHat)
		float c2 = (tmpEHat-tmpE)/(2*tmpEHat)+0.0625; //nu^2+0.5nu+0.0625 = c2 -> (nu+0.25)^2 = c2
		nu = sqrt(c2)-0.25; //from solving above
	}

	return updateDerived();
}
コード例 #25
0
ファイル: fe2fluidmaterial.C プロジェクト: vivianyw/oofem
void FE2FluidMaterial :: giveStiffnessMatrices(FloatMatrix &dsdd, FloatArray &dsdp, FloatArray &dedd, double &dedp,
                                               MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)
{
    FE2FluidMaterialStatus *ms = static_cast< FE2FluidMaterialStatus * >( this->giveStatus(gp) );
    ms->computeTangents(tStep);
    if ( mode == TangentStiffness ) {
        dsdd = ms->giveDeviatoricTangent();
        dsdp = ms->giveDeviatoricPressureTangent();
        dedd = ms->giveVolumetricDeviatoricTangent();
        dedp = ms->giveVolumetricPressureTangent();
#if 0
        // Numerical ATS for debugging
        FloatMatrix numericalATS(6, 6);
        FloatArray dsig;
        FloatArray tempStrain(6);

        tempStrain.zero();
        FloatArray sig, strain, sigPert;
        double epspvol;
        computeDeviatoricStressVector(sig, epspvol, gp, tempStrain, 0., tStep);
        double h = 0.001; // Linear problem, size of this doesn't matter.
        for ( int k = 1; k <= 6; ++k ) {
            strain = tempStrain;
            strain.at(k) += h;
            double tmp = strain.at(1) + strain.at(2) + strain.at(3);
            strain.at(1) -= tmp/3.0;
            strain.at(2) -= tmp/3.0;
            strain.at(3) -= tmp/3.0;
            strain.printYourself();
            computeDeviatoricStressVector(sigPert, epspvol, gp, strain, 0., tStep);
            sigPert.printYourself();
            dsig.beDifferenceOf(sigPert, sig);
            numericalATS.setColumn(dsig, k);
        }
        numericalATS.times(1. / h);

        printf("Analytical deviatoric tangent = ");
        dsdd.printYourself();
        printf("Numerical deviatoric tangent = ");
        numericalATS.printYourself();
        numericalATS.subtract(dsdd);
        double norm = numericalATS.computeFrobeniusNorm();
        if ( norm > dsdd.computeFrobeniusNorm() * DEBUG_ERR && norm > 0.0 ) {
            OOFEM_ERROR("Error in deviatoric tangent");
        }
#endif
#if 0
        // Numerical ATS for debugging
        FloatArray strain(3);
        strain.zero();
        FloatArray sig, sigh;
        double epspvol, pressure = 0.0;
        double h = 1.00; // Linear problem, size of this doesn't matter.
        computeDeviatoricStressVector(sig, epspvol, gp, strain, pressure, tStep);
        computeDeviatoricStressVector(sigh, epspvol, gp, strain, pressure + h, tStep);

        FloatArray dsigh;
        dsigh.beDifferenceOf(sigh, sig);
        dsigh.times(1 / h);

        printf("Analytical deviatoric pressure tangent = ");
        dsdp.printYourself();
        printf("Numerical deviatoric pressure tangent = ");
        dsigh.printYourself();
        dsigh.subtract(dsdp);
        double norm = dsigh.computeNorm();
        if ( norm > dsdp.computeNorm() * DEBUG_ERR && norm > 0.0 ) {
            OOFEM_ERROR("Error in deviatoric pressure tangent");
        }
#endif
#if 0
        // Numerical ATS for debugging
        FloatArray tempStrain(3);
        tempStrain.zero();
        FloatArray sig, strain;
        double epspvol, epspvol11, epspvol22, epspvol12, pressure = 0.0;
        double h = 1.0; // Linear problem, size of this doesn't matter.

        computeDeviatoricStressVector(sig, epspvol, gp, tempStrain, pressure, tStep);
        strain = tempStrain;
        strain.at(1) += h;
        computeDeviatoricStressVector(sig, epspvol11, gp, strain, pressure, tStep);
        strain = tempStrain;
        strain.at(2) += h;
        computeDeviatoricStressVector(sig, epspvol22, gp, strain, pressure, tStep);
        strain = tempStrain;
        strain.at(3) += h;
        computeDeviatoricStressVector(sig, epspvol12, gp, strain, pressure, tStep);

        FloatArray dvol(3);
        dvol.at(1) = ( epspvol11 - epspvol ) / h;
        dvol.at(2) = ( epspvol22 - epspvol ) / h;
        dvol.at(3) = ( epspvol12 - epspvol ) / h;
        dvol.at(1) += 1.0;
        dvol.at(2) += 1.0;

        printf("Analytical volumetric deviatoric tangent = ");
        dedd.printYourself();
        printf("Numerical volumetric deviatoric tangent = ");
        dvol.printYourself();
        dvol.subtract(dedd);
        double norm = dvol.computeNorm();
        if ( norm > dedd.computeNorm() * DEBUG_ERR && norm > 0.0 ) {
            OOFEM_ERROR("Error in volumetric deviatoric tangent");
        }
#endif
#if 0
        // Numerical ATS for debugging
        FloatArray strain(3);
        strain.zero();
        FloatArray sig;
        double epspvol, epspvolh, pressure = 0.0;
        double h = 1.0; // Linear problem, size of this doesn't matter.

        computeDeviatoricStressVector(sig, epspvol, gp, strain, pressure, tStep);
        computeDeviatoricStressVector(sig, epspvolh, gp, strain, pressure + h, tStep);

        double dvol = -( epspvolh - epspvol ) / h;

        printf("Analytical volumetric pressure tangent = %e\n", dedp);
        printf("Numerical volumetric pressure tangent = %e\n", dvol);

        double norm = fabs(dvol - dedp);
        if ( norm > fabs(dedp) * DEBUG_ERR && norm > 0.0 ) {
            OOFEM_ERROR("Error in volumetric pressure tangent");
        }
#endif
    } else {
        OOFEM_ERROR("Mode not implemented");
    }
}
コード例 #26
0
LatticeMinimizer::LatticeMinimizer(Everything& e) : e(e), Rorig(e.gInfo.R)
{
	logPrintf("\n--------- Lattice Minimization ---------\n");
	
	//Ensure that lattice-move-scale is commensurate with symmetries:
	std::vector<matrix3<int>> sym = e.symm.getMatrices();
	for(const matrix3<int>& m: sym)
		for(int i=0; i<3; i++)
			for(int j=0; j<3; j++)
				if(m(i,j) && e.cntrl.lattMoveScale[i] != e.cntrl.lattMoveScale[j])
					die("latt-move-scale is not commensurate with symmetries:\n"
						"\t(Lattice vectors #%d and #%d are connected by symmetry,\n"
						"\tbut have different move scale factors %lg != %lg).\n",
						i, j, e.cntrl.lattMoveScale[i], e.cntrl.lattMoveScale[j]);
	
	//Check which lattice vectors can be altered:
	vector3<bool> isFixed, isTruncated = e.coulombParams.isTruncated();
	for(int k=0; k<3; k++)
		isFixed[k] = (e.cntrl.lattMoveScale[k]==0.) || isTruncated[k];
	
	//Create a orthonormal basis for strain commensurate with symmetries:
	for(int k=0; k<6; k++)
	{	//Initialize a basis element for arbitrary symmetric matrices:
		matrix3<int> s; //all zero:
		if(k<3) //diagonal strain
		{	s(k,k) = 1;
			if(isFixed[k]) continue; //strain alters fixed direction
		}
		else //off-diagonal strain
		{	int i=(k+1)%3;
			int j=(k+2)%3;
			s(i,j) = s(j,i) = 1;
			if(isFixed[i] || isFixed[j]) continue;  //strain alters fixed direction
		}
		//Symmetrize:
		matrix3<int> sSym;
		for(const matrix3<int>& m: sym)
		{	matrix3<int> mInv = det(m) * adjugate(m); //since |det(m)| = 1
			sSym += mInv * s * m;
		}
		//Orthonormalize w.r.t previous basis elements:
		matrix3<> strain(sSym); //convert from integer to double matrix
		for(const matrix3<>& sPrev: strainBasis)
			strain -= sPrev * dot(sPrev, strain);
		double strainNorm = nrm2(strain);
		if(strainNorm < symmThresholdSq) continue; //linearly dependent
		strainBasis.push_back((1./strainNorm) * strain);
	}
	if(!strainBasis.size())
		die("All lattice-vectors are constrained by coulomb truncation and/or\n"
			"latt-move-scale: please disable lattice minimization.\n");
	
	//Print initialization status:
	e.latticeMinParams.nDim = strainBasis.size();
	logPrintf("Minimization of dimension %lu over strains spanned by:\n", strainBasis.size());
	for(const matrix3<>& s: strainBasis)
	{	s.print(globalLog, " %lg ");
		logPrintf("\n");
	}

	h = 1e-5;
}
コード例 #27
0
int
main(int ac, char* av[])
{
  KokkosGuard kokkos(ac, av);

  typedef PHX::MDField<PHAL::AlbanyTraits::Residual::ScalarT>::size_type
                                                size_type;
  typedef PHAL::AlbanyTraits::Residual          Residual;
  typedef PHAL::AlbanyTraits::Residual::ScalarT ScalarT;
  typedef PHAL::AlbanyTraits                    Traits;
  std::cout.precision(15);
  //
  // Create a command line processor and parse command line options
  //
  Teuchos::CommandLineProcessor command_line_processor;

  command_line_processor.setDocString(
      "Material Point Simulator.\n"
      "For testing material models in LCM.\n");

  std::string input_file = "materials.xml";
  command_line_processor.setOption("input", &input_file, "Input File Name");

  std::string timing_file = "timing.csv";
  command_line_processor.setOption("timing", &timing_file, "Timing File Name");

  int workset_size = 1;
  command_line_processor.setOption("wsize", &workset_size, "Workset Size");

  int num_pts = 1;
  command_line_processor.setOption(
      "npoints", &num_pts, "Number of Gaussian Points");

  size_t memlimit = 1024;  // 1GB heap limit by default
  command_line_processor.setOption(
      "memlimit", &memlimit, "Heap memory limit in MB for CUDA kernels");

  // Throw a warning and not error for unrecognized options
  command_line_processor.recogniseAllOptions(true);

  // Don't throw exceptions for errors
  command_line_processor.throwExceptions(false);

  // Parse command line
  Teuchos::CommandLineProcessor::EParseCommandLineReturn parse_return =
      command_line_processor.parse(ac, av);

  std::ofstream tout(timing_file.c_str());

  if (parse_return == Teuchos::CommandLineProcessor::PARSE_HELP_PRINTED) {
    return 0;
  }

  if (parse_return != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL) {
    return 1;
  }

  util::TimeMonitor& tmonitor =
      util::PerformanceContext::instance().timeMonitor();
  Teuchos::RCP<Teuchos::Time> total_time   = tmonitor["MPS: Total Time"];
  Teuchos::RCP<Teuchos::Time> compute_time = tmonitor["MPS: Compute Time"];

  //
  // Process material.xml file
  // Read into materialDB and get material model name
  //

  // A mpi object must be instantiated before using the comm to read
  // material file
  Teuchos::GlobalMPISession        mpi_session(&ac, &av);
  Teuchos::RCP<const Teuchos_Comm> commT =
      Albany::createTeuchosCommFromMpiComm(Albany_MPI_COMM_WORLD);

  Teuchos::RCP<Albany::MaterialDatabase> material_db;
  material_db = Teuchos::rcp(new Albany::MaterialDatabase(input_file, commT));

  // Get the name of the material model to be used (and make sure there is one)
  std::string element_block_name = "Block0";
  std::string material_model_name;
  material_model_name =
      material_db->getElementBlockSublist(element_block_name, "Material Model")
          .get<std::string>("Model Name");
  TEUCHOS_TEST_FOR_EXCEPTION(
      material_model_name.length() == 0,
      std::logic_error,
      "A material model must be defined for block: " + element_block_name);

  //
  // Preloading stage setup
  // set up evaluators, create field and state managers
  //

  // Set up the data layout
  // const int workset_size = 1;
  const int                           num_dims     = 3;
  const int                           num_vertices = 8;
  const int                           num_nodes    = 8;
  const Teuchos::RCP<Albany::Layouts> dl = Teuchos::rcp(new Albany::Layouts(
      workset_size, num_vertices, num_nodes, num_pts, num_dims));

  // create field name strings
  LCM::FieldNameMap                                field_name_map(false);
  Teuchos::RCP<std::map<std::string, std::string>> fnm =
      field_name_map.getMap();

  //---------------------------------------------------------------------------
  // Deformation gradient
  // initially set the deformation gradient to the identity

  Teuchos::ArrayRCP<ScalarT> def_grad(workset_size * num_pts * 9);
  for (int i = 0; i < workset_size; ++i) {
    for (int j = 0; j < num_pts; ++j) {
      int base = i * num_pts * 9 + j * 9;
      for (int k = 0; k < 9; ++k) def_grad[base + k] = 0.0;

      def_grad[base + 0] = 1.0;
      def_grad[base + 4] = 1.0;
      def_grad[base + 8] = 1.0;
    }
  }
  // SetField evaluator, which will be used to manually assign a value
  // to the def_grad field
  Teuchos::ParameterList setDefGradP("SetFieldDefGrad");
  setDefGradP.set<std::string>("Evaluated Field Name", "F");
  setDefGradP.set<Teuchos::RCP<PHX::DataLayout>>(
      "Evaluated Field Data Layout", dl->qp_tensor);
  setDefGradP.set<Teuchos::ArrayRCP<ScalarT>>("Field Values", def_grad);
  auto setFieldDefGrad =
      Teuchos::rcp(new LCM::SetField<Residual, Traits>(setDefGradP));

  //---------------------------------------------------------------------------
  // Det(deformation gradient)
  Teuchos::ArrayRCP<ScalarT> detdefgrad(workset_size * num_pts);
  for (int i = 0; i < workset_size * num_pts; ++i) detdefgrad[i] = 1.0;
  // SetField evaluator, which will be used to manually assign a value
  // to the detdefgrad field
  Teuchos::ParameterList setDetDefGradP("SetFieldDetDefGrad");
  setDetDefGradP.set<std::string>("Evaluated Field Name", "J");
  setDetDefGradP.set<Teuchos::RCP<PHX::DataLayout>>(
      "Evaluated Field Data Layout", dl->qp_scalar);
  setDetDefGradP.set<Teuchos::ArrayRCP<ScalarT>>("Field Values", detdefgrad);
  auto setFieldDetDefGrad =
      Teuchos::rcp(new LCM::SetField<Residual, Traits>(setDetDefGradP));

  //---------------------------------------------------------------------------
  // Small strain tensor
  // initially set the strain tensor to zeros

  Teuchos::ArrayRCP<ScalarT> strain(workset_size * num_pts * 9);
  for (int i = 0; i < workset_size; ++i) {
    for (int j = 0; j < num_pts; ++j) {
      int base = i * num_pts * 9 + j * 9;
      for (int k = 0; k < 9; ++k) strain[base + k] = 0.0;
    }
  }

  // SetField evaluator, which will be used to manually assign a value
  // to the strain field
  Teuchos::ParameterList setStrainP("SetFieldStrain");
  setStrainP.set<std::string>("Evaluated Field Name", "Strain");
  setStrainP.set<Teuchos::RCP<PHX::DataLayout>>(
      "Evaluated Field Data Layout", dl->qp_tensor);
  setStrainP.set<Teuchos::ArrayRCP<ScalarT>>("Field Values", strain);
  auto setFieldStrain =
      Teuchos::rcp(new LCM::SetField<Residual, Traits>(setStrainP));
  //---------------------------------------------------------------------------
  // Instantiate a field manager
  PHX::FieldManager<Traits> fieldManager;

  // Instantiate a field manager for States
  PHX::FieldManager<Traits> stateFieldManager;

  // Register the evaluators with the field manager
  fieldManager.registerEvaluator<Residual>(setFieldDefGrad);
  fieldManager.registerEvaluator<Residual>(setFieldDetDefGrad);
  fieldManager.registerEvaluator<Residual>(setFieldStrain);

  // Register the evaluators with the state field manager
  stateFieldManager.registerEvaluator<Residual>(setFieldDefGrad);
  stateFieldManager.registerEvaluator<Residual>(setFieldDetDefGrad);
  stateFieldManager.registerEvaluator<Residual>(setFieldStrain);

  // Instantiate a state manager
  Albany::StateManager stateMgr;

  // extract the Material ParameterList for use below
  std::string matName = material_db->getElementBlockParam<std::string>(
      element_block_name, "material");
  Teuchos::ParameterList& paramList =
      material_db->getElementBlockSublist(element_block_name, matName);
  Teuchos::ParameterList& mpsParams =
      paramList.sublist("Material Point Simulator");

  // Get loading parameters from .xml file
  std::string load_case =
      mpsParams.get<std::string>("Loading Case Name", "uniaxial");
  int    number_steps = mpsParams.get<int>("Number of Steps", 10);
  double step_size    = mpsParams.get<double>("Step Size", 1.0e-2);

  std::cout << "Loading parameters:"
            << "\n  number of steps: " << number_steps
            << "\n  step_size      : " << step_size << std::endl;

  // determine if temperature is being used
  bool have_temperature = mpsParams.get<bool>("Use Temperature", false);
  std::cout << "have_temp: " << have_temperature << std::endl;
  //---------------------------------------------------------------------------
  // Temperature (optional)
  if (have_temperature) {
    Teuchos::ArrayRCP<ScalarT> temperature(workset_size);
    ScalarT                    temp = mpsParams.get<double>("Temperature", 1.0);
    for (int i = 0; i < workset_size * num_pts; ++i) temperature[0] = temp;
    // SetField evaluator, which will be used to manually assign a value
    // to the detdefgrad field
    Teuchos::ParameterList setTempP("SetFieldTemperature");
    setTempP.set<std::string>("Evaluated Field Name", "Temperature");
    setTempP.set<Teuchos::RCP<PHX::DataLayout>>(
        "Evaluated Field Data Layout", dl->qp_scalar);
    setTempP.set<Teuchos::ArrayRCP<ScalarT>>("Field Values", temperature);
    auto setFieldTemperature =
        Teuchos::rcp(new LCM::SetField<Residual, Traits>(setTempP));
    fieldManager.registerEvaluator<Residual>(setFieldTemperature);
    stateFieldManager.registerEvaluator<Residual>(setFieldTemperature);
  }

  //---------------------------------------------------------------------------
  // Time step
  Teuchos::ArrayRCP<ScalarT> delta_time(1);
  delta_time[0] = step_size;
  Teuchos::ParameterList setDTP("SetFieldTimeStep");
  setDTP.set<std::string>("Evaluated Field Name", "Delta Time");
  setDTP.set<Teuchos::RCP<PHX::DataLayout>>(
      "Evaluated Field Data Layout", dl->workset_scalar);
  setDTP.set<Teuchos::ArrayRCP<ScalarT>>("Field Values", delta_time);
  auto setFieldDT = Teuchos::rcp(new LCM::SetField<Residual, Traits>(setDTP));
  fieldManager.registerEvaluator<Residual>(setFieldDT);
  stateFieldManager.registerEvaluator<Residual>(setFieldDT);

  // check if the material wants the tangent to be computed
  bool check_stability;
  check_stability = mpsParams.get<bool>("Check Stability", false);
  paramList.set<bool>("Compute Tangent", check_stability);

  std::cout << "Check stability = " << check_stability << std::endl;

  //---------------------------------------------------------------------------
  // std::cout << "// Constitutive Model Parameters"
  //<< std::endl;
  Teuchos::ParameterList cmpPL;
  paramList.set<Teuchos::RCP<std::map<std::string, std::string>>>(
      "Name Map", fnm);
  cmpPL.set<Teuchos::ParameterList*>("Material Parameters", &paramList);
  if (have_temperature) {
    cmpPL.set<std::string>("Temperature Name", "Temperature");
    paramList.set<bool>("Have Temperature", true);
  }
  auto CMP = Teuchos::rcp(
      new LCM::ConstitutiveModelParameters<Residual, Traits>(cmpPL, dl));
  fieldManager.registerEvaluator<Residual>(CMP);
  stateFieldManager.registerEvaluator<Residual>(CMP);

  //---------------------------------------------------------------------------
  // std::cout << "// Constitutive Model Interface Evaluator"
  // << std::endl;
  Teuchos::ParameterList cmiPL;
  cmiPL.set<Teuchos::ParameterList*>("Material Parameters", &paramList);
  if (have_temperature) {
    cmiPL.set<std::string>("Temperature Name", "Temperature");
  }
  Teuchos::RCP<LCM::ConstitutiveModelInterface<Residual, Traits>> CMI =
      Teuchos::rcp(
          new LCM::ConstitutiveModelInterface<Residual, Traits>(cmiPL, dl));
  fieldManager.registerEvaluator<Residual>(CMI);
  stateFieldManager.registerEvaluator<Residual>(CMI);

  // Set the evaluated fields as required
  for (std::vector<Teuchos::RCP<PHX::FieldTag>>::const_iterator it =
           CMI->evaluatedFields().begin();
       it != CMI->evaluatedFields().end();
       ++it) {
    fieldManager.requireField<Residual>(**it);
  }

  // register state variables
  Teuchos::RCP<Teuchos::ParameterList> p;
  Teuchos::RCP<PHX::Evaluator<Traits>> ev;
  for (int sv(0); sv < CMI->getNumStateVars(); ++sv) {
    CMI->fillStateVariableStruct(sv);
    p = stateMgr.registerStateVariable(
        CMI->getName(),
        CMI->getLayout(),
        dl->dummy,
        element_block_name,
        CMI->getInitType(),
        CMI->getInitValue(),
        CMI->getStateFlag(),
        CMI->getOutputFlag());
    ev = Teuchos::rcp(new PHAL::SaveStateField<Residual, Traits>(*p));
    fieldManager.registerEvaluator<Residual>(ev);
    stateFieldManager.registerEvaluator<Residual>(ev);
  }

  //---------------------------------------------------------------------------
  if (check_stability) {
    std::string parametrization_type =
        mpsParams.get<std::string>("Parametrization Type", "Spherical");

    double parametrization_interval =
        mpsParams.get<double>("Parametrization Interval", 0.05);

    std::cout << "Bifurcation Check in Material Point Simulator:" << std::endl;
    std::cout << "Parametrization Type: " << parametrization_type << std::endl;

    Teuchos::ParameterList bcPL;
    bcPL.set<Teuchos::ParameterList*>("Material Parameters", &paramList);
    bcPL.set<std::string>("Parametrization Type Name", parametrization_type);
    bcPL.set<double>("Parametrization Interval Name", parametrization_interval);
    bcPL.set<std::string>("Material Tangent Name", "Material Tangent");
    bcPL.set<std::string>("Ellipticity Flag Name", "Ellipticity_Flag");
    bcPL.set<std::string>("Bifurcation Direction Name", "Direction");
    bcPL.set<std::string>("Min detA Name", "Min detA");
    Teuchos::RCP<LCM::BifurcationCheck<Residual, Traits>> BC =
        Teuchos::rcp(new LCM::BifurcationCheck<Residual, Traits>(bcPL, dl));
    fieldManager.registerEvaluator<Residual>(BC);
    stateFieldManager.registerEvaluator<Residual>(BC);

    // register the ellipticity flag
    p = stateMgr.registerStateVariable(
        "Ellipticity_Flag",
        dl->qp_scalar,
        dl->dummy,
        element_block_name,
        "scalar",
        0.0,
        false,
        true);
    ev = Teuchos::rcp(new PHAL::SaveStateField<Residual, Traits>(*p));
    fieldManager.registerEvaluator<Residual>(ev);
    stateFieldManager.registerEvaluator<Residual>(ev);

    // register the direction
    p = stateMgr.registerStateVariable(
        "Direction",
        dl->qp_vector,
        dl->dummy,
        element_block_name,
        "scalar",
        0.0,
        false,
        true);
    ev = Teuchos::rcp(new PHAL::SaveStateField<Residual, Traits>(*p));
    fieldManager.registerEvaluator<Residual>(ev);
    stateFieldManager.registerEvaluator<Residual>(ev);

    // register min(det(A))
    p = stateMgr.registerStateVariable(
        "Min detA",
        dl->qp_scalar,
        dl->dummy,
        element_block_name,
        "scalar",
        0.0,
        false,
        true);
    ev = Teuchos::rcp(new PHAL::SaveStateField<Residual, Traits>(*p));
    fieldManager.registerEvaluator<Residual>(ev);
    stateFieldManager.registerEvaluator<Residual>(ev);
  }

  //---------------------------------------------------------------------------
  // std::cout << "// register deformation gradient"
  // << std::endl;
  p = stateMgr.registerStateVariable(
      "F",
      dl->qp_tensor,
      dl->dummy,
      element_block_name,
      "identity",
      1.0,
      true,
      true);
  ev = Teuchos::rcp(new PHAL::SaveStateField<Residual, Traits>(*p));
  fieldManager.registerEvaluator<Residual>(ev);
  stateFieldManager.registerEvaluator<Residual>(ev);
  //---------------------------------------------------------------------------
  // std::cout << "// register small strain tensor"
  // << std::endl;
  p = stateMgr.registerStateVariable(
      "Strain",
      dl->qp_tensor,
      dl->dummy,
      element_block_name,
      "scalar",
      0.0,
      false,
      true);
  ev = Teuchos::rcp(new PHAL::SaveStateField<Residual, Traits>(*p));
  fieldManager.registerEvaluator<Residual>(ev);
  stateFieldManager.registerEvaluator<Residual>(ev);
  //---------------------------------------------------------------------------
  //
  Traits::SetupData setupData = "Test String";
  // std::cout << "Calling postRegistrationSetup" << std::endl;
  fieldManager.postRegistrationSetup(setupData);

  // std::cout << "// set the required fields for the state manager"
  //<< std::endl;
  Teuchos::RCP<PHX::DataLayout> dummy =
      Teuchos::rcp(new PHX::MDALayout<Dummy>(0));
  std::vector<std::string> responseIDs =
      stateMgr.getResidResponseIDsToRequire(element_block_name);
  std::vector<std::string>::const_iterator it;
  for (it = responseIDs.begin(); it != responseIDs.end(); it++) {
    const std::string&                              responseID = *it;
    PHX::Tag<PHAL::AlbanyTraits::Residual::ScalarT> res_response_tag(
        responseID, dummy);
    stateFieldManager.requireField<PHAL::AlbanyTraits::Residual>(
        res_response_tag);
  }
  stateFieldManager.postRegistrationSetup("");

  // std::cout << "Process using 'dot -Tpng -O <name>'\n";
  fieldManager.writeGraphvizFile<Residual>("FM", true, true);
  stateFieldManager.writeGraphvizFile<Residual>("SFM", true, true);

  //---------------------------------------------------------------------------
  // grab the output file name
  //
  std::string output_file =
      mpsParams.get<std::string>("Output File Name", "output.exo");

  //---------------------------------------------------------------------------
  // Create discretization, as required by the StateManager
  //
  Teuchos::RCP<Teuchos::ParameterList> discretizationParameterList =
      Teuchos::rcp(new Teuchos::ParameterList("Discretization"));
  discretizationParameterList->set<int>("1D Elements", workset_size);
  discretizationParameterList->set<int>("2D Elements", 1);
  discretizationParameterList->set<int>("3D Elements", 1);
  discretizationParameterList->set<std::string>("Method", "STK3D");
  discretizationParameterList->set<int>("Number Of Time Derivatives", 0);
  discretizationParameterList->set<std::string>(
      "Exodus Output File Name", output_file);
  discretizationParameterList->set<int>("Workset Size", workset_size);
  Teuchos::RCP<Tpetra_Map>    mapT = Teuchos::rcp(new Tpetra_Map(
      workset_size * num_dims * num_nodes,
      0,
      commT,
      Tpetra::LocallyReplicated));
  Teuchos::RCP<Tpetra_Vector> solution_vectorT =
      Teuchos::rcp(new Tpetra_Vector(mapT));

  int numberOfEquations = 3;
  Albany::AbstractFieldContainer::FieldContainerRequirements req;

  Teuchos::RCP<Albany::AbstractSTKMeshStruct> stkMeshStruct =
      Teuchos::rcp(new Albany::TmplSTKMeshStruct<3>(
          discretizationParameterList, Teuchos::null, commT));
  stkMeshStruct->setFieldAndBulkData(
      commT,
      discretizationParameterList,
      numberOfEquations,
      req,
      stateMgr.getStateInfoStruct(),
      stkMeshStruct->getMeshSpecs()[0]->worksetSize);

  Teuchos::RCP<Albany::AbstractDiscretization> discretization =
      Teuchos::rcp(new Albany::STKDiscretization(
          discretizationParameterList, stkMeshStruct, commT));

  //---------------------------------------------------------------------------
  // Associate the discretization with the StateManager
  //
  stateMgr.setupStateArrays(discretization);

  //---------------------------------------------------------------------------
  // Create a workset
  //
  PHAL::Workset workset;
  workset.numCells = workset_size;
  workset.stateArrayPtr =
      &stateMgr.getStateArray(Albany::StateManager::ELEM, 0);

  // create MDFields
  PHX::MDField<ScalarT, Cell, QuadPoint, Dim, Dim> stressField(
      "Cauchy_Stress", dl->qp_tensor);

  // construct the final deformation gradient based on the loading case
  std::vector<ScalarT> F_vector(9, 0.0);
  if (load_case == "uniaxial") {
    F_vector[0] = 1.0 + number_steps * step_size;
    F_vector[4] = 1.0;
    F_vector[8] = 1.0;
  } else if (load_case == "simple-shear") {
    F_vector[0] = 1.0;
    F_vector[1] = number_steps * step_size;
    F_vector[4] = 1.0;
    F_vector[8] = 1.0;
  } else if (load_case == "hydrostatic") {
    F_vector[0] = 1.0 + number_steps * step_size;
    F_vector[4] = 1.0 + number_steps * step_size;
    F_vector[8] = 1.0 + number_steps * step_size;
  } else if (load_case == "general") {
    F_vector =
        mpsParams.get<Teuchos::Array<double>>("Deformation Gradient Components")
            .toVector();
  } else {
    TEUCHOS_TEST_FOR_EXCEPTION(
        true,
        std::runtime_error,
        "Improper Loading Case in Material Point Simulator block");
  }

  minitensor::Tensor<ScalarT> F_tensor(3, &F_vector[0]);
  minitensor::Tensor<ScalarT> log_F_tensor = minitensor::log(F_tensor);

  std::cout << "F\n" << F_tensor << std::endl;
  // std::cout << "log F\n" << log_F_tensor << std::endl;

  //
  // Setup loading scenario and instantiate evaluatFields
  //
  PHX::MDField<ScalarT, Cell, QuadPoint> minDetA("Min detA", dl->qp_scalar);
  PHX::MDField<ScalarT, Cell, QuadPoint, Dim> direction(
      "Direction", dl->qp_vector);

  // Bifurcation check parameters
  double mu_0                  = 0;
  double mu_k                  = 0;
  int    bifurcationTime_rough = number_steps;
  bool   bifurcation_flag      = false;

  for (int istep(0); istep <= number_steps; ++istep) {
    util::TimeGuard total_time_guard(total_time);
    // std::cout << "****** in MPS step " << istep << " ****** " << std::endl;
    // alpha \in [0,1]
    double alpha = double(istep) / number_steps;

    // std::cout << "alpha: " << alpha << std::endl;
    minitensor::Tensor<ScalarT> scaled_log_F_tensor = alpha * log_F_tensor;
    minitensor::Tensor<ScalarT> current_F =
        minitensor::exp(scaled_log_F_tensor);

    // std::cout << "scaled log F\n" << scaled_log_F_tensor << std::endl;
    // std::cout << "current F\n" << current_F << std::endl;

    for (int i = 0; i < 3; ++i) {
      for (int j = 0; j < 3; ++j) { def_grad[3 * i + j] = current_F(i, j); }
    }

    // jacobian
    detdefgrad[0] = minitensor::det(current_F);

    // small strain tensor
    minitensor::Tensor<ScalarT> current_strain;
    current_strain = 0.5 * (current_F + minitensor::transpose(current_F)) -
                     minitensor::eye<ScalarT>(3);

    for (int i = 0; i < 3; ++i) {
      for (int j = 0; j < 3; ++j) { strain[3 * i + j] = current_strain(i, j); }
    }
    // std::cout << "current strain\n" << current_strain << std::endl;

    // Call the evaluators, evaluateFields() is the function that
    // computes stress based on deformation gradient
    compute_time->start();
    fieldManager.preEvaluate<Residual>(workset);
    fieldManager.evaluateFields<Residual>(workset);
    fieldManager.postEvaluate<Residual>(workset);
    compute_time->stop();

    stateFieldManager.getFieldData<Residual>(stressField);

    // Call the state field manager
    // std::cout << "+++ calling the stateFieldManager\n";
    compute_time->start();
    stateFieldManager.preEvaluate<Residual>(workset);
    stateFieldManager.evaluateFields<Residual>(workset);
    stateFieldManager.postEvaluate<Residual>(workset);
    compute_time->stop();

    stateMgr.updateStates();

    // output to the exodus file
    // Don't include this in timing data...
    total_time->stop();
    discretization->writeSolutionT(
        *solution_vectorT, Teuchos::as<double>(istep));

    // if check for bifurcation, adaptive step
    total_time->start();
    if (check_stability) {
      // get current minDet(A)
      stateFieldManager.getFieldData<Residual>(minDetA);

      if (istep == 0) { mu_0 = minDetA(0, 0); }

      if (minDetA(0, 0) <= 0 && !bifurcation_flag) {
        mu_k                  = minDetA(0, 0);
        bifurcationTime_rough = istep;
        bifurcation_flag      = true;

        // adaptive step begin
        std::cout << "\nAdaptive step begin - step " << istep << std::endl;

        // initialization for adaptive step
        double tol              = 1E-8;
        double alpha_local      = 1.0;
        double alpha_local_step = 0.5;

        int k            = 1;
        int maxIteration = 50;

        // small strain tensor
        minitensor::Tensor<ScalarT> current_strain;

        // iteration begin
        while (((mu_k <= 0) || (std::abs(mu_k / mu_0) > tol))) {
          alpha =
              double(bifurcationTime_rough - 1 + alpha_local) / number_steps;

          minitensor::Tensor<ScalarT> scaled_log_F_tensor =
              alpha * log_F_tensor;
          minitensor::Tensor<ScalarT> current_F =
              minitensor::exp(scaled_log_F_tensor);

          for (int i = 0; i < 3; ++i) {
            for (int j = 0; j < 3; ++j) {
              def_grad[3 * i + j] = current_F(i, j);
            }
          }

          // jacobian
          detdefgrad[0] = minitensor::det(current_F);

          current_strain =
              0.5 * (current_F + minitensor::transpose(current_F)) -
              minitensor::eye<ScalarT>(3);

          for (int i = 0; i < 3; ++i) {
            for (int j = 0; j < 3; ++j) {
              strain[3 * i + j] = current_strain(i, j);
            }
          }

          // Call the evaluators, evaluateFields() is the function that
          // computes stress based on deformation gradient
          fieldManager.preEvaluate<Residual>(workset);
          fieldManager.evaluateFields<Residual>(workset);
          fieldManager.postEvaluate<Residual>(workset);

          // Call the state field manager
          // std::cout << "+++ calling the stateFieldManager\n";
          stateFieldManager.preEvaluate<Residual>(workset);
          stateFieldManager.evaluateFields<Residual>(workset);
          stateFieldManager.postEvaluate<Residual>(workset);

          stateFieldManager.getFieldData<Residual>(minDetA);

          stateFieldManager.getFieldData<Residual>(direction);

          mu_k = minDetA(0, 0);

          if (mu_k > 0) {
            alpha_local += alpha_local_step;
          } else {
            alpha_local -= alpha_local_step;
          }

          alpha_local_step /= 2;

          k = k + 1;

          if (k >= maxIteration) {
            std::cout
                << "Adaptive step for bifurcation check not converging after "
                << k << " iterations" << std::endl;
            break;
          }

        }  // adaptive step iteration end

      }  // end adaptive step

    }  // end check bifurcation

    stateMgr.updateStates();

    //
    if (bifurcation_flag) {
      // break the loading step after adaptive time step loop
      break;
    }

    //

  }  // end loading steps

  // Summarize with AlbanyUtil performance monitors
  if (tout) {
    util::PerformanceContext::instance().timeMonitor().summarize(tout);
    tout.close();
  }
}
コード例 #28
0
ファイル: Kinematics_Def.hpp プロジェクト: gahansen/Albany
void
Kinematics<EvalT, Traits>::evaluateFields(typename Traits::EvalData workset)
{
  minitensor::Tensor<ScalarT> F(num_dims_), strain(num_dims_), gradu(num_dims_);
  minitensor::Tensor<ScalarT> I(minitensor::eye<ScalarT>(num_dims_));

  // Compute DefGrad tensor from displacement gradient
  if (!def_grad_rc_) {
    for (int cell(0); cell < workset.numCells; ++cell) {
      for (int pt(0); pt < num_pts_; ++pt) {
        gradu.fill(grad_u_, cell, pt, 0, 0);
        F            = I + gradu;
        j_(cell, pt) = minitensor::det(F);
        for (int i(0); i < num_dims_; ++i) {
          for (int j(0); j < num_dims_; ++j) {
            def_grad_(cell, pt, i, j) = F(i, j);
          }
        }
      }
    }
  } else {
    bool first = true;
    for (int cell = 0; cell < workset.numCells; ++cell) {
      for (int pt = 0; pt < num_pts_; ++pt) {
        gradu.fill(grad_u_, cell, pt, 0, 0);
        F = I + gradu;
        for (int i = 0; i < num_dims_; ++i)
          for (int j = 0; j < num_dims_; ++j)
            def_grad_(cell, pt, i, j) = F(i, j);
        if (first && check_det(workset, cell, pt)) first = false;
        // F[n,0] = F[n,n-1] F[n-1,0].
        def_grad_rc_.multiplyInto<ScalarT>(def_grad_, cell, pt);
        F.fill(def_grad_, cell, pt, 0, 0);
        j_(cell, pt) = minitensor::det(F);
      }
    }
  }

  if (weighted_average_) {
    ScalarT jbar, weighted_jbar, volume;
    for (int cell(0); cell < workset.numCells; ++cell) {
      jbar   = 0.0;
      volume = 0.0;
      for (int pt(0); pt < num_pts_; ++pt) {
        jbar += weights_(cell, pt) * j_(cell, pt);
        volume += weights_(cell, pt);
      }
      jbar /= volume;

      for (int pt(0); pt < num_pts_; ++pt) {
        weighted_jbar = (1 - alpha_) * jbar + alpha_ * j_(cell, pt);
        F.fill(def_grad_, cell, pt, 0, 0);
        const ScalarT p = std::pow((weighted_jbar / j_(cell, pt)), 1. / 3.);
        F *= p;
        j_(cell, pt) = weighted_jbar;
        for (int i(0); i < num_dims_; ++i) {
          for (int j(0); j < num_dims_; ++j) {
            def_grad_(cell, pt, i, j) = F(i, j);
          }
        }
      }
    }
  }

  if (needs_strain_) {
    if (!def_grad_rc_) {
      for (int cell(0); cell < workset.numCells; ++cell) {
        for (int pt(0); pt < num_pts_; ++pt) {
          gradu.fill(grad_u_, cell, pt, 0, 0);
          strain = 0.5 * (gradu + minitensor::transpose(gradu));
          for (int i(0); i < num_dims_; ++i) {
            for (int j(0); j < num_dims_; ++j) {
              strain_(cell, pt, i, j) = strain(i, j);
            }
          }
        }
      }
    } else {
      for (int cell = 0; cell < workset.numCells; ++cell) {
        for (int pt = 0; pt < num_pts_; ++pt) {
          F.fill(def_grad_, cell, pt, 0, 0);
          gradu = F - I;
          // dU/dx[0] = dx[n]/dx[0] - dx[0]/dx[0] = F[n,0] - I.
          // strain = 1/2 (dU/dx[0] + dU/dx[0]^T).
          strain = 0.5 * (gradu + minitensor::transpose(gradu));
          for (int i = 0; i < num_dims_; ++i)
            for (int j = 0; j < num_dims_; ++j)
              strain_(cell, pt, i, j) = strain(i, j);
        }
      }
    }
  }
}
コード例 #29
0
//send back the stress 
const Vector&  ElasticMembranePlateSection::getStressResultant( )
{

  double M  = E / ( 1.0 - nu*nu ) ; //membrane modulus

  double G  =  0.5 * E / ( 1.0 + nu ) ; //shear modulus
 
  G *= h ;  //multiply by thickness
  M *= h ;

  //membrane resultants

  stress(0) =  M*strain(0) + (nu*M)*strain(1)  ;
 
  stress(1) =  (nu*M)*strain(0) +  M*strain(1)  ;

  stress(2) =  G*strain(2) ;

 

  G *= five6 ;  //multiply by shear correction factor

  double D  =  E * (h*h*h) / 12.0 / ( 1.0 - nu*nu ) ;  //bending modulus

  //bending resultants

  stress(3) = -( D*strain(3) + nu*D*strain(4) ) ;
 
  stress(4) = -( nu*D*strain(3) + D*strain(4) ) ;

  stress(5) = -0.5*D*( 1.0 - nu )*strain(5) ;

  stress(6) = G*strain(6) ;

  stress(7) = G*strain(7) ;

 
  return this->stress ;
}
コード例 #30
0
//get the strain and integrate plasticity equations
int J2ThreeDimensional :: setTrialStrain( const Vector &strain_from_element) 
{
  strain.Zero( ) ;

  strain(0,0) =        strain_from_element(0) ;
  strain(1,1) =        strain_from_element(1) ;
  strain(2,2) =        strain_from_element(2) ;

  strain(0,1) = 0.50 * strain_from_element(3) ;
  strain(1,0) =        strain(0,1) ;

  strain(1,2) = 0.50 * strain_from_element(4) ;
  strain(2,1) =        strain(1,2) ;
  
  strain(2,0) = 0.50 * strain_from_element(5) ;
  strain(0,2) =        strain(2,0) ;

  this->plastic_integrator( ) ;

  return 0 ;
}