void PrescribedMean :: computeDomainSize() { if (domainSize > 0.0) return; if (elementEdges) { IntArray setList = ((GeneralBoundaryCondition *)this)->giveDomain()->giveSet(set)->giveBoundaryList(); elements.resize(setList.giveSize() / 2); sides.resize(setList.giveSize() / 2); for (int i=1; i<=setList.giveSize(); i=i+2) { elements.at(i/2+1) = setList.at(i); sides.at(i/2+1) = setList.at(i+1); } } else { IntArray setList = ((GeneralBoundaryCondition *)this)->giveDomain()->giveSet(set)->giveElementList(); elements = setList; } domainSize = 0.0; 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; if (elementEdges) { iRule = interpolator->giveBoundaryIntegrationRule(3, sides.at(i)); } else { iRule = interpolator->giveIntegrationRule(3); } for ( GaussPoint * gp: * iRule ) { FloatArray lcoords = gp->giveNaturalCoordinates(); double detJ; if (elementEdges) { detJ = fabs ( interpolator->boundaryGiveTransformationJacobian(sides.at(i), lcoords, FEIElementGeometryWrapper(thisElement)) ); } else { detJ = fabs ( interpolator->giveTransformationJacobian(lcoords, FEIElementGeometryWrapper(thisElement)) ); } domainSize = domainSize + detJ*gp->giveWeight(); } delete iRule; } printf("%f\n", domainSize); }
IntArray XfemManager :: giveEnrichedDofIDs(const DofManager &iDMan) const { IntArray dofIdArray; for(int id : mXFEMPotentialDofIDs) { if(iDMan.hasDofID( DofIDItem(id) )) { dofIdArray.followedBy(id); } } return dofIdArray; }
void EnrichmentItem :: createEnrichedDofs() { // Creates new dofs due to the enrichment and appends them to the dof managers int nrDofMan = this->giveDomain()->giveNumberOfDofManagers(); IntArray EnrDofIdArray; mEIDofIdArray.clear(); //int bcIndex = -1; int icIndex = -1; // Create new dofs for ( int i = 1; i <= nrDofMan; i++ ) { DofManager *dMan = this->giveDomain()->giveDofManager(i); if ( isDofManEnriched(* dMan) ) { //printf("dofMan %i is enriched \n", dMan->giveNumber()); computeEnrichedDofManDofIdArray(EnrDofIdArray, * dMan); // Collect boundary condition ID of existing dofs IntArray bcIndexArray; for ( Dof *dof: *dMan ) { bcIndexArray.followedBy(dof->giveBcId()); } bool foundBC = false; IntArray nonZeroBC; if ( !bcIndexArray.containsOnlyZeroes() ) { // BC is found on dofs foundBC = true; nonZeroBC.findNonzeros(bcIndexArray); } int iDof(1); for ( auto &dofid: EnrDofIdArray ) { if ( !dMan->hasDofID( ( DofIDItem ) ( dofid ) ) ) { if ( mInheritBoundaryConditions || mInheritOrderedBoundaryConditions ) { if ( foundBC ) { // Append dof with BC if ( mInheritOrderedBoundaryConditions ) { ///TODO: add choise of inheriting only specific BC. // Assume order type of new dofs are the same as original dMan->appendDof( new MasterDof(dMan, bcIndexArray.at(iDof), icIndex, ( DofIDItem ) dofid) ); } else { // Append enriched dofs with same BC dMan->appendDof( new MasterDof(dMan, bcIndexArray.at(nonZeroBC.at(1)), icIndex, ( DofIDItem ) dofid) ); } } else { // No BC found, append enriched dof without BC dMan->appendDof( new MasterDof(dMan, ( DofIDItem ) dofid) ); } } else { // Append enriched dof without BC dMan->appendDof( new MasterDof(dMan, ( DofIDItem ) dofid) ); } } iDof++; } } } // Remove old dofs int poolStart = giveStartOfDofIdPool(); int poolEnd = giveEndOfDofIdPool(); for ( int i = 1; i <= nrDofMan; i++ ) { DofManager *dMan = this->giveDomain()->giveDofManager(i); computeEnrichedDofManDofIdArray(EnrDofIdArray, * dMan); std :: vector< DofIDItem >dofsToRemove; for ( Dof *dof: *dMan ) { DofIDItem dofID = dof->giveDofID(); if ( dofID >= DofIDItem(poolStart) && dofID <= DofIDItem(poolEnd) ) { bool dofIsInIdArray = false; for ( int k = 1; k <= EnrDofIdArray.giveSize(); k++ ) { if ( dofID == DofIDItem( EnrDofIdArray.at(k) ) ) { dofIsInIdArray = true; break; } } if ( !dofIsInIdArray ) { dofsToRemove.push_back(dofID); } if(mEIDofIdArray.findFirstIndexOf(dofID) == 0 && dofIsInIdArray) { mEIDofIdArray.followedBy(dofID); } } } for ( size_t j = 0; j < dofsToRemove.size(); j++ ) { dMan->removeDof(dofsToRemove [ j ]); } } }
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; } }