IntegrationRule *FEI2dLineLin :: giveIntegrationRule(int order) { IntegrationRule *iRule = new GaussIntegrationRule(1, NULL); int points = iRule->getRequiredNumberOfIntegrationPoints(_Line, order + 0); iRule->SetUpPointsOnLine(points, _Unknown); return iRule; }
void PrescribedGradientBCNeumann :: integrateTangent(FloatMatrix &oTangent, Element *e, int iBndIndex) { FloatArray normal, n; FloatMatrix nMatrix, E_n; FloatMatrix contrib; Domain *domain = e->giveDomain(); XfemElementInterface *xfemElInt = dynamic_cast< XfemElementInterface * >( e ); FEInterpolation *interp = e->giveInterpolation(); // Geometry interpolation int nsd = e->giveDomain()->giveNumberOfSpatialDimensions(); // Interpolation order int order = interp->giveInterpolationOrder(); IntegrationRule *ir = NULL; IntArray edgeNodes; FEInterpolation2d *interp2d = dynamic_cast< FEInterpolation2d * >( interp ); if ( interp2d == NULL ) { OOFEM_ERROR("failed to cast to FEInterpolation2d.") } interp2d->computeLocalEdgeMapping(edgeNodes, iBndIndex); const FloatArray &xS = * ( e->giveDofManager( edgeNodes.at(1) )->giveCoordinates() ); const FloatArray &xE = * ( e->giveDofManager( edgeNodes.at( edgeNodes.giveSize() ) )->giveCoordinates() ); if ( xfemElInt != NULL && domain->hasXfemManager() ) { std :: vector< Line >segments; std :: vector< FloatArray >intersecPoints; xfemElInt->partitionEdgeSegment(iBndIndex, segments, intersecPoints); MaterialMode matMode = e->giveMaterialMode(); ir = new DiscontinuousSegmentIntegrationRule(1, e, segments, xS, xE); int numPointsPerSeg = 1; ir->SetUpPointsOnLine(numPointsPerSeg, matMode); } else { ir = interp->giveBoundaryIntegrationRule(order, iBndIndex); } oTangent.clear(); for ( GaussPoint *gp: *ir ) { FloatArray &lcoords = * gp->giveNaturalCoordinates(); FEIElementGeometryWrapper cellgeo(e); // Evaluate the normal; double detJ = interp->boundaryEvalNormal(normal, iBndIndex, lcoords, cellgeo); interp->boundaryEvalN(n, iBndIndex, lcoords, cellgeo); // If cracks cross the edge, special treatment is necessary. // Exploit the XfemElementInterface to minimize duplication of code. if ( xfemElInt != NULL && domain->hasXfemManager() ) { // Compute global coordinates of Gauss point FloatArray globalCoord; interp->boundaryLocal2Global(globalCoord, iBndIndex, lcoords, cellgeo); // Compute local coordinates on the element FloatArray locCoord; e->computeLocalCoordinates(locCoord, globalCoord); xfemElInt->XfemElementInterface_createEnrNmatrixAt(nMatrix, locCoord, * e, false); } else { // Evaluate the velocity/displacement coefficients nMatrix.beNMatrixOf(n, nsd); } if ( nsd == 3 ) { OOFEM_ERROR("not implemented for nsd == 3.") } else if ( nsd == 2 ) { E_n.resize(4, 2); E_n.at(1, 1) = normal.at(1); E_n.at(1, 2) = 0.0; E_n.at(2, 1) = 0.0; E_n.at(2, 2) = normal.at(2); E_n.at(3, 1) = normal.at(2); E_n.at(3, 2) = 0.0; E_n.at(4, 1) = 0.0; E_n.at(4, 2) = normal.at(1); } else { E_n.clear(); } contrib.beProductOf(E_n, nMatrix); oTangent.add(detJ * gp->giveWeight(), contrib); } delete ir; }