void MatlabExportModule :: doOutputHomogenizeDofIDs(TimeStep *tStep, FILE *FID) { std :: vector <FloatArray*> HomQuantities; double Vol = 0.0; // Initialize vector of arrays constaining homogenized quantities HomQuantities.resize(internalVarsToExport.giveSize()); for (int j=0; j<internalVarsToExport.giveSize(); j++) { HomQuantities.at(j) = new FloatArray; } int nelem = this->elList.giveSize(); for (int i = 1; i<=nelem; i++) { Element *e = this->emodel->giveDomain(1)->giveElement(elList.at(i)); FEInterpolation *Interpolation = e->giveInterpolation(); Vol = Vol + e->computeVolumeAreaOrLength(); for ( GaussPoint *gp: *e->giveDefaultIntegrationRulePtr() ) { for (int j=0; j<internalVarsToExport.giveSize(); j++) { FloatArray elementValues; e->giveIPValue(elementValues, gp, (InternalStateType) internalVarsToExport(j), tStep); double detJ=fabs(Interpolation->giveTransformationJacobian( gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(e))); elementValues.times(gp->giveWeight()*detJ); if (HomQuantities.at(j)->giveSize() == 0) { HomQuantities.at(j)->resize(elementValues.giveSize()); HomQuantities.at(j)->zero(); }; HomQuantities.at(j)->add(elementValues); } } } if (noscaling) Vol=1.0; for ( std :: size_t i = 0; i < HomQuantities.size(); i ++) { FloatArray *thisIS; thisIS = HomQuantities.at(i); thisIS->times(1.0/Vol); fprintf(FID, "\tspecials.%s = [", __InternalStateTypeToString ( InternalStateType (internalVarsToExport(i)) ) ); for (int j = 0; j<thisIS->giveSize(); j++) { fprintf(FID, "%e", thisIS->at(j+1)); if (j!=(thisIS->giveSize()-1) ) { fprintf(FID, ", "); } } fprintf(FID, "];\n"); delete HomQuantities.at(i); } }
void MisesMat :: giveRealStressVector_1d(FloatArray &answer, GaussPoint *gp, const FloatArray &totalStrain, TimeStep *tStep) { /// @note: One should obtain the same answer using the iterations in the default implementation (this is verified for this model). #if 1 MisesMatStatus *status = static_cast< MisesMatStatus * >( this->giveStatus(gp) ); this->performPlasticityReturn(gp, totalStrain); double omega = computeDamage(gp, tStep); answer = status->giveTempEffectiveStress(); answer.times(1 - omega); // Compute the other components of the strain: LinearElasticMaterial *lmat = this->giveLinearElasticMaterial(); double E = lmat->give('E', gp), nu = lmat->give('n', gp); FloatArray strain = status->getTempPlasticStrain(); strain[0] = totalStrain[0]; strain[1] -= nu / E * status->giveTempEffectiveStress()[0]; strain[2] -= nu / E * status->giveTempEffectiveStress()[0]; status->letTempStrainVectorBe(strain); status->setTempDamage(omega); status->letTempStressVectorBe(answer); #else StructuralMaterial :: giveRealStressVector_1d(answer, gp, totalStrain, tStep); #endif }
void FE2FluidMaterial :: giveDeviatoricPressureStiffness(FloatArray &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) { FE2FluidMaterialStatus *ms = static_cast<FE2FluidMaterialStatus*> (this->giveStatus(gp)); ms->computeTangents(tStep); if ( mode == TangentStiffness ) { answer = ms->giveDeviatoricPressureTangent(); #ifdef DEBUG_TANGENT // Numerical ATS for debugging FloatArray strain(3); strain.zero(); FloatArray sig, sigh; double epspvol, pressure = 0.0; double h = 1.00; // Linear problem, size of this doesn't matter. computeDeviatoricStressVector (sig, epspvol, gp, strain, pressure, tStep); computeDeviatoricStressVector (sigh, epspvol, gp, strain, pressure+h, tStep); FloatArray dsigh; dsigh.beDifferenceOf(sigh,sig); dsigh.times(1/h); printf("Analytical deviatoric pressure tangent = "); answer.printYourself(); printf("Numerical deviatoric pressure tangent = "); dsigh.printYourself(); dsigh.subtract(answer); double norm = dsigh.computeNorm(); if (norm > answer.computeNorm()*DEBUG_ERR && norm > 0.0) { OOFEM_ERROR("Error in deviatoric pressure tangent"); } #endif } else { OOFEM_ERROR("Mode not implemented"); } }
void NonlinearFluidMaterial :: computeDeviatoricStressVector(FloatArray &answer, GaussPoint *gp, const FloatArray &eps, TimeStep *tStep) { NonlinearFluidMaterialStatus *status = static_cast< NonlinearFluidMaterialStatus * >( this->giveStatus(gp) ); double normeps2; answer = eps; if ( eps.giveSize() == 3 ) { normeps2 = eps.at(1) * eps.at(1) + eps.at(2) * eps.at(2) + 0.5 * ( eps.at(3) * eps.at(3) ); answer.at(3) *= 0.5; } else if ( eps.giveSize() == 4 ) { normeps2 = eps.at(1) * eps.at(1) + eps.at(2) * eps.at(2) + eps.at(3) * eps.at(3) + 0.5 * ( eps.at(4) * eps.at(4) ); answer.at(4) *= 0.5; } else { normeps2 = eps.at(1) * eps.at(1) + eps.at(2) * eps.at(2) + eps.at(3) * eps.at(3) + 0.5 * ( eps.at(4) * eps.at(4) + eps.at(5) * eps.at(5) + eps.at(6) * eps.at(6) ); answer.at(4) *= 0.5; answer.at(5) *= 0.5; answer.at(6) *= 0.5; } answer.times( 2.0 * viscosity * ( 1.0 + c * pow(normeps2, alpha * 0.5) ) ); status->letTempDeviatoricStressVectorBe(answer); status->letTempDeviatoricStrainVectorBe(eps); status->letTempStrainNorm2Be(normeps2); }
void Node2NodeContactL :: computeContactTangent(FloatMatrix &answer, CharType type, TimeStep *tStep) { answer.resize(7,7); answer.zero(); FloatArray gap; this->computeGap(gap, tStep); if( gap.at(1) < 0.0 ) { GaussPoint *gp = this->integrationRule->getIntegrationPoint(0); FloatArray C; this->computeCmatrixAt(gp, C, tStep); int sz = C.giveSize(); C.times(this->area); answer.addSubVectorCol(C, 1, sz + 1); answer.addSubVectorRow(C, sz + 1, 1); } //TODO need to add a small number for the solver for ( int i = 1; i <= 7; i++ ) { answer.at(i,i) += 1.0e-8; } }
void ConstantEdgeLoad :: computeValueAt(FloatArray &answer, TimeStep *stepN, FloatArray &coords, ValueModeType mode) { // we overload general implementation on the boundary load level due // to implementation efficiency double factor; if ( ( mode != VM_Total ) && ( mode != VM_Incremental ) ) { _error("computeValueAt: mode not supported"); } // ask time distribution /* * factor = this -> giveLoadTimeFunction() -> at(stepN->giveTime()) ; * if ((mode==VM_Incremental) && (!stepN->isTheFirstStep())) * //factor -= this->giveLoadTimeFunction()->at(stepN->givePreviousStep()->giveTime()) ; * factor -= this->giveLoadTimeFunction()->at(stepN->giveTime()-stepN->giveTimeIncrement()) ; */ factor = this->giveLoadTimeFunction()->evaluate(stepN, mode); answer = componentArray; answer.times(factor); if ( !isImposed(stepN) ){ answer.zero(); } }
void PhaseFieldElement :: computeStiffnessMatrix_ud(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep) { FloatMatrix B, DB, N_d, DN, S(3,1); FloatArray stress; NLStructuralElement *el = this->giveElement(); StructuralCrossSection *cs = dynamic_cast<StructuralCrossSection* > (el->giveCrossSection() ); answer.clear(); for ( auto &gp: el->giveIntegrationRule(0) ) { StructuralMaterialStatus *matStat = static_cast< StructuralMaterialStatus * >( gp->giveMaterialStatus() ); double dV = el->computeVolumeAround(gp); // compute int_V ( B^t * D_B * B )dV this->computeNd_matrixAt(*gp->giveNaturalCoordinates(), N_d); // stress FloatArray reducedStrain, a_u; FloatMatrix B_u; el->computeBmatrixAt( gp, B_u ); stress = matStat->giveTempStressVector(); stress.times( this->computeGPrim( gp, VM_Total, tStep ) ); S.setColumn(stress,1); DN.beProductOf(S, N_d); answer.plusProductUnsym(B_u, DN, dV); } }
void LIBeam2d :: computeBodyLoadVectorAt(FloatArray &answer, Load *load, TimeStep *tStep, ValueModeType mode) { FloatArray lc(1); StructuralElement :: computeBodyLoadVectorAt(answer, load, tStep, mode); answer.times( this->giveCrossSection()->give(CS_Area, lc, this) ); }
void IntMatCoulombContact :: computeEngTraction(double &normalStress, FloatArray &shearStress, FloatArray &tempShearStressShift, double normalJump, const FloatArray &shearJump ) { double maxShearStress = 0.0; double shift = -this->kn * this->stiffCoeff * normalClearance; if ( normalJump + normalClearance <= 0. ) { normalStress = this->kn * ( normalJump + normalClearance ) + shift; //in compression and after the clearance gap closed maxShearStress = fabs( normalStress ) * this->frictCoeff; } else { normalStress = this->kn * this->stiffCoeff * ( normalJump + normalClearance ) + shift; maxShearStress = 0.; } if ( shearJump.giveSize() != 0 ) { shearStress = this->kn * shearJump - tempShearStressShift; double dp = shearStress.computeNorm(); double eps = 1.0e-15; // small number if ( dp > maxShearStress ) { shearStress.times( maxShearStress / ( dp + eps ) ); } tempShearStressShift = this->kn * shearJump - shearStress; } else { // 1d -> no shear stresses return; } }
void EnrichmentItem :: calcPolarCoord(double &oR, double &oTheta, const FloatArray &iOrigin, const FloatArray &iPos, const FloatArray &iN, const FloatArray &iT, const EfInput &iEfInput, bool iFlipTangent) { FloatArray q = { iPos.at(1) - iOrigin.at(1), iPos.at(2) - iOrigin.at(2) }; const double tol = 1.0e-20; // Compute polar coordinates oR = iOrigin.distance(iPos); if ( oR > tol ) { q.times(1.0 / oR); } const double pi = M_PI; // if( q.dotProduct(iT) > 0.0 ) { // oTheta = asin( q.dotProduct(iN) ); // } else { // if ( q.dotProduct(iN) > 0.0 ) { // oTheta = pi - asin( q.dotProduct(iN) ); // } else { // oTheta = -pi - asin( q.dotProduct(iN) ); // } // } const double tol_q = 1.0e-3; double phi = iEfInput.mLevelSet; if ( iFlipTangent ) { phi *= -1.0; } double phi_r = 0.0; if ( oR > tol ) { phi_r = fabs(phi / oR); } if ( phi_r > 1.0 - XfemTolerances :: giveApproxZero() ) { phi_r = 1.0 - XfemTolerances :: giveApproxZero(); } if ( iEfInput.mArcPos < tol_q || iEfInput.mArcPos > ( 1.0 - tol_q ) ) { double q_dot_n = q.dotProduct(iN); if ( q_dot_n > 1.0 - XfemTolerances :: giveApproxZero() ) { q_dot_n = 1.0 - XfemTolerances :: giveApproxZero(); } oTheta = asin(q_dot_n); } else { if ( phi > 0.0 ) { oTheta = pi - asin( fabs(phi_r) ); } else { oTheta = -pi + asin( fabs(phi_r) ); } } }
int IntElPoint :: computeGlobalCoordinates(FloatArray &answer, const FloatArray &lcoords) { answer = *this->giveNode(1)->giveCoordinates(); answer.add(*this->giveNode(2)->giveCoordinates()); answer.times(0.5); return 1; }
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); }
double LineSurfaceTension :: SpatialLocalizerI_giveDistanceFromParametricCenter(const FloatArray &coords) { FloatArray c; c = *this->giveNode(1)->giveCoordinates(); c.add(*this->giveNode(2)->giveCoordinates()); c.times(0.5); c.subtract(coords); return c.computeNorm(); }
double FEI3dTrQuad :: surfaceEvalNormal(FloatArray &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) { FloatArray G1, G2; // local curvilinear base vectors this->surfaceEvalBaseVectorsAt(G1, G2, lcoords, cellgeo); answer.beVectorProductOf(G1, G2); double J = answer.computeNorm(); answer.times(1 / J); return J; }
void NonLinearStatic :: computeExternalLoadReactionContribution(FloatArray &reactions, TimeStep *tStep, int di) { if ( ( di == 1 ) && ( tStep == this->giveCurrentStep() ) ) { reactions = incrementalLoadVectorOfPrescribed; reactions.times(loadLevel); reactions.add(initialLoadVectorOfPrescribed); } else { _error("computeExternalLoadReactionContribution: unable to respond due to invalid solution step or domain"); } }
void PointLoad :: computeValueAt(FloatArray &answer, TimeStep *tStep, FloatArray &coords, ValueModeType mode) { double factor; // returns component array for elements which use direct formulae Load :: computeComponentArrayAt(answer, tStep, mode); // time distribution factor = this->giveLoadTimeFunction()->evaluate(tStep, mode); answer.times(factor); }
void QPlaneStress2d :: NodalAveragingRecoveryMI_computeNodalValue(FloatArray &answer, int node, InternalStateType type, TimeStep *tStep) { if ( numberOfGaussPoints != 4 ) { return; } GaussPoint *gp; if ( node < 5 ) { int i = 0; switch ( node ) { case 1: i = 4; break; case 2: i = 2; break; case 3: i = 1; break; case 4: i = 3; break; } gp = integrationRulesArray [ 0 ]->getIntegrationPoint(i - 1); this->giveIPValue(answer, gp, type, tStep); } else { int i1 = 0, i2 = 0; switch ( node ) { case 5: i1 = 4; i2 = 2; break; case 6: i1 = 2; i2 = 1; break; case 7: i1 = 1; i2 = 3; break; case 8: i1 = 3; i2 = 4; break; } FloatArray contrib; gp = integrationRulesArray [ 0 ]->getIntegrationPoint(i1 - 1); this->giveIPValue(contrib, gp, type, tStep); gp = integrationRulesArray [ 0 ]->getIntegrationPoint(i2 - 1); this->giveIPValue(answer, gp, type, tStep); answer.add(contrib); answer.times(0.5); } }
void SlaveDof :: computeDofTransformation(FloatArray &primaryMasterContribs) { FloatArray subPrimaryMasterContribs; primaryMasterContribs.resize( this->giveNumberOfPrimaryMasterDofs() ); 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(); } }
void HydratingHeMoMaterial :: updateInternalState(const FloatArray &vec, GaussPoint *gp, TimeStep *tStep) { TransportMaterialStatus *ms = static_cast< TransportMaterialStatus * >( this->giveStatus(gp) ); FloatArray aux; if ( ms ) { ms->letTempStateVectorBe(vec); if ( hydration ) { /* OBSOLETE * FloatArray s = ms->giveStateVector (); * if (vec.isEmpty()) OOFEM_ERROR("empty new state vector"); * aux.resize(2); * aux.at(1) = vec.at(1); * if (s.isEmpty()||(tStep->giveTime()<=0)) aux.at(2) = initialHydrationDegree; // apply initial conditions * else { * aux.at(2) = s.at(2); * if (!castAt || (tStep->giveTime()>=castAt)) aux.at(2) += hydrationModel->dksi (s.at(2), vec.at(1), tStep->giveTimeIncrement()); // compute hydration degree increment * } */ // it is necessary to convert the passed state vector to relative humidity expected by the hydration model //!!! might be cleaner to choose wc / h in hydration model, but it must be defined which one is passed anyway; so relative humidity was chosen //!!! also, the humidity vector might be evaluated by a function (ensure 2 elements and set humidity) FloatArray vech = vec; if ( vech.giveSize() >= 2 ) { vech.at(2) = inverse_sorption_isotherm( vec.at(2) ); // compute relative humidity } else { vech.resize(2); vech.at(2) = 1.; // saturated if undefined } HydrationModelInterface :: updateInternalState(vech, gp, tStep); // additional file output !!! if ( teplotaOut && ( gp->giveNumber() == 1 ) && giveStatus(gp) ) { FILE *vyst = fopen("teplota.out", "a"); computeInternalSourceVector(aux, gp, tStep, VM_Incremental); if ( aux.isEmpty() ) { aux.resize(1); aux.zero(); } aux.times( 1. / give('d', gp) ); fprintf( vyst, "Elem %.3d krok %.2d: t= %.0f, dt=%.0f, %ld. it, ksi= %.12f, T= %.8f, heat=%.8f\n", gp->giveElement()->giveNumber(), tStep->giveNumber(), tStep->giveTargetTime(), tStep->giveTimeIncrement(), tStep->giveSolutionStateCounter(), giveHydrationDegree(gp, tStep, VM_Total), vec.at(1), aux.at(1) * tStep->giveTimeIncrement() ); fclose(vyst); } } } }
void MaxwellChainMaterial :: computeHiddenVars(GaussPoint *gp, TimeStep *tStep) { /* * Updates hidden variables used to effectively trace the load history */ double deltaYmu, Emu, lambdaMu; FloatArray help, deltaEps0, help1; FloatArray muthHiddenVarsVector; FloatMatrix Binv; MaxwellChainMaterialStatus *status = static_cast< MaxwellChainMaterialStatus * >( this->giveStatus(gp) ); this->giveUnitStiffnessMatrix(Binv, gp, tStep); help = status->giveTempStrainVector(); help.subtract( status->giveStrainVector() ); // Subtract the stress-independent part of strain this->computeTrueStressIndependentStrainVector(deltaEps0, gp, tStep, VM_Incremental); if ( deltaEps0.giveSize() ) { help.subtract(deltaEps0); } help1.beProductOf(Binv, help); ///@warning THREAD UNSAFE! double tPrime = relMatAge + ( tStep->giveTargetTime() - 0.5 * tStep->giveTimeIncrement() ) / timeFactor; this->updateEparModuli(tPrime, gp, tStep); for ( int mu = 1; mu <= nUnits; mu++ ) { deltaYmu = tStep->giveTimeIncrement() / timeFactor / this->giveCharTime(mu); deltaYmu = pow( deltaYmu, this->giveCharTimeExponent(mu) ); lambdaMu = ( 1.0 - exp(-deltaYmu) ) / deltaYmu; Emu = this->giveEparModulus(mu); muthHiddenVarsVector = status->giveHiddenVarsVector(mu); help = help1; help.times(lambdaMu * Emu); if ( muthHiddenVarsVector.giveSize() ) { muthHiddenVarsVector.times( exp(-deltaYmu) ); muthHiddenVarsVector.add(help); status->letTempHiddenVarsVectorBe(mu, muthHiddenVarsVector); } else { status->letTempHiddenVarsVectorBe(mu, help); } } }
void ConstantPressureLoad :: computeValueAt(FloatArray &answer, TimeStep *tStep, const FloatArray &coords, ValueModeType mode) { // we overload general implementation on the boundary load level due // to implementation efficiency if ( ( mode != VM_Total ) && ( mode != VM_Incremental ) ) { OOFEM_ERROR("mode not supported"); } // ask time distribution double factor = this->giveTimeFunction()->evaluate(tStep, mode); answer = componentArray; answer.times(factor); }
void PhaseFieldElement :: computeBStress_u(FloatArray &answer, GaussPoint *gp, TimeStep *tStep, int useUpdatedGpRecord) { // computes G(d)*sig(u) NLStructuralElement *el = this->giveElement(); FloatArray strain, a_u; FloatMatrix B_u; el->computeBmatrixAt(gp, B_u); this->computeDisplacementUnknowns(a_u, VM_Total, tStep); strain.beProductOf(B_u, a_u); el->computeStressVector(answer, strain, gp, tStep); answer.times( this->computeG(gp, VM_Total, tStep) ); }
void MisesMat :: giveRealStressVector_3d(FloatArray &answer, GaussPoint *gp, const FloatArray &totalStrain, TimeStep *tStep) { MisesMatStatus *status = static_cast< MisesMatStatus * >( this->giveStatus(gp) ); this->performPlasticityReturn(gp, totalStrain); double omega = computeDamage(gp, tStep); answer = status->giveTempEffectiveStress(); answer.times(1 - omega); status->setTempDamage(omega); status->letTempStrainVectorBe(totalStrain); status->letTempStressVectorBe(answer); }
void NonlinearMassTransferMaterial :: giveFluxVector(FloatArray &answer, GaussPoint *gp, const FloatArray &eps, TimeStep *tStep) { AnisotropicMassTransferMaterialStatus *thisMaterialStatus; thisMaterialStatus = ( ( AnisotropicMassTransferMaterialStatus * ) this->giveStatus(gp) ); thisMaterialStatus->setPressureGradient(eps); double gradPNorm = eps.computeNorm(); answer = eps; answer.times( 1 + C * pow(gradPNorm, alpha) ); answer.negated(); thisMaterialStatus->setSeepageValocity(answer); }
int TrPlaneStrRot3d :: giveIPValue(FloatArray &answer, GaussPoint *aGaussPoint, InternalStateType type, TimeStep *tStep) { FloatMatrix globTensor; CharTensor cht; answer.resize(12); if ( ( type == IST_ShellForceMomentumTensor ) || ( type == IST_ShellStrainCurvatureTensor ) ) { if ( type == IST_ShellForceMomentumTensor ) { cht = GlobalForceTensor; } else { cht = GlobalStrainTensor; } this->giveCharacteristicTensor(globTensor, cht, aGaussPoint, tStep); answer.at(1) = globTensor.at(1, 1); //sxForce answer.at(2) = globTensor.at(2, 2); //syForce answer.at(3) = globTensor.at(3, 3); //szForce answer.at(4) = globTensor.at(2, 3); //syzForce answer.at(5) = globTensor.at(1, 3); //qxzForce answer.at(6) = globTensor.at(1, 2); //qxyForce // mutiply stresses by thickness to get forces answer.times(this->giveCrossSection()->give(CS_Thickness)); if ( type == IST_ShellForceMomentumTensor ) { cht = GlobalMomentumTensor; } else { cht = GlobalCurvatureTensor; } this->giveCharacteristicTensor(globTensor, cht, aGaussPoint, tStep); answer.at(7) = globTensor.at(1, 1); //mxForce answer.at(8) = globTensor.at(2, 2); //myForce answer.at(9) = globTensor.at(3, 3); //mzForce answer.at(10) = globTensor.at(2, 3); //myzForce answer.at(11) = globTensor.at(1, 3); //mxzForce answer.at(12) = globTensor.at(1, 2); //mxyForce return 1; } else { answer.resize(0); return 0; } }
void TransportGradientPeriodic :: computeField(FloatArray &flux, TimeStep *tStep) { DofIDEquationNumbering pnum(true, grad_ids); EngngModel *emodel = this->giveDomain()->giveEngngModel(); FloatArray tmp; int npeq = grad_ids.giveSize(); // sigma = residual (since we use the slave dofs) = f_ext - f_int flux.resize(npeq); flux.zero(); emodel->assembleVector(flux, tStep, InternalForceAssembler(), VM_Total, pnum, this->domain); tmp.resize(npeq); tmp.zero(); emodel->assembleVector(tmp, tStep, ExternalForceAssembler(), VM_Total, pnum, this->domain); flux.subtract(tmp); // Divide by the RVE-volume flux.times(1.0 / ( this->domainSize(this->giveDomain(), this->set) + this->domainSize(this->giveDomain(), this->masterSet) )); }
void StokesFlowVelocityHomogenization :: computeSeepage(FloatArray &v, TimeStep *tStep) { FloatMatrix N; FloatArray v_hatTemp, unknowns; v.clear(); for ( auto &elem : this->giveDomain(1)->giveElements() ) { this->integrateNMatrix(N, *elem, tStep); elem->computeVectorOf({V_u, V_v, V_w}, VM_Total, tStep, unknowns); v_hatTemp.beProductOf(N, unknowns); v.add(v_hatTemp); } v.times( 1. / this->giveAreaOfRVE() ); }
void FEI2dLineLin :: edgeEvaldNds(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) { double xi = lcoords(0); answer.resize(2); answer(0) = -0.5*xi; answer(1) = 0.5*xi; double es1 = answer(0)*cellgeo.giveVertexCoordinates(1)->at(xind) + answer(1)*cellgeo.giveVertexCoordinates(2)->at(xind); double es2 = answer(0)*cellgeo.giveVertexCoordinates(1)->at(yind) + answer(1)*cellgeo.giveVertexCoordinates(2)->at(yind); double J = sqrt(es1*es1+es2*es2); answer.times(1/J); //return J; }
void LIBeam3dNL :: computeTempCurv(FloatArray &answer, TimeStep *tStep) { Material *mat = this->giveMaterial(); IntegrationRule *iRule = integrationRulesArray [ giveDefaultIntegrationRule() ]; GaussPoint *gp = iRule->getIntegrationPoint(0); ; FloatArray ui(3), xd(3), curv(3), ac(3), PrevEpsilon; FloatMatrix sc(3, 3), tmid(3, 3); answer.resize(3); // update curvature at midpoint // first, compute Tmid // ask increments this->computeVectorOf(EID_MomentumBalance, 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 PrevEpsilon = ( ( StructuralMaterialStatus * ) mat->giveStatus(gp) )->giveStrainVector(); if ( PrevEpsilon.giveSize() ) { answer.at(1) += PrevEpsilon.at(4); answer.at(2) += PrevEpsilon.at(5); answer.at(3) += PrevEpsilon.at(6); } }
void LineSurfaceTension :: computeLoadVector(FloatArray &answer, ValueModeType mode, TimeStep *tStep) { domainType dt = this->giveDomain()->giveDomainType(); Node *node1, *node2; FloatArray v1, v2, v; double x1, x2, length, t, gamma_s; gamma_s = this->giveMaterial()->give('g',NULL); node1 = giveNode(1); node2 = giveNode(2); v.beDifferenceOf(*node2->giveCoordinates(), *node1->giveCoordinates()); length = v.computeNorm(); v.times(1.0/length); x1 = node1->giveCoordinate(1); x2 = node1->giveCoordinate(2); answer.resize(4); answer.zero(); if (dt == _3dAxisymmMode) { OOFEM_CLASS_ERROR("Not tested"); t = M_PI*(x1+x2); answer.at(1) = v.at(1)*t - length; answer.at(2) = v.at(2)*t; answer.at(3) = -v.at(1)*t - length; answer.at(4) = -v.at(2)*t; } else { //t = this->giveDomain()->giveCrossSection(1)->give(CS_Thickness); t = 1.0; // In this case simple linear case, the boundary term would cancel out the edge term, // so it can be simplified to check when the boundary is not there. answer.at(1) = v.at(1)*t; answer.at(2) = v.at(2)*t; answer.at(3) = -v.at(1)*t; answer.at(4) = -v.at(2)*t; } answer.times(gamma_s); }