OOFEM 3.0
Loading...
Searching...
No Matches
sprnodalrecoverymodel.C
Go to the documentation of this file.
1/*
2 *
3 * ##### ##### ###### ###### ### ###
4 * ## ## ## ## ## ## ## ### ##
5 * ## ## ## ## #### #### ## # ##
6 * ## ## ## ## ## ## ## ##
7 * ## ## ## ## ## ## ## ##
8 * ##### ##### ## ###### ## ##
9 *
10 *
11 * OOFEM : Object Oriented Finite Element Code
12 *
13 * Copyright (C) 1993 - 2025 Borek Patzak
14 *
15 *
16 *
17 * Czech Technical University, Faculty of Civil Engineering,
18 * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19 *
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License as published by the Free Software Foundation; either
23 * version 2.1 of the License, or (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * Lesser General Public License for more details.
29 *
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library; if not, write to the Free Software
32 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 */
34
36#include "timestep.h"
37#include "element.h"
38#include "node.h"
39#include "connectivitytable.h"
40#include "integrationrule.h"
41#include "gausspoint.h"
42#include "engngm.h"
43#include "classfactory.h"
44
45#ifdef __MPI_PARALLEL_MODE
46 #include "processcomm.h"
47 #include "problemcomm.h"
48#endif
49
50#include <cstdlib>
51#include <list>
52
53namespace oofem {
54REGISTER_NodalRecoveryModel(SPRNodalRecoveryModel, NodalRecoveryModel :: NRM_SPR);
55
56SPRNodalRecoveryModel :: SPRNodalRecoveryModel(Domain *d) : NodalRecoveryModel(d)
57{ }
58
59SPRNodalRecoveryModel :: ~SPRNodalRecoveryModel()
60{ }
61
62int
63SPRNodalRecoveryModel :: recoverValues(Set elementSet, InternalStateType type, TimeStep *tStep)
64{
65 int nnodes = domain->giveNumberOfDofManagers();
66 IntArray regionNodalNumbers(nnodes);
67 IntArray patchElems, dofManToDetermine, pap;
69 FloatArray dofManValues;
70 IntArray dofManPatchCount;
71
72 if ( ( this->valType == type ) && ( this->stateCounter == tStep->giveSolutionStateCounter() ) ) {
73 return 1;
74 }
75
76#ifdef __MPI_PARALLEL_MODE
77 this->initCommMaps();
78#endif
79
80 // clear nodal table
81 this->clear();
82
83 int regionValSize;
84 int regionDofMans;
85
86
87 regionValSize = 0;
88 // loop over elements and determine local region node numbering and determine and check nodal values size
89 if ( this->initRegionNodeNumbering(regionNodalNumbers, regionDofMans, elementSet) == 0 ) {
90 return 0;
91 }
92
93 SPRPatchType regType = this->determinePatchType(elementSet);
94
95 dofManPatchCount.resize(regionDofMans);
96 dofManPatchCount.zero();
97
98
99 //pap = patch assembly points
100 this->determinePatchAssemblyPoints(pap, regType, elementSet);
101
102 int npap = pap.giveSize();
103 for ( int ipap = 1; ipap <= npap; ipap++ ) {
104 int papNumber = pap.at(ipap);
105 int oldSize = regionValSize;
106
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);
111 dofManValues.zero();
112 }
113 this->determineValuesFromPatch(dofManValues, dofManPatchCount, regionNodalNumbers,
114 dofManToDetermine, a, regType);
115 }
116
117#ifdef __MPI_PARALLEL_MODE
118 this->exchangeDofManValues(dofManValues, dofManPatchCount, regionNodalNumbers, regionValSize);
119#endif
120
121 // average recovered values of active region
122 bool abortFlag = false;
123 for ( int i = 1; i <= nnodes; i++ ) {
124 if ( regionNodalNumbers.at(i) &&
125 ( ( domain->giveDofManager(i)->giveParallelMode() == DofManager_local ) ||
126 ( domain->giveDofManager(i)->giveParallelMode() == DofManager_shared ) ) ) {
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) );
131 }
132 } else {
133 OOFEM_WARNING("values of %s in dofmanager %d undetermined", __InternalStateTypeToString(type), i);
134
135 for ( int j = 1; j <= regionValSize; j++ ) {
136 dofManValues.at(eq + j) = 0.0;
137 }
138 //abortFlag = true;
139 }
140 }
141
142 if ( abortFlag ) {
143 abort();
144 }
145
146 // update recovered values
147 this->updateRegionRecoveredValues(regionNodalNumbers, regionValSize, dofManValues);
148 }
149
150 this->valType = type;
151 this->stateCounter = tStep->giveSolutionStateCounter();
152 return 1;
153}
154
155void
156SPRNodalRecoveryModel :: determinePatchAssemblyPoints(IntArray &pap, SPRPatchType regType, Set &elementSet)
157{
158 int idofMan, ndofMan = domain->giveNumberOfDofManagers();
159 int ielem;
160 int npap, ipap, count, neq, nip;
161 IntArray dofManFlags(ndofMan);
162 IntArray elemPap;
164 Element *element;
165 const IntArray *papDofManConnectivity;
166 enum { papStatus_noPap, papStatus_regular, papStatus_boundary, papStatus_littleNIPs };
167
168 // init all dof man statuses
169 for ( idofMan = 1; idofMan <= ndofMan; idofMan++ ) {
170 dofManFlags.at(idofMan) = papStatus_noPap;
171 }
172
173 IntArray elements = elementSet.giveElementList();
174 // assign all possible paps with corresponding count
175 for ( int i = 1; i <= elements.giveSize(); i++ ) {
176 ielem = elements.at(i);
177 element = domain->giveElement(ielem);
178
179 if ( element->giveParallelMode() != Element_local ) {
180 continue;
181 }
182
183 if ( ( interface = static_cast< SPRNodalRecoveryModelInterface * >( element->giveInterface(SPRNodalRecoveryModelInterfaceType) ) ) ) {
185 npap = elemPap.giveSize();
186 for ( ipap = 1; ipap <= npap; ipap++ ) {
187 dofManFlags.at( elemPap.at(ipap) ) = papStatus_regular;
188 }
189 }
190 }
191
192 // after loop all possible paps (patch assembly points) will have papStatus_regular flag
193
194 // but we now have to skip those pap reported by elements, which have not enough integration points
195 // to determine the least square fit of patch
196 // and also we mark those dofManagers which are on boundary
197
199 for ( idofMan = 1; idofMan <= ndofMan; idofMan++ ) {
200 // mark boundary dofManagers
201 if ( domain->giveDofManager(idofMan)->isBoundary() ) {
202 dofManFlags.at(idofMan) = papStatus_boundary;
203 }
204
205 nip = 0;
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) );
210
211 if ( element->giveParallelMode() != Element_local ) {
212 continue;
213 }
214
215 if ( elementSet.hasElement( element->giveNumber() ) ) {
216 if ( ( interface = static_cast< SPRNodalRecoveryModelInterface * >( element->giveInterface(SPRNodalRecoveryModelInterfaceType) ) ) ) {
217 nip += interface->SPRNodalRecoveryMI_giveNumberOfIP();
218 }
219 }
220 }
221
222 if ( nip < neq ) {
223 // this pap has not enough integration points to determine patch polynomial
224 // reset its count to zero
225 dofManFlags.at(idofMan) = papStatus_littleNIPs;
226 }
227 }
228 }
229
230 //
231 // generally boundary pap can be removed from pap list
232 // if their value can be determined from other paps
233 // and if they are not the last resort to determine other dofManagers values (for example those with little nips).
234 //
235 //
236 // here only test if paps with papStatus_littleNIPs can be determined using regular paps (papStatus_regular)
237 // or the boundary paps must be employed. In such case these boundary paps are marked as regular ones
238 // to force paches to be assembled.
239 //
240 bool foundRegularPap, foundBoundaryPap, abort_flag = false;
241 // loop over boundary candidates to remove and try to confirm whether they can be removed
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++ ) {
247 // try to determine if they can be determined from surronuding elements paps
248 element = domain->giveElement( papDofManConnectivity->at(ielem) );
249
250 if ( element->giveParallelMode() != Element_local ) {
251 continue;
252 }
253
254 if ( !elementSet.hasElement( element->giveNumber() ) ) {
255 continue;
256 }
257
258 if ( ( interface = static_cast< SPRNodalRecoveryModelInterface * >( element->giveInterface(SPRNodalRecoveryModelInterfaceType) ) ) ) {
260 npap = elemPap.giveSize();
261 for ( ipap = 1; ipap <= npap; ipap++ ) {
262 // skip other dofMans with littleNIPs
263 if ( dofManFlags.at( elemPap.at(ipap) ) == papStatus_littleNIPs ) {
264 continue;
265 }
266
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;
271 }
272 }
273 }
274 }
275
276 if ( foundRegularPap ) {
277 continue; // can be determined from regular pap - ok
278 }
279
280 // boundary dof man can be removed <= can be determined
281 if ( foundBoundaryPap ) {
282 // try the last possibility-> determine its value from boundary patches
283 // mark boundaryPap as regulars -> they can be used to assemble patch (they have enough nips)
284 for ( ielem = 1; ielem <= papDofManConnectivity->giveSize(); ielem++ ) {
285 element = domain->giveElement( papDofManConnectivity->at(ielem) );
286 if ( !elementSet.hasElement( element->giveNumber() ) ) {
287 continue;
288 }
289
290 if ( ( interface = static_cast< SPRNodalRecoveryModelInterface * >( element->giveInterface(SPRNodalRecoveryModelInterfaceType) ) ) ) {
292 npap = elemPap.giveSize();
293 for ( ipap = 1; ipap <= npap; ipap++ ) {
294 if ( dofManFlags.at( elemPap.at(ipap) ) == papStatus_boundary ) {
295 // change status to regular pap
296 dofManFlags.at( elemPap.at(ipap) ) = papStatus_regular;
297 }
298 }
299 }
300 }
301 } else {
302 // if the pap with papStatus_littleNIPs status found, which values could not be determined using
303 // regular pap or boundary pap then we are unable to determine such value
304 if ( dofManFlags.at(idofMan) == papStatus_littleNIPs ) {
305 OOFEM_WARNING("unable to determine dofMan %d\n", idofMan);
306 //abort_flag = true;
307 }
308 }
309 }
310 }
311
312 if ( abort_flag ) {
313 abort();
314 }
315
316
317 count = 0;
318 // count regular paps - those for which patch will be assembled
319 for ( idofMan = 1; idofMan <= ndofMan; idofMan++ ) {
320 if ( dofManFlags.at(idofMan) == papStatus_regular ) {
321 count++;
322 }
323 }
324
325 pap.resize(count);
326 count = 0;
327 for ( idofMan = 1; idofMan <= ndofMan; idofMan++ ) {
328 if ( dofManFlags.at(idofMan) == papStatus_regular ) {
329 pap.at(++count) = idofMan;
330 }
331 }
332}
333
334
335void
336SPRNodalRecoveryModel :: initPatch(IntArray &patchElems, IntArray &dofManToDetermine,
337 IntArray &pap, int papNumber, Set &elementSet)
338{
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;
344 Element *element;
345
346 IntArray regionelements = elementSet.giveElementList();
347
348 // loop over elements sharing dofManager with papNumber and
349 // determine those in region in ireg
350 //
351 nelem = papDofManConnectivity->giveSize();
352 count = 0;
353 for ( int ielem = 1; ielem <= nelem; ielem++ ) {
354 if ( domain->giveElement( papDofManConnectivity->at(ielem) )->giveParallelMode() != Element_local ) {
355 continue;
356 }
357
358 if ( elementSet.hasElement(papDofManConnectivity->at(ielem)) ) {
359 count++;
360 }
361 }
362
363 patchElems.resize(count);
364 patchElements = 0;
365 //for ( int i = 1; i <= nelem; i++ ) {
366 for ( int ielem = 1; ielem <= nelem; ielem++ ) {
367 //int ielem = regionelements.at(i);
368
369 if ( domain->giveElement( papDofManConnectivity->at(ielem) )->giveParallelMode() != Element_local ) {
370 continue;
371 }
372
373 if ( elementSet.hasElement(papDofManConnectivity->at(ielem)) ) {
374 patchElems.at(++patchElements) = papDofManConnectivity->at(ielem);
375 }
376 }
377
378 // Invert the pap array for faster access later
379 ndofman = this->domain->giveNumberOfDofManagers();
380 papInv.resize(ndofman);
381 papInv.zero();
382 for ( int i = 1; i <= pap.giveSize(); ++i ) {
383 papInv.at( pap.at(i) ) = 1;
384 }
385
386 // determine dofManagers which values will be determined by this patch
387 // first add those required by elements participating in patch
388 dofManToDetermine.clear();
389 for (int ielem = 1; ielem <= patchElements; ielem++ ) {
390 element = domain->giveElement( patchElems.at(ielem) );
391
392 if ( element->giveParallelMode() != Element_local ) {
393 continue;
394 }
395
396 if ( ( interface = static_cast< SPRNodalRecoveryModelInterface * >( element->giveInterface(SPRNodalRecoveryModelInterfaceType) ) ) ) {
397 // add element reported dofMans for pap dofMan
398 interface->SPRNodalRecoveryMI_giveDofMansDeterminedByPatch(toDetermine, papNumber);
399 for ( int i = 1; i <= toDetermine.giveSize(); i++ ) {
400 includes = 0;
401 // test if INCLUDED
402 for ( int dman: dofManToDetermineList ) {
403 if ( dman == toDetermine.at(i) ) {
404 includes = 1;
405 }
406 }
407
408 if ( !includes ) {
409 dofManToDetermineList.push_back( toDetermine.at(i) );
410 }
411
412 // determine those dofManagers which are not reported by elements,
413 // but their values shoud be determined from this patch
414 // Example include pap DofMans with connectivity 1
416 npap = elemPap.giveSize();
417 for ( ipap = 1; ipap <= npap; ipap++ ) {
418 // test if element reported SPRAssembly point is not global assembly point
419 // then determine this point from this patch
420 if ( papInv.at( elemPap.at(ipap) ) == 0 ) {
421 includes = 0;
422 // test if INCLUDED
423 for ( int dman: dofManToDetermineList ) {
424 if ( dman == elemPap.at(ipap) ) {
425 includes = 1;
426 }
427 }
428
429 if ( !includes ) {
430 dofManToDetermineList.push_back( elemPap.at(ipap) );
431 }
432
433 // add also all dofManagers which are reported by element for this Assembly node
434 interface->SPRNodalRecoveryMI_giveDofMansDeterminedByPatch( toDetermine2, elemPap.at(ipap) );
435 for ( j = 1; j <= toDetermine2.giveSize(); j++ ) {
436 includes = 0;
437 // test if INCLUDED
438 for ( int dman: dofManToDetermineList ) {
439 if ( dman == toDetermine2.at(j) ) {
440 includes = 1;
441 }
442 }
443
444 if ( !includes ) {
445 dofManToDetermineList.push_back( toDetermine2.at(j) );
446 }
447 }
448 }
449 }
450 }
451 }
452 } // end loop over patch elements
453
454 // transform set to dofManToDetermine array
455 count = (int)dofManToDetermineList.size();
456
457 dofManToDetermine.resize(count);
458
459 count = 0;
460 for ( int dman: dofManToDetermineList ) {
461 dofManToDetermine.at(++count) = dman;
462 }
463}
464
465
466
467void
468SPRNodalRecoveryModel :: computePatch(FloatMatrix &a, IntArray &patchElems, int &regionValSize,
469 SPRPatchType regType, InternalStateType type, TimeStep *tStep)
470{
471 int nelem, neq;
472 FloatArray ipVal, coords, P;
473 FloatMatrix A, rhs;
474
476 rhs.resize(neq, regionValSize);
477 rhs.zero();
478 A.resize(neq, neq);
479 A.zero();
480
481 // loop over elements in patch
482 nelem = patchElems.giveSize();
483 for ( int ielem = 1; ielem <= nelem; ielem++ ) {
484 Element *element = domain->giveElement( patchElems.at(ielem) );
487 for ( GaussPoint *gp: *iRule ) {
488 int hasVal = element->giveIPValue(ipVal, gp, type, tStep);
489 if ( !hasVal ) {
490 ipVal.resize(regionValSize);
491 ipVal.zero();
492 } else if ( regionValSize == 0 ) {
493 regionValSize = ipVal.giveSize();
494 rhs.resize(neq, regionValSize);
495 rhs.zero();
496 }
497
498 element->computeGlobalCoordinates( coords, gp->giveSubPatchCoordinates() );
499 // compute ip contribution
500 this->computePolynomialTerms(P, coords, regType);
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);
504 }
505
506 for ( int k = 1; k <= neq; k++ ) {
507 A.at(j, k) += P.at(j) * P.at(k);
508 }
509 }
510 } // end loop over nip
511 }
512 } // end loop over elements
513
514 A.solveForRhs(rhs, a);
515}
516
517void
518SPRNodalRecoveryModel :: determineValuesFromPatch(FloatArray &dofManValues, IntArray &dofManCount,
519 IntArray &regionNodalNumbers, IntArray &dofManToDetermine,
520 FloatMatrix &a, SPRPatchType type)
521{
522 int ndofMan = dofManToDetermine.giveSize();
523 FloatArray P, vals;
524
525 for ( int dofMan = 1; dofMan <= ndofMan; dofMan++ ) {
526 const auto &coords = domain->giveNode( dofManToDetermine.at(dofMan) )->giveCoordinates();
527 this->computePolynomialTerms(P, coords, type);
528 vals.beTProductOf(a, P);
529
530 // assemble values
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);
534 }
535
536 dofManCount.at( regionNodalNumbers.at( dofManToDetermine.at(dofMan) ) )++;
537 }
538}
539
540void
541SPRNodalRecoveryModel :: computePolynomialTerms(FloatArray &P, const FloatArray &coords, SPRPatchType type)
542{
543 if ( type == SPRPatchType_2dxy ) {
544 P.resize(3);
545 P.at(1) = 1.0;
546 P.at(2) = coords.at(1);
547 P.at(3) = coords.at(2);
548 } else if ( type == SPRPatchType_3dBiLin ) {
549 P.resize(4);
550 P.at(1) = 1.0;
551 P.at(2) = coords.at(1);
552 P.at(3) = coords.at(2);
553 P.at(4) = coords.at(3);
554 } else if ( type == SPRPatchType_2dquadratic ) {
555 P.resize(6);
556 P.at(1) = 1.0;
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);
562 } else if ( type == SPRPatchType_3dBiQuadratic ) {
563 P.resize(10);
564 P.at(1) = 1.0;
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);
574 } else {
575 OOFEM_ERROR("unknown regionType");
576 }
577}
578
579int
580SPRNodalRecoveryModel :: giveNumberOfUnknownPolynomialCoefficients(SPRPatchType regType)
581{
582 if ( regType == SPRPatchType_2dxy ) {
583 return 3;
584 } else if ( regType == SPRPatchType_3dBiLin ) {
585 return 4;
586 } else if ( regType == SPRPatchType_2dquadratic ) {
587 return 6;
588 } else if ( regType == SPRPatchType_3dBiQuadratic ) {
589 return 10;
590 } else {
591 return 0;
592 }
593}
594
595
596SPRPatchType SPRNodalRecoveryModel :: determinePatchType(Set &elementList)
597{
599 if ( elementList.giveElementList().giveSize() ) {
600 Element *e = domain->giveElement( elementList.giveElementList().at(1) );
601 if ( ( interface = static_cast< SPRNodalRecoveryModelInterface * >( e->giveInterface(SPRNodalRecoveryModelInterfaceType) ) ) ) {
602 return interface->SPRNodalRecoveryMI_givePatchType();
603 } else {
604 OOFEM_ERROR("unable to determine region patchtype");
605 }
606 } else {
607 OOFEM_ERROR("empty region set");
608 }
609 // return SPRPatchType_none; // to make compiler happy
610}
611
612
613
614#ifdef __MPI_PARALLEL_MODE
615
616void
617SPRNodalRecoveryModel :: initCommMaps()
618{
619 #ifdef __MPI_PARALLEL_MODE
620 if ( initCommMap ) {
621 EngngModel *emodel = domain->giveEngngModel();
623 communicator = new NodeCommunicator(emodel, commBuff, emodel->giveRank(),
624 emodel->giveNumberOfProcesses());
625 communicator->setUpCommunicationMaps(domain->giveEngngModel(), true, true);
626 OOFEM_LOG_INFO("SPRNodalRecoveryModel :: initCommMaps: initialized comm maps");
627 initCommMap = false;
628 }
629
630 #endif
631}
632
633void
634SPRNodalRecoveryModel :: exchangeDofManValues(FloatArray &dofManValues, IntArray &dofManPatchCount,
635 IntArray &regionNodalNumbers, int regionValSize)
636{
637 parallelStruct ls( &dofManValues, &dofManPatchCount, &regionNodalNumbers, regionValSize);
638
639 // exchange data for shared nodes
640 communicator->packAllData(this, & ls, & SPRNodalRecoveryModel :: packSharedDofManData);
641 communicator->initExchange(789);
642 communicator->unpackAllData(this, & ls, & SPRNodalRecoveryModel :: unpackSharedDofManData);
643 communicator->finishExchange();
644}
645
646int
647SPRNodalRecoveryModel :: packSharedDofManData(parallelStruct *s, ProcessCommunicator &processComm)
648{
649 int result = 1;
651 const IntArray &toSendMap = processComm.giveToSendMap();
652
653 for ( int inode : toSendMap ) {
654 // toSendMap contains all shared dofmans with remote partition
655 // one has to check, if particular shared node value is available for given region
656 int indx = s->regionNodalNumbers->at( inode );
657 if ( indx && s->dofManPatchCount->at(indx) ) {
658 // pack "1" to indicate that for given shared node this is a valid contribution
659 result &= pcbuff->write(1);
660 int eq = ( indx - 1 ) * s->regionValSize;
661 for ( int j = 1; j <= s->regionValSize; j++ ) {
662 result &= pcbuff->write( s->dofManValues->at(eq + j) );
663 }
664 } else {
665 // ok shared node is not in active region (determined by s->regionNodalNumbers)
666 result &= pcbuff->write(0);
667 }
668 }
669
670 return result;
671}
672
673int
674SPRNodalRecoveryModel :: unpackSharedDofManData(parallelStruct *s, ProcessCommunicator &processComm)
675{
676 int result = 1;
677 int flag;
678 const IntArray &toRecvMap = processComm.giveToRecvMap();
680
681 for ( int inode : toRecvMap ) {
682 int indx = s->regionNodalNumbers->at( inode );
683 // toRecvMap contains all shared dofmans with remote partition
684 // one has to check, if particular shared node received contribution is available for given region
685 result &= pcbuff->read(flag);
686 if ( flag ) {
687 // "1" to indicates that for given shared node this is a valid contribution
688 int eq = ( indx - 1 ) * s->regionValSize;
689 for ( int j = 1; j <= s->regionValSize; j++ ) {
690 double value;
691 result &= pcbuff->read(value);
692 if ( indx ) {
693 s->dofManValues->at(eq + j) += value;
694 }
695 }
696
697 if ( indx ) {
698 s->dofManPatchCount->at(indx)++;
699 }
700 }
701 }
702
703 return result;
704}
705
706#endif
707} // end namespace oofem
#define REGISTER_NodalRecoveryModel(class, type)
virtual int computeGlobalCoordinates(FloatArray &answer, const FloatArray &lcoords)
Definition element.C:1225
elementParallelMode giveParallelMode() const
Definition element.h:1139
virtual IntegrationRule * giveDefaultIntegrationRulePtr()
Definition element.h:886
virtual int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
Definition element.C:1298
int giveNumberOfProcesses() const
Returns the number of collaborating processes.
Definition engngm.h:1156
int giveRank() const
Returns domain rank in a group of collaborating processes (0..groupSize-1).
Definition engngm.h:1154
virtual Interface * giveInterface(InterfaceType t)
Definition femcmpnn.h:181
int giveNumber() const
Definition femcmpnn.h:104
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void beTProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Definition floatarray.C:721
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
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 resize(int n)
Definition intarray.C:73
void zero()
Sets all component to zero.
Definition intarray.C:52
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
bool initCommMap
Communication init flag.
int initRegionNodeNumbering(IntArray &regionNodalNumbers, int &regionDofMans, Set &region)
int updateRegionRecoveredValues(const IntArray &regionNodalNumbers, 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.
Definition processcomm.h:94
int write(const int *data, std::size_t count) override
Writes count integer values from array pointed by data.
Definition processcomm.h:86
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 &regionValSize, 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 &regionNodalNumbers, int regionValSize)
void determinePatchAssemblyPoints(IntArray &pap, SPRPatchType regType, Set &elemset)
SPRPatchType determinePatchType(Set &elementList)
void determineValuesFromPatch(FloatArray &dofManValues, IntArray &dofManCount, IntArray &regionNodalNumbers, IntArray &dofManToDetermine, FloatMatrix &a, SPRPatchType type)
int giveNumberOfUnknownPolynomialCoefficients(SPRPatchType regType)
bool hasElement(int elem) const
Return True if given element is contained.
Definition set.C:245
const IntArray & giveElementList()
Definition set.C:158
StateCounterType giveSolutionStateCounter()
Definition timestep.h:211
#define OOFEM_WARNING(...)
Definition error.h:80
#define OOFEM_ERROR(...)
Definition error.h:79
#define OOFEM_LOG_INFO(...)
Definition logger.h:143
const char * __InternalStateTypeToString(InternalStateType _value)
Definition cltypes.C:309
@ Element_local
Element is local, there are no contributions from other domains to this element.
Definition element.h:88
@ DofManager_local
Definition dofmanager.h:67
@ DofManager_shared
Definition dofmanager.h:68
@ CBT_dynamic
@ SPRNodalRecoveryModelInterfaceType

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011