double QTrPlaneStrain :: SpatialLocalizerI_giveDistanceFromParametricCenter(const FloatArray &coords) { FloatArray lcoords(3), gcoords; double dist; int size, gsize; lcoords.at(1) = lcoords.at(2) = lcoords.at(3) = 1. / 3.; this->computeGlobalCoordinates(gcoords, lcoords); if ( ( size = coords.giveSize() ) < ( gsize = gcoords.giveSize() ) ) { _error("SpatialLocalizerI_giveDistanceFromParametricCenter: coordinates size mismatch"); } if ( size == gsize ) { dist = coords.distance(gcoords); } else { FloatArray helpCoords = coords; helpCoords.resize(gsize); dist = helpCoords.distance(gcoords); } return dist; }
double Tetrah1_ht :: SpatialLocalizerI_giveDistanceFromParametricCenter(const FloatArray &coords) { FloatArray lcoords(3), gcoords; double dist; int size, gsize; lcoords.zero(); this->computeGlobalCoordinates(gcoords, lcoords); if ( ( size = coords.giveSize() ) < ( gsize = gcoords.giveSize() ) ) { OOFEM_ERROR("coordinates size mismatch"); } if ( size == gsize ) { dist = coords.distance(gcoords); } else { FloatArray helpCoords = coords; helpCoords.resizeWithValues(gsize); dist = helpCoords.distance(gcoords); } return dist; }
void PrescribedGradientBCWeakPeriodic :: checkIfCorner(bool &oIsCorner, bool &oDuplicatable, const FloatArray &iPos, const double &iNodeDistTol) const { oIsCorner = false; oDuplicatable = false; FloatArray cornerPos = mLC; if( iPos.distance(cornerPos) < iNodeDistTol ) { oIsCorner = true; } cornerPos = {mUC[0], mLC[1]}; if( iPos.distance( cornerPos ) < iNodeDistTol ) { oIsCorner = true; } cornerPos = {mUC[0], mUC[1]}; if( iPos.distance( cornerPos ) < iNodeDistTol ) { oIsCorner = true; if(mTractionInterpOrder == 1) { oDuplicatable = true; } } cornerPos = {mLC[0], mUC[1]}; if( iPos.distance( cornerPos ) < iNodeDistTol ) { oIsCorner = true; } }
void PrescribedGradientBCWeakDirichlet :: checkIfCorner(bool &oIsCorner, bool &oDuplicatable, const FloatArray &iPos, const double &iNodeDistTol) const { oIsCorner = false; oDuplicatable = false; FloatArray cornerPos = mLC; if ( iPos.distance(cornerPos) < iNodeDistTol ) { oIsCorner = true; oDuplicatable = true; } cornerPos = { mUC [ 0 ], mLC [ 1 ] }; if ( iPos.distance(cornerPos) < iNodeDistTol ) { oIsCorner = true; oDuplicatable = true; } cornerPos = { mUC [ 0 ], mUC [ 1 ] }; if ( iPos.distance(cornerPos) < iNodeDistTol ) { oIsCorner = true; oDuplicatable = true; } cornerPos = { mLC [ 0 ], mUC [ 1 ] }; if ( iPos.distance(cornerPos) < iNodeDistTol ) { oIsCorner = true; oDuplicatable = true; } }
void MMAContainingElementProjection :: __init(Domain *dold, IntArray &type, FloatArray &coords, Set &elemSet, TimeStep *tStep, bool iCohesiveZoneGP) { SpatialLocalizer *sl = dold->giveSpatialLocalizer(); FloatArray jGpCoords; double distance, minDist = 1.e6; Element *srcElem; if ( ( srcElem = sl->giveElementContainingPoint(coords, elemSet) ) ) { this->source = NULL; for ( GaussPoint *jGp: *srcElem->giveDefaultIntegrationRulePtr() ) { if ( srcElem->computeGlobalCoordinates( jGpCoords, jGp->giveNaturalCoordinates() ) ) { distance = coords.distance(jGpCoords); if ( distance < minDist ) { minDist = distance; this->source = jGp; } } } if ( !source ) { OOFEM_ERROR("no suitable source found"); } } else { OOFEM_ERROR("No suitable element found"); } }
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) ); } } }
double Tr21Stokes :: SpatialLocalizerI_giveDistanceFromParametricCenter(const FloatArray &coords) { FloatArray center; FloatArray lcoords; lcoords.setValues(3, 0.333333, 0.333333, 0.333333); interpolation_quad.local2global(center, lcoords, FEIElementGeometryWrapper(this)); return center.distance(coords); }
double TrabBoneNL3D :: computeWeightFunction(const FloatArray &src, const FloatArray &coord) { double dist = src.distance(coord); if ( ( dist >= 0. ) && ( dist <= this->R ) ) { double help = ( 1. - dist * dist / ( R * R ) ); return help * help; } return 0.0; }
bool Delaunay :: isInsideCC(const FloatArray &iP, const FloatArray &iP1, const FloatArray &iP2, const FloatArray &iP3) const { Triangle tr(iP1, iP2, iP3); double r = tr.getRadiusOfCircumCircle(); FloatArray circumCenter; tr.computeCenterOfCircumCircle(circumCenter); double distance = circumCenter.distance(iP); if ( distance < r ) { return true; } else { return false; } }
double RCSDNLMaterial :: computeWeightFunction(const FloatArray &src, const FloatArray &coord) { // Bell shaped function decaying with the distance. double dist = src.distance(coord); if ( ( dist >= 0. ) && ( dist <= this->R ) ) { double help = ( 1. - dist * dist / ( R * R ) ); return help * help; } return 0.0; }
void DummySpatialLocalizer :: giveAllNodesWithinBox(nodeContainerType &nodeSet, const FloatArray &coords, const double radius) { int nnode; nnode = this->giveDomain()->giveNumberOfDofManagers(); for ( int i = 1; i <= nnode; i++ ) { DofManager *idofman = this->giveDomain()->giveDofManager(i); Node *inode = dynamic_cast< Node * >(idofman); if ( inode != NULL ) { if ( coords.distance( inode->giveCoordinates() ) <= radius ) { nodeSet.push_back(i); } } } }
bool Circle :: intersects(Element *element) { int count = 0; for ( int i = 1; i <= element->giveNumberOfDofManagers(); i++ ) { FloatArray *nodeCoor = element->giveDofManager(i)->giveCoordinates(); // distance from the node to the center of the circle double dist = nodeCoor->distance(mVertices [ 0 ]); if ( dist > this->radius ) { count++; } } if ( count == 0 || count == element->giveNumberOfDofManagers() ) { return false; } else { return true; } }
void DummySpatialLocalizer :: giveAllElementsWithIpWithinBox(elementContainerType &elemSet, const FloatArray &coords, const double radius) { int nelem; FloatArray jGpCoords; nelem = this->giveDomain()->giveNumberOfElements(); for ( int i = 1; i <= nelem; i++ ) { Element *ielem = this->giveDomain()->giveElement(i); IntegrationRule *iRule = ielem->giveDefaultIntegrationRulePtr(); for ( GaussPoint *jGp: *iRule ) { if ( ielem->computeGlobalCoordinates( jGpCoords, * ( jGp->giveCoordinates() ) ) ) { double currDist = coords.distance(jGpCoords); if ( currDist <= radius ) { elemSet.insert(i); } } } } // end element loop }
void PolygonLine :: giveBoundingSphere(FloatArray &oCenter, double &oRadius) { int nVert = giveNrVertices(); oCenter = { 0.0, 0.0 }; oRadius = 0.0; if ( nVert > 0 ) { for ( int i = 1; i <= nVert; i++ ) { oCenter.add( giveVertex(i) ); } oCenter.times( 1.0 / double( nVert ) ); for ( int i = 1; i <= nVert; i++ ) { oRadius = std :: max( oRadius, oCenter.distance( giveVertex(i) ) ); } } }
double NonlocalMaterialExtensionInterface :: computeWeightFunction(const FloatArray &src, const FloatArray &coord) { return computeWeightFunction( src.distance(coord) ); }
void MMALeastSquareProjection :: __init(Domain *dold, IntArray &type, FloatArray &coords, Set &elemSet, TimeStep *tStep, bool iCohesiveZoneGP) //(Domain* dold, IntArray& varTypes, GaussPoint* gp, TimeStep* tStep) { GaussPoint *sourceIp; Element *sourceElement; SpatialLocalizer *sl = dold->giveSpatialLocalizer(); IntegrationRule *iRule; IntArray patchList; this->patchDomain = dold; // find the closest IP on old mesh sourceElement = sl->giveElementContainingPoint(coords, elemSet); if ( !sourceElement ) { OOFEM_ERROR("no suitable source element found"); } // determine the type of patch Element_Geometry_Type egt = sourceElement->giveGeometryType(); if ( egt == EGT_line_1 ) { this->patchType = MMALSPPatchType_1dq; } else if ( ( egt == EGT_triangle_1 ) || ( egt == EGT_quad_1 ) ) { this->patchType = MMALSPPatchType_2dq; } else { OOFEM_ERROR("unsupported material mode"); } /* Determine the state of closest point. * Only IP in the neighbourhood with same state can be used * to interpolate the values. */ FloatArray dam; int state = 0; if ( this->stateFilter ) { iRule = sourceElement->giveDefaultIntegrationRulePtr(); for ( GaussPoint *gp: *iRule ) { sourceElement->giveIPValue(dam, gp, IST_PrincipalDamageTensor, tStep); if ( dam.computeNorm() > 1.e-3 ) { state = 1; // damaged } } } // from source neighbours the patch will be constructed Element *element; IntArray neighborList; patchList.resize(1); patchList.at(1) = sourceElement->giveNumber(); int minNumberOfPoints = this->giveNumberOfUnknownPolynomialCoefficients(this->patchType); int actualNumberOfPoints = sourceElement->giveDefaultIntegrationRulePtr()->giveNumberOfIntegrationPoints(); int nite = 0; int elemFlag; // check if number of IP in patchList is sufficient // some recursion control would be appropriate while ( ( actualNumberOfPoints < minNumberOfPoints ) && ( nite <= 2 ) ) { //if not, construct the neighborhood dold->giveConnectivityTable()->giveElementNeighbourList(neighborList, patchList); // count number of available points patchList.clear(); actualNumberOfPoints = 0; for ( int i = 1; i <= neighborList.giveSize(); i++ ) { if ( this->stateFilter ) { element = patchDomain->giveElement( neighborList.at(i) ); // exclude elements in different regions if ( !elemSet.hasElement( element->giveNumber() ) ) { continue; } iRule = element->giveDefaultIntegrationRulePtr(); elemFlag = 0; for ( GaussPoint *gp: *iRule ) { element->giveIPValue(dam, gp, IST_PrincipalDamageTensor, tStep); if ( state && ( dam.computeNorm() > 1.e-3 ) ) { actualNumberOfPoints++; elemFlag = 1; } else if ( ( state == 0 ) && ( dam.computeNorm() < 1.e-3 ) ) { actualNumberOfPoints++; elemFlag = 1; } } if ( elemFlag ) { // include this element with corresponding state in neighbor search. patchList.followedBy(neighborList.at(i), 10); } } else { // if (! yhis->stateFilter) element = patchDomain->giveElement( neighborList.at(i) ); // exclude elements in different regions if ( !elemSet.hasElement( element->giveNumber() ) ) { continue; } actualNumberOfPoints += element->giveDefaultIntegrationRulePtr()->giveNumberOfIntegrationPoints(); patchList.followedBy(neighborList.at(i), 10); } } // end loop over neighbor list nite++; } if ( nite > 2 ) { // not enough points -> take closest point projection patchGPList.clear(); sourceIp = sl->giveClosestIP(coords, elemSet); patchGPList.push_front(sourceIp); //fprintf(stderr, "MMALeastSquareProjection: too many neighbor search iterations\n"); //exit (1); return; } #ifdef MMALSP_ONLY_CLOSEST_POINTS // select only the nval closest IP points GaussPoint **gpList = ( GaussPoint ** ) malloc(sizeof( GaussPoint * ) * actualNumberOfPoints); FloatArray dist(actualNumberOfPoints), srcgpcoords; int npoints = 0; // check allocation of gpList if ( gpList == NULL ) { OOFEM_FATAL("memory allocation error"); } for ( int ielem = 1; ielem <= patchList.giveSize(); ielem++ ) { element = patchDomain->giveElement( patchList.at(ielem) ); iRule = element->giveDefaultIntegrationRulePtr(); for ( GaussPoint *srcgp: *iRule ) { if ( element->computeGlobalCoordinates( srcgpcoords, * ( srcgp->giveNaturalCoordinates() ) ) ) { element->giveIPValue(dam, srcgp, IST_PrincipalDamageTensor, tStep); if ( this->stateFilter ) { // consider only points with same state if ( ( ( state == 1 ) && ( norm(dam) > 1.e-3 ) ) || ( ( ( state == 0 ) && norm(dam) < 1.e-3 ) ) ) { npoints++; dist.at(npoints) = coords.distance(srcgpcoords); gpList [ npoints - 1 ] = srcgp; } } else { // take all points into account npoints++; dist.at(npoints) = coords.distance(srcgpcoords); gpList [ npoints - 1 ] = srcgp; } } else { OOFEM_ERROR("computeGlobalCoordinates failed"); } } } if ( npoints != actualNumberOfPoints ) { OOFEM_ERROR("internal error"); } //minNumberOfPoints = min (actualNumberOfPoints, minNumberOfPoints+2); patchGPList.clear(); // now find the minNumberOfPoints with smallest distance // from point of interest double swap, minDist; int minDistIndx = 0; // loop over all points for ( int i = 1; i <= minNumberOfPoints; i++ ) { minDist = dist.at(i); minDistIndx = i; // search for point with i-th smallest distance for ( j = i + 1; j <= actualNumberOfPoints; j++ ) { if ( dist.at(j) < minDist ) { minDist = dist.at(j); minDistIndx = j; } } // remember this ip patchGPList.push_front(gpList [ minDistIndx - 1 ]); swap = dist.at(i); dist.at(i) = dist.at(minDistIndx); dist.at(minDistIndx) = swap; srcgp = gpList [ i - 1 ]; gpList [ i - 1 ] = gpList [ minDistIndx - 1 ]; gpList [ minDistIndx - 1 ] = srcgp; } if ( patchGPList.size() != minNumberOfPoints ) { OOFEM_ERROR("internal error 2"); exit(1); } free(gpList); #else // take all neighbors patchGPList.clear(); for ( int ielem = 1; ielem <= patchList.giveSize(); ielem++ ) { element = patchDomain->giveElement( patchList.at(ielem) ); iRule = element->giveDefaultIntegrationRulePtr(); for ( GaussPoint *gp: *iRule ) { patchGPList.push_front( gp ); } } #endif }
void PolygonLine :: computeTangentialSignDist(double &oDist, const FloatArray &iPoint, double &oMinArcDist) const { const int numSeg = this->giveNrVertices() - 1; double xi = 0.0, xiUnbounded = 0.0; if(numSeg == 1) { const FloatArray &crackP1 = giveVertex ( 1 ); const FloatArray &crackP2 = giveVertex ( 2 ); iPoint.distance(crackP1, crackP2, xi, xiUnbounded); if( xiUnbounded < 0.0 ) { oDist = xiUnbounded*crackP1.distance(crackP2); oMinArcDist = 0.0; return; } if( xiUnbounded > 1.0 ) { oDist = -(xiUnbounded-1.0)*crackP1.distance(crackP2); oMinArcDist = 1.0; return; } const double L = computeLength(); double distToStart = xi*L; oDist = std::min(distToStart, (L - distToStart) ); oMinArcDist = distToStart/L; return; } bool isBeforeStart = false, isAfterEnd = false; double distBeforeStart = 0.0, distAfterEnd = 0.0; /////////////////////////////////////////////////////////////////// // Check first segment const FloatArray &crackP1_start = giveVertex ( 1 ); const FloatArray &crackP2_start = giveVertex ( 2 ); const double distSeg_start = iPoint.distance(crackP1_start, crackP2_start, xi, xiUnbounded); if( xiUnbounded < 0.0 ) { isBeforeStart = true; distBeforeStart = xiUnbounded*crackP1_start.distance(crackP2_start); } double arcPosPassed = crackP1_start.distance(crackP2_start); double distToStart = xi*crackP1_start.distance(crackP2_start); double minGeomDist = distSeg_start; /////////////////////////////////////////////////////////////////// // Check interior segments for ( int segId = 2; segId <= numSeg-1; segId++ ) { const FloatArray &crackP1 = giveVertex ( segId ); const FloatArray &crackP2 = giveVertex ( segId+1 ); const double distSeg = iPoint.distance(crackP1, crackP2, xi, xiUnbounded); if(distSeg < minGeomDist) { isBeforeStart = false; minGeomDist = distSeg; distToStart = arcPosPassed + xi*crackP1.distance(crackP2); } arcPosPassed += crackP1.distance(crackP2); } /////////////////////////////////////////////////////////////////// // Check last segment const FloatArray &crackP1_end = giveVertex ( numSeg ); const FloatArray &crackP2_end = giveVertex ( numSeg+1 ); const double distSeg_end = iPoint.distance(crackP1_end, crackP2_end, xi, xiUnbounded); if(numSeg > 1) { if( xiUnbounded > 1.0 ) { arcPosPassed += xiUnbounded*crackP1_end.distance(crackP2_end); } else { arcPosPassed += xi*crackP1_end.distance(crackP2_end); } } if(distSeg_end < minGeomDist) { isBeforeStart = false; if( xiUnbounded > 1.0 ) { isAfterEnd = true; distAfterEnd = -(xiUnbounded-1.0)*crackP1_end.distance(crackP2_end); } distToStart = arcPosPassed; } /////////////////////////////////////////////////////////////////// // Return result if(isBeforeStart) { oDist = distBeforeStart; oMinArcDist = 0.0; return; } if(isAfterEnd) { oDist = distAfterEnd; oMinArcDist = 1.0; return; } const double L = computeLength(); oDist = std::min(distToStart, (L - distToStart) ); oMinArcDist = distToStart/L; }