void PerfectlyPlasticMaterial :: giveEffectiveMaterialStiffnessMatrix(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *atTime) // // // for case of perfectly plastic material // computes full elastic constitutive matrix for case of gp stress-strain state. // if strainIncrement == NULL a loading is assumed // // we follow terminology based on paper from R. de Borst: // "Smeared Cracking, plasticity, creep - Unified Aproach" // // if derived material would like to implement failure behaviour // it must redefine basic Give3dMaterialStiffnessMatrix function // in order to take possible failure (tension cracking) into account // { // FloatMatrix *de; // elastic matrix respecting fracture or failure StructuralMaterial *lMat = static_cast< StructuralMaterial * >( this->giveLinearElasticMaterial() ); if ( lMat->hasMaterialModeCapability( gp->giveMaterialMode() ) ) { FloatMatrix stiff; lMat->giveStiffnessMatrix(stiff, mode, gp, atTime); this->giveFullSymMatrixForm(answer, stiff, gp->giveMaterialMode()); } else { OOFEM_ERROR("PerfectlyPlasticMaterial :: giveEffectiveMaterialStiffnessMatrix - unsupported material mode"); } }
void SimpleCrossSection :: give3dShellStiffMtrx(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) { StructuralMaterial *mat = dynamic_cast< StructuralMaterial * >( this->giveMaterial(gp) ); FloatMatrix mat3d; double thickness = this->give(CS_Thickness, gp); double thickness3 = thickness * thickness * thickness; mat->givePlaneStressStiffMtrx(mat3d, rMode, gp, tStep); answer.resize(8, 8); answer.zero(); for ( int i = 1; i <= 3; i++ ) { for ( int j = 1; j <= 3; j++ ) { answer.at(i, j) = mat3d.at(i, j) * thickness; } } for ( int i = 1; i <= 3; i++ ) { for ( int j = 1; j <= 3; j++ ) { answer.at(i + 3, j + 3) = mat3d.at(i, j) * thickness3 / 12.0; } } answer.at(8, 8) = answer.at(7, 7) = mat3d.at(3, 3) * thickness * ( 5. / 6. ); }
void SimpleCrossSection :: give2dPlateSubSoilStiffMtrx(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) { StructuralMaterial *mat; mat = dynamic_cast< StructuralMaterial * >( this->giveMaterial(gp) ); mat->give2dPlateSubSoilStiffMtrx(answer, ElasticStiffness, gp, tStep); }
void SimpleCrossSection :: giveGeneralizedStress_Shell(FloatArray &answer, GaussPoint *gp, const FloatArray &strain, TimeStep *tStep) { /**Note: (by bp): This assumes that the behaviour is elastic there exist a nuumber of nonlinear integral material models for beams/plates/shells defined directly in terms of integral forces and moments and corresponding deformations and curvatures. This would require to implement support at material model level. */ StructuralMaterial *mat = static_cast< StructuralMaterial * >( this->giveMaterial(gp) ); FloatArray elasticStrain, et, e0; FloatMatrix tangent; elasticStrain = strain; this->giveTemperatureVector(et, gp, tStep); if ( et.giveSize() ) { double thick = this->give(CS_Thickness, gp); mat->giveThermalDilatationVector(e0, gp, tStep); elasticStrain.at(1) -= e0.at(1) * ( et.at(1) - mat->giveReferenceTemperature() ); elasticStrain.at(2) -= e0.at(2) * ( et.at(1) - mat->giveReferenceTemperature() ); if ( et.giveSize() > 1 ) { elasticStrain.at(4) -= e0.at(1) * et.at(2) / thick; // kappa_x elasticStrain.at(5) -= e0.at(2) * et.at(2) / thick; // kappa_y } } this->give3dShellStiffMtrx(tangent, ElasticStiffness, gp, tStep); answer.beProductOf(tangent, elasticStrain); StructuralMaterialStatus *status = static_cast< StructuralMaterialStatus * >( mat->giveStatus(gp) ); status->letTempStrainVectorBe(strain); status->letTempStressVectorBe(answer); }
void SimpleCrossSection :: give3dBeamStiffMtrx(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) { StructuralMaterial *mat = dynamic_cast< StructuralMaterial * >( this->giveMaterial(gp) ); FloatMatrix mat3d; double area, E, G, Iy, Iz, Ik; double shearAreay, shearAreaz; mat->give1dStressStiffMtrx(mat3d, rMode, gp, tStep); E = mat3d.at(1, 1); G = mat->give('G', gp); area = this->give(CS_Area, gp); Iy = this->give(CS_InertiaMomentY, gp); Iz = this->give(CS_InertiaMomentZ, gp); Ik = this->give(CS_TorsionMomentX, gp); //shearCoeff = this->give(CS_BeamShearCoeff); shearAreay = this->give(CS_ShearAreaY, gp); shearAreaz = this->give(CS_ShearAreaZ, gp); answer.resize(6, 6); answer.zero(); answer.at(1, 1) = E * area; ///@todo Do this by using the general 3d tangent matrix instead somehow!!! answer.at(2, 2) = shearAreay * G; answer.at(3, 3) = shearAreaz * G; //answer.at(2, 2) = shearCoeff * G * area; //answer.at(3, 3) = shearCoeff * G * area; answer.at(4, 4) = G * Ik; answer.at(5, 5) = E * Iy; answer.at(6, 6) = E * Iz; }
void StructuralCrossSection :: giveRealStresses(FloatArray &answer, GaussPoint *gp, const FloatArray &strain, TimeStep *tStep) { MaterialMode mode = gp->giveMaterialMode(); if ( mode == _2dBeam ) { this->giveGeneralizedStress_Beam2d(answer, gp, strain, tStep); } else if ( mode == _3dBeam ) { this->giveGeneralizedStress_Beam3d(answer, gp, strain, tStep); } else if ( mode == _2dPlate ) { this->giveGeneralizedStress_Plate(answer, gp, strain, tStep); } else if ( mode == _3dShell ) { this->giveGeneralizedStress_Shell(answer, gp, strain, tStep); } else if ( mode == _3dMat ) { this->giveRealStress_3d(answer, gp, strain, tStep); } else if ( mode == _PlaneStrain ) { this->giveRealStress_PlaneStrain(answer, gp, strain, tStep); } else if ( mode == _PlaneStress ) { this->giveRealStress_PlaneStress(answer, gp, strain, tStep); } else if ( mode == _1dMat ) { this->giveRealStress_1d(answer, gp, strain, tStep); } else if ( mode == _Warping ) { this->giveRealStress_Warping(answer, gp, strain, tStep); } else { // This should never happen ? ///@todo this part only works for simple cross section and will be removed soon when new interface elements are done /JB StructuralMaterial *mat = dynamic_cast< StructuralMaterial * >( this->giveMaterial(gp) ); if ( mat->hasMaterialModeCapability( gp->giveMaterialMode() ) ) { mat->giveRealStressVector(answer, gp, strain, tStep); } else { OOFEM_ERROR("unsupported mode"); } } }
void StructuralCrossSection :: giveFullCharacteristicVector(FloatArray &answer, GaussPoint *gp, const FloatArray &strainVector) // // returns full 3d general strain vector from strainVector in reducedMode // based on StressStrainMode in gp. Included are strains which // perform nonzero work. // General strain vector has one of the following forms: // 1) strainVector3d {eps_x,eps_y,eps_z,gamma_yz,gamma_zx,gamma_xy} // 2) strainVectorShell {eps_x,eps_y,gamma_xy, kappa_x, kappa_y, kappa_xy, gamma_zx, gamma_zy} // // you must assigng your stress strain mode to one of the folloving modes (or add new) // FullForm of MaterialStiffnessMatrix must have the same form. // { MaterialMode mode = gp->giveMaterialMode(); StructuralMaterial *mat = static_cast< StructuralMaterial * >( gp->giveElement()->giveMaterial() ); if ( ( mode == _3dMat ) || ( mode == _3dMicroplane ) ) { answer = strainVector; return; } else { mat->giveFullCharacteristicVector(answer, gp, strainVector); } }
void FiberedCrossSection :: giveCharMaterialStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) { MaterialMode mode = gp->giveMaterialMode(); if ( mode == _2dBeam ) { this->give2dBeamStiffMtrx(answer, rMode, gp, tStep); } else if ( mode == _3dBeam ) { this->give3dBeamStiffMtrx(answer, rMode, gp, tStep); } else if ( mode == _2dPlate ) { this->give2dPlateStiffMtrx(answer, rMode, gp, tStep); } else if ( mode == _3dShell ) { this->give3dShellStiffMtrx(answer, rMode, gp, tStep); } else { OOFEM_ERROR("Not implemented for bulk materials."); ///@todo What about the fibers?! Rather give just an error message if the fibers aren't supported than to just silently ignore them. #if 0 StructuralMaterial *mat = dynamic_cast< StructuralMaterial * >( gp->giveElement()->giveMaterial() ); if ( mat->hasMaterialModeCapability( gp->giveMaterialMode() ) ) { mat->giveStiffnessMatrix(answer, rMode, gp, tStep); } else { OOFEM_ERROR("unsupported StressStrainMode"); } #endif } }
contextIOResultType FiberedCrossSection :: restoreIPContext(DataStream *stream, ContextMode mode, GaussPoint *masterGp) // // restores full material context (saves state variables, that completely describe // current state) // // restores also slaves of master gp // { contextIOResultType iores; if ( ( iores = CrossSection :: restoreIPContext(stream, mode, masterGp) ) != CIO_OK ) { THROW_CIOERR(iores); // saved masterGp } for ( int i = 1; i <= numberOfFibers; i++ ) { // creates also slaves if they don't exists GaussPoint *slaveGP = this->giveSlaveGaussPoint(masterGp, i - 1); StructuralMaterial *mat = dynamic_cast< StructuralMaterial * >( domain->giveMaterial( fiberMaterials.at(i) ) ); if ( ( iores = mat->restoreIPContext(stream, mode, slaveGP) ) != CIO_OK ) { THROW_CIOERR(iores); } } return CIO_OK; }
void SimpleCrossSection :: giveGeneralizedStress_Beam2d(FloatArray &answer, GaussPoint *gp, const FloatArray &strain, TimeStep *tStep) { /**Note: (by bp): This assumes that the behaviour is elastic * there exist a nuumber of nonlinear integral material models for beams defined directly in terms of integral forces and moments and corresponding * deformations and curvatures. This would require to implement support at material model level. * Mikael: That would not be a continuum material model, but it would highly depend on the cross-section shape, thus, it should be a special cross-section model instead. * This cross-section assumes you can split the response into inertia moments and pure material response. This is only possible for a constant, elastic response (i.e. elastic). * Therefore, this cross-section may only be allowed to give the elastic response. */ StructuralMaterial *mat = static_cast< StructuralMaterial * >( this->giveMaterial(gp) ); FloatArray elasticStrain, et, e0; FloatMatrix tangent; elasticStrain = strain; this->giveTemperatureVector(et, gp, tStep); if ( et.giveSize() > 0 ) { mat->giveThermalDilatationVector(e0, gp, tStep); double thick = this->give(CS_Thickness, gp); elasticStrain.at(1) -= e0.at(1) * ( et.at(1) - mat->giveReferenceTemperature() ); if ( et.giveSize() > 1 ) { elasticStrain.at(2) -= e0.at(1) * et.at(2) / thick; // kappa_x } } this->give2dBeamStiffMtrx(tangent, ElasticStiffness, gp, tStep); answer.beProductOf(tangent, elasticStrain); StructuralMaterialStatus *status = static_cast< StructuralMaterialStatus * >( mat->giveStatus(gp) ); status->letTempStrainVectorBe(strain); status->letTempStressVectorBe(answer); }
void FiberedCrossSection :: giveFiberMaterialStiffnessMatrix(FloatMatrix &fiberMatrix, MatResponseMode rMode, GaussPoint *layerGp, TimeStep *tStep) { StructuralMaterial *mat = dynamic_cast< StructuralMaterial * >( domain->giveMaterial( fiberMaterials.at( layerGp->giveNumber() ) ) ); mat->giveStiffnessMatrix(fiberMatrix, rMode, layerGp, tStep); }
void SimpleCrossSection :: giveReducedCharacteristicVector(FloatArray &answer, GaussPoint *gp, const FloatArray &charVector3d) // // returns reduced stressVector or strainVector from full 3d vector reduced // to vector required by gp->giveStressStrainMode() // { MaterialMode mode = gp->giveMaterialMode(); StructuralMaterial *mat = static_cast< StructuralMaterial * >( gp->giveElement()->giveMaterial() ); IntArray indx; int size = charVector3d.giveSize(); int i, j; if ( ( mode == _3dShell ) || ( mode == _3dBeam ) || ( mode == _2dPlate ) || ( mode == _2dBeam ) ) { if ( size != 12 ) { OOFEM_ERROR("SimpleCrossSection :: giveReducedCharacteristicVector - charVector3d size mismatch"); } mat->giveStressStrainMask( indx, ReducedForm, gp->giveMaterialMode() ); answer.resize( indx.giveSize() ); answer.zero(); for ( i = 1; i <= indx.giveSize(); i++ ) { if ( ( j = indx.at(i) ) ) { answer.at(i) = charVector3d.at(j); } } return; } else if ( mode == _3dBeam ) { if ( size != 6 ) { OOFEM_ERROR("SimpleCrossSection :: giveReducedCharacteristicVector - charVector3d size mismatch"); } answer = charVector3d; return; } else if ( mode == _PlaneStressRot ) { if ( size != 7 ) { OOFEM_ERROR("SimpleCrossSection :: giveReducedCharacteristicVector - charVector3d size mismatch"); } mat->giveStressStrainMask( indx, ReducedForm, gp->giveMaterialMode() ); answer.resize( indx.giveSize() ); answer.zero(); for ( i = 1; i <= indx.giveSize(); i++ ) { if ( ( j = indx.at(i) ) ) { answer.at(i) = charVector3d.at(j); } } return; } else { StructuralCrossSection :: giveReducedCharacteristicVector(answer, gp, charVector3d); return; } }
void FiberedCrossSection :: createMaterialStatus(GaussPoint &iGP) { for ( int i = 1; i <= numberOfFibers; i++ ) { GaussPoint *fiberGp = this->giveSlaveGaussPoint(& iGP, i - 1); StructuralMaterial *mat = static_cast< StructuralMaterial * >( domain->giveMaterial( fiberMaterials.at(i) ) ); MaterialStatus *matStat = mat->CreateStatus(fiberGp); iGP.setMaterialStatus(matStat); } }
void SimpleCrossSection :: giveRealStress_3dDegeneratedShell(FloatArray &answer, GaussPoint *gp, const FloatArray &strain, TimeStep *tStep) { StructuralMaterial *mat = dynamic_cast< StructuralMaterial * >( this->giveMaterial(gp) ); IntArray strainControl = { 1, 2, 4, 5, 6 }; mat->giveRealStressVector_ShellStressControl(answer, gp, strain, strainControl, tStep); }
void SimpleCrossSection :: giveMembraneRotStiffMtrx(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) { StructuralMaterial *mat; mat = dynamic_cast< StructuralMaterial * >( this->giveMaterial(gp) ); mat->givePlaneStressStiffMtrx(answer, ElasticStiffness, gp, tStep); answer.resizeWithData(4, 4); answer.at(4, 4) = this->give(CS_DrillingStiffness, gp); }
void SimpleCrossSection :: giveFullCharacteristicVector(FloatArray &answer, GaussPoint *gp, const FloatArray &strainVector) // // returns full 3d strain vector from strainVector in reducedMode // based on StressStrainMode in gp // strainVector {eps_x,eps_y,eps_z,gamma_yz,gamma_zx,gamma_xy} // // enhaced method in order to support cases with integral bending (2dplate, 3dshell..) // in such cases full strain vector has the form: // strainVectorShell {eps_x,eps_y,eps_z,gamma_yz,gamma_zx,gamma_xy, kappa_x,kappa_y,kappa_y,kappa_yz,kappa_xz,kappa_xy} // // enhanced method in order to support 3dbeam elements // in such cases full strain vector has the form: // strainVector {eps_x, gamma_xz, gamma_xy, \der{phi_x}{x}, kappa_y, kappa_z} // // enhance support also for PlaneStressRot case with full strain vector of form // {eps_x,eps_y,eps_z,gamma_yz,gamma_zx,gamma_xy,(omega_xy-(dv/dx-du/dy)*0.5)} // // { MaterialMode mode = gp->giveMaterialMode(); StructuralMaterial *mat = static_cast< StructuralMaterial * >( gp->giveMaterial() ); IntArray indx; int i, j, answerSize = 0; //if (mode == _3dShell) {answer = strainVector; return ;} //if (mode == _3dBeam) {answer = strainVector; return ;} if ( ( mode == _3dShell ) || ( mode == _3dBeam ) || ( mode == _2dPlate ) || ( mode == _2dBeam ) || ( mode == _PlaneStressRot ) ||(mode == _3dMatGrad)||(mode == _1dMatGrad)||(mode == _PlaneStrainGrad)||(mode == _PlaneStressGrad) ) { if ( ( mode == _3dShell ) || ( mode == _3dBeam ) || ( mode == _2dPlate ) || ( mode == _2dBeam ) ) { answerSize = 12; } if ( mode == _PlaneStressRot || (mode == _3dMatGrad) || (mode == _1dMatGrad) || (mode == _PlaneStrainGrad) || (mode == _PlaneStressGrad) ) { answerSize = 7; } answer.resize(answerSize); answer.zero(); mat->giveStressStrainMask( indx, ReducedForm, gp->giveMaterialMode() ); for ( i = 1; i <= indx.giveSize(); i++ ) { if ( ( j = indx.at(i) ) ) { answer.at(j) = strainVector.at(i); } } return; } else { StructuralCrossSection :: giveFullCharacteristicVector(answer, gp, strainVector); return; } }
void RCM2Material :: giveNormalElasticStiffnessMatrix(FloatMatrix &answer, MatResponseForm form, MatResponseMode rMode, GaussPoint *gp, TimeStep *atTime, const FloatMatrix &dir) // // return Elastic Stiffness matrix for normal Stresses // taking into account the directions of normal stresses // (not supported now) // { StructuralMaterial *lMat = static_cast< StructuralMaterial * >( this->giveLinearElasticMaterial() ); FloatMatrix de, fullAnswer(3, 3); IntArray mask; int i, j, sd; lMat->giveCharacteristicMatrix(de, FullForm, rMode, gp, atTime); // copy first 3x3 submatrix to answer for ( i = 1; i <= 3; i++ ) { for ( j = 1; j <= 3; j++ ) { fullAnswer.at(i, j) = de.at(i, j); } } if ( form == FullForm ) { // 3x3 full form required answer = fullAnswer; } else { // reduced form for only // nonzero normal stresses // // first find spatial dimension of problem sd = 0; for ( i = 1; i <= 3; i++ ) { if ( ( this->giveStressStrainComponentIndOf(FullForm, gp->giveMaterialMode(), i) ) ) { sd++; } } answer.resize(sd, sd); answer.zero(); // copy fullAnswer to reduced one this->giveStressStrainMask( mask, FullForm, gp->giveMaterialMode() ); for ( i = 1; i <= 3; i++ ) { for ( j = 1; j <= 3; j++ ) { if ( mask.at(i) && mask.at(j) ) { answer.at( mask.at(i), mask.at(j) ) = fullAnswer.at(i, j); } } } return; } }
void FiberedCrossSection :: giveGeneralizedStress_Beam3d(FloatArray &answer, GaussPoint *gp, const FloatArray &strain, TimeStep *tStep) { double fiberThick, fiberWidth, fiberZCoord, fiberYCoord; FloatArray fiberStrain, reducedFiberStress; StructuralElement *element = static_cast< StructuralElement * >( gp->giveElement() ); FiberedCrossSectionInterface *interface; if ( ( interface = static_cast< FiberedCrossSectionInterface * >( element->giveInterface(FiberedCrossSectionInterfaceType) ) ) == NULL ) { OOFEM_ERROR("element with no fiber support encountered"); } answer.resize(6); answer.zero(); for ( int i = 1; i <= numberOfFibers; i++ ) { GaussPoint *fiberGp = this->giveSlaveGaussPoint(gp, i - 1); StructuralMaterial *fiberMat = static_cast< StructuralMaterial * >( domain->giveMaterial( fiberMaterials.at(i) ) ); // the question is whether this function should exist ? // if yes the element details will be hidden. // good idea also should be existence of element::GiveBmatrixOfLayer // and computing strains here - but first idea looks better // but treating of geometric non-linearities may become more complicated // another approach - use several functions with assumed kinematic constraints // resolve current layer z-coordinate fiberThick = this->fiberThicks.at(i); fiberWidth = this->fiberWidths.at(i); fiberYCoord = fiberGp->giveNaturalCoordinate(1); fiberZCoord = fiberGp->giveNaturalCoordinate(2); interface->FiberedCrossSectionInterface_computeStrainVectorInFiber(fiberStrain, strain, fiberGp, tStep); fiberMat->giveRealStressVector_Fiber(reducedFiberStress, fiberGp, fiberStrain, tStep); // perform integration // 1) membrane terms N, Qz, Qy answer.at(1) += reducedFiberStress.at(1) * fiberWidth * fiberThick; answer.at(2) += reducedFiberStress.at(2) * fiberWidth * fiberThick; answer.at(3) += reducedFiberStress.at(3) * fiberWidth * fiberThick; // 2) bending terms mx, my, mxy answer.at(4) += ( reducedFiberStress.at(2) * fiberWidth * fiberThick * fiberYCoord - reducedFiberStress.at(3) * fiberWidth * fiberThick * fiberZCoord ); answer.at(5) += reducedFiberStress.at(1) * fiberWidth * fiberThick * fiberZCoord; answer.at(6) -= reducedFiberStress.at(1) * fiberWidth * fiberThick * fiberYCoord; } // now we must update master gp ///@ todo simply chosen the first fiber material as master material /JB StructuralMaterialStatus *status = static_cast< StructuralMaterialStatus * > ( domain->giveMaterial( fiberMaterials.at(1) )->giveStatus(gp) ); status->letTempStrainVectorBe(strain); status->letTempStressVectorBe(answer); }
void SimpleCrossSection :: giveEshelbyStresses(FloatArray &answer, GaussPoint *gp, const FloatArray &reducedvF, TimeStep *tStep) { MaterialMode mode = gp->giveMaterialMode(); StructuralMaterial *mat = dynamic_cast< StructuralMaterial * >( this->giveMaterial(gp) ); if ( mode == _3dMat ) { // mat->giveCauchyStressVector_3d(answer, gp, reducedvF, tStep); } else if ( mode == _PlaneStrain ) { mat->giveEshelbyStressVector_PlaneStrain(answer, gp, reducedvF, tStep); } else if ( mode == _PlaneStress ) { // mat->giveCauchyStressVector_PlaneStress(answer, gp, reducedvF, tStep); } else if ( mode == _1dMat ) { // mat->giveCauchyStressVector_1d(answer, gp, reducedvF, tStep); } }
void SimpleCrossSection :: give3dDegeneratedShellStiffMtrx(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) { StructuralMaterial *mat = dynamic_cast< StructuralMaterial * >( this->giveMaterial(gp) ); mat->give3dMaterialStiffnessMatrix(answer, rMode, gp, tStep); answer.at(1, 1) -= answer.at(1, 3) * answer.at(3, 1) / answer.at(3, 3); answer.at(2, 1) -= answer.at(2, 3) * answer.at(3, 1) / answer.at(3, 3); answer.at(1, 2) -= answer.at(1, 3) * answer.at(3, 2) / answer.at(3, 3); answer.at(2, 2) -= answer.at(2, 3) * answer.at(3, 2) / answer.at(3, 3); answer.at(3, 1) = 0.0; answer.at(3, 2) = 0.0; answer.at(3, 3) = 0.0; answer.at(2, 3) = 0.0; answer.at(1, 3) = 0.0; }
void StructuralCrossSection :: giveReducedCharacteristicVector(FloatArray &answer, GaussPoint *gp, const FloatArray &charVector3d) // // returns reduced stressVector or strainVector from full 3d vector reduced // to vector required by gp->giveStressStrainMode() // { MaterialMode mode = gp->giveMaterialMode(); StructuralMaterial *mat = static_cast< StructuralMaterial * >( gp->giveElement()->giveMaterial() ); if ( ( mode == _3dMat ) || ( mode == _3dMicroplane ) ) { answer = charVector3d; return; } else { mat->giveReducedCharacteristicVector(answer, gp, charVector3d); } }
void StructuralCrossSection :: computeStressIndependentStrainVector(FloatArray &answer, GaussPoint *gp, TimeStep *stepN, ValueModeType mode) // // returns initial strain vector induced by stress independent effects // like temperatue or shrinkage. // takes into account form of load vector assumed by engngModel (Incremental or Total Load form). // { StructuralMaterial *mat = ( StructuralMaterial * ) gp->giveElement()->giveMaterial(); FloatArray e0, fullAnswer; // // add parts caused by material // mat->computeStressIndependentStrainVector(answer, gp, stepN, mode); }
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 :: giveCauchyStresses(FloatArray &answer, GaussPoint *gp, const FloatArray &reducedvF, TimeStep *tStep) { // This function returns the Cauchy 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->giveCauchyStressVector_3d(answer, gp, reducedvF, tStep); } else if ( mode == _PlaneStrain ) { mat->giveCauchyStressVector_PlaneStrain(answer, gp, reducedvF, tStep); } else if ( mode == _PlaneStress ) { mat->giveCauchyStressVector_PlaneStress(answer, gp, reducedvF, tStep); } else if ( mode == _1dMat ) { mat->giveCauchyStressVector_1d(answer, gp, reducedvF, tStep); } }
void SimpleCrossSection :: give2dBeamStiffMtrx(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) { StructuralMaterial *mat = dynamic_cast< StructuralMaterial * >( this->giveMaterial(gp) ); FloatMatrix mat3d; double area, Iy, shearAreaz; mat->give1dStressStiffMtrx(mat3d, rMode, gp, tStep); area = this->give(CS_Area, gp); Iy = this->give(CS_InertiaMomentY, gp); shearAreaz = this->give(CS_ShearAreaZ, gp); answer.resize(3, 3); answer.zero(); answer.at(1, 1) = mat3d.at(1, 1) * area; answer.at(2, 2) = mat3d.at(1, 1) * Iy; answer.at(3, 3) = shearAreaz * mat->give('G', gp); }
void SimpleCrossSection :: giveRealStresses(FloatArray &answer, MatResponseForm form, GaussPoint *gp, const FloatArray &totalStrain, TimeStep *tStep) // // this function returns a real stresses corresponding to // given totalStrain according to stressStrain mode stored // in each gp. // IMPORTANT: // { MaterialMode mode = gp->giveMaterialMode(); StructuralMaterial *mat = static_cast< StructuralMaterial * >( gp->giveElement()->giveMaterial() ); if ( mat->hasMaterialModeCapability(mode) ) { StructuralCrossSection :: giveRealStresses(answer, form, gp, totalStrain, tStep); return; } else { _error("giveRealStresses : unsupported mode"); } }
void SimpleCrossSection :: giveCharMaterialStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) { MaterialMode mode = gp->giveMaterialMode(); if ( mode == _2dBeam ) { this->give2dBeamStiffMtrx(answer, rMode, gp, tStep); } else if ( mode == _3dBeam ) { this->give3dBeamStiffMtrx(answer, rMode, gp, tStep); } else if ( mode == _2dPlate ) { this->give2dPlateStiffMtrx(answer, rMode, gp, tStep); } else if ( mode == _3dShell ) { this->give3dShellStiffMtrx(answer, rMode, gp, tStep); } else { StructuralMaterial *mat = dynamic_cast< StructuralMaterial * >( this->giveMaterial(gp) ); if ( mode == _3dMat ) { mat->give3dMaterialStiffnessMatrix(answer, rMode, gp, tStep); } else if ( mode == _PlaneStress ) { mat->givePlaneStressStiffMtrx(answer, rMode, gp, tStep); } else if ( mode == _PlaneStrain ) { mat->givePlaneStrainStiffMtrx(answer, rMode, gp, tStep); } else if ( mode == _1dMat ) { mat->give1dStressStiffMtrx(answer, rMode, gp, tStep); } else { mat->giveStiffnessMatrix(answer, rMode, gp, tStep); } } }
void StructuralMaterialEvaluator :: solveYourself() { Domain *d = this->giveDomain(1); MaterialMode mode = _3dMat; FloatArray initialStrain(6); gps.clear(); gps.reserve(d->giveNumberOfMaterialModels()); for ( int i = 1; i <= d->giveNumberOfMaterialModels(); i++ ) { std :: unique_ptr< GaussPoint > gp = std::make_unique<GaussPoint>(nullptr, i, FloatArray(0), 1, mode); gps.emplace_back( std :: move(gp) ); // Initialize the strain vector; StructuralMaterialStatus *status = static_cast< StructuralMaterialStatus * >( d->giveMaterial(i)->giveStatus( gps[i-1].get() ) ); status->letStrainVectorBe(initialStrain); } std :: string outname = this->giveOutputBaseFileName() + ".matdata"; this->outfile.open( outname.c_str() ); this->timer.startTimer(EngngModelTimer :: EMTT_AnalysisTimer); TimeStep *tStep = giveNextStep(); // Note, strain == strain-rate (kept as strain for brevity) int maxiter = 100; // User input? FloatArray stressC, deltaStrain, strain, stress, res; stressC.resize( sControl.giveSize() ); res.resize( sControl.giveSize() ); FloatMatrix tangent, reducedTangent; for ( int istep = 1; istep <= this->numberOfSteps; ++istep ) { this->timer.startTimer(EngngModelTimer :: EMTT_SolutionStepTimer); for ( int imat = 1; imat <= d->giveNumberOfMaterialModels(); ++imat ) { GaussPoint *gp = gps[imat-1].get(); StructuralMaterial *mat = static_cast< StructuralMaterial * >( d->giveMaterial(imat) ); StructuralMaterialStatus *status = static_cast< StructuralMaterialStatus * >( mat->giveStatus(gp) ); strain = status->giveStrainVector(); // Update the controlled parts for ( int j = 1; j <= eControl.giveSize(); ++j ) { int p = eControl.at(j); strain.at(p) = d->giveFunction( cmpntFunctions.at(p) )->evaluateAtTime( tStep->giveIntrinsicTime() ); } for ( int j = 1; j <= sControl.giveSize(); ++j ) { int p = sControl.at(j); stressC.at(j) = d->giveFunction( cmpntFunctions.at(p) )->evaluateAtTime( tStep->giveIntrinsicTime() ); } //strain.add(-100, {6.27e-06, 6.27e-06, 6.27e-06, 0, 0, 0}); for ( int iter = 1; iter < maxiter; iter++ ) { #if 0 // Debugging: mat->give3dMaterialStiffnessMatrix(tangent, TangentStiffness, gp, tStep); tangent.printYourself("# tangent"); strain.zero(); mat->giveRealStressVector_3d(stress, gp, strain, tStep); FloatArray strain2; tangent.solveForRhs(stress, strain2); strain2.printYourself("# thermal expansion"); break; #endif strain.printYourself("Macro strain guess"); mat->giveRealStressVector_3d(stress, gp, strain, tStep); for ( int j = 1; j <= sControl.giveSize(); ++j ) { res.at(j) = stressC.at(j) - stress.at( sControl.at(j) ); } OOFEM_LOG_INFO("*** Time step: %d (t = %.2e), Material %d, Iteration: %d, Residual = %e (tolerance %.2e)\n", istep, tStep->giveIntrinsicTime(), imat, iter, res.computeNorm(), tolerance); if ( res.computeNorm() <= tolerance ) { break; } else { if ( tangent.giveNumberOfRows() == 0 || !keepTangent ) { mat->give3dMaterialStiffnessMatrix(tangent, TangentStiffness, gp, tStep); } // Pick out the stress-controlled part; reducedTangent.beSubMatrixOf(tangent, sControl, sControl); // Update stress-controlled part of the strain reducedTangent.solveForRhs(res, deltaStrain); //deltaStrain.printYourself("deltaStrain"); for ( int j = 1; j <= sControl.giveSize(); ++j ) { strain.at( sControl.at(j) ) += deltaStrain.at(j); } } } if ( res.computeNorm() > tolerance ) { OOFEM_WARNING("Residual did not converge!"); } // This material model has converged, so we update it and go on to the next. gp->updateYourself(tStep); } this->timer.stopTimer(EngngModelTimer :: EMTT_SolutionStepTimer); this->doStepOutput(tStep); tStep = giveNextStep(); } this->timer.stopTimer(EngngModelTimer :: EMTT_AnalysisTimer); this->outfile.close(); }
void SimpleCrossSection :: giveStiffnessMatrix_PlaneStress(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) { StructuralMaterial *mat = dynamic_cast< StructuralMaterial * >( this->giveMaterial(gp) ); mat->givePlaneStressStiffMtrx(answer, rMode, gp, tStep); }
void SimpleCrossSection :: giveRealStress_Warping(FloatArray &answer, GaussPoint *gp, const FloatArray &strain, TimeStep *tStep) { StructuralMaterial *mat = dynamic_cast< StructuralMaterial * >( this->giveMaterial(gp) ); mat->giveRealStressVector_Warping(answer, gp, strain, tStep); }