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); }
double Lattice2d :: giveCrackWidth() { GaussPoint *gp = this->giveDefaultIntegrationRulePtr()->getIntegrationPoint(0); LatticeMaterialStatus *status = static_cast< LatticeMaterialStatus * >( gp->giveMaterialStatus() ); double crackWidth = 0; crackWidth = status->giveCrackWidth(); return crackWidth; }
int Lattice2d :: giveCrackFlag() { GaussPoint *gp = this->giveDefaultIntegrationRulePtr()->getIntegrationPoint(0); LatticeMaterialStatus *status = static_cast< LatticeMaterialStatus * >( gp->giveMaterialStatus() ); int crackFlag = 0; crackFlag = status->giveCrackFlag(); return crackFlag; }
double Lattice2d :: giveNormalStress() { GaussPoint *gp = this->giveDefaultIntegrationRulePtr()->getIntegrationPoint(0); LatticeMaterialStatus *status = static_cast< LatticeMaterialStatus * >( gp->giveMaterialStatus() ); double normalStress = 0; normalStress = status->giveNormalStress(); return normalStress; }
double Lattice2d :: giveDeltaDissipation() { GaussPoint *gp = this->giveDefaultIntegrationRulePtr()->getIntegrationPoint(0); LatticeMaterialStatus *status = static_cast< LatticeMaterialStatus * >( gp->giveMaterialStatus() ); double deltaDissipation = 0; deltaDissipation = status->giveDeltaDissipation(); return deltaDissipation; }
double Lattice2d_mt :: givePressure() { LatticeTransportMaterialStatus *status; IntegrationRule *iRule = this->giveDefaultIntegrationRulePtr(); GaussPoint *gp = iRule->getIntegrationPoint(0); status = static_cast< LatticeTransportMaterialStatus * >( gp->giveMaterialStatus() ); return status->givePressure(); }
int Lattice2d :: hasBeenUpdated() { LatticeMaterialStatus *status; IntegrationRule *iRule = this->giveDefaultIntegrationRulePtr(); GaussPoint *gp = iRule->getIntegrationPoint(0); status = static_cast< LatticeMaterialStatus * >( gp->giveMaterialStatus() ); int updateFlag = 0; updateFlag = status->hasBeenUpdated(); return updateFlag; }
double Lattice2d :: giveCrackWidth() { LatticeMaterialStatus *status; GaussPoint *gp; IntegrationRule *iRule = integrationRulesArray [ giveDefaultIntegrationRule() ]; gp = iRule->getIntegrationPoint(0); status = static_cast< LatticeMaterialStatus * >( gp->giveMaterialStatus() ); double crackWidth = 0; crackWidth = status->giveCrackWidth(); return crackWidth; }
int Lattice2d :: giveCrackFlag() { LatticeMaterialStatus *status; GaussPoint *gp; IntegrationRule *iRule = integrationRulesArray [ giveDefaultIntegrationRule() ]; gp = iRule->getIntegrationPoint(0); status = static_cast< LatticeMaterialStatus * >( gp->giveMaterialStatus() ); int crackFlag = 0; crackFlag = status->giveCrackFlag(); return crackFlag; }
double Lattice2d :: giveOldNormalStress() { LatticeMaterialStatus *status; GaussPoint *gp; IntegrationRule *iRule = integrationRulesArray [ giveDefaultIntegrationRule() ]; gp = iRule->getIntegrationPoint(0); status = static_cast< LatticeMaterialStatus * >( gp->giveMaterialStatus() ); double normalStress = 0; normalStress = status->giveOldNormalStress(); return normalStress; }
double Lattice2d :: giveDeltaDissipation() { LatticeMaterialStatus *status; GaussPoint *gp; IntegrationRule *iRule = integrationRulesArray [ giveDefaultIntegrationRule() ]; gp = iRule->getIntegrationPoint(0); status = static_cast< LatticeMaterialStatus * >( gp->giveMaterialStatus() ); double deltaDissipation = 0; deltaDissipation = status->giveDeltaDissipation(); return deltaDissipation; }
double Lattice2d_mt :: giveMass() { LatticeTransportMaterialStatus *status; IntegrationRule *iRule = this->giveDefaultIntegrationRulePtr(); GaussPoint *gp = iRule->getIntegrationPoint(0); status = static_cast< LatticeTransportMaterialStatus * >( gp->giveMaterialStatus() ); double mass = 0; mass = status->giveMass(); //multiply with volume mass *= this->length * this->width / 2.; return mass; }
void LIBeam3dNL :: computeTempCurv(FloatArray &answer, TimeStep *tStep) { IntegrationRule *iRule = this->giveDefaultIntegrationRulePtr(); GaussPoint *gp = iRule->getIntegrationPoint(0); FloatArray ui(3), ac(3), PrevEpsilon; FloatMatrix sc(3, 3), tmid(3, 3); // update curvature at midpoint // first, compute Tmid // ask increments this->computeVectorOf(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 StructuralMaterialStatus *matStat = static_cast< StructuralMaterialStatus * >( gp->giveMaterialStatus() ); if ( matStat ) { PrevEpsilon = matStat->giveStrainVector(); } if ( PrevEpsilon.giveSize() ) { answer.at(1) += PrevEpsilon.at(4); answer.at(2) += PrevEpsilon.at(5); answer.at(3) += PrevEpsilon.at(6); } }
std::vector<std::unique_ptr<EnrichmentItem>> NCPrincipalStress::nucleateEnrichmentItems() { SpatialLocalizer *octree = this->mpDomain->giveSpatialLocalizer(); XfemManager *xMan = mpDomain->giveXfemManager(); std::vector<std::unique_ptr<EnrichmentItem>> eiList; // Center coordinates of newly inserted cracks std::vector<FloatArray> center_coord_inserted_cracks; // Loop over all elements and all bulk GP. for(auto &el : mpDomain->giveElements() ) { int numIR = el->giveNumberOfIntegrationRules(); int csNum = el->giveCrossSection()->giveNumber(); if(csNum == mCrossSectionInd || true) { for(int irInd = 0; irInd < numIR; irInd++) { IntegrationRule *ir = el->giveIntegrationRule(irInd); int numGP = ir->giveNumberOfIntegrationPoints(); for(int gpInd = 0; gpInd < numGP; gpInd++) { GaussPoint *gp = ir->getIntegrationPoint(gpInd); // int csNum = gp->giveCrossSection()->giveNumber(); // printf("csNum: %d\n", csNum); StructuralMaterialStatus *ms = dynamic_cast<StructuralMaterialStatus*>(gp->giveMaterialStatus()); if(ms != NULL) { const FloatArray &stress = ms->giveTempStressVector(); FloatArray principalVals; FloatMatrix principalDirs; StructuralMaterial::computePrincipalValDir(principalVals, principalDirs, stress, principal_stress); if(principalVals[0] > mStressThreshold) { // printf("\nFound GP with stress above threshold.\n"); // printf("principalVals: "); principalVals.printYourself(); FloatArray crackNormal; crackNormal.beColumnOf(principalDirs, 1); // printf("crackNormal: "); crackNormal.printYourself(); FloatArray crackTangent = {-crackNormal(1), crackNormal(0)}; crackTangent.normalize(); // printf("crackTangent: "); crackTangent.printYourself(); // Create geometry FloatArray pc = {gp->giveGlobalCoordinates()(0), gp->giveGlobalCoordinates()(1)}; // printf("Global coord: "); pc.printYourself(); FloatArray ps = pc; ps.add(-0.5*mInitialCrackLength, crackTangent); FloatArray pe = pc; pe.add(0.5*mInitialCrackLength, crackTangent); if(mCutOneEl) { // If desired, ensure that the crack cuts exactly one element. Line line(ps, pe); std::vector<FloatArray> intersecPoints; // line.computeIntersectionPoints(el.get(), intersecPoints); for ( int i = 1; i <= el->giveNumberOfDofManagers(); i++ ) { // int n1 = i; // int n2 = 0; // if ( i < el->giveNumberOfDofManagers() ) { // n2 = i + 1; // } else { // n2 = 1; // } // const FloatArray &p1 = *(el->giveDofManager(n1)->giveCoordinates()); // const FloatArray &p2 = *(el->giveDofManager(n2)->giveCoordinates()); } // printf("intersecPoints.size(): %lu\n", intersecPoints.size()); if(intersecPoints.size() == 2) { ps = std::move(intersecPoints[0]); pe = std::move(intersecPoints[1]); } else { OOFEM_ERROR("intersecPoints.size() != 2") } } FloatArray points = {ps(0), ps(1), pc(0), pc(1), pe(0), pe(1)}; // double diffX = 0.5*(ps(0) + pe(0)) - pc(0); // printf("diffX: %e\n", diffX); // double diffY = 0.5*(ps(1) + pe(1)) - pc(1); // printf("diffY: %e\n", diffY); // TODO: Check if nucleation is allowed, by checking for already existing cracks close to the GP. // Idea: Nucleation is not allowed if we are within an enriched element. In this way, branching is not // completely prohibited, but we avoid initiating multiple similar cracks. bool insertionAllowed = true; Element *el_s = octree->giveElementContainingPoint(ps); if(el_s) { if( xMan->isElementEnriched(el_s) ) { insertionAllowed = false; } } Element *el_c = octree->giveElementContainingPoint(pc); if(el_c) { if( xMan->isElementEnriched(el_c) ) { insertionAllowed = false; } } Element *el_e = octree->giveElementContainingPoint(pe); if(el_e) { if( xMan->isElementEnriched(el_e) ) { insertionAllowed = false; } } for(const auto &x: center_coord_inserted_cracks) { if( x.distance(pc) < 2.0*mInitialCrackLength) { insertionAllowed = false; break; printf("Preventing insertion.\n"); } } if(insertionAllowed) { int n = xMan->giveNumberOfEnrichmentItems() + 1; std::unique_ptr<Crack> crack = std::make_unique<Crack>(n, xMan, mpDomain); // Geometry std::unique_ptr<BasicGeometry> geom = std::make_unique<PolygonLine>(); geom->insertVertexBack(ps); geom->insertVertexBack(pc); geom->insertVertexBack(pe); crack->setGeometry(std::move(geom)); // Enrichment function EnrichmentFunction *ef = new HeavisideFunction(1, mpDomain); crack->setEnrichmentFunction(ef); // Enrichment fronts // EnrichmentFront *efStart = new EnrFrontLinearBranchFuncOneEl(); EnrichmentFront *efStart = new EnrFrontCohesiveBranchFuncOneEl(); crack->setEnrichmentFrontStart(efStart); // EnrichmentFront *efEnd = new EnrFrontLinearBranchFuncOneEl(); EnrichmentFront *efEnd = new EnrFrontCohesiveBranchFuncOneEl(); crack->setEnrichmentFrontEnd(efEnd); /////////////////////////////////////// // Propagation law // Options // double radius = 0.5*mInitialCrackLength, angleInc = 10.0, incrementLength = 0.5*mInitialCrackLength, hoopStressThreshold = 0.0; // bool useRadialBasisFunc = true; // PLHoopStressCirc *pl = new PLHoopStressCirc(); // pl->setRadius(radius); // pl->setAngleInc(angleInc); // pl->setIncrementLength(incrementLength); // pl->setHoopStressThreshold(hoopStressThreshold); // pl->setUseRadialBasisFunc(useRadialBasisFunc); // PLDoNothing *pl = new PLDoNothing(); PLMaterialForce *pl = new PLMaterialForce(); pl->setRadius(mMatForceRadius); pl->setIncrementLength(mIncrementLength); // pl->setIncrementLength(0.25); // pl->setCrackPropThreshold(0.25); pl->setCrackPropThreshold(mCrackPropThreshold); crack->setPropagationLaw(pl); crack->updateDofIdPool(); center_coord_inserted_cracks.push_back(pc); eiList.push_back( std::unique_ptr<EnrichmentItem>(std::move(crack)) ); // printf("Nucleating a crack in NCPrincipalStress::nucleateEnrichmentItems.\n"); // printf("el->giveGlobalNumber(): %d\n", el->giveGlobalNumber() ); // We only introduce one crack per element in a single time step. break; } } } } } } // If correct csNum }