void CCTPlate3d :: giveCharacteristicTensor(FloatMatrix &answer, CharTensor type, GaussPoint *gp, TimeStep *tStep) // returns characteristic tensor of the receiver at given gp and tStep // strain vector = (Kappa_x, Kappa_y, Kappa_xy, Gamma_zx, Gamma_zy) { FloatArray charVect; Material *mat = this->giveMaterial(); StructuralMaterialStatus *ms = static_cast< StructuralMaterialStatus * >( mat->giveStatus(gp) ); answer.resize(3, 3); answer.zero(); if ( ( type == LocalForceTensor ) || ( type == GlobalForceTensor ) ) { //this->computeStressVector(charVect, gp, tStep); charVect = ms->giveStressVector(); answer.at(1, 3) = charVect.at(4); answer.at(3, 1) = charVect.at(4); answer.at(2, 3) = charVect.at(5); answer.at(3, 2) = charVect.at(5); } else if ( ( type == LocalMomentumTensor ) || ( type == GlobalMomentumTensor ) ) { //this->computeStressVector(charVect, gp, tStep); charVect = ms->giveStressVector(); answer.at(1, 1) = charVect.at(1); answer.at(2, 2) = charVect.at(2); answer.at(1, 2) = charVect.at(3); answer.at(2, 1) = charVect.at(3); } else if ( ( type == LocalStrainTensor ) || ( type == GlobalStrainTensor ) ) { //this->computeStrainVector(charVect, gp, tStep); charVect = ms->giveStrainVector(); answer.at(1, 3) = charVect.at(4) / 2.; answer.at(3, 1) = charVect.at(4) / 2.; answer.at(2, 3) = charVect.at(5) / 2.; answer.at(3, 2) = charVect.at(5) / 2.; } else if ( ( type == LocalCurvatureTensor ) || ( type == GlobalCurvatureTensor ) ) { //this->computeStrainVector(charVect, gp, tStep); charVect = ms->giveStrainVector(); answer.at(1, 1) = charVect.at(1); answer.at(2, 2) = charVect.at(2); answer.at(1, 2) = charVect.at(3) / 2.; answer.at(2, 1) = charVect.at(3) / 2.; } else { _error("GiveCharacteristicTensor: unsupported tensor mode"); exit(1); } if ( ( type == GlobalForceTensor ) || ( type == GlobalMomentumTensor ) || ( type == GlobalStrainTensor ) || ( type == GlobalCurvatureTensor ) ) { this->computeGtoLRotationMatrix(); answer.rotatedWith(* GtoLRotationMatrix); } }
void SimpleVitrificationMaterial :: giveRealStressVector_3d(FloatArray &answer, GaussPoint *gp, const FloatArray &reducedStrain, TimeStep *tStep) { FloatArray strainVector; FloatMatrix d; FloatArray deltaStrain; StructuralMaterialStatus *status = dynamic_cast< StructuralMaterialStatus * >( this->giveStatus(gp) ); this->giveStressDependentPartOfStrainVector(strainVector, gp, reducedStrain, tStep, VM_Total); deltaStrain.beDifferenceOf( strainVector, status->giveStrainVector() ); this->give3dMaterialStiffnessMatrix(d, TangentStiffness, gp, tStep); FloatArray deltaStress; deltaStress.beProductOf(d, deltaStrain); answer = status->giveStressVector(); answer.add(deltaStress); // update gp status->letTempStrainVectorBe(reducedStrain); status->letTempStressVectorBe(answer); }
int FiberedCrossSection :: giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep) { Material *mat = this->giveDomain()->giveMaterial( fiberMaterials.at(1) ); ///@todo For now, create material status according to the first fiber material StructuralMaterialStatus *status = static_cast< StructuralMaterialStatus * >( mat->giveStatus(gp) ); if ( type == IST_BeamForceMomentTensor ) { answer = status->giveStressVector(); return 1; } else if ( type == IST_BeamStrainCurvatureTensor ) { answer = status->giveStrainVector(); return 1; } return CrossSection :: giveIPValue(answer, gp, type, tStep); }
void LIBeam3dNL :: computeTempCurv(FloatArray &answer, TimeStep *tStep) { IntegrationRule *iRule = this->giveDefaultIntegrationRulePtr(); GaussPoint *gp = iRule->getIntegrationPoint(0); FloatArray ui(3), ac(3), PrevEpsilon; FloatMatrix sc(3, 3), tmid(3, 3); // update curvature at midpoint // first, compute Tmid // ask increments this->computeVectorOf(VM_Incremental, tStep, ui); ac.at(1) = 0.5 * ( ui.at(10) - ui.at(4) ); ac.at(2) = 0.5 * ( ui.at(11) - ui.at(5) ); ac.at(3) = 0.5 * ( ui.at(12) - ui.at(6) ); this->computeSMtrx(sc, ac); sc.times(1. / 2.); // compute I+sc sc.at(1, 1) += 1.0; sc.at(2, 2) += 1.0; sc.at(3, 3) += 1.0; tmid.beProductOf(sc, this->tc); // update curvature at centre ac.at(1) = ( ui.at(10) - ui.at(4) ); ac.at(2) = ( ui.at(11) - ui.at(5) ); ac.at(3) = ( ui.at(12) - ui.at(6) ); answer.beTProductOf(tmid, ac); answer.times(1 / this->l0); // ask for previous kappa StructuralMaterialStatus *matStat = static_cast< StructuralMaterialStatus * >( gp->giveMaterialStatus() ); if ( matStat ) { PrevEpsilon = matStat->giveStrainVector(); } if ( PrevEpsilon.giveSize() ) { answer.at(1) += PrevEpsilon.at(4); answer.at(2) += PrevEpsilon.at(5); answer.at(3) += PrevEpsilon.at(6); } }
void LinQuad3DPlaneStress :: giveCharacteristicTensor(FloatMatrix &answer, CharTensor type, GaussPoint *gp, TimeStep *tStep) // returns characteristic tensor of the receiver at given gp and tStep // strain vector = (Eps_X, Eps_y, Gamma_xy, Kappa_z) { FloatArray charVect; StructuralMaterialStatus *ms = static_cast< StructuralMaterialStatus * >( gp->giveMaterialStatus() ); answer.resize(3, 3); answer.zero(); if ( ( type == LocalForceTensor ) || ( type == GlobalForceTensor ) ) { //this->computeStressVector(charVect, gp, tStep); charVect = ms->giveStressVector(); answer.at(1, 1) = charVect.at(1); answer.at(2, 2) = charVect.at(2); answer.at(1, 2) = charVect.at(3); answer.at(2, 1) = charVect.at(3); } else if ( ( type == LocalMomentTensor ) || ( type == GlobalMomentTensor ) ) { } else if ( ( type == LocalStrainTensor ) || ( type == GlobalStrainTensor ) ) { //this->computeStrainVector(charVect, gp, tStep); charVect = ms->giveStrainVector(); answer.at(1, 1) = charVect.at(1); answer.at(2, 2) = charVect.at(2); answer.at(1, 2) = charVect.at(3) / 2.; answer.at(2, 1) = charVect.at(3) / 2.; } else if ( ( type == LocalCurvatureTensor ) || ( type == GlobalCurvatureTensor ) ) { } else { OOFEM_ERROR("unsupported tensor mode"); exit(1); } if ( ( type == GlobalForceTensor ) || ( type == GlobalMomentTensor ) || ( type == GlobalStrainTensor ) || ( type == GlobalCurvatureTensor ) ) { this->computeGtoLRotationMatrix(); answer.rotatedWith(* GtoLRotationMatrix); } }
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(); }