int SPRNodalRecoveryModel :: recoverValues(Set elementSet, InternalStateType type, TimeStep *tStep) { int nnodes = domain->giveNumberOfDofManagers(); IntArray regionNodalNumbers(nnodes); IntArray patchElems, dofManToDetermine, pap; FloatMatrix a; FloatArray dofManValues; IntArray dofManPatchCount; if ( ( this->valType == type ) && ( this->stateCounter == tStep->giveSolutionStateCounter() ) ) { return 1; } #ifdef __PARALLEL_MODE this->initCommMaps(); #endif // clear nodal table this->clear(); int regionValSize; int regionDofMans; regionValSize = 0; // loop over elements and determine local region node numbering and determine and check nodal values size if ( this->initRegionNodeNumbering(regionNodalNumbers, regionDofMans, elementSet) == 0 ) { return 0; } SPRPatchType regType = this->determinePatchType(elementSet); dofManPatchCount.resize(regionDofMans); dofManPatchCount.zero(); //pap = patch assembly points this->determinePatchAssemblyPoints(pap, regType, elementSet); int npap = pap.giveSize(); for ( int ipap = 1; ipap <= npap; ipap++ ) { int papNumber = pap.at(ipap); int oldSize = regionValSize; this->initPatch(patchElems, dofManToDetermine, pap, papNumber, elementSet); this->computePatch(a, patchElems, regionValSize, regType, type, tStep); if ( oldSize == 0 ) { dofManValues.resize(regionDofMans * regionValSize); dofManValues.zero(); } this->determineValuesFromPatch(dofManValues, dofManPatchCount, regionNodalNumbers, dofManToDetermine, a, regType); } #ifdef __PARALLEL_MODE this->exchangeDofManValues(dofManValues, dofManPatchCount, regionNodalNumbers, regionValSize); #endif // average recovered values of active region bool abortFlag = false; for ( int i = 1; i <= nnodes; i++ ) { if ( regionNodalNumbers.at(i) && ( ( domain->giveDofManager(i)->giveParallelMode() == DofManager_local ) || ( domain->giveDofManager(i)->giveParallelMode() == DofManager_shared ) ) ) { int eq = ( regionNodalNumbers.at(i) - 1 ) * regionValSize; if ( dofManPatchCount.at( regionNodalNumbers.at(i) ) ) { for ( int j = 1; j <= regionValSize; j++ ) { dofManValues.at(eq + j) /= dofManPatchCount.at( regionNodalNumbers.at(i) ); } } else { OOFEM_WARNING("values of %s in dofmanager %d undetermined", __InternalStateTypeToString(type), i); for ( int j = 1; j <= regionValSize; j++ ) { dofManValues.at(eq + j) = 0.0; } //abortFlag = true; } } if ( abortFlag ) { abort(); } // update recovered values this->updateRegionRecoveredValues(regionNodalNumbers, regionValSize, dofManValues); } this->valType = type; this->stateCounter = tStep->giveSolutionStateCounter(); return 1; }
int NodalAveragingRecoveryModel :: recoverValues(InternalStateType type, TimeStep *tStep) { int ireg, nregions = this->giveNumberOfVirtualRegions(); int ielem, nelem = domain->giveNumberOfElements(); int inode, nnodes = domain->giveNumberOfDofManagers(); int elemNodes; int regionValSize; int elementNode, node; int regionDofMans; int i, neq, eq; Element *element; NodalAveragingRecoveryModelInterface *interface; IntArray skipRegionMap(nregions), regionRecSize(nregions); IntArray regionNodalNumbers(nnodes); IntArray regionDofMansConnectivity; FloatArray lhs, val; if ( ( this->valType == type ) && ( this->stateCounter == tStep->giveSolutionStateCounter() ) ) { return 1; } #ifdef __PARALLEL_MODE bool parallel = this->domain->giveEngngModel()->isParallel(); if (parallel) this->initCommMaps(); #endif // clear nodal table this->clear(); // init region table indicating regions to skip this->initRegionMap(skipRegionMap, regionRecSize, type); #ifdef __PARALLEL_MODE if (parallel) { // synchronize skipRegionMap over all cpus IntArray temp_skipRegionMap(skipRegionMap); MPI_Allreduce(temp_skipRegionMap.givePointer(), skipRegionMap.givePointer(), nregions, MPI_INT, MPI_LOR, MPI_COMM_WORLD); } #endif // loop over regions for ( ireg = 1; ireg <= nregions; ireg++ ) { // skip regions if ( skipRegionMap.at(ireg) ) { continue; } // loop over elements and determine local region node numbering and determine and check nodal values size if ( this->initRegionNodeNumbering(regionNodalNumbers, regionDofMans, ireg) == 0 ) { break; } regionValSize = regionRecSize.at(ireg); neq = regionDofMans * regionValSize; lhs.resize(neq); lhs.zero(); regionDofMansConnectivity.resize(regionDofMans); regionDofMansConnectivity.zero(); // assemble element contributions for ( ielem = 1; ielem <= nelem; ielem++ ) { element = domain->giveElement(ielem); #ifdef __PARALLEL_MODE if ( element->giveParallelMode() != Element_local ) { continue; } #endif if ( this->giveElementVirtualRegionNumber(ielem) != ireg ) { continue; } // If an element doesn't implement the interface, it is ignored. if ( ( interface = ( NodalAveragingRecoveryModelInterface * ) element->giveInterface(NodalAveragingRecoveryModelInterfaceType) ) == NULL ) { //abort(); continue; } elemNodes = element->giveNumberOfDofManagers(); // ask element contributions for ( elementNode = 1; elementNode <= elemNodes; elementNode++ ) { node = element->giveDofManager(elementNode)->giveNumber(); interface->NodalAveragingRecoveryMI_computeNodalValue(val, elementNode, type, tStep); // if the element cannot evaluate this variable, it is ignored if ( val.giveSize() == 0 ) { continue; } eq = ( regionNodalNumbers.at(node) - 1 ) * regionValSize; for ( i = 1; i <= regionValSize; i++ ) { lhs.at(eq + i) += val.at(i); } regionDofMansConnectivity.at( regionNodalNumbers.at(node) )++; } } // end assemble element contributions #ifdef __PARALLEL_MODE if (parallel) this->exchangeDofManValues(ireg, lhs, regionDofMansConnectivity, regionNodalNumbers, regionValSize); #endif // solve for recovered values of active region for ( inode = 1; inode <= nnodes; inode++ ) { if ( regionNodalNumbers.at(inode) ) { eq = ( regionNodalNumbers.at(inode) - 1 ) * regionValSize; for ( i = 1; i <= regionValSize; i++ ) { if ( regionDofMansConnectivity.at( regionNodalNumbers.at(inode) ) > 0 ) { lhs.at(eq + i) /= regionDofMansConnectivity.at( regionNodalNumbers.at(inode) ); } else { OOFEM_WARNING2("NodalAveragingRecoveryModel::recoverValues: values of dofmanager %d undetermined", inode); lhs.at(eq + i) = 0.0; } } } } // update recovered values this->updateRegionRecoveredValues(ireg, regionNodalNumbers, regionValSize, lhs); } // end loop over regions this->valType = type; this->stateCounter = tStep->giveSolutionStateCounter(); return 1; }
int NodalAveragingRecoveryModel :: recoverValues(Set elementSet, InternalStateType type, TimeStep *tStep) { int nnodes = domain->giveNumberOfDofManagers(); IntArray regionNodalNumbers(nnodes); IntArray regionDofMansConnectivity; FloatArray lhs, val; if ( ( this->valType == type ) && ( this->stateCounter == tStep->giveSolutionStateCounter() ) ) { return 1; } #ifdef __PARALLEL_MODE bool parallel = this->domain->giveEngngModel()->isParallel(); if ( parallel ) { this->initCommMaps(); } #endif // clear nodal table this->clear(); int regionValSize = 0; int regionDofMans; // loop over elements and determine local region node numbering and determine and check nodal values size if ( this->initRegionNodeNumbering(regionNodalNumbers, regionDofMans, elementSet) == 0 ) { return 0; } regionDofMansConnectivity.resize(regionDofMans); regionDofMansConnectivity.zero(); IntArray elements = elementSet.giveElementList(); // assemble element contributions for ( int i = 1; i <= elements.giveSize(); i++ ) { int ielem = elements.at(i); NodalAveragingRecoveryModelInterface *interface; Element *element = domain->giveElement(ielem); if ( element->giveParallelMode() != Element_local ) { continue; } // If an element doesn't implement the interface, it is ignored. if ( ( interface = static_cast< NodalAveragingRecoveryModelInterface * > ( element->giveInterface(NodalAveragingRecoveryModelInterfaceType) ) ) == NULL ) { //abort(); continue; } int elemNodes = element->giveNumberOfDofManagers(); // ask element contributions for ( int elementNode = 1; elementNode <= elemNodes; elementNode++ ) { int node = element->giveDofManager(elementNode)->giveNumber(); interface->NodalAveragingRecoveryMI_computeNodalValue(val, elementNode, type, tStep); // if the element cannot evaluate this variable, it is ignored if ( val.giveSize() == 0 ) { continue; } else if ( regionValSize == 0 ) { regionValSize = val.giveSize(); lhs.resize(regionDofMans * regionValSize); lhs.zero(); } else if ( val.giveSize() != regionValSize ) { OOFEM_LOG_RELEVANT("NodalAveragingRecoveryModel :: size mismatch for InternalStateType %s, ignoring all elements that doesn't use the size %d\n", __InternalStateTypeToString(type), regionValSize); continue; } int eq = ( regionNodalNumbers.at(node) - 1 ) * regionValSize; for ( int j = 1; j <= regionValSize; j++ ) { lhs.at(eq + j) += val.at(j); } regionDofMansConnectivity.at( regionNodalNumbers.at(node) )++; } } // end assemble element contributions #ifdef __PARALLEL_MODE if ( parallel ) { this->exchangeDofManValues(lhs, regionDofMansConnectivity, regionNodalNumbers, regionValSize); } #endif // solve for recovered values of active region for ( int inode = 1; inode <= nnodes; inode++ ) { if ( regionNodalNumbers.at(inode) ) { int eq = ( regionNodalNumbers.at(inode) - 1 ) * regionValSize; for ( int i = 1; i <= regionValSize; i++ ) { if ( regionDofMansConnectivity.at( regionNodalNumbers.at(inode) ) > 0 ) { lhs.at(eq + i) /= regionDofMansConnectivity.at( regionNodalNumbers.at(inode) ); } else { OOFEM_WARNING("values of dofmanager %d undetermined", inode); lhs.at(eq + i) = 0.0; } } } } // update recovered values this->updateRegionRecoveredValues(regionNodalNumbers, regionValSize, lhs); this->valType = type; this->stateCounter = tStep->giveSolutionStateCounter(); return 1; }