void StructuralFE2MaterialStatus :: copyStateVariables(const MaterialStatus &iStatus) { //static int num = 0; //printf("Entering StructuralFE2MaterialStatus :: copyStateVariables.\n"); this->oldTangent = true; // if ( !this->createRVE(this->giveNumber(), gp, mInputFile) ) { // OOFEM_ERROR("Couldn't create RVE"); // } StructuralMaterialStatus :: copyStateVariables(iStatus); ////////////////////////////// MaterialStatus &tmpStat = const_cast< MaterialStatus & >(iStatus); StructuralFE2MaterialStatus *fe2ms = dynamic_cast<StructuralFE2MaterialStatus*>(&tmpStat); if ( !fe2ms ) { OOFEM_ERROR("Failed to cast StructuralFE2MaterialStatus.") } this->mNewlyInitialized = fe2ms->mNewlyInitialized; // The proper way to do this would be to clone the RVE from iStatus. // However, this is a mess due to all pointers that need to be tracked. // Therefore, we consider a simplified version: copy only the enrichment items. Domain *ext_domain = fe2ms->giveRVE()->giveDomain(1); if ( ext_domain->hasXfemManager() ) { Domain *rve_domain = rve->giveDomain(1); XfemManager *ext_xMan = ext_domain->giveXfemManager(); XfemManager *this_xMan = rve->giveDomain(1)->giveXfemManager(); DynamicDataReader dataReader("fe2"); if ( ext_xMan != NULL ) { IRResultType result; // Required by IR_GIVE_FIELD macro std::vector<std::unique_ptr<EnrichmentItem>> eiList; //DynamicInputRecord *xmanRec = new DynamicInputRecord(); //ext_xMan->giveInputRecord(* xmanRec); //dataReader.insertInputRecord(DataReader :: IR_xfemManRec, xmanRec); // Enrichment items int nEI = ext_xMan->giveNumberOfEnrichmentItems(); for ( int i = 1; i <= nEI; i++ ) { EnrichmentItem *ext_ei = ext_xMan->giveEnrichmentItem(i); ext_ei->appendInputRecords(dataReader); InputRecord *mir = dataReader.giveInputRecord(DataReader :: IR_enrichItemRec, i); std :: string name; result = mir->giveRecordKeywordField(name); if ( result != IRRT_OK ) { mir->report_error(this->giveClassName(), __func__, "", result, __FILE__, __LINE__); } std :: unique_ptr< EnrichmentItem >ei( classFactory.createEnrichmentItem( name.c_str(), i, this_xMan, rve_domain ) ); if ( ei.get() == NULL ) { OOFEM_ERROR( "unknown enrichment item (%s)", name.c_str() ); } ei->initializeFrom(mir); ei->instanciateYourself(dataReader); eiList.push_back( std :: move(ei) ); } this_xMan->clearEnrichmentItems(); this_xMan->appendEnrichmentItems(eiList); rve_domain->postInitialize(); rve->forceEquationNumbering(); } } //printf("done.\n"); #if 0 Domain *newDomain = fe2ms->giveRVE()->giveDomain(1)->Clone(); newDomain->SetEngngModel(rve.get()); bool deallocateOld = true; rve->setDomain(1, newDomain, deallocateOld); //rve->giveDomain(1)->postInitialize(); rve->giveNumericalMethod(NULL)->setDomain(newDomain); rve->postInitialize(); //rve->forceEquationNumbering(); rve->initMetaStepAttributes( rve->giveMetaStep(1) ); rve->giveNextStep(); // Makes sure there is a timestep (which we will modify before solving a step) rve->init(); // std :: ostringstream name; // name << this->rve->giveOutputBaseFileName() << "-gp" << n; // this->rve->letOutputBaseFileNameBe( name.str() ); // n++; double crackLength = 0.0; XfemStructureManager *xMan = dynamic_cast<XfemStructureManager*>( rve->giveDomain(1)->giveXfemManager() ); if ( xMan ) { crackLength = xMan->computeTotalCrackLength(); } std :: ostringstream name; name << this->rve->giveOutputBaseFileName() << "-gp" << num << "crackLength" << crackLength; if ( this->domain->giveEngngModel()->isParallel() && this->domain->giveEngngModel()->giveNumberOfProcesses() > 1 ) { name << "." << this->domain->giveEngngModel()->giveRank(); } num++; this->rve->letOutputBaseFileNameBe( name.str() ); // Update BC this->bc = dynamic_cast< PrescribedGradientHomogenization * >( this->rve->giveDomain(1)->giveBc(1) ); #if 1 XfemSolverInterface *xfemSolInt = dynamic_cast<XfemSolverInterface*>(rve.get()); StaticStructural *statStruct = dynamic_cast<StaticStructural*>(rve.get()); if ( xfemSolInt && statStruct ) { //printf("Successfully casted to XfemSolverInterface.\n"); TimeStep *tStep = rve->giveCurrentStep(); EModelDefaultEquationNumbering num; int numDofsNew = rve->giveNumberOfDomainEquations( 1, num ); FloatArray u; u.resize(numDofsNew); u.zero(); xfemSolInt->xfemUpdatePrimaryField(*statStruct, tStep, u); // Set domain pointer to various components ... rve->giveNumericalMethod(NULL)->setDomain(newDomain); //ioEngngModel.nMethod->setDomain(domain); } // TimeStep *tStep = rve->giveNextStep(); // setTimeStep(tStep); // rve->solveYourselfAt(tStep); int numExpModules = rve->giveExportModuleManager()->giveNumberOfModules(); for ( int i = 1; i <= numExpModules; i++ ) { // ... by diving deep into the hierarchies ... :-/ VTKXMLExportModule *vtkxmlMod = dynamic_cast< VTKXMLExportModule * >( rve->giveExportModuleManager()->giveModule(i) ); if ( vtkxmlMod != NULL ) { vtkxmlMod->giveSmoother()->setDomain(newDomain); vtkxmlMod->givePrimVarSmoother()->setDomain(newDomain); } } #endif #endif }
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 } } }