void TrabBoneNL3D :: NonlocalMaterialStiffnessInterface_addIPContribution(SparseMtrx &dest, const UnknownNumberingScheme &s, GaussPoint *gp, TimeStep *tStep) { TrabBoneNL3DStatus *nlStatus = static_cast< TrabBoneNL3DStatus * >( this->giveStatus(gp) ); std :: list< localIntegrationRecord > *list = nlStatus->giveIntegrationDomainList(); TrabBoneNL3D *rmat; double coeff; FloatArray rcontrib, lcontrib; IntArray loc, rloc; FloatMatrix contrib; if ( this->giveLocalNonlocalStiffnessContribution(gp, loc, s, lcontrib, tStep) == 0 ) { return; } for ( auto &lir: *list ) { rmat = dynamic_cast< TrabBoneNL3D * >( lir.nearGp->giveMaterial() ); if ( rmat ) { rmat->giveRemoteNonlocalStiffnessContribution(lir.nearGp, rloc, s, rcontrib, tStep); coeff = gp->giveElement()->computeVolumeAround(gp) * lir.weight / nlStatus->giveIntegrationScale(); contrib.clear(); contrib.plusDyadUnsym(lcontrib, rcontrib, - 1.0 * coeff); dest.assemble(loc, rloc, contrib); } } }
void SurfaceTensionBoundaryCondition :: assemble(SparseMtrx &answer, TimeStep *tStep, CharType type, const UnknownNumberingScheme &r_s, const UnknownNumberingScheme &c_s) { if ( !this->useTangent || type != TangentStiffnessMatrix ) { return; } OOFEM_ERROR("Not implemented yet."); FloatMatrix Ke; IntArray r_loc, c_loc, bNodes; Set *set = this->giveDomain()->giveSet(this->set); const IntArray &boundaries = set->giveBoundaryList(); for ( int pos = 1; pos <= boundaries.giveSize() / 2; ++pos ) { Element *e = this->giveDomain()->giveElement( boundaries.at(pos * 2 - 1) ); int boundary = boundaries.at(pos * 2); e->giveInterpolation()->boundaryGiveNodes(bNodes, boundary); e->giveBoundaryLocationArray(r_loc, bNodes, this->dofs, r_s); e->giveBoundaryLocationArray(c_loc, bNodes, this->dofs, c_s); this->computeTangentFromElement(Ke, e, boundary, tStep); answer.assemble(r_loc, c_loc, Ke); } }
void ContactDefinition :: computeContactTangent(SparseMtrx &answer, TimeStep *tStep, CharType type, const UnknownNumberingScheme &r_s, const UnknownNumberingScheme &c_s) { FloatMatrix Kc; IntArray locArrayR, locArrayC; for ( auto &master : this->masterElementList ) { //if ( master->isInContact() ) { // tangent becomes singular with this //printf("node in contact: computeContactTangent\n\n"); master->computeContactTangent(Kc, type, tStep); // do this in contact element? Kc.negated(); // should be negated! master->giveLocationArray(locArrayR, r_s); master->giveLocationArray(locArrayC, c_s); answer.assemble(locArrayR, locArrayC, Kc); //} } }
void PrescribedGradientBCWeak :: assemble(SparseMtrx &answer, TimeStep *tStep, CharType type, const UnknownNumberingScheme &r_s, const UnknownNumberingScheme &c_s) { std::vector<FloatArray> gpCoordArray; if ( type == TangentStiffnessMatrix || type == SecantStiffnessMatrix || type == ElasticStiffnessMatrix ) { for( TracSegArray* el : mpTracElNew ) { for ( GaussPoint *gp: *(el->mIntRule.get()) ) { gpCoordArray.push_back( gp->giveGlobalCoordinates() ); assembleGPContrib(answer, tStep, type, r_s, c_s, *el, *gp); } } if ( mpDisplacementLock != NULL ) { int nsd = domain->giveNumberOfSpatialDimensions(); FloatMatrix KeDispLock(nsd, nsd); KeDispLock.beUnitMatrix(); KeDispLock.times(mDispLockScaling); int placeInArray = domain->giveDofManPlaceInArray(mLockNodeInd); DofManager *node = domain->giveDofManager(placeInArray); IntArray lockRows, lockCols, nodeRows, nodeCols; mpDisplacementLock->giveLocationArray(giveDispLockDofIDs(), lockRows, r_s); node->giveLocationArray(giveRegularDispDofIDs(), nodeRows, r_s); mpDisplacementLock->giveLocationArray(giveDispLockDofIDs(), lockCols, c_s); node->giveLocationArray(giveRegularDispDofIDs(), nodeCols, c_s); answer.assemble(lockRows, nodeCols, KeDispLock); answer.assemble(nodeRows, lockCols, KeDispLock); FloatMatrix KZero( lockRows.giveSize(), lockCols.giveSize() ); KZero.zero(); answer.assemble(lockRows, lockCols, KZero); } } else { printf("Skipping assembly in PrescribedGradientBCWeak::assemble().\n"); } // std :: string fileName("TracGpCoord.vtk"); // XFEMDebugTools :: WritePointsToVTK(fileName, gpCoordArray); }
void MixedGradientPressureWeakPeriodic :: assemble(SparseMtrx &answer, TimeStep *tStep, CharType type, const UnknownNumberingScheme &r_s, const UnknownNumberingScheme &c_s) { if ( type == TangentStiffnessMatrix || type == SecantStiffnessMatrix || type == ElasticStiffnessMatrix ) { FloatMatrix Ke_v, Ke_vT, Ke_e, Ke_eT; IntArray v_loc_r, v_loc_c, t_loc_r, t_loc_c, e_loc_r, e_loc_c; IntArray bNodes; Set *set = this->giveDomain()->giveSet(this->set); const IntArray &boundaries = set->giveBoundaryList(); // Fetch the columns/rows for the stress contributions; this->tractionsdman->giveLocationArray(t_id, t_loc_r, r_s); this->tractionsdman->giveLocationArray(t_id, t_loc_c, c_s); this->voldman->giveLocationArray(v_id, e_loc_r, r_s); this->voldman->giveLocationArray(v_id, e_loc_c, c_s); for ( int pos = 1; pos <= boundaries.giveSize() / 2; ++pos ) { Element *el = this->giveDomain()->giveElement( boundaries.at(pos * 2 - 1) ); int boundary = boundaries.at(pos * 2); // Fetch the element information; el->giveInterpolation()->boundaryGiveNodes(bNodes, boundary); el->giveBoundaryLocationArray(v_loc_r, bNodes, this->dofs, r_s); el->giveBoundaryLocationArray(v_loc_c, bNodes, this->dofs, c_s); this->integrateTractionVelocityTangent(Ke_v, el, boundary); this->integrateTractionXTangent(Ke_e, el, boundary); Ke_v.negated(); Ke_vT.beTranspositionOf(Ke_v); Ke_eT.beTranspositionOf(Ke_e); answer.assemble(t_loc_r, v_loc_c, Ke_v); answer.assemble(v_loc_r, t_loc_c, Ke_vT); answer.assemble(t_loc_r, e_loc_c, Ke_e); answer.assemble(e_loc_r, t_loc_c, Ke_eT); } } }
void PrescribedGradientBCNeumann :: assemble(SparseMtrx &answer, TimeStep *tStep, CharType type, const UnknownNumberingScheme &r_s, const UnknownNumberingScheme &c_s) { if ( type == TangentStiffnessMatrix || type == SecantStiffnessMatrix || type == ElasticStiffnessMatrix ) { FloatMatrix Ke, KeT; IntArray loc_r, loc_c, sigma_loc_r, sigma_loc_c; Set *set = this->giveDomain()->giveSet(this->set); const IntArray &boundaries = set->giveBoundaryList(); // Fetch the columns/rows for the stress contributions; mpSigmaHom->giveCompleteLocationArray(sigma_loc_r, r_s); mpSigmaHom->giveCompleteLocationArray(sigma_loc_c, c_s); for ( int pos = 1; pos <= boundaries.giveSize() / 2; ++pos ) { Element *e = this->giveDomain()->giveElement( boundaries.at(pos * 2 - 1) ); int boundary = boundaries.at(pos * 2); // Here, we could use only the nodes actually located on the boundary, but we don't. // Instead, we use all nodes belonging to the element, which is allowed because the // basis functions related to the interior nodes will be zero on the boundary. // Obviously, this is less efficient, so why do we want to do it this way? // Because it is easier when XFEM enrichments are present. /ES e->giveLocationArray(loc_r, r_s); e->giveLocationArray(loc_c, c_s); this->integrateTangent(Ke, e, boundary); Ke.negated(); KeT.beTranspositionOf(Ke); answer.assemble(sigma_loc_r, loc_c, Ke); // Contribution to delta_s_i equations answer.assemble(loc_r, sigma_loc_c, KeT); // Contributions to delta_v equations } } else { printf("Skipping assembly in PrescribedGradientBCNeumann::assemble().\n"); } }
// this method is running over all neighboring Gauss points // and computes the contribution of the nonlocal interaction to tangent stiffness // it uses methods // giveLocalNonlocalStiffnessContribution // giveRemoteNonlocalStiffnessContribution // the first one computes m*gprime*Btransposed*sigmaeff for the present point // the second one computes Btransposed*eta for the neighboring point // (where eta is the derivative of cum. plastic strain wrt final strain) // THIS METHOD CAN BE USED IN THE SAME FORM FOR ALL NONLOCAL DAMAGE-PLASTIC MODELS void RankineMatNl :: NonlocalMaterialStiffnessInterface_addIPContribution(SparseMtrx &dest, const UnknownNumberingScheme &s, GaussPoint *gp, TimeStep *atTime) { double coeff; RankineMatNlStatus *status = ( RankineMatNlStatus * ) this->giveStatus(gp); dynaList< localIntegrationRecord > *list = status->giveIntegrationDomainList(); dynaList< localIntegrationRecord > :: iterator pos; RankineMatNl *rmat; FloatArray rcontrib, lcontrib; IntArray loc, rloc; FloatMatrix contrib; if ( this->giveLocalNonlocalStiffnessContribution(gp, loc, s, lcontrib, atTime) == 0 ) { return; } for ( pos = list->begin(); pos != list->end(); ++pos ) { rmat = ( RankineMatNl * )( ( * pos ).nearGp )->giveMaterial(); if ( rmat->giveClassID() == this->giveClassID() ) { rmat->giveRemoteNonlocalStiffnessContribution( ( * pos ).nearGp, rloc, s, rcontrib, atTime ); coeff = gp->giveElement()->computeVolumeAround(gp) * ( * pos ).weight / status->giveIntegrationScale(); int i, j, dim1 = loc.giveSize(), dim2 = rloc.giveSize(); contrib.resize(dim1, dim2); for ( i = 1; i <= dim1; i++ ) { for ( j = 1; j <= dim2; j++ ) { contrib.at(i, j) = -1.0 * lcontrib.at(i) * rcontrib.at(j) * coeff; } } dest.assemble(loc, rloc, contrib); } } }
void PrescribedGradientBCWeak :: assembleGPContrib(SparseMtrx &answer, TimeStep *tStep, CharType type, const UnknownNumberingScheme &r_s, const UnknownNumberingScheme &c_s, TracSegArray &iEl, GaussPoint &iGP) { SpatialLocalizer *localizer = domain->giveSpatialLocalizer(); /////////////// // Gamma_plus FloatMatrix contrib; assembleTangentGPContributionNew(contrib, iEl, iGP, -1.0, iGP.giveGlobalCoordinates()); // Compute vector of traction unknowns FloatArray tracUnknowns; iEl.mFirstNode->giveUnknownVector(tracUnknowns, giveTracDofIDs(), VM_Total, tStep); IntArray trac_rows; iEl.giveTractionLocationArray(trac_rows, type, r_s); FloatArray dispElLocCoord, closestPoint; Element *dispEl = localizer->giveElementClosestToPoint(dispElLocCoord, closestPoint, iGP.giveGlobalCoordinates() ); IntArray disp_cols; dispEl->giveLocationArray(disp_cols, c_s); answer.assemble(trac_rows, disp_cols, contrib); FloatMatrix contribT; contribT.beTranspositionOf(contrib); answer.assemble(disp_cols, trac_rows, contribT); /////////////// // Gamma_minus contrib.clear(); FloatArray xMinus; this->giveMirroredPointOnGammaMinus(xMinus, iGP.giveGlobalCoordinates() ); assembleTangentGPContributionNew(contrib, iEl, iGP, 1.0, xMinus); // Compute vector of traction unknowns tracUnknowns.clear(); iEl.mFirstNode->giveUnknownVector(tracUnknowns, giveTracDofIDs(), VM_Total, tStep); trac_rows.clear(); iEl.giveTractionLocationArray(trac_rows, type, r_s); dispElLocCoord.clear(); closestPoint.clear(); dispEl = localizer->giveElementClosestToPoint(dispElLocCoord, closestPoint, xMinus ); disp_cols.clear(); dispEl->giveLocationArray(disp_cols, c_s); answer.assemble(trac_rows, disp_cols, contrib); contribT.clear(); contribT.beTranspositionOf(contrib); answer.assemble(disp_cols, trac_rows, contribT); // Assemble zeros on diagonal (required by PETSc solver) FloatMatrix KZero(1,1); KZero.zero(); for( int i : trac_rows) { answer.assemble(IntArray({i}), IntArray({i}), KZero); } }
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; } }