void GradDpElement :: computeDeformationGradientVector(FloatArray &answer, GaussPoint *gp, TimeStep *tStep) { // Computes the deformation gradient in the Voigt format at the Gauss point gp of // the receiver at time step tStep. // Order of components: 11, 22, 33, 23, 13, 12, 32, 31, 21 in the 3D. // Obtain the current displacement vector of the element and subtract initial displacements (if present) FloatArray u; FloatMatrix B; NLStructuralElement *elem = this->giveNLStructuralElement(); this->computeDisplacementDegreesOfFreedom(u, tStep); // Displacement gradient H = du/dX elem->computeBHmatrixAt(gp, B); answer.beProductOf(B, u); // Deformation gradient F = H + I MaterialMode matMode = gp->giveMaterialMode(); if ( matMode == _3dMat || matMode == _PlaneStrain ) { answer.at(1) += 1.0; answer.at(2) += 1.0; answer.at(3) += 1.0; } else if ( matMode == _PlaneStress ) { answer.at(1) += 1.0; answer.at(2) += 1.0; } else if ( matMode == _1dMat ) { answer.at(1) += 1.0; } else { OOFEM_ERROR( "MaterialMode is not supported yet (%s)", __MaterialModeToString(matMode) ); } }
void IsotropicHeatTransferMaterial :: giveCharacteristicMatrix(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) { /* * returns constitutive (conductivity) matrix of receiver */ MaterialMode mMode = gp->giveMaterialMode(); double cond = this->giveIsotropicConductivity(gp, tStep); switch ( mMode ) { case _1dHeat: answer.resize(1, 1); answer.at(1, 1) = cond; case _2dHeat: answer.resize(2, 2); answer.at(1, 1) = cond; answer.at(2, 2) = cond; return; case _3dHeat: answer.resize(3, 3); answer.at(1, 1) = cond; answer.at(2, 2) = cond; answer.at(3, 3) = cond; return; default: OOFEM_ERROR("unknown mode (%s)", __MaterialModeToString(mMode) ); } }
void LargeStrainMasterMaterialGrad :: givePDGradMatrix_ku(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) { MaterialMode mMode = gp->giveMaterialMode(); switch ( mMode ) { case _3dMat: give3dKappaMatrix(answer, mode, gp, tStep); break; default: OOFEM_ERROR( "unknown mode (%s)", __MaterialModeToString(mMode) ); } }
FloatArray * StructuralCrossSection :: imposeStressConstrainsOnGradient(GaussPoint *gp, FloatArray *gradientStressVector3d) // // returns modified gradient of stress vector, which is used to // bring stresses back to yield surface. // // imposes zeros on places, where zero stress occurs. if energetically connected // strain is zero, we do not impose zero there, because stress exist and // must be taken into account when computing yeld function. In such case // a problem is assumed to be full 3d with some explicit strain equal to 0. // // On the other hand, if some stress is imposed to be zero, we understand // such case as subspace of 3d case (like a classical plane stess problem, with no // tracing of ez, sigma_z) // { MaterialMode mode = gp->giveMaterialMode(); int i, size = gradientStressVector3d->giveSize(); if ( size != 6 ) { _error("ImposeStressConstrainsOnGradient: gradientStressVector3d size mismatch"); } if ( mode == _3dMat ) { return gradientStressVector3d; } switch ( mode ) { case _PlaneStress: gradientStressVector3d->at(3) = 0.; gradientStressVector3d->at(4) = 0.; gradientStressVector3d->at(5) = 0.; break; case _PlaneStrain: // gradientStressVector3d ->at(3) = 0.; gradientStressVector3d->at(4) = 0.; gradientStressVector3d->at(5) = 0.; break; case _1dMat: for ( i = 2; i <= 6; i++ ) { gradientStressVector3d->at(i) = 0.; } break; default: _error2( "ImposeStressConstrainsOnGradient: unknown mode (%s)", __MaterialModeToString(mode) ); break; } return gradientStressVector3d; }
void AnisotropicMassTransferMaterial :: giveCharacteristicMatrix(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *atTime) { MaterialMode mMode = gp->giveMaterialMode(); switch ( mMode ) { case _1dHeat: case _2dHeat: case _3dHeat: answer = k; return; default: _error2( "giveCharacteristicMatrix : unknown mode (%s)", __MaterialModeToString(mMode) ); } }
FloatArray * StructuralCrossSection :: imposeStrainConstrainsOnGradient(GaussPoint *gp, FloatArray *gradientStrainVector3d) // // returns modified gradient of strain vector, which is used to // compute plastic strain increment. // // imposes zeros on places, where zero strain occurs or energetically connected stress // is prescribed to be zero. // { MaterialMode mode = gp->giveMaterialMode(); int i, size = gradientStrainVector3d->giveSize(); if ( size != 6 ) { _error("ImposeStrainConstrainsOnGradient: gradientStrainVector3d size mismatch"); } if ( mode == _3dMat ) { return gradientStrainVector3d; } switch ( mode ) { case _PlaneStress: gradientStrainVector3d->at(3) = 0.; gradientStrainVector3d->at(4) = 0.; gradientStrainVector3d->at(5) = 0.; break; case _PlaneStrain: gradientStrainVector3d->at(3) = 0.; gradientStrainVector3d->at(4) = 0.; gradientStrainVector3d->at(5) = 0.; break; case _1dMat: for ( i = 2; i <= 6; i++ ) { gradientStrainVector3d->at(i) = 0.; } break; default: _error2( "ImposeStrainConstrainsOnGradient: unknown mode (%s)", __MaterialModeToString(mode) ); break; } return gradientStrainVector3d; }
void MisesMatGrad :: givePDGradMatrix_uu(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) { MaterialMode mMode = gp->giveMaterialMode(); switch ( mMode ) { case _1dMat: give1dStressStiffMtrx(answer, mode, gp, tStep); break; case _PlaneStrain: givePlaneStrainStiffMtrx(answer, mode, gp, tStep); break; case _3dMat: give3dMaterialStiffnessMatrix(answer, mode, gp, tStep); break; default: OOFEM_ERROR("unknown mode (%s)", __MaterialModeToString(mMode) ); } }
void NonlinearMassTransferMaterial :: giveCharacteristicMatrix(FloatMatrix &answer, MatResponseForm form, MatResponseMode mode, GaussPoint *gp, TimeStep *atTime) { MaterialMode mMode = gp->giveMaterialMode(); AnisotropicMassTransferMaterialStatus *status = ( ( AnisotropicMassTransferMaterialStatus * ) this->giveStatus(gp) ); FloatArray eps = status->giveGradP(); double gradPNorm; FloatMatrix t1, t2; gradPNorm = eps.computeNorm(); t1.beDyadicProductOf(eps, eps); if ( gradPNorm != 0.0 ) { t1.times( C * alpha * pow(gradPNorm, alpha - 2) ); } switch ( mMode ) { case _1dHeat: t2.resize(1, 1); t2.at(1, 1) = 1; break; case _2dHeat: t2.resize(2, 2); t2.at(1, 1) = t2.at(2, 2) = 1; break; case _3dHeat: t2.resize(3, 3); t2.at(1, 1) = t2.at(2, 2) = t2.at(3, 3) = 1; break; default: _error2( "giveCharacteristicMatrix : unknown mode (%s)", __MaterialModeToString(mMode) ); } answer.beEmptyMtrx(); answer.add(t1); answer.add(1 + C * pow(gradPNorm, alpha), t2); }
void SimpleCrossSection :: giveStiffnessMatrix_dCde(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) { StructuralMaterial *mat = dynamic_cast< StructuralMaterial * >( this->giveMaterial(gp) ); MaterialMode mode = gp->giveMaterialMode(); if ( mode == _3dMat ) { mat->give3dMaterialStiffnessMatrix_dCde(answer, rMode, gp, tStep); } else if ( mode == _PlaneStress ) { mat->givePlaneStressStiffMtrx_dCde(answer, rMode, gp, tStep); } else if ( mode == _PlaneStrain ) { mat->givePlaneStrainStiffMtrx_dCde(answer, rMode, gp, tStep); } else if ( mode == _1dMat ) { mat->give1dStressStiffMtrx_dCde(answer, rMode, gp, tStep); } else { OOFEM_ERROR("unknown mode (%s)", __MaterialModeToString(mode) ); } }
void SimpleCrossSection :: giveFirstPKStresses(FloatArray &answer, GaussPoint *gp, const FloatArray &reducedvF, TimeStep *tStep) { // This function returns the first Piola-Kirchoff stress in vector format // corresponding to a given deformation gradient according to the stress-deformation // mode stored in the each gp. MaterialMode mode = gp->giveMaterialMode(); StructuralMaterial *mat = dynamic_cast< StructuralMaterial * >( this->giveMaterial(gp) ); if ( mode == _3dMat ) { mat->giveFirstPKStressVector_3d(answer, gp, reducedvF, tStep); } else if ( mode == _PlaneStrain ) { mat->giveFirstPKStressVector_PlaneStrain(answer, gp, reducedvF, tStep); } else if ( mode == _PlaneStress ) { mat->giveFirstPKStressVector_PlaneStress(answer, gp, reducedvF, tStep); } else if ( mode == _1dMat ) { mat->giveFirstPKStressVector_1d(answer, gp, reducedvF, tStep); } else { OOFEM_ERROR("unknown mode (%s)", __MaterialModeToString(mode) ); } }
void IsotropicHeatTransferMaterial :: giveCharacteristicMatrix(FloatMatrix &answer, MatResponseForm form, MatResponseMode mode, GaussPoint *gp, TimeStep *atTime) { /* * returns constitutive (conductivity) matrix of receiver */ MaterialMode mMode = gp->giveMaterialMode(); double cond = this->giveIsotropicConductivity(gp); /*if ( !isActivated(atTime) ) //element, which is inactive (activityLTF==0), will never go into this function cond = 0.; } */ switch ( mMode ) { case _1dHeat: answer.resize(1, 1); answer.at(1, 1) = cond; case _2dHeat: answer.resize(2, 2); answer.at(1, 1) = cond; answer.at(2, 2) = cond; return; case _3dHeat: answer.resize(3, 3); answer.at(1, 1) = cond; answer.at(2, 2) = cond; answer.at(3, 3) = cond; return; default: _error2( "giveCharacteristicMatrix : unknown mode (%s)", __MaterialModeToString(mMode) ); } }
void IsotropicMoistureTransferMaterial :: giveCharacteristicMatrix(FloatMatrix &answer, MatResponseForm form, MatResponseMode mode, GaussPoint *gp, TimeStep *atTime) { /* * returns constitutive (conductivity) matrix of receiver */ double permeability; permeability = this->givePermeability(gp, atTime); MaterialMode mMode = gp->giveMaterialMode(); switch ( mMode ) { case _1dHeat: answer.resize(1, 1); answer.at(1, 1) = permeability; case _2dHeat: answer.resize(2, 2); answer.at(1, 1) = permeability; answer.at(2, 2) = permeability; return; case _3dHeat: answer.resize(3, 3); answer.at(1, 1) = permeability; answer.at(2, 2) = permeability; answer.at(3, 3) = permeability; return; default: _error2( "giveCharacteristicMatrix : unknown mode (%s)", __MaterialModeToString(mMode) ); } return; }
void NonlinearMassTransferMaterial :: giveCharacteristicMatrix(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) { MaterialMode mMode = gp->giveMaterialMode(); TransportMaterialStatus *status = static_cast< TransportMaterialStatus * >( this->giveStatus(gp) ); const FloatArray &eps = status->giveTempGradient(); double gradPNorm; FloatMatrix t1, t2; gradPNorm = eps.computeNorm(); t1.beDyadicProductOf(eps, eps); if ( gradPNorm != 0.0 ) { t1.times( C * alpha * pow(gradPNorm, alpha - 2) ); } switch ( mMode ) { case _1dHeat: t2.resize(1, 1); break; case _2dHeat: t2.resize(2, 2); break; case _3dHeat: t2.resize(3, 3); break; default: OOFEM_ERROR("unknown mode (%s)", __MaterialModeToString(mMode)); } t2.beUnitMatrix(); answer.clear(); answer.add(t1); answer.add(1 + C * pow(gradPNorm, alpha), t2); }
//necesarry only for mpm_ClosestPoint, see Jirasek: Inelastic analysis of structures, pp. 411. //Hessian matrix void DruckerPragerCutMat :: computeReducedSSGradientMatrix(FloatMatrix &gradientMatrix, int isurf, GaussPoint *gp, const FloatArray &fullStressVector, const FloatArray &strainSpaceHardeningVariables) { switch ( gp->giveMaterialMode() ) { case _3dMat: gradientMatrix.resize(6, 6); break; case _PlaneStrain: gradientMatrix.resize(4, 4); break; default: OOFEM_ERROR("Unknown material mode (%s)", __MaterialModeToString( gp->giveMaterialMode() ) ); } gradientMatrix.zero(); if ( isurf == 4 ) { int i, j; double c1 = 0.; //MaterialMode mmode = gp->giveMaterialMode(); MaterialMode mmode = _3dMat; StressVector stressVector1(fullStressVector, mmode); //convert from array StressVector deviatoricStress(mmode); double JTwo, sqrtJTwo, volumetricStress; stressVector1.computeDeviatoricVolumetricSplit(deviatoricStress, volumetricStress); JTwo = deviatoricStress.computeSecondInvariant(); sqrtJTwo = sqrt(JTwo); if ( gp->giveMaterialMode() == _3dMat ) { for ( i = 1; i <= 6; i++ ) { for ( j = i; j <= 6; j++ ) { if ( ( i == 1 && j == 1 ) || ( i == 2 && j == 2 ) || ( i == 3 && j == 3 ) ) { c1 = 2 / 3.; } else if ( ( i == 4 && j == 4 ) || ( i == 5 && j == 5 ) || ( i == 6 && j == 6 ) ) { c1 = 1.; } else if ( i <= 3 && j <= 3 ) { c1 = -1 / 3.; } else { c1 = 0; } gradientMatrix.at(i, j) = 0.5 / JTwo * ( c1 * sqrtJTwo - deviatoricStress.at(i) * deviatoricStress.at(j) / 2. / sqrtJTwo ); } } gradientMatrix.symmetrized(); } else if ( gp->giveMaterialMode() == _PlaneStrain ) { for ( i = 1; i <= 4; i++ ) { for ( j = i; j <= 4; j++ ) { if ( ( i == 1 && j == 1 ) || ( i == 2 && j == 2 ) || ( i == 3 && j == 3 ) ) { c1 = 2 / 3.; } else if ( ( i == 4 && j == 4 ) ) { c1 = 1.; } else if ( i <= 3 && j <= 3 ) { c1 = -1 / 3.; } else { c1 = 0; } gradientMatrix.at(i, j) = 0.5 / JTwo * ( c1 * sqrtJTwo - deviatoricStress.at(i) * deviatoricStress.at(j) / 2. / sqrtJTwo ); } } gradientMatrix.symmetrized(); } else { OOFEM_ERROR("Unknown material mode (%s)", __MaterialModeToString( gp->giveMaterialMode() ) ); } } }
void SimpleCrossSection :: giveMaterialStiffnessMatrixOf(FloatMatrix &answer, MatResponseForm form, MatResponseMode rMode, GaussPoint *gp, StructuralMaterial *mat, TimeStep *tStep) // // may be only simple interface to material class, forcing returned matrix to be in reduced form. // otherwise special methods called to obtain required stiffness from 3d case. // { // Material *mat = gp->giveElement()->giveMaterial(); if ( mat->hasMaterialModeCapability( gp->giveMaterialMode() ) ) { mat->giveCharacteristicMatrix(answer, form, rMode, gp, tStep); return; } else { OOFEM_ERROR3("GiveMaterialStiffnessMatrixOf: unsupported StressStrainMode %s on Element number %d", __MaterialModeToString(gp->giveMaterialMode()), gp->giveElement()->giveGlobalNumber() ); } }
void AbaqusUserMaterial :: giveRealStressVector(FloatArray &answer, MatResponseForm form, GaussPoint *gp, const FloatArray &reducedStrain, TimeStep *tStep) { AbaqusUserMaterialStatus *ms = static_cast< AbaqusUserMaterialStatus * >( this->giveStatus(gp) ); /* User-defined material name, left justified. Some internal material models are given names starting with * the “ABQ_” character string. To avoid conflict, you should not use “ABQ_” as the leading string for * CMNAME. */ //char cmname[80]; MaterialMode mMode = gp->giveMaterialMode(); // Sizes of the tensors. int ndi; int nshr; ///@todo Check how to deal with large deformations. ///@todo Check order of entries in the Voigt notation (which order does Abaqus use? convert to that). if ( mMode == _3dMat ) { ndi = 3; nshr = 3; } else if ( mMode == _PlaneStress ) { ndi = 2; nshr = 1; } else if ( mMode == _PlaneStrain ) { ndi = 3; nshr = 1; } /*else if ( mMode == _3dMat_F ) { * ndi = 3; * nshr = 6; * } */ else if ( mMode == _1dMat ) { ndi = 1; nshr = 0; } else { ndi = nshr = 0; OOFEM_ERROR2( "AbaqusUserMaterial :: giveRealStressVector : unsupported material mode (%s)", __MaterialModeToString(mMode) ); } int ntens = ndi + nshr; FloatArray stress(ntens); FloatArray strain = ms->giveStrainVector(); FloatArray strainIncrement; strainIncrement.beDifferenceOf(reducedStrain, strain); FloatArray state = ms->giveStateVector(); FloatMatrix jacobian(ntens, ntens); int numProperties = this->properties.giveSize(); // Temperature and increment double temp = 0.0, dtemp = 0.0; // Times and increment double dtime = tStep->giveTimeIncrement(); ///@todo Check this. I'm just guessing. Maybe intrinsic time instead? double time [ 2 ] = { tStep->giveTargetTime() - dtime, tStep->giveTargetTime() }; double pnewdt = 1.0; ///@todo Right default value? umat routines may change this (although we ignore it) /* Specific elastic strain energy, plastic dissipation, and “creep” dissipation, respectively. These are passed * in as the values at the start of the increment and should be updated to the corresponding specific energy * values at the end of the increment. They have no effect on the solution, except that they are used for * energy output. */ double sse, spd, scd; // Outputs only in a fully coupled thermal-stress analysis: double rpl = 0.0; // Volumetric heat generation per unit time at the end of the increment caused by mechanical working of the material. FloatArray ddsddt(ntens); // Variation of the stress increments with respect to the temperature. FloatArray drplde(ntens); // Variation of RPL with respect to the strain increments. double drpldt = 0.0; // Variation of RPL with respect to the temperature. /* An array containing the coordinates of this point. These are the current coordinates if geometric * nonlinearity is accounted for during the step (see “Procedures: overview,” Section 6.1.1); otherwise, * the array contains the original coordinates of the point */ FloatArray coords; gp->giveElement()->computeGlobalCoordinates( coords, * gp->giveCoordinates() ); ///@todo Large deformations? /* Rotation increment matrix. This matrix represents the increment of rigid body rotation of the basis * system in which the components of stress (STRESS) and strain (STRAN) are stored. It is provided so * that vector- or tensor-valued state variables can be rotated appropriately in this subroutine: stress and * strain components are already rotated by this amount before UMAT is called. This matrix is passed in * as a unit matrix for small-displacement analysis and for large-displacement analysis if the basis system * for the material point rotates with the material (as in a shell element or when a local orientation is used).*/ FloatMatrix drot(3, 3); drot.beUnitMatrix(); /* Characteristic element length, which is a typical length of a line across an element for a first-order * element; it is half of the same typical length for a second-order element. For beams and trusses it is a * characteristic length along the element axis. For membranes and shells it is a characteristic length in * the reference surface. For axisymmetric elements it is a characteristic length in the * plane only. * For cohesive elements it is equal to the constitutive thickness.*/ double celent = 0.0; /// @todo Include the characteristic element length /* Array containing the deformation gradient at the beginning of the increment. See the discussion * regarding the availability of the deformation gradient for various element types. */ FloatMatrix dfgrd0(3, 3); /* Array containing the deformation gradient at the end of the increment. The components of this array * are set to zero if nonlinear geometric effects are not included in the step definition associated with * this increment. See the discussion regarding the availability of the deformation gradient for various * element types. */ FloatMatrix dfgrd1(3, 3); int noel = gp->giveElement()->giveNumber(); // Element number. int npt = 0; // Integration point number. int layer = 0; // Layer number (for composite shells and layered solids).. int kspt = 0.0; // Section point number within the current layer. int kstep = 0; // Step number. int kinc = 0; // Increment number. ///@todo No idea about these parameters double predef; double dpred; OOFEM_LOG_DEBUG("AbaqusUserMaterial :: giveRealStressVector - Calling subroutine"); this->umat(stress.givePointer(), // STRESS state.givePointer(), // STATEV jacobian.givePointer(), // DDSDDE & sse, // SSE & spd, // SPD & scd, // SCD & rpl, // RPL ddsddt.givePointer(), // DDSDDT drplde.givePointer(), // DRPLDE & drpldt, // DRPLDT strain.givePointer(), // STRAN strainIncrement.givePointer(), // DSTRAN time, // TIME & dtime, // DTIME & temp, // TEMP & dtemp, // DTEMP & predef, // PREDEF & dpred, // DPRED this->cmname, // CMNAME & ndi, // NDI & nshr, // NSHR & ntens, // NTENS & numState, // NSTATV properties.givePointer(), // PROPS & numProperties, // NPROPS coords.givePointer(), // COORDS drot.givePointer(), // DROT & pnewdt, // PNEWDT & celent, // CELENT dfgrd0.givePointer(), // DFGRD0 dfgrd1.givePointer(), // DFGRD1 & noel, // NOEL & npt, // NPT & layer, // LAYER & kspt, // KSPT & kstep, // KSTEP & kinc); // KINC ms->letTempStrainVectorBe(reducedStrain); ms->letTempStressVectorBe(stress); ms->letTempStateVectorBe(state); ms->letTempTangentBe(jacobian); answer = stress; OOFEM_LOG_DEBUG("AbaqusUserMaterial :: giveRealStressVector - Calling subroutine was successful"); }
void MisesMatGrad :: givePDGradMatrix_LD(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) { MaterialMode mMode = gp->giveMaterialMode(); OOFEM_ERROR("unknown mode (%s)", __MaterialModeToString(mMode) ); }