void FEI3dTetQuad :: local2global(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) { FloatArray N; this->evalN(N, lcoords, cellgeo); answer.resize(0); for ( int i = 1; i <= N.giveSize(); i++ ) { answer.add( N(i), *cellgeo.giveVertexCoordinates(i)); } }
void MicroplaneMaterial :: giveMicroplaneNormal(FloatArray &answer, Microplane *mplane) { int mnumber = mplane->giveNumber(); answer.resize(3); answer.at(1) = microplaneNormals [ mnumber - 1 ] [ 0 ]; answer.at(2) = microplaneNormals [ mnumber - 1 ] [ 1 ]; answer.at(3) = microplaneNormals [ mnumber - 1 ] [ 2 ]; }
void PhaseFieldElement :: computeBStress_d(FloatArray &answer, GaussPoint *gp, TimeStep *tStep, int useUpdatedGpRecord) { // computes g_c*l // PhaseFieldCrossSection *cs = static_cast... double l = this->giveInternalLength(); double g_c = this->giveCriticalEnergy(); answer.resize(1); answer.at(1) = g_c*l; }
int RankineMatNl :: giveIPValue(FloatArray &answer, GaussPoint *aGaussPoint, InternalStateType type, TimeStep *atTime) { if ( type == IST_CumPlasticStrain_2 ) { answer.resize(1); double dummy; // this method also stores the nonlocal kappa in status ... kappa_nl computeCumPlasticStrain(dummy, aGaussPoint, atTime); RankineMatNlStatus *status = ( RankineMatNlStatus * ) this->giveStatus(aGaussPoint); answer.at(1) = status->giveKappa_nl(); return 1; } else if ( type == IST_MaxEquivalentStrainLevel ) { answer.resize(1); computeCumPlasticStrain(answer.at(1), aGaussPoint, atTime); return 1; } else { return RankineMat :: giveIPValue(answer, aGaussPoint, type, atTime); } }
int SimpleCrossSection :: giveIPValue(FloatArray &answer, GaussPoint *ip, InternalStateType type, TimeStep *tStep) { if ( type == IST_CrossSectionNumber ) { answer.resize(1); answer.at(1) = this->giveNumber(); return 1; } return this->giveMaterial(ip)->giveIPValue(answer, ip, type, tStep); }
void FEI3dWedgeLin :: surfaceEvalN(FloatArray &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) { double ksi = lcoords.at(1); double eta = lcoords.at(2); if ( isurf <= 2 ) { answer.resize(3); answer.at(1) = ksi; answer.at(2) = eta; answer.at(3) = 1.0 - ksi - eta; } else { answer.resize(4); answer.at(1) = ( 1. + ksi ) * ( 1. + eta ) * 0.25; answer.at(2) = ( 1. - ksi ) * ( 1. + eta ) * 0.25; answer.at(3) = ( 1. - ksi ) * ( 1. - eta ) * 0.25; answer.at(4) = ( 1. + ksi ) * ( 1. - eta ) * 0.25; } }
int InterfaceElem1d :: computeGlobalCoordinates(FloatArray &answer, const FloatArray &lcoords) { answer.resize(3); answer.at(1) = this->giveNode(1)->giveCoordinate(1); answer.at(2) = this->giveNode(1)->giveCoordinate(2); answer.at(3) = this->giveNode(1)->giveCoordinate(3); return 1; }
int DruckerPragerCutMat :: giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep) { //MaterialStatus *status = this->giveStatus(gp); if ( type == IST_DamageScalar ) { answer.resize(1); answer.zero(); ///@todo Actually export the relevant damage value here! //answer.at(1) = status->giveDamage(); return 1; } else if ( type == IST_DamageTensor ) { answer.resize(6); answer.zero(); //answer.at(1) = answer.at(2) = answer.at(3) = status->giveDamage(); return 1; } else { return MPlasticMaterial2 :: giveIPValue(answer, gp, type, tStep); } }
int MisesMat :: giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep) { MisesMatStatus *status = static_cast< MisesMatStatus * >( this->giveStatus(gp) ); if ( type == IST_PlasticStrainTensor ) { answer = status->givePlasDef(); return 1; } else if ( type == IST_MaxEquivalentStrainLevel ) { answer.resize(1); answer.at(1) = status->giveCumulativePlasticStrain(); return 1; } else if ( ( type == IST_DamageScalar ) || ( type == IST_DamageTensor ) ) { answer.resize(1); answer.at(1) = status->giveDamage(); return 1; } else { return StructuralMaterial :: giveIPValue(answer, gp, type, tStep); } }
void LineSurfaceTension :: giveCharacteristicVector(FloatArray &answer, CharType mtrx, ValueModeType mode, TimeStep *tStep) { if( mtrx == ExternalForcesVector ) { this->computeLoadVector(answer, mode, tStep); } else if ( mtrx == InternalForcesVector ){ answer.resize(0); } else { OOFEM_ERROR2("giveCharacteristicVector: Unknown CharType (%s).",__CharTypeToString(mtrx)); } }
void TR_SHELL02 :: ZZErrorEstimatorI_computeLocalStress(FloatArray &answer, FloatArray &sig) { // sig is global ShellForceMomentumTensor FloatMatrix globTensor(3, 3); const FloatMatrix *GtoLRotationMatrix = plate->computeGtoLRotationMatrix(); FloatMatrix LtoGRotationMatrix; answer.resize(8); // reduced, local form LtoGRotationMatrix.beTranspositionOf(* GtoLRotationMatrix); // Forces globTensor.at(1, 1) = sig.at(1); //sxForce globTensor.at(1, 2) = sig.at(6); //qxyForce globTensor.at(1, 3) = sig.at(5); //qxzForce globTensor.at(2, 1) = sig.at(6); //qxyForce globTensor.at(2, 2) = sig.at(2); //syForce globTensor.at(2, 3) = sig.at(4); //syzForce globTensor.at(3, 1) = sig.at(5); //qxzForce globTensor.at(3, 2) = sig.at(4); //syzForce globTensor.at(3, 3) = sig.at(3); //szForce globTensor.rotatedWith(LtoGRotationMatrix); // Forces: now globTensoris transformed into local c.s // answer should be in reduced, local form answer.at(1) = globTensor.at(1, 1); //sxForce answer.at(2) = globTensor.at(2, 2); //syForce answer.at(3) = globTensor.at(1, 2); //qxyForce answer.at(7) = globTensor.at(2, 3); //syzForce answer.at(8) = globTensor.at(1, 3); //qxzForce // Moments: globTensor.at(1, 1) = sig.at(7); //mxForce globTensor.at(1, 2) = sig.at(12); //mxyForce globTensor.at(1, 3) = sig.at(11); //mxzForce globTensor.at(2, 1) = sig.at(12); //mxyForce globTensor.at(2, 2) = sig.at(8); //myForce globTensor.at(2, 3) = sig.at(10); //myzForce globTensor.at(3, 1) = sig.at(11); //mxzForce globTensor.at(3, 2) = sig.at(10); //myzForce globTensor.at(3, 3) = sig.at(9); //mzForce globTensor.rotatedWith(LtoGRotationMatrix); // now globTensoris transformed into local c.s answer.at(4) = globTensor.at(1, 1); //mxForce answer.at(5) = globTensor.at(2, 2); //myForce answer.at(6) = globTensor.at(1, 2); //mxyForce }
int EIPrimaryUnknownMapper :: mapAndUpdate(FloatArray &answer, ValueModeType mode, Domain *oldd, Domain *newd, TimeStep *tStep) { int inode, nd_nnodes = newd->giveNumberOfDofManagers(); int nsize = newd->giveEngngModel()->giveNumberOfDomainEquations( newd->giveNumber(), EModelDefaultEquationNumbering() ); FloatArray unknownValues; IntArray dofidMask, locationArray; IntArray reglist; #ifdef OOFEM_MAPPING_CHECK_REGIONS ConnectivityTable *conTable = newd->giveConnectivityTable(); const IntArray *nodeConnectivity; #endif answer.resize(nsize); answer.zero(); for ( inode = 1; inode <= nd_nnodes; inode++ ) { DofManager *node = newd->giveNode(inode); /* HUHU CHEATING */ if ( node->giveParallelMode() != DofManager_local ) { continue; } #ifdef OOFEM_MAPPING_CHECK_REGIONS // build up region list for node nodeConnectivity = conTable->giveDofManConnectivityArray(inode); reglist.resize( nodeConnectivity->giveSize() ); reglist.clear(); for ( int indx = 1; indx <= nodeConnectivity->giveSize(); indx++ ) { reglist.insertSortedOnce( newd->giveElement( nodeConnectivity->at(indx) )->giveRegionNumber() ); } #endif ///@todo Shouldn't we pass a primary field or something to this function? if ( this->evaluateAt(unknownValues, dofidMask, mode, oldd, * node->giveCoordinates(), reglist, tStep) ) { ///@todo This doesn't respect local coordinate systems in nodes. Supporting that would require major reworking. for ( int ii = 1; ii <= dofidMask.giveSize(); ii++ ) { // exclude slaves; they are determined from masters auto it = node->findDofWithDofId((DofIDItem)dofidMask.at(ii)); if ( it != node->end() ) { Dof *dof = *it; if ( dof->isPrimaryDof() ) { int eq = dof->giveEquationNumber(EModelDefaultEquationNumbering()); answer.at( eq ) += unknownValues.at(ii); } } } } else { OOFEM_ERROR("evaluateAt service failed for node %d", inode); } } return 1; }
// returns hydration power [W/m3 of concrete] void HydratingConcreteMat :: computeInternalSourceVector(FloatArray &val, GaussPoint *gp, TimeStep *atTime, ValueModeType mode) { HydratingConcreteMatStatus *ms = ( HydratingConcreteMatStatus * ) this->giveStatus(gp); val.resize(1); if ( mode == VM_Total ) { val.at(1) = ms->GivePower(atTime); } else { OOFEM_ERROR2( "Undefined mode %s\n", __ValueModeTypeToString(mode) ); } }
int IntMatBilinearCZ :: giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep) { IntMatBilinearCZStatus *status = static_cast< IntMatBilinearCZStatus * >( this->giveStatus(gp) ); if ( type == IST_DamageScalar ) { answer.resize(1); answer.at(1) = status->mDamageNew; return 1; } else { return StructuralInterfaceMaterial :: giveIPValue(answer, gp, type, tStep); } }
int LineSurfaceTension :: EIPrimaryUnknownMI_computePrimaryUnknownVectorAt(ValueModeType mode, TimeStep *tStep, const FloatArray &gcoords, FloatArray &answer) { FloatArray lcoords; if (!this->computeLocalCoordinates(lcoords, gcoords)) { answer.resize(0); return false; } this->EIPrimaryUnknownMI_computePrimaryUnknownVectorAtLocal(mode, tStep, lcoords, answer); return true; }
void L4Axisymm :: computeStrainVector(FloatArray &answer, GaussPoint *gp, TimeStep *stepN) // Computes the vector containing the strains at the Gauss point gp of // the receiver, at time step stepN. The nature of these strains depends // on the element's type. { int i; FloatMatrix b, A; FloatArray u, Epsilon, help; fMode mode = domain->giveEngngModel()->giveFormulation(); answer.resize(6); answer.zero(); if ( mode == TL ) { // Total Lagrange formulation this->computeVectorOf(EID_MomentumBalance, VM_Total, stepN, u); // linear part of strain tensor (in vector form) this->computeBmatrixAt(gp, b, 1, 2); Epsilon.beProductOf(b, u); answer.at(1) = Epsilon.at(1); answer.at(2) = Epsilon.at(2); if ( numberOfFiAndShGaussPoints == 1 ) { // // if reduced integration in one gp only // force the evaluation of eps_fi in this gauss point // instead of evaluating in given gp // GaussPoint *helpGaussPoint; helpGaussPoint = integrationRulesArray [ 1 ]->getIntegrationPoint(0); this->computeBmatrixAt(helpGaussPoint, b, 3, 6); } else { _error("computeStrainVector: numberOfFiAndShGaussPoints size mismatch"); } Epsilon.beProductOf(b, u); answer.at(3) = Epsilon.at(1); answer.at(6) = Epsilon.at(4); if ( nlGeometry ) { for ( i = 1; i <= 6; i++ ) { // nonlin part of strain vector this->computeNLBMatrixAt(A, gp, i); if ( A.isNotEmpty() ) { help.beProductOf(A, u); answer.at(i) += 0.5 * u.dotProduct(help); } } } } else if ( mode == AL ) { // actualized Lagrange formulation _error("computeStrainVector : unsupported mode"); } }
void ActiveDof :: computeDofTransformation(FloatArray &primaryMasterContribs) { if ( this->isPrimaryDof() ) { primaryMasterContribs.resize(1); primaryMasterContribs.at(1) = 1.0; return; } FloatArray masterContribution, subPrimaryMasterContribs; this->giveActiveBoundaryCondition()->computeDofTransformation(this, masterContribution); primaryMasterContribs.resize( this->giveNumberOfPrimaryMasterDofs() ); int countOfMasterDofs = this->giveNumberOfMasterDofs(); for ( int k = 1, i = 1; i <= countOfMasterDofs; i++ ) { this->giveMasterDof(i)->computeDofTransformation(subPrimaryMasterContribs); subPrimaryMasterContribs.times( masterContribution.at(i) ); primaryMasterContribs.copySubVector(subPrimaryMasterContribs, k); k += subPrimaryMasterContribs.giveSize(); } }
int IsotropicHeatTransferMaterial :: giveIPValue(FloatArray &answer, GaussPoint *aGaussPoint, InternalStateType type, TimeStep *atTime) { if ( type == IST_HydrationDegree ) { answer.resize(1); answer.at(1)=0.; return 1; } return TransportMaterial :: giveIPValue(answer, aGaussPoint, type, atTime); }
void LineDistributedSpring :: computeStressVector(FloatArray &answer, const FloatArray &strain, GaussPoint *gp, TimeStep *tStep) { int ndofs = this->dofs.giveSize(); answer.resize(ndofs); for (int idof=1; idof<=ndofs; idof++) { answer.at(idof) = strain.at(idof)*this->springStiffnesses.at(idof); } //this->giveStructuralCrossSection()->giveGeneralizedStress_DistributedSpring(answer, gp, strain, tStep); }
void RheoChainMaterial :: generateLogTimeScale(FloatArray &answer, double from, double to, int nsteps) { answer.resize(nsteps); answer.zero(); double help = log(to / from) / nsteps; for ( int i = 1; i <= nsteps; i++ ) { answer.at(i) = exp(i * help) * from; } }
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 Triangle :: computeCenterOfCircumCircle(FloatArray &answer) const { FloatArray bar; this->computeBarycentrCoor(bar); double sum = bar.at(1) + bar.at(2) + bar.at(3); // center of the circumcircle answer.resize(2); for ( int i = 1; i <= answer.giveSize(); i++ ) { answer.at(i) = ( bar.at(1) * mVertices [ 0 ].at(i) + bar.at(2) * mVertices [ 1 ].at(i) + bar.at(3) * mVertices [ 2 ].at(i) ) / sum; } }
int IsoInterfaceDamageMaterial :: giveIPValue(FloatArray &answer, GaussPoint *aGaussPoint, InternalStateType type, TimeStep *atTime) { IsoInterfaceDamageMaterialStatus *status = ( IsoInterfaceDamageMaterialStatus * ) this->giveStatus(aGaussPoint); if ( ( type == IST_DamageTensor ) || ( type == IST_PrincipalDamageTensor ) ) { answer.resize(1); answer.at(1) = status->giveDamage(); return 1; } else if ( ( type == IST_DamageTensorTemp ) || ( type == IST_PrincipalDamageTempTensor ) ) { answer.resize(1); answer.at(1) = status->giveTempDamage(); return 1; } else if ( type == IST_MaxEquivalentStrainLevel ) { answer.resize(1); answer.at(1) = status->giveKappa(); return 1; } else { return StructuralMaterial :: giveIPValue(answer, aGaussPoint, type, atTime); } }
void GradDpElement :: giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord) { answer.resize(totalSize); answer.zero(); FloatArray answerU; answerU.resize(locSize); answer.zero(); FloatArray answerK(nlSize); answerK.zero(); ///@todo This code relies on locU and locK already exists. Design seems highly unsafe. /// Instead locU and locK shoulld be statically determined (cf. with the Taylor-Hood elements) / Mikael this->giveNonlocalInternalForcesVector(answerK, tStep, useUpdatedGpRecord); this->giveLocalInternalForcesVector(answerU, tStep, useUpdatedGpRecord); answer.assemble(answerU, locU); answer.assemble(answerK, locK); }
void CCTPlate3d :: computeBodyLoadVectorAt(FloatArray &answer, Load *forLoad, TimeStep *tStep, ValueModeType mode) // Computes numerically the load vector of the receiver due to the body loads, at tStep. // load is assumed to be in global cs. // load vector is then transformed to coordinate system in each node. // (should be global coordinate system, but there may be defined // different coordinate system in each node) { double dens, dV, load; FloatArray force; FloatMatrix T; if ( ( forLoad->giveBCGeoType() != BodyLoadBGT ) || ( forLoad->giveBCValType() != ForceLoadBVT ) ) { OOFEM_ERROR("unknown load type"); } GaussIntegrationRule irule(1, this, 1, 5); irule.SetUpPointsOnTriangle(1, _2dPlate); // note: force is assumed to be in global coordinate system. forLoad->computeComponentArrayAt(force, tStep, mode); if ( force.giveSize() ) { GaussPoint *gp = irule.getIntegrationPoint(0); dens = this->giveStructuralCrossSection()->give('d', gp); // constant density assumed dV = this->computeVolumeAround(gp) * this->giveCrossSection()->give(CS_Thickness, gp); // constant thickness assumed answer.resize(18); answer.zero(); load = force.at(1) * dens * dV / 3.0; answer.at(1) = load; answer.at(7) = load; answer.at(13) = load; load = force.at(2) * dens * dV / 3.0; answer.at(2) = load; answer.at(8) = load; answer.at(14) = load; load = force.at(3) * dens * dV / 3.0; answer.at(3) = load; answer.at(9) = load; answer.at(15) = load; // transform result from global cs to local element cs. if ( this->computeGtoLRotationMatrix(T) ) { answer.rotatedWith(T, 'n'); } } else { answer.clear(); // nil resultant } }
void FEI3dHexaLin :: local2global(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) { FloatArray n; this->evalN(n, lcoords, cellgeo); answer.resize(0); for (int i = 1; i <= 8; i++ ) { answer.add(n.at(i), *cellgeo.giveVertexCoordinates(i)); } }
void FEI2dLineLin :: local2global(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) { FloatArray n; this->evalN(n, lcoords, cellgeo); answer.resize(max(xind,yind)); answer.zero(); answer.at(xind) = ( n(0) * cellgeo.giveVertexCoordinates(1)->at(xind) + n(1) * cellgeo.giveVertexCoordinates(2)->at(xind) ); answer.at(yind) = ( n(0) * cellgeo.giveVertexCoordinates(1)->at(yind) + n(1) * cellgeo.giveVertexCoordinates(2)->at(yind) ); }
void ls2fit(const FloatArray &x, const FloatArray &y, FloatArray &a) { int n = x.giveSize(); a.resize(3); if ( n > 2 ) { // Least square fitting. double f1 = 0, f2 = 0, f3 = 0; double sx = 0, sx2 = 0, sx3 = 0, sx4 = 0; double detCi, Ci11, Ci12, Ci13, Ci22, Ci23, Ci33; double yi, xi, xi2, xi3, xi4; for ( int i = 0; i < n; ++i ) { // Calculate foot points in local coord.sys. xi = x(i); yi = y(i); xi2 = xi * xi; xi3 = xi * xi2; xi4 = xi * xi3; // Construct the coefficient matrix. sx += xi; sx2 += xi2; sx3 += xi3; sx4 += xi4; // And the RHS. f1 += yi; f2 += xi * yi; f3 += xi2 * yi; } // Explicit inverse (avoids numerical problems) Ci11 = sx2 * sx4 - sx3 * sx3; Ci12 = sx2 * sx3 - sx * sx4; Ci13 = sx * sx3 - sx2 * sx2; Ci22 = n * sx4 - sx2 * sx2; Ci23 = sx * sx2 - n * sx3; Ci33 = n * sx2 - sx * sx; detCi = 1 / ( n * Ci11 + sx * Ci12 + sx2 * Ci13 ); a(0) = ( Ci11 * f1 + Ci12 * f2 + Ci13 * f3 ) * detCi; a(1) = ( Ci12 * f1 + Ci22 * f2 + Ci23 * f3 ) * detCi; a(2) = ( Ci13 * f1 + Ci23 * f2 + Ci33 * f3 ) * detCi; } else if ( n == 2 ) { a(2) = 0; a(1) = ( y(1) - y(0) ) / ( x(1) - x(0) ); a(0) = y(0) - a(1) * x(0); } else if ( n == 1 ) { a(0) = y(0); a(1) = 0; a(2) = 0; } else { a.zero(); } }
int HeMoTKMaterial :: giveIPValue(FloatArray &answer, GaussPoint *aGaussPoint, InternalStateType type, TimeStep *atTime) // IST_Humidity overriden to use inverse_sorption_isotherm { if ( type == IST_Humidity ) { answer.resize(1); answer.at(1) = giveHumidity(aGaussPoint, VM_Velocity); // VM_Previous = equilibrated value of humidity return 1; } else { return TransportMaterial :: giveIPValue(answer, aGaussPoint, type, atTime); } }
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); }