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 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 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_3d(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) { StructuralMaterial *mat = dynamic_cast< StructuralMaterial * >( this->giveMaterial(gp) ); mat->give3dMaterialStiffnessMatrix(answer, rMode, gp, tStep); }