void M1Material :: giveRealStressVector_3d(FloatArray &answer, GaussPoint *gp, const FloatArray &totalStrain, TimeStep *tStep) { answer.resize(6); answer.zero(); // get the status at the beginning M1MaterialStatus *status = static_cast< M1MaterialStatus * >( this->giveStatus(gp) ); // prepare status at the end this->initTempStatus(gp); // get the initial values of plastic strains on microplanes (set to zero in the first step) FloatArray epspN = status->giveNormalMplanePlasticStrains(); if ( epspN.giveSize() < numberOfMicroplanes ) { epspN.resize(numberOfMicroplanes); epspN.zero(); } // loop over microplanes FloatArray sigN(numberOfMicroplanes); IntArray plState(numberOfMicroplanes); for ( int imp = 1; imp <= numberOfMicroplanes; imp++ ) { Microplane *mPlane = this->giveMicroplane(imp - 1, gp); //IntegrationPointStatus *mPlaneStatus = this->giveMicroplaneStatus(mPlane); double epsN = computeNormalStrainComponent(mPlane, totalStrain); // evaluate trial stress on the microplane double sigTrial = EN * ( epsN - epspN.at(imp) ); // evaluate the yield stress (from total microplane strain, not from its plastic part) double sigYield = EN * ( s0 + HN * epsN ) / ( EN + HN ); if ( sigYield < 0. ) { sigYield = 0.; } // check whether the yield stress is exceeded and set the microplane stress if ( sigTrial > sigYield ) { //plastic yielding sigN.at(imp) = sigYield; epspN.at(imp) = epsN - sigYield / EN; plState.at(imp) = 1; } else { sigN.at(imp) = sigTrial; plState.at(imp) = 0; } // add the contribution of the microplane to macroscopic stresses for ( int i = 1; i <= 6; i++ ) { answer.at(i) += N [ imp - 1 ] [ i - 1 ] * sigN.at(imp) * microplaneWeights [ imp - 1 ]; } } // multiply the integral over unit hemisphere by 6 answer.times(6); // update status status->letTempStrainVectorBe(totalStrain); status->letTempStressVectorBe(answer); status->letTempNormalMplaneStressesBe(sigN); status->letTempNormalMplanePlasticStrainsBe(epspN); status->letPlasticStateIndicatorsBe(plState); }