int ZZErrorEstimator :: estimateError(EE_ErrorMode mode, TimeStep *tStep) { int nelems = this->domain->giveNumberOfElements(); ZZErrorEstimatorInterface *interface; double sNorm; InternalStateType type = IStype; if ( mode == temporaryEM ) { type = IST_StressTensorTemp; // OOFEM_ERROR("temporaryEM mode not supported"); } if ( this->stateCounter == tStep->giveSolutionStateCounter() ) { return 1; } NodalRecoveryModel *oldSmoother, *rm = NULL; if ( this->nodalRecoveryType == ZZRecovery ) { rm = new ZZNodalRecoveryModel(this->domain); } else if ( this->nodalRecoveryType == SPRRecovery ) { rm = new SPRNodalRecoveryModel(this->domain); } else { OOFEM_ERROR("unknown nodal recovery type"); } // first set the domain Smoother to suitable one, keep old one to be recovered oldSmoother = this->domain->giveSmoother(); this->domain->setSmoother(rm, 0); // do not delete old one // create a new set containing all elements Set elemSet(0, this->domain); elemSet.addAllElements(); // recover nodal values on entire elemSet (domain) rm->recoverValues(elemSet, type, tStep); #ifdef ZZErrorEstimator_ElementResultCashed this->eNorms.resize(nelems); #ifdef EXPERIMENT sNorms.resize(nelems); #endif #else double eNorm; #endif this->globalENorm = this->globalSNorm = 0.0; // loop over domain's elements for ( int ielem = 1; ielem <= nelems; ielem++ ) { if ( this->skipRegion( this->domain->giveElement(ielem)->giveRegionNumber() ) ) { continue; } interface = static_cast< ZZErrorEstimatorInterface * >( this->domain->giveElement(ielem)->giveInterface(ZZErrorEstimatorInterfaceType) ); if ( interface == NULL ) { OOFEM_ERROR("Element has no ZZ error estimator interface defined"); } #ifdef ZZErrorEstimator_ElementResultCashed interface->ZZErrorEstimatorI_computeElementContributions(eNorms.at(ielem), sNorm, this->normType, type, tStep); this->globalENorm += eNorms.at(ielem) * eNorms.at(ielem); #ifdef EXPERIMENT sNorms.at(ielem) = sNorm; #endif #else interface->ZZErrorEstimatorI_computeElementContributions(eNorm, sNorm, this->normType, type, tStep); this->globalENorm += eNorm * eNorm; #endif this->globalSNorm += sNorm * sNorm; } FloatArray gnorms; ParallelContext *parallel_context = this->domain->giveEngngModel()->giveParallelContext(this->domain->giveNumber()); parallel_context->accumulate({this->globalENorm, this->globalSNorm}, gnorms); this->globalENorm = gnorms [ 0 ]; this->globalSNorm = gnorms [ 1 ]; // recover the stored smoother this->domain->setSmoother(oldSmoother); //delete old one (the rm) // report the error estimate double pe = sqrt( this->globalENorm / ( this->globalENorm + this->globalSNorm ) ); OOFEM_LOG_RELEVANT("Relative stress error estimate: %5.2f%%\n", pe * 100.0); this->globalENorm = sqrt(this->globalENorm); this->globalSNorm = sqrt(this->globalSNorm); this->globalErrorEstimate = pe; this->stateCounter = tStep->giveSolutionStateCounter(); return 1; }
int Structural3DElement :: computeLoadLSToLRotationMatrix(FloatMatrix &answer, int, GaussPoint *) { OOFEM_ERROR("surface local coordinate system not supported"); return 1; }
void SUPGElement2 :: computeSurfaceLoadVector_MC(FloatArray &answer, Load *load, int id, TimeStep *tStep) { OOFEM_ERROR("not implemented"); }
void XFEMStatic :: terminate(TimeStep *tStep) { this->doStepOutput(tStep); this->printReactionForces(tStep, 1); // update load vectors before storing context fflush( this->giveOutputStream() ); this->updateLoadVectors(tStep); this->saveStepContext(tStep); // Propagate fronts for ( auto &domain: domainList ) { XfemManager *xMan = domain->giveXfemManager(); xMan->propagateFronts(); } // Update element subdivisions if necessary // (e.g. if a crack has moved and cut a new element) for ( int domInd = 1; domInd <= this->giveNumberOfDomains(); domInd++ ) { Domain *domain = this->giveDomain(domInd); // create a new set containing all elements Set elemSet(0, domain); elemSet.addAllElements(); if ( domain->giveXfemManager()->hasPropagatingFronts() || mForceRemap ) { // If domain cloning is performed, there is no need to // set values from the dof map. mSetValsFromDofMap = false; // Take copy of the domain to allow mapping of state variables // to the new Gauss points. Domain *dNew = domain->Clone(); bool deallocateOld = false; setDomain(1, dNew, deallocateOld); forceEquationNumbering(); // Map primary variables LSPrimaryVariableMapper primMapper; FloatArray u; primMapper.mapPrimaryVariables(u, * domain, * dNew, VM_Total, * tStep); if ( totalDisplacement.giveSize() == u.giveSize() ) { FloatArray diff; diff.beDifferenceOf(totalDisplacement, u); printf( "diff norm: %e\n", diff.computeNorm() ); } totalDisplacement = u; primMapper.mapPrimaryVariables(incrementOfDisplacement, * domain, * dNew, VM_Incremental, * tStep); int numEl = dNew->giveNumberOfElements(); for ( int i = 1; i <= numEl; i++ ) { //////////////////////////////////////////////////////// // Map state variables for regular Gauss points StructuralElement *el = dynamic_cast< StructuralElement * >( dNew->giveElement(i) ); el->createMaterialStatus(); el->mapStateVariables(* domain, * tStep); //////////////////////////////////////////////////////// // Map state variables for cohesive zone if applicable XfemStructuralElementInterface *xFemEl = dynamic_cast< XfemStructuralElementInterface * >(el); if ( xFemEl != NULL ) { if ( xFemEl->mpCZMat != NULL ) { size_t numCzRules = xFemEl->mpCZIntegrationRules.size(); for ( size_t czIndex = 0; czIndex < numCzRules; czIndex++ ) { if ( xFemEl->mpCZIntegrationRules [ czIndex ] != NULL ) { for ( GaussPoint *gp: *xFemEl->mpCZIntegrationRules [ czIndex ] ) { MaterialStatus *ms = xFemEl->mpCZMat->giveStatus(gp); if ( ms == NULL ) { OOFEM_ERROR("Failed to fetch material status."); } MaterialStatusMapperInterface *interface = dynamic_cast< MaterialStatusMapperInterface * > ( xFemEl->mpCZMat->giveStatus(gp) ); if ( interface == NULL ) { OOFEM_ERROR("Failed to fetch MaterialStatusMapperInterface."); } MaterialStatus *matStat = dynamic_cast< MaterialStatus * >( xFemEl->mpCZMat->giveStatus(gp) ); StructuralInterfaceMaterialStatus *siMatStat = dynamic_cast< StructuralInterfaceMaterialStatus * >(matStat); if ( siMatStat == NULL ) { OOFEM_ERROR("Failed to cast to StructuralInterfaceMaterialStatus."); } interface->MSMI_map_cz(* gp, * domain, elemSet, * tStep, * siMatStat); } } } } } } delete domain; domain = this->giveDomain(1); // Set domain pointer to various components ... this->nMethod->setDomain(domain); int numExpModules = this->exportModuleManager->giveNumberOfModules(); for ( int i = 1; i <= numExpModules; i++ ) { // ... by diving deep into the hierarchies ... :-/ VTKXMLExportModule *vtkxmlMod = dynamic_cast< VTKXMLExportModule * >( this->exportModuleManager->giveModule(i) ); if ( vtkxmlMod != NULL ) { vtkxmlMod->giveSmoother()->setDomain(domain); vtkxmlMod->givePrimVarSmoother()->setDomain(domain); } } this->setUpdateStructureFlag(true); } // if( domain->giveXfemManager()->hasPropagatingFronts() ) //#endif } // Fracture/failure mechanics evaluation for ( auto &domain: domainList ) { if ( domain->hasFractureManager() ) { // Will most likely fail if numDom > 1 FractureManager *fracMan = domain->giveFractureManager(); fracMan->evaluateYourself(tStep); fracMan->updateXFEM(tStep); // Update XFEM structure based on the fracture manager this->setUpdateStructureFlag( fracMan->giveUpdateFlag() ); // if the internal structure need to be updated } } }
void IDGMaterial :: giveRealStressVectorGrad(FloatArray &answer1, double &answer2, GaussPoint *gp, const FloatArray &totalStrain, double nonlocalCumulatedStrain, TimeStep *tStep) // // returns real stress vector in 3d stress space of receiver according to // previous level of stress and current // strain increment, the only way, how to correctly update gp records // { IDGMaterialStatus *status = static_cast< IDGMaterialStatus * >( this->giveStatus(gp) ); LinearElasticMaterial *lmat = this->giveLinearElasticMaterial(); FloatArray reducedTotalStrainVector, strain; FloatMatrix de; double f, equivStrain, tempKappa = 0.0, omega = 0.0; //this->initGpForNewStep(gp); this->initTempStatus(gp); // subtract stress independent part // note: eigenStrains (temperature) is not contained in mechanical strain stored in gp // therefore it is necessary to subtract always the total eigen strain value this->giveStressDependentPartOfStrainVector(reducedTotalStrainVector, gp, totalStrain, tStep, VM_Total); // compute equivalent strain this->computeEquivalentStrain(equivStrain, reducedTotalStrainVector, gp, tStep); if ( llcriteria == idm_strainLevelCR ) { // compute value of loading function if strainLevel crit apply f = nonlocalCumulatedStrain - status->giveKappa(); if ( f <= 0.0 ) { // damage does not grow tempKappa = status->giveKappa(); omega = status->giveDamage(); } else { // damage grow this->initDamaged(tempKappa, reducedTotalStrainVector, gp); // evaluate damage parameter this->computeDamageParam(omega, nonlocalCumulatedStrain, reducedTotalStrainVector, gp); } } else if ( llcriteria == idm_damageLevelCR ) { // evaluate damage parameter first tempKappa = nonlocalCumulatedStrain; this->initDamaged(tempKappa, strain, gp); this->computeDamageParam(omega, tempKappa, reducedTotalStrainVector, gp); if ( omega < status->giveDamage() ) { // unloading takes place omega = status->giveDamage(); //printf ("."); } } else { OOFEM_ERROR("unsupported loading/uloading criteria"); } lmat->giveStiffnessMatrix(de, SecantStiffness, gp, tStep); de.times(1.0 - omega); answer1.beProductOf(de, strain); answer2 = equivStrain; // update gp status->letTempStrainVectorBe(totalStrain); status->letTempStressVectorBe(answer1); status->setNonlocalCumulatedStrain(nonlocalCumulatedStrain); status->setTempKappa(tempKappa); status->setTempDamage(omega); }
void NonlocalMaterialExtensionInterface :: buildNonlocalPointTable(GaussPoint *gp) { double weight, elemVolume, integrationVolume = 0.; NonlocalMaterialStatusExtensionInterface *statusExt = static_cast< NonlocalMaterialStatusExtensionInterface * >( gp->giveMaterialStatus()-> giveInterface(NonlocalMaterialStatusExtensionInterfaceType) ); std :: list< localIntegrationRecord > *iList; Element *ielem; IntegrationRule *iRule; if ( !statusExt ) { OOFEM_ERROR("local material status encountered"); } if ( !statusExt->giveIntegrationDomainList()->empty() ) { return; // already done } iList = statusExt->giveIntegrationDomainList(); FloatArray gpCoords, jGpCoords, shiftedGpCoords; SpatialLocalizer :: elementContainerType elemSet; if ( gp->giveElement()->computeGlobalCoordinates( gpCoords, gp->giveNaturalCoordinates() ) == 0 ) { OOFEM_ERROR("computeGlobalCoordinates of target failed"); } // If nonlocal variation is set to the distance-based approach, a new nonlocal radius // is calculated as a function of the distance from the Gauss point to the nonlocal boundaries if ( nlvar == NLVT_DistanceBasedLinear || nlvar == NLVT_DistanceBasedExponential ) { // cl=cl0; cl = giveDistanceBasedInteractionRadius(gpCoords); suprad = evaluateSupportRadius(); } // If the mesh represents a periodic cell, nonlocal interaction is considered not only for the real neighbors // but also for their periodic images, shifted by +px or -px in the x-direction. In the implementation, // instead of shifting the potential neighbors, we shift the receiver point gp. In the non-periodic case (typical), // px=0 and the following loop is executed only once. int ix, nx = 0; // typical case if ( px > 0. ) nx = 1; // periodicity taken into account for (ix=-nx; ix<=nx; ix++) { // loop over periodic images shifted in x-direction shiftedGpCoords = gpCoords; shiftedGpCoords.at(1) += ix*px; // ask domain spatial localizer for list of elements with IP within this zone #ifdef NMEI_USE_ALL_ELEMENTS_IN_SUPPORT this->giveDomain()->giveSpatialLocalizer()->giveAllElementsWithNodesWithinBox(elemSet, shiftedGpCoords, suprad); // insert element containing given gp elemSet.insert( gp->giveElement()->giveNumber() ); #else this->giveDomain()->giveSpatialLocalizer()->giveAllElementsWithIpWithinBox_EvenIfEmpty(elemSet, shiftedGpCoords, suprad); #endif // initialize iList for ( auto elindx: elemSet ) { ielem = this->giveDomain()->giveElement(elindx); if ( regionMap.at( ielem->giveRegionNumber() ) == 0 ) { iRule = ielem->giveDefaultIntegrationRulePtr(); for ( GaussPoint *jGp: *iRule ) { if ( ielem->computeGlobalCoordinates( jGpCoords, jGp->giveNaturalCoordinates() ) ) { weight = this->computeWeightFunction(shiftedGpCoords, jGpCoords); //manipulate weights for a special averaging of strain (OFF by default) this->manipulateWeight(weight, gp, jGp); this->applyBarrierConstraints(shiftedGpCoords, jGpCoords, weight); #ifdef NMEI_USE_ALL_ELEMENTS_IN_SUPPORT if ( 1 ) { #else if ( weight > 0. ) { #endif localIntegrationRecord ir; ir.nearGp = jGp; // store gp elemVolume = weight * jGp->giveElement()->computeVolumeAround(jGp); ir.weight = elemVolume; // store gp weight iList->push_back(ir); // store own copy in list integrationVolume += elemVolume; } } else { OOFEM_ERROR("computeGlobalCoordinates of target failed"); } } } } // loop over elements } statusExt->setIntegrationScale(integrationVolume); // store scaling factor /* * // Old implementation without spatial localizer * * FloatArray jGpCoords; * for (i=1; i<=nelem; i++) { * ielem = this->giveDomain()->giveElement(i); * if (regionMap.at(ielem->giveRegionNumber()) == 0) { * iRule = ielem->giveDefaultIntegrationRulePtr (); * for (GaussPoint *jGp: *iRule ) { * if (ielem->computeGlobalCoordinates (jGpCoords, *(jGp->giveCoordinates()))) { * weight = this->computeWeightFunction (gpCoords, jGpCoords); * if (weight > NonlocalMaterialZeroWeight) { * localIntegrationRecord ir; * ir.nearGp = jGp; // store gp * elemVolume = weight * jGp->giveElement()->computeVolumeAround (jGp); * ir.weight = elemVolume; // store gp weight * iList->append(ir); // store own copy in list * integrationVolume += elemVolume; * } * } else OOFEM_ERROR("computeGlobalCoordinates failed"); * } * } * } // loop over elements * statusExt->setIntegrationScale (integrationVolume); // remember scaling factor */ } void NonlocalMaterialExtensionInterface :: rebuildNonlocalPointTable(GaussPoint *gp, IntArray *contributingElems) { double weight, elemVolume, integrationVolume = 0.; NonlocalMaterialStatusExtensionInterface *statusExt = static_cast< NonlocalMaterialStatusExtensionInterface * >( gp->giveMaterialStatus()-> giveInterface(NonlocalMaterialStatusExtensionInterfaceType) ); std :: list< localIntegrationRecord > *iList; Element *ielem; IntegrationRule *iRule; if ( !statusExt ) { OOFEM_ERROR("local material status encountered"); } iList = statusExt->giveIntegrationDomainList(); iList->clear(); if ( contributingElems == NULL ) { // no element table provided, use standard method this->buildNonlocalPointTable(gp); } else { FloatArray gpCoords, jGpCoords; int _size = contributingElems->giveSize(); if ( gp->giveElement()->computeGlobalCoordinates( gpCoords, gp->giveNaturalCoordinates() ) == 0 ) { OOFEM_ERROR("computeGlobalCoordinates of target failed"); } //If nonlocal variation is set to the distance-based approach calculates new nonlocal radius // based on the distance from the nonlocal boundaries if ( nlvar == NLVT_DistanceBasedLinear || nlvar == NLVT_DistanceBasedExponential ) { cl = cl0; cl = giveDistanceBasedInteractionRadius(gpCoords); suprad = evaluateSupportRadius(); } // initialize iList for ( int _e = 1; _e <= _size; _e++ ) { ielem = this->giveDomain()->giveElement( contributingElems->at(_e) ); if ( regionMap.at( ielem->giveRegionNumber() ) == 0 ) { iRule = ielem->giveDefaultIntegrationRulePtr(); for ( GaussPoint *jGp: *iRule ) { if ( ielem->computeGlobalCoordinates( jGpCoords, jGp->giveNaturalCoordinates() ) ) { weight = this->computeWeightFunction(gpCoords, jGpCoords); //manipulate weights for a special averaging of strain (OFF by default) this->manipulateWeight(weight, gp, jGp); this->applyBarrierConstraints(gpCoords, jGpCoords, weight); #ifdef NMEI_USE_ALL_ELEMENTS_IN_SUPPORT if ( 1 ) { #else if ( weight > 0. ) { #endif localIntegrationRecord ir; ir.nearGp = jGp; // store gp elemVolume = weight * jGp->giveElement()->computeVolumeAround(jGp); ir.weight = elemVolume; // store gp weight iList->push_back(ir); // store own copy in list integrationVolume += elemVolume; } } else { OOFEM_ERROR("computeGlobalCoordinates of target failed"); } } } } // loop over elements statusExt->setIntegrationScale(integrationVolume); // remember scaling factor #ifdef __PARALLEL_MODE #ifdef __VERBOSE_PARALLEL fprintf( stderr, "%d(%d):", gp->giveElement()->giveGlobalNumber(), gp->giveNumber() ); for ( auto &lir: iList ) { fprintf(stderr, "%d,%d(%e)", lir.nearGp->giveElement()->giveGlobalNumber(), lir.nearGp->giveNumber(), lir.weight); } fprintf(stderr, "\n"); #endif #endif } } std :: list< localIntegrationRecord > * NonlocalMaterialExtensionInterface :: giveIPIntegrationList(GaussPoint *gp) { NonlocalMaterialStatusExtensionInterface *statusExt = static_cast< NonlocalMaterialStatusExtensionInterface * >( gp->giveMaterialStatus()-> giveInterface(NonlocalMaterialStatusExtensionInterfaceType) ); if ( !statusExt ) { OOFEM_ERROR("local material status encountered"); } if ( statusExt->giveIntegrationDomainList()->empty() ) { this->buildNonlocalPointTable(gp); } return statusExt->giveIntegrationDomainList(); }
void Beam3d :: computeEdgeLoadVectorAt(FloatArray &answer, Load *load, int iedge, TimeStep *tStep, ValueModeType mode) { FloatArray coords, components, endComponents; FloatMatrix T; double l = this->computeLength(); double kappay = this->giveKappayCoeff(tStep); double kappaz = this->giveKappazCoeff(tStep); double fx, fy, fz, fmx, fmy, fmz, dfx, dfy, dfz, dfmx, dfmy, dfmz; // evaluates the receivers edge load vector // for clamped beam // BoundaryLoad *edgeLoad = dynamic_cast< BoundaryLoad * >( load ); if ( edgeLoad ) { answer.resize(12); answer.zero(); switch ( edgeLoad->giveApproxOrder() ) { case 0: if ( edgeLoad->giveFormulationType() == Load :: FT_Entity ) { coords.resize(1); coords.at(1) = 0.0; } else { coords = * ( this->giveNode(1)->giveCoordinates() ); } edgeLoad->computeValues(components, tStep, coords, {D_u, D_v, D_w, R_u, R_v, R_w}, mode); // prepare transformation coeffs if ( edgeLoad->giveCoordSystMode() == Load :: CST_Global ) { if ( this->computeLoadGToLRotationMtrx(T) ) { components.rotatedWith(T, 'n'); } } fx = components.at(1); fy = components.at(2); fz = components.at(3); fmx = components.at(4); fmy = components.at(5); fmz = components.at(6); answer.at(1) = fx * l / 2.; answer.at(2) = fy * l / 2. + fmz / ( 1. + 2. * kappaz ); answer.at(3) = fz * l / 2. + fmy / ( 1. + 2. * kappay ); answer.at(4) = fmx * l / 2.; answer.at(5) = ( -1. ) * fz * l * l / 12. + fmy * l * kappay / ( 1. + 2. * kappay ); answer.at(6) = ( 1. ) * fy * l * l / 12. + fmz * l * kappaz / ( 1. + 2. * kappaz ); answer.at(7) = fx * l / 2.; answer.at(8) = fy * l / 2. - fmz / ( 1. + 2. * kappaz ); answer.at(9) = fz * l / 2. - fmy / ( 1. + 2. * kappay ); answer.at(10) = fmx * l / 2.; answer.at(11) = ( 1. ) * fz * l * l / 12. + fmy * l * kappay / ( 1. + 2. * kappay ); answer.at(12) = ( -1. ) * fy * l * l / 12. + fmz * l * kappaz / ( 1. + 2. * kappaz ); break; case 1: if ( edgeLoad->giveFormulationType() == Load :: FT_Entity ) { coords.resize(1); coords.at(1) = -1.0; } else { coords = * ( this->giveNode(1)->giveCoordinates() ); } edgeLoad->computeValues(components, tStep, coords, {D_u, D_v, D_w, R_u, R_v, R_w}, mode); // prepare transformation coeffs if ( edgeLoad->giveCoordSystMode() == Load :: CST_Global ) { if ( this->computeLoadGToLRotationMtrx(T) ) { components.rotatedWith(T, 'n'); } } fx = components.at(1); fy = components.at(2); fz = components.at(3); fmx = components.at(4); fmy = components.at(5); fmz = components.at(6); if ( edgeLoad->giveFormulationType() == Load :: FT_Entity ) { coords.resize(1); coords.at(1) = 1.0; } else { coords = * ( this->giveNode(2)->giveCoordinates() ); } edgeLoad->computeValues(endComponents, tStep, coords, {D_u, D_v, D_w, R_u, R_v, R_w}, mode); // prepare transformation coeffs if ( edgeLoad->giveCoordSystMode() == Load :: CST_Global ) { if ( T.isNotEmpty() ) { endComponents.rotatedWith(T, 'n'); } } // compute differences endComponents.subtract(components); dfx = endComponents.at(1); dfy = endComponents.at(2); dfz = endComponents.at(3); dfmx = endComponents.at(4); dfmy = endComponents.at(5); dfmz = endComponents.at(6); answer.at(1) = fx * l / 2. + dfx * l / 6.; answer.at(2) = fy * l / 2. + dfy * l * ( 20. * kappaz + 9 ) / ( 60. * ( 1. + 2. * kappaz ) ) + fmz / ( 1. + 2. * kappaz ) + dfmz * ( 1. / 2. ) / ( 1. + 2. * kappaz ); answer.at(3) = fz * l / 2. + dfz * l * ( 20. * kappay + 9 ) / ( 60. * ( 1. + 2. * kappay ) ) + fmy / ( 1. + 2. * kappay ) + dfmy * ( 1. / 2. ) / ( 1. + 2. * kappay ); answer.at(4) = fmx * l / 2. + dfmx * l / 6.; answer.at(5) = ( -1. ) * fz * l * l / 12. - dfz * l * l * ( 5. * kappay + 2. ) / ( 60. * ( 1. + 2. * kappay ) ) + fmy * l * kappay / ( 1. + 2. * kappay ) + dfmy * l * ( 4. * kappay - 1. ) / ( 12. * ( 1. + 2. * kappay ) ); answer.at(6) = ( 1. ) * fy * l * l / 12. + dfy * l * l * ( 5. * kappaz + 2. ) / ( 60. * ( 1. + 2. * kappaz ) ) + fmz * l * kappaz / ( 1. + 2. * kappaz ) + dfmz * l * ( 4. * kappaz - 1. ) / ( 12. * ( 1. + 2. * kappaz ) ); answer.at(7) = fx * l / 2. + dfx * l / 3.; answer.at(8) = fy * l / 2. + dfy * l * ( 40. * kappaz + 21 ) / ( 60. * ( 1. + 2. * kappaz ) ) - fmz / ( 1. + 2. * kappaz ) - dfmz * ( 1. / 2. ) / ( ( 1. + 2. * kappaz ) ); answer.at(9) = fz * l / 2. + dfz * l * ( 40. * kappay + 21 ) / ( 60. * ( 1. + 2. * kappay ) ) - fmy / ( 1. + 2. * kappay ) - dfmy * ( 1. / 2. ) / ( ( 1. + 2. * kappay ) ); answer.at(10) = fmx * l / 2. + dfmx * l / 3.; answer.at(11) = ( 1. ) * fz * l * l / 12. + dfz * l * l * ( 5. * kappay + 3. ) / ( 60. * ( 1. + 2. * kappay ) ) + fmy * l * kappay / ( 1. + 2. * kappay ) + dfmy * l * ( 8. * kappay + 1. ) / ( 12. * ( 1. + 2. * kappay ) ); answer.at(12) = ( -1. ) * fy * l * l / 12. - dfy * l * l * ( 5. * kappaz + 3. ) / ( 60. * ( 1. + 2. * kappaz ) ) + fmz * l * kappaz / ( 1. + 2. * kappaz ) + dfmz * l * ( 8. * kappaz + 1. ) / ( 12. * ( 1. + 2. * kappaz ) ); break; default: OOFEM_ERROR("unsupported load type"); } } }
BasicGeometry *CreateUsrDefGeometry(classType type) { OOFEM_ERROR("CreateUsrDefGeometry: Unknown type\n"); return NULL; }
void StaticStructural :: solveYourselfAt(TimeStep *tStep) { int neq; int di = 1; this->field->advanceSolution(tStep); this->field->applyBoundaryCondition(tStep); ///@todo Temporary hack, advanceSolution should apply the boundary conditions directly. neq = this->giveNumberOfDomainEquations( di, EModelDefaultEquationNumbering() ); if (tStep->giveNumber()==1) { this->field->initialize(VM_Total, tStep, this->solution, EModelDefaultEquationNumbering() ); } else { this->field->initialize(VM_Total, tStep->givePreviousStep(), this->solution, EModelDefaultEquationNumbering() ); this->field->update(VM_Total, tStep, this->solution, EModelDefaultEquationNumbering() ); } FloatArray incrementOfSolution(neq), externalForces(neq); // Create "stiffness matrix" if ( !this->stiffnessMatrix ) { this->stiffnessMatrix.reset( classFactory.createSparseMtrx(sparseMtrxType) ); if ( !this->stiffnessMatrix ) { OOFEM_ERROR("Couldn't create requested sparse matrix of type %d", sparseMtrxType); } this->stiffnessMatrix->buildInternalStructure( this, di, EModelDefaultEquationNumbering() ); } this->internalForces.resize(neq); this->giveNumericalMethod( this->giveCurrentMetaStep() ); this->initMetaStepAttributes( this->giveCurrentMetaStep() ); if ( this->initialGuessType == IG_Tangent ) { OOFEM_LOG_RELEVANT("Computing initial guess\n"); FloatArray extrapolatedForces(neq); this->assembleExtrapolatedForces( extrapolatedForces, tStep, TangentStiffnessMatrix, this->giveDomain(di) ); extrapolatedForces.negated(); ///@todo Need to find a general way to support this before enabling it by default. //this->assembleVector(extrapolatedForces, tStep, LinearizedDilationForceAssembler(), VM_Incremental, EModelDefaultEquationNumbering(), this->giveDomain(di) ); #if 0 // Some debug stuff: extrapolatedForces.printYourself("extrapolatedForces"); this->internalForces.zero(); this->assembleVectorFromElements(this->internalForces, tStep, InternalForceAssembler(), VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(di)); this->internalForces.printYourself("internal forces"); #endif OOFEM_LOG_RELEVANT("Computing old tangent\n"); this->updateComponent( tStep, NonLinearLhs, this->giveDomain(di) ); SparseLinearSystemNM *linSolver = nMethod->giveLinearSolver(); OOFEM_LOG_RELEVANT("Solving for increment\n"); linSolver->solve(*stiffnessMatrix, extrapolatedForces, incrementOfSolution); OOFEM_LOG_RELEVANT("Initial guess found\n"); this->solution.add(incrementOfSolution); this->field->update(VM_Total, tStep, this->solution, EModelDefaultEquationNumbering()); this->field->applyBoundaryCondition(tStep); ///@todo Temporary hack to override the incorrect values that is set by "update" above. Remove this when that is fixed. } else if ( this->initialGuessType != IG_None ) { OOFEM_ERROR("Initial guess type: %d not supported", initialGuessType); } else { incrementOfSolution.zero(); } // Build initial/external load externalForces.zero(); this->assembleVector( externalForces, tStep, ExternalForceAssembler(), VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(1) ); this->updateSharedDofManagers(externalForces, EModelDefaultEquationNumbering(), LoadExchangeTag); if ( this->giveProblemScale() == macroScale ) { OOFEM_LOG_INFO("\nStaticStructural :: solveYourselfAt - Solving step %d, metastep %d, (neq = %d)\n", tStep->giveNumber(), tStep->giveMetaStepNumber(), neq); } double loadLevel; int currentIterations; NM_Status status = this->nMethod->solve(*this->stiffnessMatrix, externalForces, NULL, this->solution, incrementOfSolution, this->internalForces, this->eNorm, loadLevel, // Only relevant for incrementalBCLoadVector? SparseNonLinearSystemNM :: rlm_total, currentIterations, tStep); if ( !( status & NM_Success ) ) { OOFEM_ERROR("No success in solving problem"); } }
EnrichmentItem *CreateUsrDefEnrichmentItem(classType type, int number, XfemManager *xm, Domain *domain) { OOFEM_ERROR("CreateUsrDefEnrichmentItem: Unknown type\n"); return NULL; }
EnrichmentFunction *CreateUsrDefEnrichmentFunction(classType type, int number, Domain *domain) { OOFEM_ERROR("CreateUsrDefEnrichmentFunction: Unknown type\n"); return NULL; }
void UniformGridField::setValues(const FloatArray& vv){ int s=1; for(int i=0; i<div.giveSize(); i++) s*=div[i]+1; if(vv.giveSize()!=s) OOFEM_ERROR((std::string("Array size must be exactly prod(div[i]+1)=")+std::to_string(s)).c_str()); values=vv; }
NM_Status SubspaceIteration :: solve(SparseMtrx &a, SparseMtrx &b, FloatArray &_eigv, FloatMatrix &_r, double rtol, int nroot) // // this function solve the generalized eigenproblem using the Generalized // jacobi iteration // // { FILE *outStream; FloatArray temp, w, d, tt, rtolv, eigv; FloatMatrix r; int nn, nc1, i, j, k, ij = 0, nite, is; double rt, art, brt, eigvt, dif; FloatMatrix ar, br, vec; GJacobi mtd(domain, engngModel); outStream = domain->giveEngngModel()->giveOutputStream(); nc = min(2 * nroot, nroot + 8); // // check matrix size // if ( a.giveNumberOfColumns() != b.giveNumberOfColumns() ) { OOFEM_ERROR("matrices size mismatch"); } // check matrix for factorization support if ( !a.canBeFactorized() ) { OOFEM_ERROR("a matrix not support factorization"); } // // check for wery small problem // nn = a.giveNumberOfColumns(); if ( nc > nn ) { nc = nn; } ar.resize(nc, nc); ar.zero(); br.resize(nc, nc); br.zero(); // // creation of initial iteration vectors // nc1 = nc - 1; w.resize(nn); w.zero(); d.resize(nc); d.zero(); tt.resize(nn); tt.zero(); rtolv.resize(nc); rtolv.zero(); vec.resize(nc, nc); vec.zero(); // eigen vectors of reduced problem _r.resize(nn, nroot); _eigv.resize(nroot); // // create work arrays // r.resize(nn, nc); r.zero(); eigv.resize(nc); eigv.zero(); FloatArray h(nn); for ( i = 1; i <= nn; i++ ) { h.at(i) = 1.0; w.at(i) = b.at(i, i) / a.at(i, i); } b.times(h, tt); for ( i = 1; i <= nn; i++ ) { r.at(i, 1) = tt.at(i); } for ( j = 2; j <= nc; j++ ) { rt = 0.0; for ( i = 1; i <= nn; i++ ) { if ( fabs( w.at(i) ) >= rt ) { rt = fabs( w.at(i) ); ij = i; } } tt.at(j) = ij; w.at(ij) = 0.; for ( i = 1; i <= nn; i++ ) { if ( i == ij ) { h.at(i) = 1.0; } else { h.at(i) = 0.0; } } b.times(h, tt); for ( i = 1; i <= nn; i++ ) { r.at(i, j) = tt.at(i); } } // (r = z) # ifdef DETAILED_REPORT printf("SubspaceIteration :: solveYourselfAt: Degrees of freedom invoked by initial vectors :\n"); tt.printYourself(); printf("SubspaceIteration :: solveYourselfAt: initial vectors for iteration:\n"); r.printYourself(); # endif //ish = 0; a.factorized(); // // start of iteration loop // for ( nite = 0; ; ++nite ) { // label 100 # ifdef DETAILED_REPORT printf("SubspaceIteration :: solveYourselfAt: Iteration loop no. %d\n", nite); # endif // // compute projection ar and br of matrices a , b // for ( j = 1; j <= nc; j++ ) { for ( k = 1; k <= nn; k++ ) { tt.at(k) = r.at(k, j); } //a. forwardReductionWith(&tt) -> diagonalScalingWith (&tt) // -> backSubstitutionWithtt) ; a.backSubstitutionWith(tt); for ( i = j; i <= nc; i++ ) { art = 0.; for ( k = 1; k <= nn; k++ ) { art += r.at(k, i) * tt.at(k); } ar.at(j, i) = art; } for ( k = 1; k <= nn; k++ ) { r.at(k, j) = tt.at(k); // (r = xbar) } } ar.symmetrized(); // label 110 #ifdef DETAILED_REPORT printf("SubspaceIteration :: solveYourselfAt: Printing projection matrix ar\n"); ar.printYourself(); #endif // for ( j = 1; j <= nc; j++ ) { for ( k = 1; k <= nn; k++ ) { tt.at(k) = r.at(k, j); } b.times(tt, temp); for ( i = j; i <= nc; i++ ) { brt = 0.; for ( k = 1; k <= nn; k++ ) { brt += r.at(k, i) * temp.at(k); } br.at(j, i) = brt; } // label 180 for ( k = 1; k <= nn; k++ ) { r.at(k, j) = temp.at(k); // (r=zbar) } } // label 160 br.symmetrized(); #ifdef DETAILED_REPORT printf("SubspaceIteration :: solveYourselfAt: Printing projection matrix br\n"); br.printYourself(); #endif // // solution of reduced eigenvalue problem // mtd.solve(ar, br, eigv, vec); /// START EXPERIMENTAL // solve the reduced problem by Inverse iteration /* * { * FloatMatrix x(nc,nc), z(nc,nc), zz(nc,nc), arinv; * FloatArray w(nc), ww(nc), tt(nc), t(nc); * double c; * int ii, i,j,k,ac; * * * // initial setting * for (i=1;i<=nc;i++){ * ww.at(i)=1.0; * } * * for (i=1;i<=nc;i++) * for (j=1; j<=nc;j++) * z.at(i,j)=1.0; * * arinv.beInverseOf (ar); * * for (i=0;i<nitem;i++) { * * // copy zz=z * zz = z; * * // solve matrix equation K.X = M.X * x.beProductOf (arinv, z); * // evaluation of Rayleigh quotients * for (j=1;j<=nc;j++){ * w.at(j) = 0.0; * for (k = 1; k<= nc; k++) w.at(j) += zz.at(k,j)*x.at(k,j); * } * * z.beProductOf (br, x); * * for (j=1;j<=nc;j++){ * c = 0; * for (k = 1; k<= nc; k++) c+= z.at(k,j)*x.at(k,j); * w.at(j) /= c; * } * * // check convergence * ac=0; * for (j=1;j<=nc;j++){ * if (fabs((ww.at(j)-w.at(j))/w.at(j))< rtol) ac++; * ww.at(j)=w.at(j); * } * * printf ("\n iterace cislo %d %d",i,ac); * w.printYourself(); * * // Gramm-Schmidt ortogonalization * for (j=1;j<=nc;j++) { * for (k = 1; k<= nc; k++) tt.at(k) = x.at(k,j) ; * t.beProductOf(br,tt) ; * for (ii=1;ii<j;ii++) { * c = 0.0; * for (k = 1; k<= nc; k++) c += x.at(k,ii)*t.at(k); * for (k = 1; k<= nc; k++) x.at(k,j) -= x.at(k,ii)*c; * } * for (k = 1; k<= nc; k++) tt.at(k) = x.at(k,j) ; * t.beProductOf (br,tt) ; * c = 0.0; * for (k = 1; k<= nc; k++) c += x.at(k,j)*t.at(k); * for (k = 1; k<= nc; k++) x.at(k,j) /= sqrt(c); * } * * if (ac>nroot){ * break; * } * * // compute new approximation of Z * z.beProductOf (br,x); * } * * eigv = w; * vec = x; * } * /// END EXPERIMANTAL */ // // sorting eigenvalues according to their values // do { is = 0; // label 350 for ( i = 1; i <= nc1; i++ ) { if ( fabs( eigv.at(i + 1) ) < fabs( eigv.at(i) ) ) { is++; eigvt = eigv.at(i + 1); eigv.at(i + 1) = eigv.at(i); eigv.at(i) = eigvt; for ( k = 1; k <= nc; k++ ) { rt = vec.at(k, i + 1); vec.at(k, i + 1) = vec.at(k, i); vec.at(k, i) = rt; } } } // label 360 } while ( is != 0 ); # ifdef DETAILED_REPORT printf("SubspaceIteration :: solveYourselfAt: current eigen values of reduced problem \n"); eigv.printYourself(); printf("SubspaceIteration :: solveYourselfAt: current eigen vectors of reduced problem \n"); vec.printYourself(); # endif // // compute eigenvectors // for ( i = 1; i <= nn; i++ ) { // label 375 for ( j = 1; j <= nc; j++ ) { tt.at(j) = r.at(i, j); } for ( k = 1; k <= nc; k++ ) { rt = 0.; for ( j = 1; j <= nc; j++ ) { rt += tt.at(j) * vec.at(j, k); } r.at(i, k) = rt; } } // label 420 (r = z) // // convergency check // for ( i = 1; i <= nc; i++ ) { dif = ( eigv.at(i) - d.at(i) ); rtolv.at(i) = fabs( dif / eigv.at(i) ); } # ifdef DETAILED_REPORT printf("SubspaceIteration :: solveYourselfAt: Reached precision of eigenvalues:\n"); rtolv.printYourself(); # endif for ( i = 1; i <= nroot; i++ ) { if ( rtolv.at(i) > rtol ) { goto label400; } } fprintf(outStream, "SubspaceIteration :: solveYourselfAt: Convergence reached for RTOL=%20.15f", rtol); break; label400: if ( nite >= nitem ) { fprintf(outStream, " SubspaceIteration :: solveYourselfAt: Convergence not reached in %d iteration - using current values", nitem); break; } for ( i = 1; i <= nc; i++ ) { d.at(i) = eigv.at(i); // label 410 and 440 } continue; } // compute eigenvectors for ( j = 1; j <= nc; j++ ) { for ( k = 1; k <= nn; k++ ) { tt.at(k) = r.at(k, j); } a.backSubstitutionWith(tt); for ( k = 1; k <= nn; k++ ) { r.at(k, j) = tt.at(k); // (r = xbar) } } // one cad add a normalization of eigen-vectors here for ( i = 1; i <= nroot; i++ ) { _eigv.at(i) = eigv.at(i); for ( j = 1; j <= nn; j++ ) { _r.at(j, i) = r.at(j, i); } } solved = 1; return NM_Success; }
///////////////////////////////////////////////// // Help functions void GnuplotExportModule::outputReactionForces(TimeStep *tStep) { // Add sum of reaction forces to arrays // Compute sum of reaction forces for each BC number Domain *domain = emodel->giveDomain(1); StructuralEngngModel *seMod = dynamic_cast<StructuralEngngModel* >(emodel); if(seMod == NULL) { OOFEM_ERROR("failed to cast to StructuralEngngModel."); } FloatArray reactions; IntArray dofManMap, dofidMap, eqnMap; // test if solution step output is active if ( !testTimeStepOutput(tStep) ) { return; } // map contains corresponding dofmanager and dofs numbers corresponding to prescribed equations // sorted according to dofmanger number and as a minor crit. according to dof number // this is necessary for extractor, since the sorted output is expected seMod->buildReactionTable(dofManMap, dofidMap, eqnMap, tStep, 1); // compute reaction forces seMod->computeReaction(reactions, tStep, 1); // Find highest index of prescribed dofs int maxIndPresDof = 0; for ( int i = 1; i <= dofManMap.giveSize(); i++ ) { maxIndPresDof = std::max(maxIndPresDof, dofidMap.at(i)); } int numBC = domain->giveNumberOfBoundaryConditions(); while ( mReactionForceHistory.size() < size_t(numBC) ) { std::vector<FloatArray> emptyArray; mReactionForceHistory.push_back( emptyArray ); } maxIndPresDof = domain->giveNumberOfSpatialDimensions(); while ( mDispHist.size() < size_t(numBC) ) { std::vector<double> emptyArray; mDispHist.push_back( emptyArray ); } for(int bcInd = 0; bcInd < numBC; bcInd++) { FloatArray fR(maxIndPresDof), disp(numBC); fR.zero(); for ( int i = 1; i <= dofManMap.giveSize(); i++ ) { DofManager *dMan = domain->giveDofManager( dofManMap.at(i) ); Dof *dof = dMan->giveDofWithID( dofidMap.at(i) ); if ( dof->giveBcId() == bcInd+1 ) { fR.at( dofidMap.at(i) ) += reactions.at( eqnMap.at(i) ); // Slightly dirty BoundaryCondition *bc = dynamic_cast<BoundaryCondition*> (domain->giveBc(bcInd+1)); if ( bc != NULL ) { disp.at(bcInd+1) = bc->give(dof, VM_Total, tStep->giveTargetTime()); } ///@todo This function should be using the primaryfield instead of asking BCs directly. / Mikael } } mDispHist[bcInd].push_back(disp.at(bcInd+1)); mReactionForceHistory[bcInd].push_back(fR); // X FILE * pFileX; char fileNameX[100]; sprintf(fileNameX, "ReactionForceGnuplotBC%dX.dat", bcInd+1); pFileX = fopen ( fileNameX , "wb" ); fprintf(pFileX, "#u Fx\n"); for ( size_t j = 0; j < mDispHist[bcInd].size(); j++ ) { fprintf(pFileX, "%e %e\n", mDispHist[bcInd][j], mReactionForceHistory[bcInd][j].at(1) ); } fclose(pFileX); // Y FILE * pFileY; char fileNameY[100]; sprintf(fileNameY, "ReactionForceGnuplotBC%dY.dat", bcInd+1); pFileY = fopen ( fileNameY , "wb" ); fprintf(pFileY, "#u Fx\n"); for ( size_t j = 0; j < mDispHist[bcInd].size(); j++ ) { if( mReactionForceHistory[bcInd][j].giveSize() >= 2 ) { fprintf(pFileY, "%e %e\n", mDispHist[bcInd][j], mReactionForceHistory[bcInd][j].at(2) ); } } fclose(pFileY); } }
void FEI3dHexaQuad :: computeLocalEdgeMapping(IntArray &edgeNodes, int iedge) { OOFEM_ERROR("FEI3dHexaQuad :: computeLocalEdgeMapping not implemented"); }
/* * should be called after basic local migration is finalized, * when all local elements are already available */ void NonlocalMaterialWTP :: migrate() { Domain *domain = this->lb->giveDomain(); EngngModel *emodel = domain->giveEngngModel(); int nproc = emodel->giveNumberOfProcesses(); int myrank = emodel->giveRank(); CommunicatorBuff cb(nproc, CBT_dynamic); Communicator com(emodel, &cb, myrank, nproc, CommMode_Dynamic); StaticCommunicationBuffer commBuff(MPI_COMM_WORLD); /* * build domain nonlocal element dependency list. Then exclude local elements - what remains are unsatisfied * remote dependencies that have to be broadcasted and received from partitions owning relevant elements */ int _locsize, i, _i, ie, _size, _globnum, result, nelems = domain->giveNumberOfElements(); int _globsize, _val; Element *elem; std :: set< int >domainElementDepSet; // loop over each element dep list to assemble domain list for ( ie = 1; ie <= nelems; ie++ ) { elem = domain->giveElement(ie); if ( ( elem->giveParallelMode() == Element_local ) ) { _globnum = elem->giveGlobalNumber(); IntArray &iedep = nonlocElementDependencyMap [ _globnum ]; _size = iedep.giveSize(); for ( _i = 1; _i <= _size; _i++ ) { domainElementDepSet.insert( iedep.at(_i) ); } #if NonlocalMaterialWTP_DEBUG_PRINT fprintf(stderr, "[%d] element %d dependency:", myrank, _globnum); for ( _i = 1; _i <= _size; _i++ ) { fprintf( stderr, "%d ", iedep.at(_i) ); } fprintf(stderr, "\n"); #endif } } #if NonlocalMaterialWTP_DEBUG_PRINT fprintf(stderr, "[%d] nonlocal domain dependency:", myrank); for ( int eldep: domainElementDepSet ) { fprintf(stderr, "%d ", eldep); } fprintf(stderr, "\n"); #endif // now exclude local elements (local dependency is always satisfied) for ( _i = 1; _i <= nelems; _i++ ) { elem = domain->giveElement(_i); if ( elem->giveParallelMode() == Element_local ) { domainElementDepSet.erase( elem->giveGlobalNumber() ); } } #if NonlocalMaterialWTP_DEBUG_PRINT fprintf(stderr, "[%d] remote elem wish list:", myrank); for ( int eldep: domainElementDepSet ) { fprintf(stderr, "%d ", eldep); } fprintf(stderr, "\n"); #endif // broadcast remaining elements (unsatisfied domain nonlocal dependency) to remaining partitions _locsize = domainElementDepSet.size() + 1; result = MPI_Allreduce(& _locsize, & _globsize, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD); if ( result != MPI_SUCCESS ) { OOFEM_ERROR("MPI_Allreduce to determine broadcast buffer size failed"); } commBuff.resize( commBuff.givePackSize(MPI_INT, _globsize) ); // remote domain wish list std :: set< int >remoteWishSet; toSendList.resize(nproc); for ( i = 0; i < nproc; i++ ) { // loop over partitions commBuff.init(); toSendList [ i ].clear(); if ( i == myrank ) { // current domain has to send its receive wish list to all domains commBuff.packInt(_locsize); for ( int eldep: domainElementDepSet ) { commBuff.packInt(eldep); } result = commBuff.bcast(i); } else { // unpack remote domain wish list remoteWishSet.clear(); result = commBuff.bcast(i); // unpack size commBuff.unpackInt(_size); for ( _i = 1; _i < _size; _i++ ) { commBuff.unpackInt(_val); remoteWishSet.insert(_val); } // determine which local elements are to be sent to remotepartition for ( _i = 1; _i <= nelems; _i++ ) { elem = domain->giveElement(_i); if ( elem->giveParallelMode() == Element_local ) { if ( remoteWishSet.find( elem->giveGlobalNumber() ) != remoteWishSet.end() ) { // store local element number toSendList [ i ].push_back(_i); } } } } } // end loop over partitions broadcast #if NonlocalMaterialWTP_DEBUG_PRINT for ( i = 0; i < nproc; i++ ) { // loop over partitions // print some info fprintf(stderr, "[%d] elements scheduled for mirroring at [%d]:", myrank, i); for ( int elnum: toSendList [ i ] ) { fprintf( stderr, "%d[%d] ", elnum, domain->giveElement(elnum)->giveGlobalNumber() ); } fprintf(stderr, "\n"); } #endif com.packAllData(this, domain, & NonlocalMaterialWTP :: packRemoteElements); com.initExchange(MIGRATE_REMOTE_ELEMENTS_TAG); com.unpackAllData(this, domain, & NonlocalMaterialWTP :: unpackRemoteElements); com.finishExchange(); domain->commitTransactions( domain->giveTransactionManager() ); #ifdef __VERBOSE_PARALLEL VERBOSEPARALLEL_PRINT("NonlocalMaterialWTP::migrate", "Finished migrating remote elements", myrank); #endif }
int PiecewiseLinFunctionBlock :: giveInputRecordString(std :: string &str, bool keyword) { OOFEM_ERROR("Not implemented"); return 1; }
void Tria1PlateSubSoil :: computeLumpedMassMatrix(FloatMatrix &answer, TimeStep *tStep) // Returns the lumped mass matrix of the receiver. { OOFEM_ERROR("Mass matrix not provided"); }
IRResultType NonlocalMaterialExtensionInterface :: initializeFrom(InputRecord *ir) { IRResultType result; // Required by IR_GIVE_FIELD macro if ( ir->hasField(_IFT_NonlocalMaterialExtensionInterface_regionmap) ) { IR_GIVE_FIELD(ir, regionMap, _IFT_NonlocalMaterialExtensionInterface_regionmap); if ( regionMap.giveSize() != this->giveDomain()->giveNumberOfRegions() ) { OOFEM_ERROR("regionMap size mismatch"); } } else { regionMap.zero(); } if ( this->hasBoundedSupport() ) { permanentNonlocTableFlag = true; } else { permanentNonlocTableFlag = false; } IR_GIVE_OPTIONAL_FIELD(ir, this->permanentNonlocTableFlag, _IFT_NonlocalMaterialExtensionInterface_permanentNonlocTableFlag); // read the characteristic length IR_GIVE_FIELD(ir, cl, _IFT_NonlocalMaterialExtensionInterface_r); if ( cl < 0.0 ) { cl = 0.0; } // read the type of weight function int val = WFT_Bell; IR_GIVE_OPTIONAL_FIELD(ir, val, _IFT_NonlocalMaterialExtensionInterface_wft); this->weightFun = ( WeightFunctionType ) val; // this is introduced for compatibility of input format with previous versions // ("averagingtype 1" in the input means that the weight function // should be uniform over an element, // which can now be described as "wft 5") int avt = 0; IR_GIVE_OPTIONAL_FIELD(ir, avt, _IFT_NonlocalMaterialExtensionInterface_averagingtype); if ( avt == 1 ) { weightFun = WFT_UniformOverElement; } // evaluate the support radius based on type of weight function and characteristic length suprad = evaluateSupportRadius(); // read the optional parameter for overnonlocal formulation mm = 1.; IR_GIVE_OPTIONAL_FIELD(ir, mm, _IFT_NonlocalMaterialExtensionInterface_m); // read the type of scaling val = ST_Standard; IR_GIVE_OPTIONAL_FIELD(ir, val, _IFT_NonlocalMaterialExtensionInterface_scalingtype); this->scaling = ( ScalingType ) val; // read the type of averaged variable val = AVT_EqStrain; IR_GIVE_OPTIONAL_FIELD(ir, val, _IFT_NonlocalMaterialExtensionInterface_averagedquantity); this->averagedVar = ( AveragedVarType ) val; // read the nonlocal variation type (default is zero) cl0 = cl; int nlvariation = 0; IR_GIVE_OPTIONAL_FIELD(ir, nlvariation, _IFT_NonlocalMaterialExtensionInterface_nonlocalvariation); if ( nlvariation == 1 ) { nlvar = NLVT_DistanceBasedLinear; IR_GIVE_FIELD(ir, beta, _IFT_NonlocalMaterialExtensionInterface_beta); IR_GIVE_FIELD(ir, zeta, _IFT_NonlocalMaterialExtensionInterface_zeta); } else if ( nlvariation == 2 ) { nlvar = NLVT_StressBased; IR_GIVE_FIELD(ir, beta, _IFT_NonlocalMaterialExtensionInterface_beta); } else if ( nlvariation == 3 ) { nlvar = NLVT_DistanceBasedExponential; IR_GIVE_FIELD(ir, beta, _IFT_NonlocalMaterialExtensionInterface_beta); IR_GIVE_FIELD(ir, zeta, _IFT_NonlocalMaterialExtensionInterface_zeta); } // read the periodic shift (default is zero) px = 0.; IR_GIVE_OPTIONAL_FIELD(ir, px, _IFT_NonlocalMaterialExtensionInterface_px); return IRRT_OK; }
void Tria1PlateSubSoil :: computeBodyLoadVectorAt(FloatArray &answer, Load *forLoad, TimeStep *tStep, ValueModeType mode) { OOFEM_ERROR("Body load not supported, use surface load instead"); }
void LSPrimaryVariableMapper :: mapPrimaryVariables(FloatArray &oU, Domain &iOldDom, Domain &iNewDom, ValueModeType iMode, TimeStep &iTStep) { EngngModel *engngMod = iNewDom.giveEngngModel(); EModelDefaultEquationNumbering num; const int dim = iNewDom.giveNumberOfSpatialDimensions(); int numElNew = iNewDom.giveNumberOfElements(); // Count dofs int numDofsNew = engngMod->giveNumberOfDomainEquations( 1, num ); oU.resize(numDofsNew); oU.zero(); FloatArray du(numDofsNew); du.zero(); FloatArray res(numDofsNew); #ifdef __PETSC_MODULE PetscSparseMtrx *K = dynamic_cast<PetscSparseMtrx*>( classFactory.createSparseMtrx(SMT_PetscMtrx) ); SparseLinearSystemNM *solver = classFactory.createSparseLinSolver(ST_Petsc, & iOldDom, engngMod); #else SparseMtrx *K = classFactory.createSparseMtrx(SMT_Skyline); SparseLinearSystemNM *solver = classFactory.createSparseLinSolver(ST_Direct, & iOldDom, engngMod); #endif K->buildInternalStructure( engngMod, 1, num ); int maxIter = 1; for ( int iter = 0; iter < maxIter; iter++ ) { K->zero(); res.zero(); // Contribution from elements for ( int elIndex = 1; elIndex <= numElNew; elIndex++ ) { StructuralElement *elNew = dynamic_cast< StructuralElement * >( iNewDom.giveElement(elIndex) ); if ( elNew == NULL ) { OOFEM_ERROR("Failed to cast Element new to StructuralElement."); } /////////////////////////////////// // Compute residual // Count element dofs int numElNodes = elNew->giveNumberOfDofManagers(); int numElDofs = 0; for ( int i = 1; i <= numElNodes; i++ ) { numElDofs += elNew->giveDofManager(i)->giveNumberOfDofs(); } FloatArray elRes(numElDofs); elRes.zero(); IntArray elDofsGlob; elNew->giveLocationArray( elDofsGlob, num ); // Loop over Gauss points for ( int intRuleInd = 0; intRuleInd < elNew->giveNumberOfIntegrationRules(); intRuleInd++ ) { IntegrationRule *iRule = elNew->giveIntegrationRule(intRuleInd); for ( GaussPoint *gp: *iRule ) { // New N-matrix FloatMatrix NNew; elNew->computeNmatrixAt(* ( gp->giveNaturalCoordinates() ), NNew); ////////////// // Global coordinates of GP const int nDofMan = elNew->giveNumberOfDofManagers(); FloatArray Nc; FEInterpolation *interp = elNew->giveInterpolation(); const FloatArray &localCoord = * ( gp->giveNaturalCoordinates() ); interp->evalN( Nc, localCoord, FEIElementGeometryWrapper(elNew) ); const IntArray &elNodes = elNew->giveDofManArray(); FloatArray globalCoord(dim); globalCoord.zero(); for ( int i = 1; i <= nDofMan; i++ ) { DofManager *dMan = elNew->giveDofManager(i); for ( int j = 1; j <= dim; j++ ) { globalCoord.at(j) += Nc.at(i) * dMan->giveCoordinate(j); } } ////////////// // Localize element and point in the old domain FloatArray localCoordOld(dim), pointCoordOld(dim); StructuralElement *elOld = dynamic_cast< StructuralElement * >( iOldDom.giveSpatialLocalizer()->giveElementClosestToPoint(localCoordOld, pointCoordOld, globalCoord, 0) ); if ( elOld == NULL ) { OOFEM_ERROR("Failed to cast Element old to StructuralElement."); } // Compute N-Matrix for the old element FloatMatrix NOld; elOld->computeNmatrixAt(localCoordOld, NOld); // Fetch nodal displacements for the new element FloatArray nodeDispNew( elDofsGlob.giveSize() ); int dofsPassed = 1; for ( int i = 1; i <= elNodes.giveSize(); i++ ) { DofManager *dMan = elNew->giveDofManager(i); for ( Dof *dof: *dMan ) { if ( elDofsGlob.at(dofsPassed) != 0 ) { nodeDispNew.at(dofsPassed) = oU.at( elDofsGlob.at(dofsPassed) ); } else { if ( dof->hasBc(& iTStep) ) { nodeDispNew.at(dofsPassed) = dof->giveBcValue(iMode, & iTStep); } } dofsPassed++; } } FloatArray newDisp; newDisp.beProductOf(NNew, nodeDispNew); // Fetch nodal displacements for the old element FloatArray nodeDispOld; dofsPassed = 1; IntArray elDofsGlobOld; elOld->giveLocationArray( elDofsGlobOld, num ); // elOld->computeVectorOf(iMode, &(iTStep), nodeDisp); int numElNodesOld = elOld->giveNumberOfDofManagers(); for(int nodeIndOld = 1; nodeIndOld <= numElNodesOld; nodeIndOld++) { DofManager *dManOld = elOld->giveDofManager(nodeIndOld); for ( Dof *dof: *dManOld ) { if ( elDofsGlobOld.at(dofsPassed) != 0 ) { FloatArray dofUnknowns; dof->giveUnknowns(dofUnknowns, iMode, &iTStep); #ifdef DEBUG if(!dofUnknowns.isFinite()) { OOFEM_ERROR("!dofUnknowns.isFinite()") } if(dofUnknowns.giveSize() < 1) { OOFEM_ERROR("dofUnknowns.giveSize() < 1") } #endif nodeDispOld.push_back(dofUnknowns.at(1)); } else { if ( dof->hasBc(& iTStep) ) { // printf("hasBC.\n"); #ifdef DEBUG if(!std::isfinite(dof->giveBcValue(iMode, & iTStep))) { OOFEM_ERROR("!std::isfinite(dof->giveBcValue(iMode, & iTStep))") } #endif nodeDispOld.push_back( dof->giveBcValue(iMode, & iTStep) ); } else { // printf("Unhandled case in LSPrimaryVariableMapper :: mapPrimaryVariables().\n"); nodeDispOld.push_back( 0.0 ); } } dofsPassed++; } } FloatArray oldDisp; oldDisp.beProductOf(NOld, nodeDispOld); FloatArray temp, du; #ifdef DEBUG if(!oldDisp.isFinite()) { OOFEM_ERROR("!oldDisp.isFinite()") } if(!newDisp.isFinite()) { OOFEM_ERROR("!newDisp.isFinite()") } #endif du.beDifferenceOf(oldDisp, newDisp); temp.beTProductOf(NNew, du); double dV = elNew->computeVolumeAround(gp); elRes.add(dV, temp); } }
void FEI3dHexaQuad :: edgeEvalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) { OOFEM_ERROR("FEI3dHexaQuad :: edgeEvalN not implemented"); }
void IDGMaterial :: giveInternalLength(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) { if ( averType == 0 ) { answer.resize(1, 1); answer.at(1, 1) = cl; } else if ( averType == 1 ) { answer.resize(1, 1); FloatArray gpCoords; if ( gp->giveElement()->computeGlobalCoordinates( gpCoords, gp->giveNaturalCoordinates() ) == 0 ) { OOFEM_ERROR("computeGlobalCoordinates of GP failed"); } this->giveDistanceBasedCharacteristicLength(gpCoords); answer.at(1, 1) = cl; } else if ( averType == 2 ) { MaterialMode mMode = gp->giveMaterialMode(); if ( mMode == _PlaneStress ) { answer.resize(2, 2); answer.zero(); IDGMaterialStatus *status = static_cast< IDGMaterialStatus * >( this->giveStatus(gp) ); FloatArray stress = status->giveTempStressVector(); StressVector fullStress(stress, _PlaneStress); FloatArray sigPrinc; FloatMatrix nPrinc; // get principal stresses (ordered) and principal stress directions fullStress.computePrincipalValDir(sigPrinc, nPrinc); if ( nPrinc.giveNumberOfRows() == 0 ) { nPrinc.resize(2, 2); nPrinc.at(1, 1) = 1; nPrinc.at(2, 2) = 1; } // principal internal lengths double l1 = cl0; double l2 = cl0; double gamma; if ( sigPrinc.at(1) > 0 ) { if ( sigPrinc.at(2) > 0 ) { gamma = beta + ( 1 - beta ) * sigPrinc.at(2) * sigPrinc.at(2) / ( sigPrinc.at(1) * sigPrinc.at(1) ); } else { gamma = beta; } } else { gamma = 1; } l2 = l2 * gamma; // compose the internal Length matrix in global coordinates // the first subscript refers to coordinate // the second subscript refers to eigenvalue double n11 = nPrinc.at(1, 1); double n12 = nPrinc.at(1, 2); double n21 = nPrinc.at(2, 1); double n22 = nPrinc.at(2, 2); answer.at(1, 1) = l1 * l1 * n11 * n11 + l2 * l2 * n12 * n12; answer.at(1, 2) = l1 * l1 * n11 * n21 + l2 * l2 * n12 * n22; answer.at(2, 1) = l1 * l1 * n11 * n21 + l2 * l2 * n12 * n22; answer.at(2, 2) = l1 * l1 * n21 * n21 + l2 * l2 * n22 * n22; } else { OOFEM_ERROR("Unknown material mode."); } } }
void FEI3dHexaQuad :: edgeEvaldNdx(FloatMatrix &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) { OOFEM_ERROR("FEI3dHexaQuad :: edgeEvaldNdx not implemented"); }
void TR_SHELL02 :: computeBodyLoadVectorAt(FloatArray &answer, Load *forLoad, TimeStep *tStep, ValueModeType mode) { OOFEM_ERROR("This function is not implemented yet."); }
void FEI3dHexaQuad :: edgeLocal2global(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) { OOFEM_ERROR("FEI3dHexaQuad :: edgeLocal2global not implemented"); }
void SUPGElement2 :: giveCharacteristicVector(FloatArray &answer, CharType mtrx, ValueModeType mode, TimeStep *tStep) // // returns characteristics vector of receiver according to requested type // { if ( mtrx == ExternalForcesVector ) { // stokes flow IntArray vloc, ploc; FloatArray h; int size = this->computeNumberOfDofs(); this->giveLocalVelocityDofMap(vloc); this->giveLocalPressureDofMap(ploc); answer.resize(size); answer.zero(); this->computeBCRhsTerm_MB(h, tStep); answer.assemble(h, vloc); this->computeBCRhsTerm_MC(h, tStep); answer.assemble(h, ploc); } else #if 0 if ( mtrx == InternalForcesVector ) { // stokes flow IntArray vloc, ploc; FloatArray h; int size = this->computeNumberOfDofs(); this->giveLocalVelocityDofMap(vloc); this->giveLocalPressureDofMap(ploc); answer.resize(size); answer.zero(); this->computeAdvectionTerm_MB(h, tStep); answer.assemble(h, vloc); this->computeAdvectionTerm_MC(h, tStep); answer.assemble(h, ploc); this->computeDiffusionTerm_MB(h, tStep); answer.assemble(h, vloc); this->computeDiffusionTerm_MC(h, tStep); answer.assemble(h, ploc); FloatMatrix m1; FloatArray v, p; // add lsic stabilization term this->giveCharacteristicMatrix(m1, LSICStabilizationTerm_MB, tStep); //m1.times( lscale / ( dscale * uscale * uscale ) ); this->computeVectorOfVelocities(VM_Total, tStep, v); h.beProductOf(m1, v); answer.assemble(h, vloc); this->giveCharacteristicMatrix(m1, LinearAdvectionTerm_MC, tStep); //m1.times( 1. / ( dscale * uscale ) ); h.beProductOf(m1, v); answer.assemble(h, ploc); // add pressure term this->giveCharacteristicMatrix(m1, PressureTerm_MB, tStep); this->computeVectorOfPressures(VM_Total, tStep, v); h.beProductOf(m1, v); answer.assemble(h, vloc); // pressure term this->giveCharacteristicMatrix(m1, PressureTerm_MC, tStep); this->computeVectorOfPressures(VM_Total, tStep, v); h.beProductOf(m1, v); answer.assemble(h, ploc); } else #endif { OOFEM_ERROR("Unknown Type of characteristic mtrx."); } }
double FEI3dHexaQuad :: edgeGiveTransformationJacobian(int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) { OOFEM_ERROR("FEI3dHexaQuad :: edgeGiveTransformationJacobian not implemented"); return 0.0; }
double LocalGaussianRandomGenerator :: normal01CdfInverse(double p) { double a [ 8 ] = { 3.3871328727963666080, 1.3314166789178437745e+2, 1.9715909503065514427e+3, 1.3731693765509461125e+4, 4.5921953931549871457e+4, 6.7265770927008700853e+4, 3.3430575583588128105e+4, 2.5090809287301226727e+3 }; double b [ 8 ] = { 1.0, 4.2313330701600911252e+1, 6.8718700749205790830e+2, 5.3941960214247511077e+3, 2.1213794301586595867e+4, 3.9307895800092710610e+4, 2.8729085735721942674e+4, 5.2264952788528545610e+3 }; double c [ 8 ] = { 1.42343711074968357734, 4.63033784615654529590, 5.76949722146069140550, 3.64784832476320460504, 1.27045825245236838258, 2.41780725177450611770e-1, 2.27238449892691845833e-2, 7.74545014278341407640e-4 }; double const1 = 0.180625; double const2 = 1.6; double d [ 8 ] = { 1.0, 2.05319162663775882187, 1.67638483018380384940, 6.89767334985100004550e-1, 1.48103976427480074590e-1, 1.51986665636164571966e-2, 5.47593808499534494600e-4, 1.05075007164441684324e-9 }; double e [ 8 ] = { 6.65790464350110377720, 5.46378491116411436990, 1.78482653991729133580, 2.96560571828504891230e-1, 2.65321895265761230930e-2, 1.24266094738807843860e-3, 2.71155556874348757815e-5, 2.01033439929228813265e-7 }; double f [ 8 ] = { 1.0, 5.99832206555887937690e-1, 1.36929880922735805310e-1, 1.48753612908506148525e-2, 7.86869131145613259100e-4, 1.84631831751005468180e-5, 1.42151175831644588870e-7, 2.04426310338993978564e-15 }; double q; double r; double split1 = 0.425; double split2 = 5.0; double value; if ( p <= 0.0 ) { value = -HUGE_VAL; return value; } if ( 1.0 <= p ) { value = HUGE_VAL; return value; } q = p - 0.5; if ( fabs(q) <= split1 ) { r = const1 - q * q; value = q * dpolyValue(8, a, r) / dpolyValue(8, b, r); } else { if ( q < 0.0 ) { r = p; } else { r = 1.0 - p; } if ( r <= 0.0 ) { OOFEM_ERROR("r < 0.0!"); return -1.0; } r = sqrt( -log(r) ); if ( r <= split2 ) { r = r - const2; value = dpolyValue(8, c, r) / dpolyValue(8, d, r); } else { r = r - split2; value = dpolyValue(8, e, r) / dpolyValue(8, f, r); } if ( q < 0.0 ) { value = -value; } } return value; }
int ZZRemeshingCriteria :: estimateMeshDensities(TimeStep *tStep) { int nelem, nnode, elemPolyOrder, ielemNodes; double globValNorm = 0.0, globValErrorNorm = 0.0, elemErrLimit, eerror, iratio, currDensity, elemSize; EE_ErrorType errorType = indicatorET; double pe, coeff = 2.0; if ( stateCounter == tStep->giveSolutionStateCounter() ) { return 1; } nelem = this->domain->giveNumberOfElements(); nnode = this->domain->giveNumberOfDofManagers(); //std::vector<char> nodalDensities(nnode); this->nodalDensities.resize(nnode); std :: vector< char > dofManInitFlag(nnode); for ( int i = 0; i < nnode; i++ ) { dofManInitFlag [ i ] = 0; } // compute element error limit based on equally distribution error principle if ( mode == stressBased ) { globValNorm = this->ee->giveValue(globalNormEEV, tStep); globValErrorNorm = this->ee->giveValue(globalErrorEEV, tStep); errorType = internalStressET; } else { OOFEM_ERROR("unknown mode"); } // test if solution is allowable pe = sqrt( globValErrorNorm * globValErrorNorm / ( globValErrorNorm * globValErrorNorm + globValNorm * globValNorm ) ); if ( pe <= this->requiredError ) { this->remeshingStrategy = NoRemeshing_RS; // added by bp /* * for (i=1; i<=nnode; i++) nodalDensities.at(i) = this->giveDofManDensity (i); * stateCounter = tStep->giveSolutionStateCounter(); * return 1; // remove to force computing densities */ } else { this->remeshingStrategy = RemeshingFromPreviousState_RS; } elemErrLimit = sqrt( ( globValNorm * globValNorm + globValErrorNorm * globValErrorNorm ) / nelem ) * this->requiredError * coeff; for ( auto &elem : domain->giveElements() ) { if ( this->ee->skipRegion( elem->giveRegionNumber() ) ) { continue; } eerror = this->ee->giveElementError(errorType, elem.get(), tStep); iratio = eerror / elemErrLimit; if ( fabs(iratio) < 1.e-3 ) { continue; } if ( iratio > 1.0 ) { this->remeshingStrategy = RemeshingFromPreviousState_RS; } if ( iratio < 0.5 ) { iratio = 0.5; } // if (iratio > 5.0)iratio = 5.0; currDensity = elem->computeMeanSize(); elemPolyOrder = elem->giveInterpolation()->giveInterpolationOrder(); elemSize = currDensity / pow(iratio, 1.0 / elemPolyOrder); ielemNodes = elem->giveNumberOfDofManagers(); for ( int j = 1; j <= ielemNodes; j++ ) { int jnode = elem->giveDofManager(j)->giveNumber(); if ( dofManInitFlag [ jnode - 1 ] ) { this->nodalDensities.at(jnode) = min(this->nodalDensities.at(jnode), elemSize); } else { this->nodalDensities.at(jnode) = elemSize; dofManInitFlag [ jnode - 1 ] = 1; } } } // init non-initialized nodes -> those in skip regions for ( int i = 0; i < nnode; i++ ) { if ( dofManInitFlag [ i ] == 0 ) { this->nodalDensities.at(i + 1) = this->giveDofManDensity(i + 1); } } // remember time stamp stateCounter = tStep->giveSolutionStateCounter(); return 1; }