void GradDpElement :: giveNonlocalInternalForcesVector(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord) { double localCumulatedStrain = 0.; NLStructuralElement *elem = this->giveNLStructuralElement(); FloatMatrix stiffKappa; FloatArray Nk; FloatArray aux, dKappa, stress; int size = nSecVars * nSecNodes; //set displacement and nonlocal location array this->setDisplacementLocationArray(); this->setNonlocalLocationArray(); answer.resize(size); for ( GaussPoint *gp: *elem->giveIntegrationRule(0) ) { this->computeNkappaMatrixAt(gp, Nk); double dV = elem->computeVolumeAround(gp); this->computeStressVectorAndLocalCumulatedStrain(stress, localCumulatedStrain, gp, tStep); aux.add(-dV * localCumulatedStrain, Nk); } this->computeStiffnessMatrix_kk(stiffKappa, TangentStiffness, tStep); this->computeNonlocalDegreesOfFreedom(dKappa, tStep); answer.beProductOf(stiffKappa, dKappa); answer.add(aux); }
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 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 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); }
void LIBeam3dNL :: giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord) { GaussPoint *gp = this->giveDefaultIntegrationRulePtr()->getIntegrationPoint(0); FloatArray nm(6), stress, strain; FloatMatrix x; double s1, s2; // update temp triad this->updateTempTriad(tStep); if ( useUpdatedGpRecord == 1 ) { stress = static_cast< StructuralMaterialStatus * >( gp->giveMaterialStatus() )->giveStrainVector(); } else { this->computeStrainVector(strain, gp, tStep); this->computeStressVector(stress, strain, gp, tStep); } for ( int i = 1; i <= 3; i++ ) { s1 = s2 = 0.0; for ( int j = 1; j <= 3; j++ ) { s1 += tempTc.at(i, j) * stress.at(j); s2 += tempTc.at(i, j) * stress.at(j + 3); } nm.at(i) = s1; nm.at(i + 3) = s2; } this->computeXMtrx(x, tStep); answer.beProductOf(x, nm); }
void TrabBoneEmbed :: giveRealStressVector(FloatArray &answer, MatResponseForm form, GaussPoint *gp, const FloatArray &totalStrain, TimeStep *atTime) { double tempDam, tempTSED; FloatArray newTotalDef, plasDef; FloatArray totalStress; FloatMatrix compliance, elasticity; this->constructIsoComplTensor(compliance, eps0, nu0); elasticity.beInverseOf(compliance); TrabBoneEmbedStatus *status = ( TrabBoneEmbedStatus * ) this->giveStatus(gp); this->initGpForNewStep(gp); performPlasticityReturn(gp, totalStrain); tempDam = computeDamage(gp, atTime); plasDef.resize(6); totalStress.beProductOf(elasticity, totalStrain); tempTSED = 0.5 * totalStrain.dotProduct(totalStress); answer.resize(6); answer = totalStress; status->setTempDam(tempDam); status->letTempStrainVectorBe(totalStrain); status->letTempStressVectorBe(answer); status->setTempTSED(tempTSED); }
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. Mikael: See earlier response to comment */ 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 GradDpElement :: giveNonlocalInternalForcesVector(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord) { double dV, localCumulatedStrain = 0.; NLStructuralElement *elem = this->giveNLStructuralElement(); FloatMatrix stiffKappa, Nk; FloatArray fKappa(nlSize), aux(nlSize), dKappa, stress; aux.zero(); int size = nSecVars * nSecNodes; //set displacement and nonlocal location array this->setDisplacementLocationArray(locU, nPrimNodes, nPrimVars, nSecNodes, nSecVars); this->setNonlocalLocationArray(locK, nPrimNodes, nPrimVars, nSecNodes, nSecVars); answer.resize(size); for ( GaussPoint *gp: *elem->giveIntegrationRule(0) ) { this->computeNkappaMatrixAt(gp, Nk); for ( int j = 1; j <= nlSize; j++ ) { fKappa.at(j) = Nk.at(1, j); } dV = elem->computeVolumeAround(gp); this->computeStressVectorAndLocalCumulatedStrain(stress, localCumulatedStrain, gp, tStep); fKappa.times(localCumulatedStrain); fKappa.times(-dV); aux.add(fKappa); } this->computeStiffnessMatrix_kk(stiffKappa, TangentStiffness, tStep); this->computeNonlocalDegreesOfFreedom(dKappa, tStep); answer.beProductOf(stiffKappa, dKappa); answer.add(aux); }
void LIBeam3dNL :: giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord) { int i, j; Material *mat = this->giveMaterial(); IntegrationRule *iRule = integrationRulesArray [ giveDefaultIntegrationRule() ]; GaussPoint *gp = iRule->getIntegrationPoint(0); FloatArray nm(6), TotalStressVector(6); FloatMatrix x; double s1, s2; // update temp triad this->updateTempTriad(tStep); if ( useUpdatedGpRecord == 1 ) { TotalStressVector = ( ( StructuralMaterialStatus * ) mat->giveStatus(gp) ) ->giveStressVector(); } else { this->computeStressVector(TotalStressVector, gp, tStep); } for ( i = 1; i <= 3; i++ ) { s1 = s2 = 0.0; for ( j = 1; j <= 3; j++ ) { s1 += tempTc.at(i, j) * TotalStressVector.at(j); s2 += tempTc.at(i, j) * TotalStressVector.at(j + 3); } nm.at(i) = s1; nm.at(i + 3) = s2; } this->computeXMtrx(x, tStep); answer.beProductOf(x, nm); }
void Quad1MindlinShell3D :: computeEdgeIpGlobalCoords(FloatArray &answer, GaussPoint *gp, int iEdge) { FloatArray local; this->interp.edgeLocal2global( local, iEdge, * gp->giveNaturalCoordinates(), FEIVertexListGeometryWrapper(lnodes) ); local.resize(3); local.at(3) = 0.; answer.beProductOf(this->lcsMatrix, local); }
void PolygonLine :: computeIntersectionPoints(const FloatArray &iXStart, const FloatArray &iXEnd, std :: vector< FloatArray > &oIntersectionPoints) const { const double detTol = 1.0e-15; int numSeg = this->giveNrVertices() - 1; for(int segIndex = 1; segIndex <= numSeg; segIndex++) { const FloatArray &xStart = this->giveVertex(segIndex); const FloatArray &xEnd = this->giveVertex(segIndex+1); const FloatArray t1 = {xEnd(0) - xStart(0), xEnd(1) - xStart(1)}; const FloatArray t2 = {iXEnd(0) - iXStart(0), iXEnd(1) - iXStart(1)}; double xi1 = 0.0, xi2 = 0.0; int maxIter = 1; for(int iter = 0; iter < maxIter; iter++) { FloatArray temp = {iXStart(0) + xi2*t2(0) - xStart(0) - xi1*t1(0), iXStart(1) + xi2*t2(1) - xStart(1) - xi1*t1(1)}; FloatArray res = {-t1.dotProduct(temp), t2.dotProduct(temp)}; //printf("iter: %d res: %e\n", iter, res.computeNorm() ); FloatMatrix K(2,2); K(0,0) = t1.dotProduct(t1); K(0,1) = -t1.dotProduct(t2); K(1,0) = -t1.dotProduct(t2); K(1,1) = t2.dotProduct(t2); double detK = K.giveDeterminant(); if(detK < detTol) { return; } FloatMatrix KInv; KInv.beInverseOf(K); FloatArray dxi; dxi.beProductOf(KInv, res); xi1 -= dxi(0); xi2 -= dxi(1); } // printf("xi1: %e xi2: %e\n", xi1, xi2); if(xi1 >= 0.0 && xi1 <= 1.0 && xi2 >= 0.0 && xi2 <= 1.0) { FloatArray pos = xStart; pos.add(xi1, t1); oIntersectionPoints.push_back(pos); } } }
void GradDpElement :: computeNonlocalGradient(FloatArray &answer, GaussPoint *gp, TimeStep *tStep) { FloatMatrix Bk; FloatArray u; this->computeBkappaMatrixAt(gp, Bk); this->computeNonlocalDegreesOfFreedom(u, tStep); answer.beProductOf(Bk, u); }
void CBSElement :: computePrescribedTermsI(FloatArray &answer, ValueModeType mode, TimeStep *tStep) { FloatMatrix mass; FloatArray usp; this->computeConsistentMassMtrx(mass, tStep); this->computeVectorOf(EID_MomentumBalance, mode, tStep, usp); answer.beProductOf(mass, usp); answer.negated(); }
void CBSElement :: computePrescribedTermsI(FloatArray &answer, TimeStep *tStep) { FloatMatrix mass; FloatArray usp; this->computeConsistentMassMtrx(mass, tStep); this->computeVectorOfVelocities(VM_Incremental, tStep, usp); answer.beProductOf(mass, usp); answer.negated(); }
void CBSElement :: computePrescribedTermsII(FloatArray &answer, ValueModeType mode, TimeStep *tStep) { FloatMatrix lhs; FloatArray usp; this->computePressureLhs(lhs, tStep); this->computeVectorOfPressures(mode, tStep, usp); answer.beProductOf(lhs, usp); answer.negated(); }
void SUPGElement2 :: computeDeviatoricStrain(FloatArray &answer, GaussPoint *gp, TimeStep *tStep) { FloatArray u; FloatMatrix b; this->computeVectorOfVelocities(VM_Total, tStep, u); this->computeBMatrix(b, gp); answer.beProductOf(b, u); }
void IsoInterfaceDamageMaterial :: giveRealStressVector(FloatArray &answer, GaussPoint *gp, const FloatArray &totalStrain, TimeStep *atTime) // // returns real stress vector in 3d stress space of receiver according to // previous level of stress and current // strain increment, the only way, how to correctly update gp records // { IsoInterfaceDamageMaterialStatus *status = static_cast< IsoInterfaceDamageMaterialStatus * >( this->giveStatus(gp) ); FloatArray strainVector, reducedTotalStrainVector; FloatMatrix de; double f, equivStrain, tempKappa = 0.0, omega = 0.0; this->initGpForNewStep(gp); // subtract stress independent part // note: eigenStrains (temperature) is not contained in mechanical strain stored in gp // therefore it is necessary to subtract always the total eigen strain value this->giveStressDependentPartOfStrainVector(reducedTotalStrainVector, gp, totalStrain, atTime, VM_Total); //crossSection->giveFullCharacteristicVector(totalStrainVector, gp, reducedTotalStrainVector); // compute equivalent strain this->computeEquivalentStrain(equivStrain, reducedTotalStrainVector, gp, atTime); // compute value of loading function if strainLevel crit apply f = equivStrain - status->giveKappa(); if ( f <= 0.0 ) { // damage do not grow tempKappa = status->giveKappa(); omega = status->giveDamage(); } else { // damage grows tempKappa = equivStrain; // evaluate damage parameter this->computeDamageParam(omega, tempKappa, reducedTotalStrainVector, gp); } this->giveStiffnessMatrix(de, ElasticStiffness, gp, atTime); // damage in tension only if ( equivStrain >= 0.0 ) { de.times(1.0 - omega); } answer.beProductOf(de, reducedTotalStrainVector); // update gp status->letTempStrainVectorBe(totalStrain); status->letTempStressVectorBe(answer); status->setTempKappa(tempKappa); status->setTempDamage(omega); }
void GradDpElement :: computeLocalStrainVector(FloatArray &answer, GaussPoint *gp, TimeStep *tStep) { FloatArray u; FloatMatrix b; NLStructuralElement *elem = this->giveNLStructuralElement(); this->computeDisplacementDegreesOfFreedom(u, tStep); elem->computeBmatrixAt(gp, b); answer.beProductOf(b, u); }
void WinklerPasternakMaterial::giveRealStressVector_2dPlateSubSoil(FloatArray &answer, GaussPoint *gp, const FloatArray &reducedE, TimeStep *tStep) { FloatMatrix tangent; this->give2dPlateSubSoilStiffMtrx(tangent, ElasticStiffness, gp, tStep); answer.beProductOf(tangent, reducedE); StructuralMaterialStatus *status = static_cast< StructuralMaterialStatus * >( this->giveStatus(gp) ); status->letTempStrainVectorBe(reducedE); status->letTempStressVectorBe(answer); }
void QTrPlaneStrain :: EIPrimaryUnknownMI_computePrimaryUnknownVectorAtLocal(ValueModeType mode, TimeStep *tStep, const FloatArray &lcoords, FloatArray &answer) { FloatArray u; FloatMatrix n; this->computeNmatrixAt(lcoords, n); this->computeVectorOf(mode, tStep, u); answer.beProductOf(n, u); }
void Quad1MindlinShell3D :: computeStrainVector(FloatArray &answer, GaussPoint *gp, TimeStep *tStep) { FloatArray shellUnknowns; FloatMatrix b; /* Here we do compute only the "traditional" part of shell strain vector, the quasi-strain related to rotations is not computed */ this->computeVectorOf({D_u, D_v, D_w, R_u, R_v}, VM_Total, tStep, shellUnknowns); this->computeBmatrixAt(gp, b); answer.beProductOf(b, shellUnknowns); }
void GradDpElement :: computeNonlocalCumulatedStrain(double &answer, GaussPoint *gp, TimeStep *tStep) { FloatMatrix Nk; FloatArray u; FloatArray aux; this->computeNkappaMatrixAt(gp, Nk); this->computeNonlocalDegreesOfFreedom(u, tStep); aux.beProductOf(Nk, u); answer = aux.at(1); }
void AnisotropicMassTransferMaterial :: giveFluxVector(FloatArray& answer, GaussPoint *gp, const FloatArray &grad, const FloatArray &field, TimeStep *tStep) { TransportMaterialStatus *ms = static_cast< TransportMaterialStatus * >( this->giveStatus(gp) ); answer.beProductOf(k, grad); answer.negated(); ms->setTempField(field); ms->setTempGradient(grad); ms->setTempFlux(answer); }
void LineDistributedSpring::giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord) { FloatArray u; FloatMatrix k; this->computeVectorOf(VM_Total, tStep, u); this->computeStiffnessMatrix(k, TangentStiffness, tStep); answer.beProductOf(k, u); }
void Line :: transformIntoPolar(FloatArray *point, FloatArray &answer) { FloatArray xp; FloatMatrix Qt; FloatArray help; this->computeTransformationMatrix(Qt); help.beDifferenceOf(* point, mVertices [ 1 ]); xp.beProductOf(Qt, help); answer.resize(2); answer.at(1) = xp.computeNorm(); answer.at(2) = atan2( xp.at(2), xp.at(1) ); }
void SimpleCrossSection :: giveGeneralizedStress_MembraneRot(FloatArray &answer, GaussPoint *gp, const FloatArray &strain, TimeStep *tStep) { FloatMatrix tangent; this->giveMembraneRotStiffMtrx(tangent, ElasticStiffness, gp, tStep); answer.beProductOf(tangent, strain); StructuralMaterialStatus *status = static_cast< StructuralMaterialStatus * >( this->giveMaterial(gp)->giveStatus(gp) ); status->letTempStrainVectorBe(strain); status->letTempStressVectorBe(answer); ///@todo We should support nonlinear behavior for the membrane part. In fact, should be even bundle the rotation part with the membrane? /// We gain nothing from this design anyway as the rotation field is always separate. Separate manual integration by the element would be an option. }
void TrPlaneStress2dXFEM :: EIPrimaryUnknownMI_computePrimaryUnknownVectorAtLocal(ValueModeType mode, TimeStep *tStep, const FloatArray &lcoords, FloatArray &answer) { // TODO: Validate implementation. FloatArray u; FloatMatrix n; XfemElementInterface_createEnrNmatrixAt(n, lcoords, * this, false); this->computeVectorOf(mode, tStep, u); answer.beProductOf(n, u); }
void J2plasticMaterial :: computeTrialStressIncrement(FloatArray &answer, GaussPoint *gp, const FloatArray &strainIncrement, TimeStep *atTime) { /* Computes the full trial elastic stress vector */ FloatArray reducedAnswer; FloatMatrix reducedModuli; StructuralCrossSection *crossSection = ( StructuralCrossSection * ) ( gp->giveElement()->giveCrossSection() ); this->giveLinearElasticMaterial()->giveCharacteristicMatrix(reducedModuli, ReducedForm, ElasticStiffness, gp, atTime); reducedAnswer.beProductOf(reducedModuli, strainIncrement); crossSection->giveFullCharacteristicVector(answer, gp, reducedAnswer); }
void OrthotropicLinearElasticMaterial :: giveThermalDilatationVector(FloatArray &answer, GaussPoint *gp, TimeStep *tStep) // // returns a FloatArray(3) of coefficients of thermal dilatation in direction // of each (local) axis given by element lcs. // { FloatMatrix transf; FloatArray help(6); help.at(1) = this->give(tAlphax, gp); help.at(2) = this->give(tAlphay, gp); help.at(3) = this->give(tAlphaz, gp); this->giveRotationMatrix(transf, gp); answer.beProductOf(transf, help); }
int TrPlaneStress2dXFEM :: EIPrimaryUnknownMI_computePrimaryUnknownVectorAt(ValueModeType mode, TimeStep *stepN, const FloatArray &coords, FloatArray &answer) { // TODO: Validate implementation. FloatArray lcoords, u; FloatMatrix n; int result; result = this->computeLocalCoordinates(lcoords, coords); XfemElementInterface_createEnrNmatrixAt(n, lcoords, *this); this->computeVectorOf(EID_MomentumBalance, mode, stepN, u); answer.beProductOf(n, u); return result; /* FloatArray lcoords, u; FloatMatrix n; int result; result = this->computeLocalCoordinates(lcoords, coords); n.resize(2, 6); n.zero(); n.at(1, 1) = lcoords.at(1); n.at(1, 3) = lcoords.at(2); n.at(1, 5) = lcoords.at(3); n.at(2, 2) = lcoords.at(1); n.at(2, 4) = lcoords.at(2); n.at(2, 6) = lcoords.at(3); this->computeVectorOf(EID_MomentumBalance, mode, stepN, u); answer.beProductOf(n, u); return result; */ }