void LIBeam2dNL :: computeInitialStressMatrix(FloatMatrix &answer, TimeStep *tStep) { double dV; GaussPoint *gp; IntegrationRule *iRule; FloatArray stress; FloatMatrix A; Material *mat = this->giveMaterial(); answer.resize(6, 6); answer.zero(); iRule = integrationRulesArray [ giveDefaultIntegrationRule() ]; // assemble initial stress matrix for ( int i = 0; i < iRule->giveNumberOfIntegrationPoints(); i++ ) { gp = iRule->getIntegrationPoint(i); dV = this->computeVolumeAround(gp); stress = static_cast< StructuralMaterialStatus * >( mat->giveStatus(gp) )->giveStressVector(); if ( stress.giveSize() ) { for ( int j = 1; j <= stress.giveSize(); j++ ) { // loop over each component of strain vector this->computeNLBMatrixAt(A, gp, j); if ( A.isNotEmpty() ) { A.times(stress.at(j) * dV); answer.add(A); } } } } }
void Quad1MindlinShell3D :: giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord) { // We need to overload this for practical reasons (this 3d shell has all 9 dofs, but the shell part only cares for the first 8) // This elements adds an additional stiffness for the so called drilling dofs, meaning we need to work with all 9 components. FloatMatrix b, d; FloatArray n, strain, stress; FloatArray shellUnknowns(20), drillUnknowns(4), unknowns; this->computeVectorOf(EID_MomentumBalance, VM_Total, tStep, unknowns); // Split this for practical reasons into normal shell dofs and drilling dofs for ( int i = 0; i < 4; ++i ) { shellUnknowns(0 + i*5) = unknowns(0 + i*6); shellUnknowns(1 + i*5) = unknowns(1 + i*6); shellUnknowns(2 + i*5) = unknowns(2 + i*6); shellUnknowns(3 + i*5) = unknowns(3 + i*6); shellUnknowns(4 + i*5) = unknowns(4 + i*6); drillUnknowns(i) = unknowns(5 + i*6); } FloatArray shellForces(20), drillMoment(4); shellForces.zero(); drillMoment.zero(); StructuralCrossSection *cs = this->giveStructuralCrossSection(); double drillCoeff = cs->give(CS_DrillingStiffness); IntegrationRule *iRule = integrationRulesArray [ 0 ]; for ( int i = 0; i < iRule->giveNumberOfIntegrationPoints(); i++ ) { GaussPoint *gp = iRule->getIntegrationPoint(i); this->computeBmatrixAt(gp, b); double dV = this->computeVolumeAround(gp); if ( useUpdatedGpRecord ) { stress = static_cast< StructuralMaterialStatus * >( this->giveMaterial()->giveStatus(gp) )->giveStressVector(); } else { strain.beProductOf(b, shellUnknowns); cs->giveRealStress_Shell(stress, gp, strain, tStep); } shellForces.plusProduct(b, stress, dV); // Drilling stiffness is here for improved numerical properties if (drillCoeff > 0.) { this->interp.evalN(n, *gp->giveCoordinates(), FEIVoidCellGeometry()); for ( int j = 0; j < 4; j++) { n(j) -= 0.25; } double dtheta = n.dotProduct(drillUnknowns); drillMoment.add(drillCoeff * dV * dtheta, n); ///@todo Decide on how to alpha should be defined. } } answer.resize(24); answer.zero(); answer.assemble(shellForces, this->shellOrdering); if (drillCoeff > 0.) { answer.assemble(drillMoment, this->drillOrdering); } }
void Quad1MindlinShell3D :: computeBodyLoadVectorAt(FloatArray &answer, Load *forLoad, TimeStep *stepN, ValueModeType mode) { // Only gravity load double dV, density; GaussPoint *gp; FloatArray forceX, forceY, forceZ, glob_gravity, gravity, n; if ( ( forLoad->giveBCGeoType() != BodyLoadBGT ) || ( forLoad->giveBCValType() != ForceLoadBVT ) ) { _error("computeBodyLoadVectorAt: unknown load type"); } // note: force is assumed to be in global coordinate system. forLoad->computeComponentArrayAt(glob_gravity, stepN, mode); // Transform the load into the local c.s. gravity.beProductOf(this->lcsMatrix, glob_gravity); ///@todo Check potential transpose here. if ( gravity.giveSize() ) { IntegrationRule *ir = integrationRulesArray [ 0 ]; for ( int i = 0; i < ir->giveNumberOfIntegrationPoints(); ++i) { gp = ir->getIntegrationPoint(i); this->interp.evalN(n, *gp->giveCoordinates(), FEIVoidCellGeometry()); dV = this->computeVolumeAround(gp) * this->giveCrossSection()->give(CS_Thickness); density = this->giveMaterial()->give('d', gp); forceX.add(density * gravity.at(1) * dV, n); forceY.add(density * gravity.at(2) * dV, n); forceZ.add(density * gravity.at(3) * dV, n); } answer.resize(24); answer.zero(); answer.at(1) = forceX.at(1); answer.at(2) = forceY.at(1); answer.at(3) = forceZ.at(1); answer.at(7) = forceX.at(2); answer.at(8) = forceY.at(2); answer.at(9) = forceZ.at(2); answer.at(13) = forceX.at(3); answer.at(14) = forceY.at(3); answer.at(15) = forceZ.at(3); answer.at(19) = forceX.at(4); answer.at(20) = forceY.at(4); answer.at(21) = forceZ.at(4); } else { answer.resize(0); } }
void NonlocalMaterialExtensionInterface :: manipulateWeight(double &weight, GaussPoint *gp, GaussPoint *jGp) { Element *ielem = jGp->giveElement(); IntegrationRule *iRule = ielem->giveDefaultIntegrationRulePtr(); if ( ielem->giveMaterial()->hasProperty(AVERAGING_TYPE, jGp) ) { if ( ielem->giveMaterial()->give(AVERAGING_TYPE, jGp) == 1 ) { weight = 1. / ( iRule->giveNumberOfIntegrationPoints() ); //assign the same weights over the whole element } } }
void InterfaceElem1d :: drawScalar(oofegGraphicContext &context) { int i, indx, result = 0; GaussPoint *gp; IntegrationRule *iRule = integrationRulesArray [ giveDefaultIntegrationRule() ]; TimeStep *tStep = this->giveDomain()->giveEngngModel()->giveCurrentStep(); FloatArray gcoord(3), v1; WCRec p [ 1 ]; GraphicObj *go; double val [ 1 ]; if ( !context.testElementGraphicActivity(this) ) { return; } if ( context.getInternalVarsDefGeoFlag() ) { double defScale = context.getDefScale(); p [ 0 ].x = ( FPNum ) 0.5 * ( this->giveNode(1)->giveUpdatedCoordinate(1, tStep, defScale) + this->giveNode(2)->giveUpdatedCoordinate(1, tStep, defScale) ); p [ 0 ].y = ( FPNum ) 0.5 * ( this->giveNode(1)->giveUpdatedCoordinate(2, tStep, defScale) + this->giveNode(2)->giveUpdatedCoordinate(2, tStep, defScale) ); p [ 0 ].z = ( FPNum ) 0.5 * ( this->giveNode(1)->giveUpdatedCoordinate(3, tStep, defScale) + this->giveNode(2)->giveUpdatedCoordinate(3, tStep, defScale) ); } else { p [ 0 ].x = ( FPNum )( this->giveNode(1)->giveCoordinate(1) ); p [ 0 ].y = ( FPNum )( this->giveNode(1)->giveCoordinate(2) ); p [ 0 ].z = ( FPNum )( this->giveNode(1)->giveCoordinate(3) ); } result += giveIPValue(v1, iRule->getIntegrationPoint(0), context.giveIntVarType(), tStep); for ( i = 0; i < iRule->giveNumberOfIntegrationPoints(); i++ ) { result = 0; gp = iRule->getIntegrationPoint(i); result += giveIPValue(v1, gp, context.giveIntVarType(), tStep); if ( result != 1 ) { continue; } indx = context.giveIntVarIndx(); val [ 0 ] = v1.at(indx); context.updateFringeTableMinMax(val, 1); EASValsSetLayer(OOFEG_VARPLOT_PATTERN_LAYER); EASValsSetMType(FILLED_CIRCLE_MARKER); go = CreateMarkerWD3D(p, val [ 0 ]); EGWithMaskChangeAttributes(LAYER_MASK | FILL_MASK | MTYPE_MASK, go); EMAddGraphicsToModel(ESIModel(), go); //} } }
void CoupledFieldsElement :: computeStiffnessMatrixGen(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep, void (*Nfunc)(GaussPoint*, FloatMatrix), void (*Bfunc)(GaussPoint*, FloatMatrix), void (*NStiffness)(FloatMatrix, MatResponseMode, GaussPoint*, TimeStep*), void (*BStiffness)(FloatMatrix, MatResponseMode, GaussPoint*, TimeStep*), double (*volumeAround)(GaussPoint*) ) { FloatMatrix B, DB, N, DN, D_B, D_N; IntegrationRule *iRule = this->giveIntegrationRule(0); bool matStiffSymmFlag = this->giveCrossSection()->isCharacteristicMtrxSymmetric(rMode); answer.resize(0,0); for ( int j = 0; j < iRule->giveNumberOfIntegrationPoints(); j++ ) { GaussPoint *gp = iRule->getIntegrationPoint(j); double dV = this->computeVolumeAround(gp); // compute int_V ( N^t * D_N * N )dV if ( NStiffness && Nfunc ) { Nfunc(gp, N); NStiffness(D_N, rMode, gp, tStep); DN.beProductOf(D_N, N); if ( matStiffSymmFlag ) { answer.plusProductSymmUpper(N, DN, dV); } else { answer.plusProductUnsym(N, DN, dV); } } // compute int_V ( B^t * D_B * B )dV if ( BStiffness && Bfunc ) { Bfunc(gp, B); BStiffness(D_B, rMode, gp, tStep); DB.beProductOf(D_B, B); if ( matStiffSymmFlag ) { answer.plusProductSymmUpper(B, DB, dV); } else { answer.plusProductUnsym(B, DB, dV); } } } if ( matStiffSymmFlag ) { answer.symmetrized(); } }
void ErrorCheckingExportModule :: writeCheck(Domain *domain, TimeStep *tStep) { if ( tStep->isTheFirstStep() ) { std :: cout << "#%BEGIN_CHECK% tolerance 1.e-3\n"; } for ( auto &dman : domain->giveDofManagers() ) { for ( Dof *dof: *dman ) { if ( dof->giveEqn() < 0 ) { continue; } std :: cout << "#NODE tStep " << tStep->giveNumber(); std :: cout << " number " << dman->giveNumber(); std :: cout << " dof " << dof->giveDofID(); std :: cout << " unknown " << 'd'; std :: cout << " value " << dof->giveUnknown(VM_Total, tStep); std :: cout << std :: endl; } } for ( auto &element : domain->giveElements() ) { IntegrationRule *iRule = element->giveDefaultIntegrationRulePtr(); FloatArray ipval; for ( int ist: this->writeIST ) { for ( int gpnum = 0; gpnum < iRule->giveNumberOfIntegrationPoints(); ++gpnum ) { GaussPoint *gp = iRule->getIntegrationPoint(gpnum); element->giveIPValue(ipval, gp, (InternalStateType)ist, tStep); for ( int component = 1; component <= ipval.giveSize(); ++component ) { std :: cout << "#ELEMENT tStep " << tStep->giveNumber(); std :: cout << " number " << element->giveNumber(); std :: cout << " gp " << gpnum+1; std :: cout << " keyword " << ist; ///@note This writes IST number and not "stresses" std :: cout << " component " << component; std :: cout << " value " << ipval.at(component); std :: cout << std :: endl; } } } } if ( !tStep->isNotTheLastStep() ) { std :: cout << "#%END_CHECK%" << std :: endl; } }
void Quad1MindlinShell3D :: computeStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep) { // We need to overload this for practical reasons (this 3d shell has all 9 dofs, but the shell part only cares for the first 8) // This elements adds an additional stiffness for the so called drilling dofs, meaning we need to work with all 9 components. FloatMatrix d, b, db; FloatArray n; FloatMatrix shellStiffness(20, 20), drillStiffness(4, 4); shellStiffness.zero(); drillStiffness.zero(); double drillCoeff = this->giveStructuralCrossSection()->give(CS_DrillingStiffness); IntegrationRule *iRule = integrationRulesArray [ 0 ]; for ( int i = 0; i < iRule->giveNumberOfIntegrationPoints(); i++ ) { GaussPoint *gp = iRule->getIntegrationPoint(i); this->computeBmatrixAt(gp, b); double dV = this->computeVolumeAround(gp); this->computeConstitutiveMatrixAt(d, rMode, gp, tStep); db.beProductOf(d, b); shellStiffness.plusProductSymmUpper(b, db, dV); // Drilling stiffness is here for improved numerical properties if (drillCoeff > 0.) { this->interp.evalN(n, *gp->giveCoordinates(), FEIVoidCellGeometry()); for ( int j = 0; j < 4; j++) { n(j) -= 0.25; } drillStiffness.plusDyadSymmUpper(n, drillCoeff * dV); } } shellStiffness.symmetrized(); answer.resize(24, 24); answer.zero(); answer.assemble(shellStiffness, this->shellOrdering); if (drillCoeff > 0.) { drillStiffness.symmetrized(); answer.assemble(drillStiffness, this->drillOrdering); } }
void Quad1MindlinShell3D :: computeLumpedMassMatrix(FloatMatrix &answer, TimeStep *tStep) // Returns the lumped mass matrix of the receiver. { double mass = 0.; IntegrationRule *ir = integrationRulesArray [ 0 ]; for ( int i = 0; i < ir->giveNumberOfIntegrationPoints(); ++i) { GaussPoint *gp = ir->getIntegrationPoint(i); mass += this->computeVolumeAround(gp) * this->giveMaterial()->give('d', gp); } answer.resize(12, 12); answer.zero(); for ( int i = 0; i < 4; i++ ) { answer(i*6 + 0, i*6 + 0) = mass*0.25; answer(i*6 + 1, i*6 + 1) = mass*0.25; answer(i*6 + 2, i*6 + 2) = mass*0.25; } }
void CoupledFieldsElement :: giveInternalForcesVectorGen(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord, void (*Nfunc)(GaussPoint*, FloatMatrix), void (*Bfunc)(GaussPoint*, FloatMatrix, int, int), //(GaussPoint*, FloatMatrix) void (*NStressFunc)(GaussPoint*, FloatArray), void (*BStressFunc)(GaussPoint*, FloatArray), double (*dVFunc)(GaussPoint*)) { // General implementation of internal forces that computes // f = sum_gp( N^T*GenStress_N + B^T*GenStress_B ) * dV IntegrationRule *iRule = this->giveIntegrationRule(0); FloatArray NStress, BStress, vGenStress, NS, BS; FloatMatrix N, B; for ( int j = 0; j < this->giveNumberOfIntegrationRules(); j++ ) { IntegrationRule *iRule = this->giveIntegrationRule(j); for ( int i = 0; i < iRule->giveNumberOfIntegrationPoints(); i++ ) { GaussPoint *gp = iRule->getIntegrationPoint(i); double dV = this->computeVolumeAround(gp); // compute generalized stress measures if ( NStressFunc && Nfunc ) { Nfunc(gp, N); NStressFunc(gp, NStress); NS.beTProductOf(N, NStress); answer.add(dV, NS); } if ( BStressFunc && Bfunc ) { Bfunc(gp, B, 1, 3); BStressFunc(gp, BStress); BS.beTProductOf(B, BStress); answer.add(dV, BS); } } } }
void Quad10_2D_SUPG :: computeMassDeltaTerm(FloatMatrix &answer, TimeStep *atTime) { FloatMatrix n, b; double dV, rho; int undofs = this->computeNumberOfDofs(EID_MomentumBalance); GaussPoint *gp; answer.resize(undofs, undofs); answer.zero(); IntegrationRule *iRule = this->integrationRulesArray [ 1 ]; /* mtrx for computing t_supg, norm of this mtrx is computed */ for ( int k = 0; k < iRule->giveNumberOfIntegrationPoints(); k++ ) { gp = iRule->getIntegrationPoint(k); this->computeNuMatrix(n, gp); this->computeUDotGradUMatrix(b, gp, atTime); dV = this->computeVolumeAround(gp); rho = this->giveMaterial()->give('d', gp); answer.plusProductUnsym(b, n, rho * dV); } }
void Quad10_2D_SUPG :: computeAdvectionTerm(FloatMatrix &answer, TimeStep *atTime) { FloatMatrix n, b; double dV, rho; int undofs = this->computeNumberOfDofs(EID_MomentumBalance); GaussPoint *gp; answer.resize(undofs, undofs); answer.zero(); IntegrationRule *iRule = this->integrationRulesArray [ 1 ]; /* consistent part + supg stabilization term */ for ( int k = 0; k < iRule->giveNumberOfIntegrationPoints(); k++ ) { gp = iRule->getIntegrationPoint(k); this->computeNuMatrix(n, gp); this->computeUDotGradUMatrix(b, gp, atTime); dV = this->computeVolumeAround(gp); rho = this->giveMaterial()->give('d', gp); answer.plusProductUnsym(n, b, rho * dV); } }
void TR_SHELL01 :: printOutputAt(FILE *file, TimeStep *tStep) // Performs end-of-step operations. { FloatArray v, aux; GaussPoint *gp, *membraneGP; IntegrationRule *iRule = this->giveDefaultIntegrationRulePtr(); fprintf( file, "element %d (%8d) :\n", this->giveLabel(), this->giveNumber() ); for ( int i = 0; i < iRule->giveNumberOfIntegrationPoints(); i++ ) { gp = iRule->getIntegrationPoint(i); fprintf(file, " GP %2d.%-2d :", iRule->giveNumber(), gp->giveNumber()); membraneGP = membrane->giveDefaultIntegrationRulePtr()->getIntegrationPoint(gp->giveNumber()-1); // Strain - Curvature plate->giveIPValue(v, gp, IST_ShellStrainCurvatureTensor, tStep); membrane->giveIPValue(aux, membraneGP, IST_ShellStrainCurvatureTensor, tStep); v.add(aux); fprintf(file, " strains "); fprintf( file, " % .4e % .4e % .4e % .4e % .4e % .4e % .4e % .4e % .4e % .4e % .4e % .4e ", v.at(1), v.at(2), v.at(3), 2. * v.at(4), 2. * v.at(5), 2. * v.at(6), v.at(7), v.at(8), v.at(9), 2. * v.at(10), 2. * v.at(11), 2. * v.at(12) ); // Strain - Curvature plate->giveIPValue(v, gp, IST_ShellForceMomentumTensor, tStep); membrane->giveIPValue(aux, membraneGP, IST_ShellForceMomentumTensor, tStep); v.add(aux); fprintf(file, "\n stresses"); fprintf( file, " % .4e % .4e % .4e % .4e % .4e % .4e % .4e % .4e % .4e % .4e % .4e % .4e ", v.at(1), v.at(2), v.at(3), v.at(4), v.at(5), v.at(6), v.at(7), v.at(8), v.at(9), v.at(10), v.at(11), v.at(12) ); fprintf(file, "\n"); } }
void Lattice2d_mt :: updateInternalState(TimeStep *stepN) // Updates the receiver at end of step. { int i, j; IntegrationRule *iRule; FloatArray f, r; FloatMatrix n; TransportMaterial *mat = ( ( TransportMaterial * ) this->giveMaterial() ); GaussPoint *gp; // force updating ip values for ( i = 0; i < numberOfIntegrationRules; i++ ) { iRule = integrationRulesArray [ i ]; for ( j = 0; j < iRule->giveNumberOfIntegrationPoints(); j++ ) { gp = iRule->getIntegrationPoint(j); this->computeNmatrixAt( n, *gp->giveCoordinates() ); this->computeVectorOf(EID_ConservationEquation, VM_Total, stepN, r); f.beProductOf(n, r); mat->updateInternalState(f, gp, stepN); } } }
void Quad10_2D_SUPG :: computeLSICTerm(FloatMatrix &answer, TimeStep *atTime) { int undofs = this->computeNumberOfDofs(EID_MomentumBalance); double dV, rho; GaussPoint *gp; FloatMatrix b; answer.resize(undofs, undofs); answer.zero(); IntegrationRule *iRule = this->integrationRulesArray [ 1 ]; for ( int k = 0; k < iRule->giveNumberOfIntegrationPoints(); k++ ) { gp = iRule->getIntegrationPoint(k); dV = this->computeVolumeAround(gp); rho = this->giveMaterial()->give('d', gp); this->computeDivUMatrix(b, gp); answer.plusProductSymmUpper(b, b, dV * rho); } answer.symmetrized(); }
void Quad10_2D_SUPG :: computeMassEpsilonTerm(FloatMatrix &answer, TimeStep *atTime) { // to compute t_pspg int pndofs = this->computeNumberOfDofs(EID_ConservationEquation); int undofs = this->computeNumberOfDofs(EID_MomentumBalance); double dV; FloatMatrix g, n; GaussPoint *gp; answer.resize(pndofs, undofs); answer.zero(); IntegrationRule *iRule = this->integrationRulesArray [ 1 ]; for ( int k = 0; k < iRule->giveNumberOfIntegrationPoints(); k++ ) { gp = iRule->getIntegrationPoint(k); this->computeGradPMatrix(g, gp); this->computeNuMatrix(n, gp); dV = this->computeVolumeAround(gp); answer.plusProductUnsym(g, n, dV); } }
void Quad1MindlinShell3D :: computeSurfaceLoadVectorAt(FloatArray &answer, Load *load, int iSurf, TimeStep *tStep, ValueModeType mode) { BoundaryLoad *surfLoad = static_cast< BoundaryLoad * >(load); if ( dynamic_cast< ConstantPressureLoad * >(surfLoad) ) { // Just checking the type of b.c. // EXPERIMENTAL CODE: IntegrationRule *iRule; FloatArray n, gcoords, pressure; answer.resize( 24 ); answer.zero(); //int approxOrder = surfLoad->giveApproxOrder() + this->giveApproxOrder(); iRule = this->integrationRulesArray[ 0 ]; for ( int i = 0; i < iRule->giveNumberOfIntegrationPoints(); i++ ) { GaussPoint *gp = iRule->getIntegrationPoint(i); double dV = this->computeVolumeAround(gp); this->interp.evalN(n, *gp->giveCoordinates(), FEIVoidCellGeometry()); this->interp.local2global(gcoords, *gp->giveCoordinates(), FEIElementGeometryWrapper(this)); surfLoad->computeValueAt(pressure, tStep, gcoords, mode); answer.at( 3) += n.at(1) * pressure.at(1) * dV; answer.at( 9) += n.at(2) * pressure.at(1) * dV; answer.at(15) += n.at(3) * pressure.at(1) * dV; answer.at(21) += n.at(4) * pressure.at(1) * dV; } // Second surface is the outside; if ( iSurf == 2 ) { answer.negated(); } } else { OOFEM_ERROR("Quad1MindlinShell3D only supports constant pressure boundary load."); } }
void tet21ghostsolid :: computeStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep) { IntegrationRule *iRule = integrationRulesArray [ giveDefaultIntegrationRule() ]; #ifdef __FM_MODULE FluidDynamicMaterial *fluidMaterial = static_cast< FluidCrossSection * >( this->giveCrossSection() )->giveFluidMaterial(); #endif FloatMatrix Kf, G, Kx, D, B, Ed, EdB, dNx; FloatArray Nlin, dNv; for (int j = 0; j<iRule->giveNumberOfIntegrationPoints(); j++) { GaussPoint *gp = iRule->getIntegrationPoint(j); double detJ = fabs( ( this->interpolation.giveTransformationJacobian( * gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(this) ) ) ); double weight = gp->giveWeight(); this->interpolation.evaldNdx( dNx, * gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(this) ); this->interpolation_lin.evalN( Nlin, * gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(this) ); dNv.resize(30); // dNv = [dN1/dx dN1/dy dN1/dz dN2/dx dN2/dy dN2/dz ... dN10/dz] for (int k = 0; k<dNx.giveNumberOfRows(); k++) { dNv.at(k*3+1) = dNx.at(k+1,1); dNv.at(k*3+2) = dNx.at(k+1,2); dNv.at(k*3+3) = dNx.at(k+1,3); } if (nlGeometry == 0) { this->computeBmatrixAt(gp, B); // Fluid part gp->setMaterialMode(_3dFlow); #ifdef __FM_MODULE fluidMaterial->giveDeviatoricStiffnessMatrix(Ed, TangentStiffness, gp, tStep); #else OOFEM_ERROR("Fluid module missing\n"); #endif gp->setMaterialMode(_3dMat); EdB.beProductOf(Ed, B); Kf.plusProductSymmUpper(B, EdB, detJ*weight); // Ghost solid part EdB.beProductOf(Dghost, B); Kx.plusProductSymmUpper(B, EdB, detJ*weight); // Incompressibility part G.plusDyadUnsym(dNv, Nlin, -detJ*weight); } else { OOFEM_ERROR ("No support for large deformations yet!"); } } FloatMatrix GT; GT.beTranspositionOf(G); //GTdeltat.beTranspositionOf(G); //GTdeltat.times(deltat); Kf.symmetrized(); Kx.symmetrized(); // Kf.printYourself(); // G.printYourself(); // GT.printYourself(); // Kx.printYourself(); answer.resize(64, 64); answer.zero(); #define USEUNCOUPLED 0 #if USEUNCOUPLED == 1 // Totaly uncoupled answer.assemble(Kf, momentum_ordering, momentum_ordering); answer.assemble(G, momentum_ordering, conservation_ordering); answer.assemble(GT, conservation_ordering, momentum_ordering); answer.assemble(Kx, ghostdisplacement_ordering, ghostdisplacement_ordering); #else answer.assemble(Kf, ghostdisplacement_ordering, ghostdisplacement_ordering); answer.assemble(Kf, ghostdisplacement_ordering, momentum_ordering); answer.assemble(G, ghostdisplacement_ordering, conservation_ordering); answer.assemble(GT, conservation_ordering, ghostdisplacement_ordering); answer.assemble(GT, conservation_ordering, momentum_ordering); answer.assemble(Kx, momentum_ordering, ghostdisplacement_ordering); #endif //answer.printYourself(); }
void tet21ghostsolid :: giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord) { IntegrationRule *iRule = integrationRulesArray [ giveDefaultIntegrationRule() ]; #ifdef __FM_MODULE FluidDynamicMaterial *fluidMaterial = static_cast< FluidCrossSection * >( this->giveCrossSection() )->giveFluidMaterial(); #endif FloatMatrix Kf, G, Kx, B, Ed, dNx; FloatArray Strain, Stress, Nlin, dNv, a, aVelocity, aPressure, aGhostDisplacement, fluidStress, epsf; FloatArray momentum, conservation, auxstress; double pressure, epsvol; this->computeVectorOf( VM_Total, tStep, a); if (!tStep->isTheFirstStep()) { // a.printYourself(); } aVelocity.beSubArrayOf(a, momentum_ordering); aPressure.beSubArrayOf(a, conservation_ordering); aGhostDisplacement.beSubArrayOf(a, ghostdisplacement_ordering); for (int j = 0; j<iRule->giveNumberOfIntegrationPoints(); j++) { GaussPoint *gp = iRule->getIntegrationPoint(j); double detJ = fabs( ( this->interpolation.giveTransformationJacobian( * gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(this) ) ) ); double weight = gp->giveWeight(); this->interpolation.evaldNdx( dNx, * gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(this) ); this->interpolation_lin.evalN( Nlin, * gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(this) ); dNv.resize(30); for (int k = 0; k<dNx.giveNumberOfColumns(); k++) { dNv.at(k*3+1) = dNx.at(1,k+1); dNv.at(k*3+2) = dNx.at(2,k+1); dNv.at(k*3+3) = dNx.at(3,k+1); } if (nlGeometry == 0) { this->computeBmatrixAt(gp, B); epsf.beProductOf(B, aVelocity); pressure = Nlin.dotProduct(aPressure); // Fluid part gp->setMaterialMode(_3dFlow); #ifdef __FM_MODULE fluidMaterial->computeDeviatoricStressVector(fluidStress, epsvol, gp, epsf, pressure, tStep); #else OOFEM_ERROR("Missing FM module"); #endif gp->setMaterialMode(_3dMat); momentum.plusProduct(B, fluidStress, detJ*weight); momentum.add(-pressure * detJ * weight, dNv); conservation.add(epsvol * detJ * weight, Nlin); // Ghost solid part Strain.beProductOf(B, aGhostDisplacement); Stress.beProductOf(Dghost, Strain); auxstress.plusProduct(B, Stress, detJ * weight); } else { OOFEM_ERROR("No support for large deformations yet!"); } } answer.resize(64); answer.zero(); #if USEUNCOUPLED == 1 // Totaly uncoupled answer.assemble(momentum, momentum_ordering); answer.assemble(conservation, conservation_ordering); answer.assemble(auxstress, ghostdisplacement_ordering); #else answer.assemble(momentum, ghostdisplacement_ordering); answer.assemble(conservation, conservation_ordering); answer.assemble(auxstress, momentum_ordering); #endif // Test linear /* if (this->giveNumber() == 364) { FloatMatrix K; FloatArray ans; this->computeStiffnessMatrix(K, TangentStiffness, tStep); ans.beProductOf(K, a); ans.printYourself(); answer.printYourself(); } */ }
void tet21ghostsolid :: computeLoadVector(FloatArray &answer, Load *load, CharType type, ValueModeType mode, TimeStep *tStep) { answer.resize(64); answer.zero(); if ( type != ExternalForcesVector ) { answer.resize(0); return; } #ifdef __FM_MODULE FluidDynamicMaterial *mat = static_cast< FluidCrossSection * >( this->giveCrossSection() )->giveFluidMaterial(); #endif IntegrationRule *iRule = this->integrationRulesArray [ 0 ]; FloatArray N, gVector, temparray(30), dNv, u, inc, u_prev, vload; FloatMatrix dNx, G; load->computeComponentArrayAt(gVector, tStep, VM_Total); temparray.zero(); vload.resize(4); vload.zero(); this->giveDisplacementsIncrementData(u_prev, u, inc, tStep); for ( int k = 0; k < iRule->giveNumberOfIntegrationPoints(); k++ ) { GaussPoint *gp = iRule->getIntegrationPoint(k); FloatArray *lcoords = gp->giveNaturalCoordinates(); double detJ = fabs( this->interpolation.giveTransformationJacobian( * lcoords, FEIElementGeometryWrapper(this) ) ); double dA = detJ * gp->giveWeight(); // Body load if ( gVector.giveSize() ) { #ifdef __FM_MODULE double rho = mat->give('d', gp); #else OOFEM_ERROR("Missing FM module"); double rho = 1.0; #endif this->interpolation.evalN( N, * lcoords, FEIElementGeometryWrapper(this) ); for ( int j = 0; j < N.giveSize(); j++ ) { temparray(3 * j + 0) += N(j) * rho * gVector(0) * dA; temparray(3 * j + 1) += N(j) * rho * gVector(1) * dA; temparray(3 * j + 2) += N(j) * rho * gVector(2) * dA; } } // "load" from previous step this->interpolation.evaldNdx( dNx, * gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(this) ); this->interpolation_lin.evalN( N, * gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(this) ); dNv.resize(30); for (int k = 0; k<dNx.giveNumberOfColumns(); k++) { dNv.at(k*3+1) = dNx.at(1,k+1); dNv.at(k*3+2) = dNx.at(2,k+1); dNv.at(k*3+3) = dNx.at(3,k+1); } G.plusDyadUnsym(N, dNv, dA); FloatMatrix GT; GT.beTranspositionOf(G); vload.plusProduct(GT, u_prev, -0.0 ); //vload.printYourself(); } #if USEUNCOUPLED == 1 // Totaly uncoupled answer.assemble(temparray, this->momentum_ordering); #else answer.assemble(temparray, this->ghostdisplacement_ordering); answer.assemble(vload, this->conservation_ordering); #endif // answer.printYourself(); }
void MatlabExportModule :: doOutputIntegrationPointFields(TimeStep *tStep, FILE *FID) { int domainIndex = 1; Domain *domain = emodel->giveDomain( domainIndex ); // Output header fprintf( FID, "\n %%%% Export of internal variables in integration points \n\n" ); fprintf( FID, "\n %% for interpretation of internal var. numbers see internalstatetype.h\n"); int numVars = this->internalVarsToExport.giveSize(); // Output the internalVarsToExport-list fprintf( FID, "\tIntegrationPointFields.InternalVarsToExport = [" ); for ( int i = 1; i <= numVars; i++ ) { fprintf( FID, "%i ", this->internalVarsToExport.at(i) ); } fprintf( FID, "];\n" ); if ( this->IPFieldsElSet > 0 ) { Set *set = domain->giveSet( this->IPFieldsElSet ); elList = set->giveElementList(); } FloatArray valueArray; int nelem = this->elList.giveSize(); fprintf( FID, "\tIntegrationPointFields.Elements = cell(%i,1); \n", nelem ); for ( int ielem = 1; ielem <= nelem; ielem++ ) { Element *el = domain->giveElement( this->elList.at(ielem) ); fprintf( FID, "\tIntegrationPointFields.Elements{%i}.elementNumber = %i; \n", ielem, el->giveNumber()); int numIntRules = el->giveNumberOfIntegrationRules(); fprintf( FID, "\tIntegrationPointFields.Elements{%i}.integrationRule = cell(%i,1); \n", ielem, numIntRules); for ( int i = 1; i <= numIntRules; i++ ) { IntegrationRule *iRule = el->giveIntegrationRule(i-1); fprintf( FID, "\tIntegrationPointFields.Elements{%i}.integrationRule{%i}.ip = cell(%i,1); \n ", ielem, i, iRule->giveNumberOfIntegrationPoints() ); // Loop over integration points for ( GaussPoint *ip: *iRule ) { double weight = ip->giveWeight(); fprintf( FID, "\tIntegrationPointFields.Elements{%i}.integrationRule{%i}.ip{%i}.ipWeight = %e; \n ", ielem, i, ip->giveNumber(), weight); // export Gauss point coordinates fprintf( FID, "\tIntegrationPointFields.Elements{%i}.integrationRule{%i}.ip{%i}.coords = [", ielem, i, ip->giveNumber()); FloatArray coords; el->computeGlobalCoordinates( coords, ip->giveNaturalCoordinates() ); for ( int ic = 1; ic <= coords.giveSize(); ic++ ) { fprintf( FID, "%e ", coords.at(ic) ); } fprintf( FID, "]; \n" ); // export internal variables fprintf( FID, "\tIntegrationPointFields.Elements{%i}.integrationRule{%i}.ip{%i}.valArray = cell(%i,1); \n", ielem, i, ip->giveNumber(), numVars); for ( int iv = 1; iv <= numVars; iv++ ) { fprintf( FID, "\tIntegrationPointFields.Elements{%i}.integrationRule{%i}.ip{%i}.valArray{%i} = [", ielem, i, ip->giveNumber(), iv); InternalStateType vartype = ( InternalStateType ) this->internalVarsToExport.at(iv); el->giveIPValue(valueArray, ip, vartype, tStep); int nv = valueArray.giveSize(); for ( int ic = 1; ic <= nv; ic++ ) { fprintf( FID, "%.6e ", valueArray.at(ic) ); } fprintf( FID, "]; \n" ); } } } } }
void Quad10_2D_SUPG :: updateStabilizationCoeffs(TimeStep *atTime) { double Re, norm_un, mu, mu_min, nu, norm_N, norm_N_d, norm_M_d, norm_LSIC, norm_G_c, norm_M_c, norm_N_c, t_p1, t_p2, t_p3, t_s1, t_s2, t_s3, rho; FloatMatrix dn, N, N_d, M_d, LSIC, G_c, M_c, N_c; FloatArray dN, s, lcoords_nodes, u, lcn, dn_a(2), n, u1(8), u2(8); GaussPoint *gp; IntegrationRule *iRule; iRule = integrationRulesArray [ 1 ]; mu_min = 1; rho = this->giveMaterial()->give('d', integrationRulesArray [ 0 ]->getIntegrationPoint(0)); for ( int j = 0; j < iRule->giveNumberOfIntegrationPoints(); j++ ) { gp = iRule->getIntegrationPoint(j); mu = static_cast< FluidDynamicMaterial* >(this->giveMaterial())->giveEffectiveViscosity(gp, atTime); if ( mu_min > mu ) { mu_min = mu; } nu = mu_min / rho; } nu = mu_min / rho; //this->computeVectorOf(EID_MomentumBalance, VM_Total, atTime->givePreviousStep(), un); this->computeVectorOf(EID_MomentumBalance, VM_Total, atTime, u); norm_un = u.computeNorm(); this->computeAdvectionTerm(N, atTime); this->computeAdvectionDeltaTerm(N_d, atTime); this->computeMassDeltaTerm(M_d, atTime); this->computeLSICTerm(LSIC, atTime); this->computeLinearAdvectionTerm_MC(G_c, atTime); this->computeMassEpsilonTerm(M_c, atTime); this->computeAdvectionEpsilonTerm(N_c, atTime); norm_N = N.computeFrobeniusNorm(); norm_N_d = N_d.computeFrobeniusNorm(); norm_M_d = M_d.computeFrobeniusNorm(); norm_LSIC = LSIC.computeFrobeniusNorm(); norm_G_c = G_c.computeFrobeniusNorm(); norm_M_c = M_c.computeFrobeniusNorm(); norm_N_c = N_c.computeFrobeniusNorm(); if ( ( norm_N == 0 ) || ( norm_N_d == 0 ) || ( norm_M_d == 0 ) ) { t_supg = 0; } else { Re = ( norm_un / nu ) * ( norm_N / norm_N_d ); t_s1 = norm_N / norm_N_d; t_s2 = atTime->giveTimeIncrement() * ( norm_N / norm_M_d ) * 0.5; t_s3 = t_s1 * Re; t_supg = 1. / sqrt( 1. / ( t_s1 * t_s1 ) + 1. / ( t_s2 * t_s2 ) + 1. / ( t_s3 * t_s3 ) ); // t_supg = 0; } if ( norm_LSIC == 0 ) { t_lsic = 0; } else { t_lsic = norm_N / norm_LSIC; // t_lsic = 0; } if ( ( norm_G_c == 0 ) || ( norm_N_c == 0 ) || ( norm_M_c == 0 ) ) { t_pspg = 0; } else { Re = ( norm_un / nu ) * ( norm_N / norm_N_d ); t_p1 = norm_G_c / norm_N_c; t_p2 = atTime->giveTimeIncrement() * ( norm_G_c / norm_M_c ) * 0.5; t_p3 = t_p1 * Re; t_pspg = 1. / sqrt( 1. / ( t_p1 * t_p1 ) + 1. / ( t_p2 * t_p2 ) + 1. / ( t_p3 * t_p3 ) ); // t_pspg = 0; } //t_pspg = 0; }
std::vector<std::unique_ptr<EnrichmentItem>> NCPrincipalStress::nucleateEnrichmentItems() { SpatialLocalizer *octree = this->mpDomain->giveSpatialLocalizer(); XfemManager *xMan = mpDomain->giveXfemManager(); std::vector<std::unique_ptr<EnrichmentItem>> eiList; // Center coordinates of newly inserted cracks std::vector<FloatArray> center_coord_inserted_cracks; // Loop over all elements and all bulk GP. for(auto &el : mpDomain->giveElements() ) { int numIR = el->giveNumberOfIntegrationRules(); int csNum = el->giveCrossSection()->giveNumber(); if(csNum == mCrossSectionInd || true) { for(int irInd = 0; irInd < numIR; irInd++) { IntegrationRule *ir = el->giveIntegrationRule(irInd); int numGP = ir->giveNumberOfIntegrationPoints(); for(int gpInd = 0; gpInd < numGP; gpInd++) { GaussPoint *gp = ir->getIntegrationPoint(gpInd); // int csNum = gp->giveCrossSection()->giveNumber(); // printf("csNum: %d\n", csNum); StructuralMaterialStatus *ms = dynamic_cast<StructuralMaterialStatus*>(gp->giveMaterialStatus()); if(ms != NULL) { const FloatArray &stress = ms->giveTempStressVector(); FloatArray principalVals; FloatMatrix principalDirs; StructuralMaterial::computePrincipalValDir(principalVals, principalDirs, stress, principal_stress); if(principalVals[0] > mStressThreshold) { // printf("\nFound GP with stress above threshold.\n"); // printf("principalVals: "); principalVals.printYourself(); FloatArray crackNormal; crackNormal.beColumnOf(principalDirs, 1); // printf("crackNormal: "); crackNormal.printYourself(); FloatArray crackTangent = {-crackNormal(1), crackNormal(0)}; crackTangent.normalize(); // printf("crackTangent: "); crackTangent.printYourself(); // Create geometry FloatArray pc = {gp->giveGlobalCoordinates()(0), gp->giveGlobalCoordinates()(1)}; // printf("Global coord: "); pc.printYourself(); FloatArray ps = pc; ps.add(-0.5*mInitialCrackLength, crackTangent); FloatArray pe = pc; pe.add(0.5*mInitialCrackLength, crackTangent); if(mCutOneEl) { // If desired, ensure that the crack cuts exactly one element. Line line(ps, pe); std::vector<FloatArray> intersecPoints; // line.computeIntersectionPoints(el.get(), intersecPoints); for ( int i = 1; i <= el->giveNumberOfDofManagers(); i++ ) { // int n1 = i; // int n2 = 0; // if ( i < el->giveNumberOfDofManagers() ) { // n2 = i + 1; // } else { // n2 = 1; // } // const FloatArray &p1 = *(el->giveDofManager(n1)->giveCoordinates()); // const FloatArray &p2 = *(el->giveDofManager(n2)->giveCoordinates()); } // printf("intersecPoints.size(): %lu\n", intersecPoints.size()); if(intersecPoints.size() == 2) { ps = std::move(intersecPoints[0]); pe = std::move(intersecPoints[1]); } else { OOFEM_ERROR("intersecPoints.size() != 2") } } FloatArray points = {ps(0), ps(1), pc(0), pc(1), pe(0), pe(1)}; // double diffX = 0.5*(ps(0) + pe(0)) - pc(0); // printf("diffX: %e\n", diffX); // double diffY = 0.5*(ps(1) + pe(1)) - pc(1); // printf("diffY: %e\n", diffY); // TODO: Check if nucleation is allowed, by checking for already existing cracks close to the GP. // Idea: Nucleation is not allowed if we are within an enriched element. In this way, branching is not // completely prohibited, but we avoid initiating multiple similar cracks. bool insertionAllowed = true; Element *el_s = octree->giveElementContainingPoint(ps); if(el_s) { if( xMan->isElementEnriched(el_s) ) { insertionAllowed = false; } } Element *el_c = octree->giveElementContainingPoint(pc); if(el_c) { if( xMan->isElementEnriched(el_c) ) { insertionAllowed = false; } } Element *el_e = octree->giveElementContainingPoint(pe); if(el_e) { if( xMan->isElementEnriched(el_e) ) { insertionAllowed = false; } } for(const auto &x: center_coord_inserted_cracks) { if( x.distance(pc) < 2.0*mInitialCrackLength) { insertionAllowed = false; break; printf("Preventing insertion.\n"); } } if(insertionAllowed) { int n = xMan->giveNumberOfEnrichmentItems() + 1; std::unique_ptr<Crack> crack = std::make_unique<Crack>(n, xMan, mpDomain); // Geometry std::unique_ptr<BasicGeometry> geom = std::make_unique<PolygonLine>(); geom->insertVertexBack(ps); geom->insertVertexBack(pc); geom->insertVertexBack(pe); crack->setGeometry(std::move(geom)); // Enrichment function EnrichmentFunction *ef = new HeavisideFunction(1, mpDomain); crack->setEnrichmentFunction(ef); // Enrichment fronts // EnrichmentFront *efStart = new EnrFrontLinearBranchFuncOneEl(); EnrichmentFront *efStart = new EnrFrontCohesiveBranchFuncOneEl(); crack->setEnrichmentFrontStart(efStart); // EnrichmentFront *efEnd = new EnrFrontLinearBranchFuncOneEl(); EnrichmentFront *efEnd = new EnrFrontCohesiveBranchFuncOneEl(); crack->setEnrichmentFrontEnd(efEnd); /////////////////////////////////////// // Propagation law // Options // double radius = 0.5*mInitialCrackLength, angleInc = 10.0, incrementLength = 0.5*mInitialCrackLength, hoopStressThreshold = 0.0; // bool useRadialBasisFunc = true; // PLHoopStressCirc *pl = new PLHoopStressCirc(); // pl->setRadius(radius); // pl->setAngleInc(angleInc); // pl->setIncrementLength(incrementLength); // pl->setHoopStressThreshold(hoopStressThreshold); // pl->setUseRadialBasisFunc(useRadialBasisFunc); // PLDoNothing *pl = new PLDoNothing(); PLMaterialForce *pl = new PLMaterialForce(); pl->setRadius(mMatForceRadius); pl->setIncrementLength(mIncrementLength); // pl->setIncrementLength(0.25); // pl->setCrackPropThreshold(0.25); pl->setCrackPropThreshold(mCrackPropThreshold); crack->setPropagationLaw(pl); crack->updateDofIdPool(); center_coord_inserted_cracks.push_back(pc); eiList.push_back( std::unique_ptr<EnrichmentItem>(std::move(crack)) ); // printf("Nucleating a crack in NCPrincipalStress::nucleateEnrichmentItems.\n"); // printf("el->giveGlobalNumber(): %d\n", el->giveGlobalNumber() ); // We only introduce one crack per element in a single time step. break; } } } } } } // If correct csNum }