const IntArray &Set :: giveNodeList() { // Lazy evaluation, we compute the unique set of nodes if needed (and store it). if ( this->totalNodes.giveSize() == 0 ) { IntArray afflictedNodes( this->domain->giveNumberOfDofManagers() ); afflictedNodes.zero(); for ( int ielem = 1; ielem <= this->elements.giveSize(); ++ielem ) { Element *e = this->domain->giveElement( this->elements.at(ielem) ); for ( int inode = 1; inode <= e->giveNumberOfNodes(); ++inode ) { afflictedNodes.at( e->giveNode(inode)->giveNumber() ) = 1; } } /* boundary entities are obsolete, use edges and/or surfaces instead */ IntArray bNodes; for ( int ibnd = 1; ibnd <= this->elementBoundaries.giveSize() / 2; ++ibnd ) { Element *e = this->domain->giveElement( this->elementBoundaries.at(ibnd * 2 - 1) ); int boundary = this->elementBoundaries.at(ibnd * 2); FEInterpolation *fei = e->giveInterpolation(); fei->boundaryGiveNodes(bNodes, boundary); for ( int inode = 1; inode <= bNodes.giveSize(); ++inode ) { afflictedNodes.at( e->giveNode( bNodes.at(inode) )->giveNumber() ) = 1; } } IntArray eNodes; for ( int iedge = 1; iedge <= this->elementEdges.giveSize() / 2; ++iedge ) { Element *e = this->domain->giveElement( this->elementEdges.at(iedge * 2 - 1) ); int edge = this->elementEdges.at(iedge * 2); FEInterpolation *fei = e->giveInterpolation(); fei->boundaryEdgeGiveNodes(eNodes, edge); for ( int inode = 1; inode <= eNodes.giveSize(); ++inode ) { afflictedNodes.at( e->giveNode( eNodes.at(inode) )->giveNumber() ) = 1; } } for ( int isurf = 1; isurf <= this->elementSurfaces.giveSize() / 2; ++isurf ) { Element *e = this->domain->giveElement( this->elementSurfaces.at(isurf * 2 - 1) ); int surf = this->elementSurfaces.at(isurf * 2); FEInterpolation *fei = e->giveInterpolation(); fei->boundarySurfaceGiveNodes(eNodes, surf); for ( int inode = 1; inode <= eNodes.giveSize(); ++inode ) { afflictedNodes.at( e->giveNode( eNodes.at(inode) )->giveNumber() ) = 1; } } for ( int inode = 1; inode <= this->nodes.giveSize(); ++inode ) { afflictedNodes.at( this->nodes.at(inode) ) = 1; } totalNodes.findNonzeros(afflictedNodes); } return this->totalNodes; }
const IntArray &Set :: giveNodeList() { // Lazy evaluation, we compute the unique set of nodes if needed (and store it). if ( this->totalNodes.giveSize() == 0 ) { IntArray afflictedNodes( this->domain->giveNumberOfDofManagers() ); afflictedNodes.zero(); for ( int ielem = 1; ielem <= this->elements.giveSize(); ++ielem ) { Element *e = this->domain->giveElement( this->elements.at(ielem) ); for ( int inode = 1; inode <= e->giveNumberOfNodes(); ++inode ) { afflictedNodes.at( e->giveNode(inode)->giveNumber() ) = 1; } } IntArray bNodes; for ( int ibnd = 1; ibnd <= this->elementBoundaries.giveSize() / 2; ++ibnd ) { Element *e = this->domain->giveElement( this->elementBoundaries.at(ibnd * 2 - 1) ); int boundary = this->elementBoundaries.at(ibnd * 2); FEInterpolation *fei = e->giveInterpolation(); fei->boundaryGiveNodes(bNodes, boundary); for ( int inode = 1; inode <= bNodes.giveSize(); ++inode ) { afflictedNodes.at( e->giveNode( bNodes.at(inode) )->giveNumber() ) = 1; } } IntArray eNodes; for ( int iedge = 1; iedge <= this->elementEdges.giveSize() / 2; ++iedge ) { Element *e = this->domain->giveElement( this->elementEdges.at(iedge * 2 - 1) ); int edge = this->elementEdges.at(iedge * 2); FEInterpolation3d *fei = static_cast< FEInterpolation3d * >( e->giveInterpolation() ); fei->computeLocalEdgeMapping(eNodes, edge); for ( int inode = 1; inode <= eNodes.giveSize(); ++inode ) { afflictedNodes.at( e->giveNode( eNodes.at(inode) )->giveNumber() ) = 1; } } for ( int inode = 1; inode <= this->nodes.giveSize(); ++inode ) { afflictedNodes.at( this->nodes.at(inode) ) = 1; } totalNodes.findNonzeros(afflictedNodes); } return this->totalNodes; }
void SolutionbasedShapeFunction :: initializeSurfaceData(modeStruct *mode) { EngngModel *m = mode->myEngngModel; double TOL2 = 1e-5; IntArray pNodes, mNodes, zNodes; Set *mySet = this->domain->giveSet( this->giveSetNumber() ); IntArray BoundaryList = mySet->giveBoundaryList(); // First add all nodes to pNodes or nNodes respectively depending on coordinate and normal. for ( int i = 0; i < BoundaryList.giveSize() / 2; i++ ) { int ElementID = BoundaryList(2 * i); int Boundary = BoundaryList(2 * i + 1); Element *e = m->giveDomain(1)->giveElement(ElementID); FEInterpolation *geoInterpolation = e->giveInterpolation(); // Check all sides of element IntArray bnodes; #define usePoints 1 #if usePoints == 1 // Check if all nodes are on the boundary geoInterpolation->boundaryGiveNodes(bnodes, Boundary); for ( int k = 1; k <= bnodes.giveSize(); k++ ) { DofManager *dman = e->giveDofManager( bnodes.at(k) ); for ( int l = 1; l <= dman->giveCoordinates()->giveSize(); l++ ) { if ( fabs( dman->giveCoordinates()->at(l) - maxCoord.at(l) ) < TOL2 ) { pNodes.insertOnce( dman->giveNumber() ); } if ( fabs( dman->giveCoordinates()->at(l) - minCoord.at(l) ) < TOL2 ) { mNodes.insertOnce( dman->giveNumber() ); } } } #else // Check normal FloatArray lcoords; lcoords.resize(2); lcoords.at(1) = 0.33333; lcoords.at(2) = 0.33333; FloatArray normal; geoInterpolation->boundaryEvalNormal( normal, j, lcoords, FEIElementGeometryWrapper(e) ); geoInterpolation->boundaryGiveNodes(bnodes, j); printf( "i=%u\tj=%u\t(%f\t%f\t%f)\n", i, j, normal.at(1), normal.at(2), normal.at(3) ); for ( int k = 1; k <= normal.giveSize(); k++ ) { if ( fabs( ( fabs( normal.at(k) ) - 1 ) ) < 1e-4 ) { // Points in x, y or z direction addTo = NULL; if ( normal.at(k) > 0.5 ) { addTo = & pNodes; } if ( normal.at(k) < -0.5 ) { addTo = & mNodes; } if ( addTo != NULL ) { for ( int l = 1; l <= bnodes.giveSize(); l++ ) { bool isSurface = false; DofManager *dman = e->giveDofManager( bnodes.at(l) ); dman->giveCoordinates()->printYourself(); for ( int m = 1; m <= dman->giveCoordinates()->giveSize(); m++ ) { if ( ( fabs( dman->giveCoordinates()->at(m) - maxCoord.at(m) ) < TOL2 ) || ( fabs( dman->giveCoordinates()->at(m) - minCoord.at(m) ) < TOL2 ) ) { isSurface = true; } } if ( isSurface ) { addTo->insertOnce( e->giveDofManagerNumber( bnodes.at(l) ) ); } } } } } #endif } #if 0 printf("p=["); for ( int i = 1; i < pNodes.giveSize(); i++ ) { printf( "%u, ", pNodes.at(i) ); } printf("];\n"); printf("m=["); for ( int i = 1; i < mNodes.giveSize(); i++ ) { printf( "%u, ", mNodes.at(i) ); } printf("];\n"); #endif //The intersection of pNodes and mNodes constitutes zNodes { int i = 1, j = 1; while ( i <= pNodes.giveSize() ) { j = 1; while ( j <= mNodes.giveSize() && ( i <= pNodes.giveSize() ) ) { //printf("%u == %u?\n", pNodes.at(i), mNodes.at(j)); if ( pNodes.at(i) == mNodes.at(j) ) { zNodes.insertOnce( pNodes.at(i) ); pNodes.erase(i); mNodes.erase(j); } else { j++; } } i++; } } // Compute base function values on nodes for dofids copyDofManagersToSurfaceData(mode, pNodes, true, false, false); copyDofManagersToSurfaceData(mode, mNodes, false, true, false); copyDofManagersToSurfaceData(mode, zNodes, false, false, true); #if 0 printf("p2=["); for ( int i = 1; i <= pNodes.giveSize(); i++ ) { printf( "%u, ", pNodes.at(i) ); } printf("];\n"); printf("m2=["); for ( int i = 1; i <= mNodes.giveSize(); i++ ) { printf( "%u, ", mNodes.at(i) ); } printf("];\n"); printf("z2=["); for ( int i = 1; i <= zNodes.giveSize(); i++ ) { printf( "%u, ", zNodes.at(i) ); } printf("];\n"); printf("pCoords=["); for ( int i = 1; i <= pNodes.giveSize(); i++ ) { FloatArray *coords = m->giveDomain(1)->giveDofManager( pNodes.at(i) )->giveCoordinates(); printf( "%f, %f, %f; ", coords->at(1), coords->at(2), coords->at(3) ); } printf("]\n"); printf("mCoords=["); for ( int i = 1; i <= mNodes.giveSize(); i++ ) { FloatArray *coords = m->giveDomain(1)->giveDofManager( mNodes.at(i) )->giveCoordinates(); printf( "%f, %f, %f; ", coords->at(1), coords->at(2), coords->at(3) ); } printf("]\n"); printf("zCoords=["); for ( int i = 1; i <= zNodes.giveSize(); i++ ) { FloatArray *coords = m->giveDomain(1)->giveDofManager( zNodes.at(i) )->giveCoordinates(); printf( "%f, %f, %f; ", coords->at(1), coords->at(2), coords->at(3) ); } printf("];\n"); #endif }
void SolutionbasedShapeFunction :: computeCorrectionFactors(modeStruct &myMode, IntArray *Dofs, double *am, double *ap) { /* * *Compute c0, cp, cm, Bp, Bm, Ap and Am */ double A0p = 0.0, App = 0.0, A0m = 0.0, Amm = 0.0, Bp = 0.0, Bm = 0.0, c0 = 0.0, cp = 0.0, cm = 0.0; EngngModel *m = myMode.myEngngModel; Set *mySet = m->giveDomain(1)->giveSet(externalSet); IntArray BoundaryList = mySet->giveBoundaryList(); for ( int i = 0; i < BoundaryList.giveSize() / 2; i++ ) { int ElementID = BoundaryList(2 * i); int Boundary = BoundaryList(2 * i + 1); Element *thisElement = m->giveDomain(1)->giveElement(ElementID); FEInterpolation *geoInterpolation = thisElement->giveInterpolation(); IntArray bnodes, zNodes, pNodes, mNodes; FloatMatrix nodeValues; geoInterpolation->boundaryGiveNodes(bnodes, Boundary); nodeValues.resize( this->dofs.giveSize(), bnodes.giveSize() ); nodeValues.zero(); // Change to global ID for bnodes and identify the intersection of bnodes and the zero boundary splitBoundaryNodeIDs(myMode, * thisElement, bnodes, pNodes, mNodes, zNodes, nodeValues); std :: unique_ptr< IntegrationRule >iRule(geoInterpolation->giveBoundaryIntegrationRule(order, Boundary)); for ( GaussPoint *gp: *iRule ) { FloatArray *lcoords = gp->giveCoordinates(); FloatArray gcoords, normal, N; FloatArray Phi; double detJ = fabs( geoInterpolation->boundaryGiveTransformationJacobian( Boundary, * lcoords, FEIElementGeometryWrapper(thisElement) ) ) * gp->giveWeight(); geoInterpolation->boundaryEvalNormal( normal, Boundary, * lcoords, FEIElementGeometryWrapper(thisElement) ); geoInterpolation->boundaryEvalN( N, Boundary, * lcoords, FEIElementGeometryWrapper(thisElement) ); geoInterpolation->boundaryLocal2Global( gcoords, Boundary, * lcoords, FEIElementGeometryWrapper(thisElement) ); FloatArray pPhi, mPhi, zPhi; pPhi.resize( Dofs->giveSize() ); pPhi.zero(); mPhi.resize( Dofs->giveSize() ); mPhi.zero(); zPhi.resize( Dofs->giveSize() ); zPhi.zero(); // Build phi (analytical averaging, not projected onto the mesh) computeBaseFunctionValueAt(Phi, gcoords, * Dofs, * myMode.myEngngModel); // Build zPhi for this DofID for ( int l = 1; l <= zNodes.giveSize(); l++ ) { int nodeID = zNodes.at(l); for ( int m = 1; m <= this->dofs.giveSize(); m++ ) { zPhi.at(m) = zPhi.at(m) + N.at(nodeID) * nodeValues.at(m, nodeID); } } // Build pPhi for this DofID for ( int l = 1; l <= pNodes.giveSize(); l++ ) { int nodeID = pNodes.at(l); for ( int m = 1; m <= this->dofs.giveSize(); m++ ) { pPhi.at(m) = pPhi.at(m) + N.at(nodeID) * nodeValues.at(m, nodeID); } } // Build mPhi for this DofID for ( int l = 1; l <= mNodes.giveSize(); l++ ) { int nodeID = mNodes.at(l); for ( int m = 1; m <= this->dofs.giveSize(); m++ ) { mPhi.at(m) = mPhi.at(m) + N.at(nodeID) * nodeValues.at(m, nodeID); } } c0 = c0 + zPhi.dotProduct(normal, 3) * detJ; cp = cp + pPhi.dotProduct(normal, 3) * detJ; cm = cm + mPhi.dotProduct(normal, 3) * detJ; App = App + pPhi.dotProduct(pPhi, 3) * detJ; Amm = Amm + mPhi.dotProduct(mPhi, 3) * detJ; A0p = A0p + zPhi.dotProduct(pPhi, 3) * detJ; A0m = A0m + zPhi.dotProduct(mPhi, 3) * detJ; Bp = Bp + Phi.dotProduct(pPhi, 3) * detJ; Bm = Bm + Phi.dotProduct(mPhi, 3) * detJ; } } * am = -( A0m * cp * cp - Bm * cp * cp - A0p * cm * cp + App * c0 * cm + Bp * cm * cp ) / ( App * cm * cm + Amm * cp * cp ); * ap = -( A0p * cm * cm - Bp * cm * cm - A0m * cm * cp + Amm * c0 * cp + Bm * cm * cp ) / ( App * cm * cm + Amm * cp * cp ); }
void PrescribedMean :: assemble(SparseMtrx &answer, TimeStep *tStep, CharType type, const UnknownNumberingScheme &r_s, const UnknownNumberingScheme &c_s) { if ( type != TangentStiffnessMatrix && type != StiffnessMatrix ) { return; } computeDomainSize(); IntArray c_loc, r_loc; lambdaDman->giveLocationArray(lambdaIDs, r_loc, r_s); lambdaDman->giveLocationArray(lambdaIDs, c_loc, c_s); for ( int i=1; i<=elements.giveSize(); i++ ) { int elementID = elements.at(i); Element *thisElement = this->giveDomain()->giveElement(elementID); FEInterpolation *interpolator = thisElement->giveInterpolation(DofIDItem(dofid)); IntegrationRule *iRule = (elementEdges) ? (interpolator->giveBoundaryIntegrationRule(3, sides.at(i))) : (interpolator->giveIntegrationRule(3)); for ( GaussPoint * gp: * iRule ) { FloatArray lcoords = gp->giveNaturalCoordinates(); FloatArray N; //, a; FloatMatrix temp, tempT; double detJ = 0.0; IntArray boundaryNodes, dofids= {(DofIDItem) this->dofid}, r_Sideloc, c_Sideloc; if (elementEdges) { // Compute boundary integral interpolator->boundaryGiveNodes( boundaryNodes, sides.at(i) ); interpolator->boundaryEvalN(N, sides.at(i), lcoords, FEIElementGeometryWrapper(thisElement)); detJ = fabs ( interpolator->boundaryGiveTransformationJacobian(sides.at(i), lcoords, FEIElementGeometryWrapper(thisElement)) ); // Retrieve locations for dofs on boundary thisElement->giveBoundaryLocationArray(r_Sideloc, boundaryNodes, dofids, r_s); thisElement->giveBoundaryLocationArray(c_Sideloc, boundaryNodes, dofids, c_s); } else { interpolator->evalN(N, lcoords, FEIElementGeometryWrapper(thisElement)); detJ = fabs ( interpolator->giveTransformationJacobian(lcoords, FEIElementGeometryWrapper(thisElement) ) ); IntArray DofIDStemp, rloc, cloc; thisElement->giveLocationArray(rloc, r_s, &DofIDStemp); thisElement->giveLocationArray(cloc, c_s, &DofIDStemp); r_Sideloc.clear(); c_Sideloc.clear(); for (int j=1; j<=DofIDStemp.giveSize(); j++) { if (DofIDStemp.at(j)==dofids.at(1)) { r_Sideloc.followedBy({rloc.at(j)}); c_Sideloc.followedBy({cloc.at(j)}); } } } // delta p part: temp = N*detJ*gp->giveWeight()*(1.0/domainSize); tempT.beTranspositionOf(temp); answer.assemble(r_Sideloc, c_loc, temp); answer.assemble(r_loc, c_Sideloc, tempT); } delete iRule; } }
void PrescribedMean :: giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, CharType type, ValueModeType mode, const UnknownNumberingScheme &s, FloatArray *eNorm) { computeDomainSize(); // Fetch unknowns of this boundary condition IntArray lambdaLoc; FloatArray lambda; lambdaDman->giveUnknownVector(lambda, lambdaIDs, mode, tStep); lambdaDman->giveLocationArray(lambdaIDs, lambdaLoc, s); for ( int i=1; i<=elements.giveSize(); i++ ) { int elementID = elements.at(i); Element *thisElement = this->giveDomain()->giveElement(elementID); FEInterpolation *interpolator = thisElement->giveInterpolation(DofIDItem(dofid)); IntegrationRule *iRule = (elementEdges) ? (interpolator->giveBoundaryIntegrationRule(3, sides.at(i))) : (interpolator->giveIntegrationRule(3)); for ( GaussPoint * gp: * iRule ) { FloatArray lcoords = gp->giveNaturalCoordinates(); FloatArray a, N, pressureEqns, lambdaEqns; IntArray boundaryNodes, dofids= {(DofIDItem) this->dofid}, locationArray; double detJ=0.0; if (elementEdges) { // Compute integral interpolator->boundaryGiveNodes( boundaryNodes, sides.at(i) ); thisElement->computeBoundaryVectorOf(boundaryNodes, dofids, VM_Total, tStep, a); interpolator->boundaryEvalN(N, sides.at(i), lcoords, FEIElementGeometryWrapper(thisElement)); detJ = fabs ( interpolator->boundaryGiveTransformationJacobian(sides.at(i), lcoords, FEIElementGeometryWrapper(thisElement)) ); // Retrieve locations for dofs with dofids thisElement->giveBoundaryLocationArray(locationArray, boundaryNodes, dofids, s); } else { thisElement->computeVectorOf(dofids, VM_Total, tStep, a); interpolator->evalN(N, lcoords, FEIElementGeometryWrapper(thisElement)); detJ = fabs ( interpolator->giveTransformationJacobian(lcoords, FEIElementGeometryWrapper(thisElement))); IntArray DofIDStemp, loc; thisElement->giveLocationArray(loc, s, &DofIDStemp); locationArray.clear(); for (int j=1; j<=DofIDStemp.giveSize(); j++) { if (DofIDStemp.at(j)==dofids.at(1)) { locationArray.followedBy({loc.at(j)}); } } } // delta p part: pressureEqns = N*detJ*gp->giveWeight()*lambda.at(1)*(1.0/domainSize); // delta lambda part lambdaEqns.resize(1); lambdaEqns.at(1) = N.dotProduct(a); lambdaEqns.times(detJ*gp->giveWeight()*1.0/domainSize); lambdaEqns.at(1) = lambdaEqns.at(1); // delta p part answer.assemble(pressureEqns, locationArray); // delta lambda part answer.assemble(lambdaEqns, lambdaLoc); } delete iRule; } }