int SmoothedNodalInternalVariableField :: evaluateAt(FloatArray &answer, FloatArray &coords, ValueModeType mode, TimeStep *tStep) { int result = 0; // assume ok FloatArray lc, n; const FloatArray *nodalValue; // use whole domain recovery // create a new set containing all elements Set elemSet(0, this->domain); elemSet.addAllElements(); this->smoother->recoverValues(elemSet, istType, tStep); // request element containing target point Element *elem = this->domain->giveSpatialLocalizer()->giveElementContainingPoint(coords); if ( elem ) { // ok element containing target point found FEInterpolation *interp = elem->giveInterpolation(); if ( interp ) { // map target point to element local coordinates if ( interp->global2local( lc, coords, FEIElementGeometryWrapper(elem) ) ) { // evaluate interpolation functions at target point interp->evalN( n, lc, FEIElementGeometryWrapper(elem) ); // loop over element nodes for ( int i = 1; i <= n.giveSize(); i++ ) { // request nodal value this->smoother->giveNodalVector( nodalValue, elem->giveDofManagerNumber(i) ); // multiply nodal value by value of corresponding shape function and add this to answer answer.add(n.at(i), * nodalValue); } } else { // mapping from global to local coordinates failed result = 1; // failed } } else { // element without interpolation result = 1; // failed } } else { // no element containing given point found result = 1; // failed } return result; }
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; }
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 } } }