45#ifdef __MPI_PARALLEL_MODE
59SPRNodalRecoveryModel :: ~SPRNodalRecoveryModel()
65 int nnodes =
domain->giveNumberOfDofManagers();
67 IntArray patchElems, dofManToDetermine, pap;
76#ifdef __MPI_PARALLEL_MODE
95 dofManPatchCount.
resize(regionDofMans);
96 dofManPatchCount.
zero();
103 for (
int ipap = 1; ipap <= npap; ipap++ ) {
104 int papNumber = pap.
at(ipap);
105 int oldSize = regionValSize;
107 this->
initPatch(patchElems, dofManToDetermine, pap, papNumber, elementSet);
108 this->
computePatch(a, patchElems, regionValSize, regType, type, tStep);
109 if ( oldSize == 0 ) {
110 dofManValues.
resize(regionDofMans * regionValSize);
114 dofManToDetermine, a, regType);
117#ifdef __MPI_PARALLEL_MODE
122 bool abortFlag =
false;
123 for (
int i = 1; i <= nnodes; i++ ) {
124 if ( regionNodalNumbers.
at(i) &&
127 int eq = ( regionNodalNumbers.
at(i) - 1 ) * regionValSize;
128 if ( dofManPatchCount.
at( regionNodalNumbers.
at(i) ) ) {
129 for (
int j = 1; j <= regionValSize; j++ ) {
130 dofManValues.
at(eq + j) /= dofManPatchCount.
at( regionNodalNumbers.
at(i) );
135 for (
int j = 1; j <= regionValSize; j++ ) {
136 dofManValues.
at(eq + j) = 0.0;
158 int idofMan, ndofMan =
domain->giveNumberOfDofManagers();
160 int npap, ipap, count, neq, nip;
165 const IntArray *papDofManConnectivity;
166 enum { papStatus_noPap, papStatus_regular, papStatus_boundary, papStatus_littleNIPs };
169 for ( idofMan = 1; idofMan <= ndofMan; idofMan++ ) {
170 dofManFlags.
at(idofMan) = papStatus_noPap;
175 for (
int i = 1; i <= elements.
giveSize(); i++ ) {
176 ielem = elements.
at(i);
177 element =
domain->giveElement(ielem);
186 for ( ipap = 1; ipap <= npap; ipap++ ) {
187 dofManFlags.
at( elemPap.
at(ipap) ) = papStatus_regular;
199 for ( idofMan = 1; idofMan <= ndofMan; idofMan++ ) {
201 if (
domain->giveDofManager(idofMan)->isBoundary() ) {
202 dofManFlags.
at(idofMan) = papStatus_boundary;
206 if ( dofManFlags.
at(idofMan) != papStatus_noPap ) {
207 papDofManConnectivity =
domain->giveConnectivityTable()->giveDofManConnectivityArray(idofMan);
208 for ( ielem = 1; ielem <= papDofManConnectivity->
giveSize(); ielem++ ) {
209 element =
domain->giveElement( papDofManConnectivity->
at(ielem) );
225 dofManFlags.
at(idofMan) = papStatus_littleNIPs;
240 bool foundRegularPap, foundBoundaryPap, abort_flag =
false;
242 for ( idofMan = 1; idofMan <= ndofMan; idofMan++ ) {
243 foundRegularPap = foundBoundaryPap =
false;
244 if ( dofManFlags.
at(idofMan) == papStatus_littleNIPs ) {
245 papDofManConnectivity =
domain->giveConnectivityTable()->giveDofManConnectivityArray(idofMan);
246 for ( ielem = 1; ielem <= papDofManConnectivity->
giveSize(); ielem++ ) {
248 element =
domain->giveElement( papDofManConnectivity->
at(ielem) );
261 for ( ipap = 1; ipap <= npap; ipap++ ) {
263 if ( dofManFlags.
at( elemPap.
at(ipap) ) == papStatus_littleNIPs ) {
267 if ( dofManFlags.
at( elemPap.
at(ipap) ) == papStatus_regular ) {
268 foundRegularPap =
true;
269 }
else if ( dofManFlags.
at( elemPap.
at(ipap) ) == papStatus_boundary ) {
270 foundBoundaryPap =
true;
276 if ( foundRegularPap ) {
281 if ( foundBoundaryPap ) {
284 for ( ielem = 1; ielem <= papDofManConnectivity->
giveSize(); ielem++ ) {
285 element =
domain->giveElement( papDofManConnectivity->
at(ielem) );
293 for ( ipap = 1; ipap <= npap; ipap++ ) {
294 if ( dofManFlags.
at( elemPap.
at(ipap) ) == papStatus_boundary ) {
296 dofManFlags.
at( elemPap.
at(ipap) ) = papStatus_regular;
304 if ( dofManFlags.
at(idofMan) == papStatus_littleNIPs ) {
319 for ( idofMan = 1; idofMan <= ndofMan; idofMan++ ) {
320 if ( dofManFlags.
at(idofMan) == papStatus_regular ) {
327 for ( idofMan = 1; idofMan <= ndofMan; idofMan++ ) {
328 if ( dofManFlags.
at(idofMan) == papStatus_regular ) {
329 pap.
at(++count) = idofMan;
339 int nelem, ndofman, count, patchElements, j, includes, npap, ipap;
340 const IntArray *papDofManConnectivity =
domain->giveConnectivityTable()->giveDofManConnectivityArray(papNumber);
341 std :: list< int >dofManToDetermineList;
343 IntArray toDetermine, toDetermine2, elemPap, papInv;
351 nelem = papDofManConnectivity->
giveSize();
353 for (
int ielem = 1; ielem <= nelem; ielem++ ) {
354 if (
domain->giveElement( papDofManConnectivity->
at(ielem) )->giveParallelMode() !=
Element_local ) {
358 if ( elementSet.
hasElement(papDofManConnectivity->
at(ielem)) ) {
366 for (
int ielem = 1; ielem <= nelem; ielem++ ) {
369 if (
domain->giveElement( papDofManConnectivity->
at(ielem) )->giveParallelMode() !=
Element_local ) {
373 if ( elementSet.
hasElement(papDofManConnectivity->
at(ielem)) ) {
374 patchElems.
at(++patchElements) = papDofManConnectivity->
at(ielem);
379 ndofman = this->
domain->giveNumberOfDofManagers();
382 for (
int i = 1; i <= pap.
giveSize(); ++i ) {
383 papInv.
at( pap.
at(i) ) = 1;
388 dofManToDetermine.
clear();
389 for (
int ielem = 1; ielem <= patchElements; ielem++ ) {
390 element =
domain->giveElement( patchElems.
at(ielem) );
399 for (
int i = 1; i <= toDetermine.
giveSize(); i++ ) {
402 for (
int dman: dofManToDetermineList ) {
403 if ( dman == toDetermine.
at(i) ) {
409 dofManToDetermineList.push_back( toDetermine.
at(i) );
417 for ( ipap = 1; ipap <= npap; ipap++ ) {
420 if ( papInv.
at( elemPap.
at(ipap) ) == 0 ) {
423 for (
int dman: dofManToDetermineList ) {
424 if ( dman == elemPap.
at(ipap) ) {
430 dofManToDetermineList.push_back( elemPap.
at(ipap) );
435 for ( j = 1; j <= toDetermine2.
giveSize(); j++ ) {
438 for (
int dman: dofManToDetermineList ) {
439 if ( dman == toDetermine2.
at(j) ) {
445 dofManToDetermineList.push_back( toDetermine2.
at(j) );
455 count = (int)dofManToDetermineList.size();
457 dofManToDetermine.
resize(count);
460 for (
int dman: dofManToDetermineList ) {
461 dofManToDetermine.
at(++count) = dman;
476 rhs.
resize(neq, regionValSize);
483 for (
int ielem = 1; ielem <= nelem; ielem++ ) {
488 int hasVal = element->
giveIPValue(ipVal, gp, type, tStep);
490 ipVal.
resize(regionValSize);
492 }
else if ( regionValSize == 0 ) {
494 rhs.
resize(neq, regionValSize);
501 for (
int j = 1; j <= neq; j++ ) {
502 for (
int k = 1; k <= regionValSize; k++ ) {
503 rhs.
at(j, k) += P.
at(j) * ipVal.
at(k);
506 for (
int k = 1; k <= neq; k++ ) {
507 A.
at(j, k) += P.
at(j) * P.
at(k);
522 int ndofMan = dofManToDetermine.
giveSize();
525 for (
int dofMan = 1; dofMan <= ndofMan; dofMan++ ) {
526 const auto &coords =
domain->giveNode( dofManToDetermine.
at(dofMan) )->giveCoordinates();
531 int eq = ( regionNodalNumbers.
at( dofManToDetermine.
at(dofMan) ) - 1 ) * vals.
giveSize();
532 for (
int i = 1; i <= vals.
giveSize(); i++ ) {
533 dofManValues.
at(eq + i) += vals.
at(i);
536 dofManCount.
at( regionNodalNumbers.
at( dofManToDetermine.
at(dofMan) ) )++;
546 P.
at(2) = coords.
at(1);
547 P.
at(3) = coords.
at(2);
551 P.
at(2) = coords.
at(1);
552 P.
at(3) = coords.
at(2);
553 P.
at(4) = coords.
at(3);
557 P.
at(2) = coords.
at(1);
558 P.
at(3) = coords.
at(2);
559 P.
at(4) = coords.
at(1) * coords.
at(2);
560 P.
at(5) = coords.
at(1) * coords.
at(1);
561 P.
at(6) = coords.
at(2) * coords.
at(2);
565 P.
at(2) = coords.
at(1);
566 P.
at(3) = coords.
at(2);
567 P.
at(4) = coords.
at(3);
568 P.
at(5) = coords.
at(1) * coords.
at(1);
569 P.
at(6) = coords.
at(1) * coords.
at(2);
570 P.
at(7) = coords.
at(1) * coords.
at(3);
571 P.
at(8) = coords.
at(2) * coords.
at(2);
572 P.
at(9) = coords.
at(2) * coords.
at(3);
573 P.
at(10) = coords.
at(3) * coords.
at(3);
580SPRNodalRecoveryModel :: giveNumberOfUnknownPolynomialCoefficients(
SPRPatchType regType)
604 OOFEM_ERROR(
"unable to determine region patchtype");
614#ifdef __MPI_PARALLEL_MODE
617SPRNodalRecoveryModel :: initCommMaps()
619 #ifdef __MPI_PARALLEL_MODE
626 OOFEM_LOG_INFO(
"SPRNodalRecoveryModel :: initCommMaps: initialized comm maps");
635 IntArray ®ionNodalNumbers,
int regionValSize)
637 parallelStruct ls( &dofManValues, &dofManPatchCount, ®ionNodalNumbers, regionValSize);
640 communicator->packAllData(
this, & ls, & SPRNodalRecoveryModel :: packSharedDofManData);
642 communicator->unpackAllData(
this, & ls, & SPRNodalRecoveryModel :: unpackSharedDofManData);
653 for (
int inode : toSendMap ) {
659 result &= pcbuff->
write(1);
666 result &= pcbuff->
write(0);
681 for (
int inode : toRecvMap ) {
685 result &= pcbuff->
read(flag);
691 result &= pcbuff->
read(value);
#define REGISTER_NodalRecoveryModel(class, type)
virtual int computeGlobalCoordinates(FloatArray &answer, const FloatArray &lcoords)
elementParallelMode giveParallelMode() const
virtual IntegrationRule * giveDefaultIntegrationRulePtr()
virtual int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
int giveNumberOfProcesses() const
Returns the number of collaborating processes.
int giveRank() const
Returns domain rank in a group of collaborating processes (0..groupSize-1).
virtual Interface * giveInterface(InterfaceType t)
Index giveSize() const
Returns the size of receiver.
void zero()
Zeroes all coefficients of receiver.
void beTProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
void resize(Index rows, Index cols)
void zero()
Zeroes all coefficient of receiver.
double at(std::size_t i, std::size_t j) const
bool solveForRhs(const FloatArray &b, FloatArray &answer, bool transpose=false)
void zero()
Sets all component to zero.
bool initCommMap
Communication init flag.
int initRegionNodeNumbering(IntArray ®ionNodalNumbers, int ®ionDofMans, Set ®ion)
int updateRegionRecoveredValues(const IntArray ®ionNodalNumbers, int regionValSize, const FloatArray &rhs)
CommunicatorBuff * commBuff
Common Communicator buffer.
NodalRecoveryModel(Domain *d)
Constructor.
StateCounterType stateCounter
Time stamp of recovered values.
InternalStateType valType
Determines the type of recovered values.
ProblemCommunicator * communicator
Communicator.
int read(int *data, std::size_t count) override
Reads count integer values into array pointed by data.
int write(const int *data, std::size_t count) override
Writes count integer values from array pointed by data.
const IntArray & giveToRecvMap()
ProcessCommunicatorBuff * giveProcessCommunicatorBuff()
Returns communication buffer.
const IntArray & giveToSendMap()
virtual SPRPatchType SPRNodalRecoveryMI_givePatchType()=0
virtual void SPRNodalRecoveryMI_giveDofMansDeterminedByPatch(IntArray &answer, int pap)=0
virtual void SPRNodalRecoveryMI_giveSPRAssemblyPoints(IntArray &pap)=0
virtual int SPRNodalRecoveryMI_giveNumberOfIP()=0
void computePatch(FloatMatrix &a, IntArray &patchElems, int ®ionValSize, SPRPatchType regType, InternalStateType type, TimeStep *tStep)
void computePolynomialTerms(FloatArray &P, const FloatArray &coords, SPRPatchType type)
void initPatch(IntArray &patchElems, IntArray &dofManToDetermine, IntArray &pap, int papNumber, Set &elementList)
void exchangeDofManValues(FloatArray &dofManValues, IntArray &dofManPatchCount, IntArray ®ionNodalNumbers, int regionValSize)
void determinePatchAssemblyPoints(IntArray &pap, SPRPatchType regType, Set &elemset)
SPRPatchType determinePatchType(Set &elementList)
void determineValuesFromPatch(FloatArray &dofManValues, IntArray &dofManCount, IntArray ®ionNodalNumbers, IntArray &dofManToDetermine, FloatMatrix &a, SPRPatchType type)
int giveNumberOfUnknownPolynomialCoefficients(SPRPatchType regType)
bool hasElement(int elem) const
Return True if given element is contained.
const IntArray & giveElementList()
StateCounterType giveSolutionStateCounter()
#define OOFEM_WARNING(...)
#define OOFEM_LOG_INFO(...)
const char * __InternalStateTypeToString(InternalStateType _value)
@ SPRPatchType_2dquadratic
@ SPRPatchType_3dBiQuadratic
@ Element_local
Element is local, there are no contributions from other domains to this element.
@ SPRNodalRecoveryModelInterfaceType
IntArray * regionNodalNumbers
FloatArray * dofManValues
IntArray * dofManPatchCount