OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
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 - 2013 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 
35 #include "sprnodalrecoverymodel.h"
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 __PARALLEL_MODE
46  #include "processcomm.h"
47  #include "problemcomm.h"
48 #endif
49 
50 #include <cstdlib>
51 #include <list>
52 
53 namespace oofem {
55 
57 { }
58 
60 { }
61 
62 int
64 {
65  int nnodes = domain->giveNumberOfDofManagers();
66  IntArray regionNodalNumbers(nnodes);
67  IntArray patchElems, dofManToDetermine, pap;
68  FloatMatrix a;
69  FloatArray dofManValues;
70  IntArray dofManPatchCount;
71 
72  if ( ( this->valType == type ) && ( this->stateCounter == tStep->giveSolutionStateCounter() ) ) {
73  return 1;
74  }
75 
76 #ifdef __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 __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) &&
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 
155 void
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) ) ) ) {
184  interface->SPRNodalRecoveryMI_giveSPRAssemblyPoints(elemPap);
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 
198  neq = this->giveNumberOfUnknownPolynomialCoefficients(regType);
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) ) ) ) {
259  interface->SPRNodalRecoveryMI_giveSPRAssemblyPoints(elemPap);
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) ) ) ) {
291  interface->SPRNodalRecoveryMI_giveSPRAssemblyPoints(elemPap);
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 
335 void
336 SPRNodalRecoveryModel :: 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
415  interface->SPRNodalRecoveryMI_giveSPRAssemblyPoints(elemPap);
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 
467 void
468 SPRNodalRecoveryModel :: 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 
475  neq = this->giveNumberOfUnknownPolynomialCoefficients(regType);
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 
517 void
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  FloatArray *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 
540 void
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 
579 int
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 
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 __PARALLEL_MODE
615 
616 void
618 {
619  #ifdef __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 
633 void
635  IntArray &regionNodalNumbers, int regionValSize)
636 {
637  parallelStruct ls( &dofManValues, &dofManPatchCount, &regionNodalNumbers, regionValSize);
638 
639  // exchange data for shared nodes
644 }
645 
646 int
648 {
649  int result = 1, i, j, indx, eq, size;
651  IntArray const *toSendMap = processComm.giveToSendMap();
652 
653  size = toSendMap->giveSize();
654  for ( i = 1; i <= size; i++ ) {
655  // toSendMap contains all shared dofmans with remote partition
656  // one has to check, if particular shared node value is available for given region
657  indx = s->regionNodalNumbers->at( toSendMap->at(i) );
658  if ( indx && s->dofManPatchCount->at(indx) ) {
659  // pack "1" to indicate that for given shared node this is a valid contribution
660  result &= pcbuff->write(1);
661  eq = ( indx - 1 ) * s->regionValSize;
662  for ( j = 1; j <= s->regionValSize; j++ ) {
663  result &= pcbuff->write( s->dofManValues->at(eq + j) );
664  }
665  } else {
666  // ok shared node is not in active region (determined by s->regionNodalNumbers)
667  result &= pcbuff->write(0);
668  }
669  }
670 
671  return result;
672 }
673 
674 int
676 {
677  int result = 1;
678  int i, j, eq, indx, size, flag;
679  IntArray const *toRecvMap = processComm.giveToRecvMap();
681  double value;
682 
683  size = toRecvMap->giveSize();
684  for ( i = 1; i <= size; i++ ) {
685  indx = s->regionNodalNumbers->at( toRecvMap->at(i) );
686  // toRecvMap contains all shared dofmans with remote partition
687  // one has to check, if particular shared node received contribution is available for given region
688  result &= pcbuff->read(flag);
689  if ( flag ) {
690  // "1" to indicates that for given shared node this is a valid contribution
691  eq = ( indx - 1 ) * s->regionValSize;
692  for ( j = 1; j <= s->regionValSize; j++ ) {
693  result &= pcbuff->read(value);
694  if ( indx ) {
695  s->dofManValues->at(eq + j) += value;
696  }
697  }
698 
699  if ( indx ) {
700  s->dofManPatchCount->at(indx)++;
701  }
702  }
703  }
704 
705  return result;
706 }
707 
708 #endif
709 } // end namespace oofem
InternalStateType
Type representing the physical meaning of element or constitutive model internal variable.
void determineValuesFromPatch(FloatArray &dofManValues, IntArray &dofManCount, IntArray &regionNodalNumbers, IntArray &dofManToDetermine, FloatMatrix &a, SPRPatchType type)
int initExchange(int tag)
Initializes data exchange with all problems.
Definition: communicator.C:104
The element interface required by ZZNodalRecoveryModel.
void exchangeDofManValues(FloatArray &dofManValues, IntArray &dofManPatchCount, IntArray &regionNodalNumbers, int regionValSize)
virtual int SPRNodalRecoveryMI_giveNumberOfIP()=0
virtual int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
Returns the integration point corresponding value in full form.
Definition: element.C:1257
virtual int recoverValues(Set elementSet, InternalStateType type, TimeStep *tStep)
Recovers the nodal values for all regions.
void computePolynomialTerms(FloatArray &P, FloatArray &coords, SPRPatchType type)
Class and object Domain.
Definition: domain.h:115
virtual IntegrationRule * giveDefaultIntegrationRulePtr()
Access method for default integration rule.
Definition: element.h:822
Helper structure to pass required arguments to packing/unpacking functions needed in parallel mode...
int initRegionNodeNumbering(IntArray &regionNodalNumbers, int &regionDofMans, Set &region)
Determine local region node numbering and determine and check nodal values size.
bool solveForRhs(const FloatArray &b, FloatArray &answer, bool transpose=false)
Solves the system of linear equations .
Definition: floatmatrix.C:1112
int giveNumberOfDofManagers() const
Returns number of dof managers in domain.
Definition: domain.h:432
int packSharedDofManData(parallelStruct *s, ProcessCommunicator &processComm)
int packAllData(T *ptr, int(T::*packFunc)(ProcessCommunicator &))
Pack all problemCommunicators data to their send buffers.
Definition: communicator.h:223
void zero()
Sets all component to zero.
Definition: intarray.C:52
void initPatch(IntArray &patchElems, IntArray &dofManToDetermine, IntArray &pap, int papNumber, Set &elementList)
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
int giveNumberOfUnknownPolynomialCoefficients(SPRPatchType regType)
ConnectivityTable * giveConnectivityTable()
Returns receiver&#39;s associated connectivity table.
Definition: domain.C:1170
EngngModel * giveEngngModel()
Returns engineering model to which receiver is associated.
Definition: domain.C:433
Abstract base class for all finite elements.
Definition: element.h:145
int giveNumberOfProcesses() const
Returns the number of collaborating processes.
Definition: engngm.h:1060
int updateRegionRecoveredValues(const IntArray &regionNodalNumbers, int regionValSize, const FloatArray &rhs)
Update the nodal table according to recovered solution for given region.
The ProcessCommunicator and corresponding buffers (represented by this class) are separated in order ...
Definition: processcomm.h:64
Class implementing an array of integers.
Definition: intarray.h:61
int & at(int i)
Coefficient access function.
Definition: intarray.h:103
virtual void SPRNodalRecoveryMI_giveSPRAssemblyPoints(IntArray &pap)=0
Abstract base class representing integration rule.
int finishExchange()
Finishes the exchange.
Definition: communicator.C:115
REGISTER_NodalRecoveryModel(NodalAveragingRecoveryModel, NodalRecoveryModel::NRM_NodalAveraging)
const IntArray * giveToSendMap()
Returns receiver to send map.
Definition: processcomm.h:223
void computePatch(FloatMatrix &a, IntArray &patchElems, int &regionValSize, SPRPatchType regType, InternalStateType type, TimeStep *tStep)
int unpackSharedDofManData(parallelStruct *s, ProcessCommunicator &processComm)
#define OOFEM_LOG_INFO(...)
Definition: logger.h:127
Element * giveElement(int n)
Service for accessing particular domain fe element.
Definition: domain.C:160
virtual int write(const int *data, int count)
Writes count integer values from array pointed by data.
Definition: processcomm.h:83
StateCounterType giveSolutionStateCounter()
Returns current solution state counter.
Definition: timestep.h:188
#define OOFEM_ERROR(...)
Definition: error.h:61
void clear()
Clears the array (zero size).
Definition: intarray.h:177
SPRPatchType determinePatchType(Set &elementList)
ProcessCommunicatorBuff * giveProcessCommunicatorBuff()
Returns communication buffer.
Definition: processcomm.h:210
const IntArray * giveToRecvMap()
Returns receiver to receive map.
Definition: processcomm.h:227
Set of elements, boundaries, edges and/or nodes.
Definition: set.h:66
void determinePatchAssemblyPoints(IntArray &pap, SPRPatchType regType, Set &elemset)
virtual ~SPRNodalRecoveryModel()
Destructor.
Class representing process communicator for engineering model.
Definition: processcomm.h:176
CommunicatorBuff * commBuff
Common Communicator buffer.
virtual SPRPatchType SPRNodalRecoveryMI_givePatchType()=0
void beTProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Receiver becomes the result of the product of aMatrix^T and anArray.
Definition: floatarray.C:708
double at(int i, int j) const
Coefficient access function.
Definition: floatmatrix.h:176
void resize(int n)
Checks size of receiver towards requested bounds.
Definition: intarray.C:124
SPRNodalRecoveryModel(Domain *d)
Constructor.
ProblemCommunicator * communicator
Communicator.
StateCounterType stateCounter
Time stamp of recovered values.
virtual int clear()
Clears the receiver&#39;s nodal table.
Class representing vector of real numbers.
Definition: floatarray.h:82
int unpackAllData(T *ptr, int(T::*unpackFunc)(ProcessCommunicator &))
Unpack all problemCommuncators data from recv buffers.
Definition: communicator.h:262
elementParallelMode giveParallelMode() const
Return elementParallelMode of receiver.
Definition: element.h:1069
Element is local, there are no contributions from other domains to this element.
Definition: element.h:101
Implementation of matrix containing floating point numbers.
Definition: floatmatrix.h:94
const IntArray * giveDofManConnectivityArray(int dofman)
void resize(int rows, int cols)
Checks size of receiver towards requested bounds.
Definition: floatmatrix.C:1358
void zero()
Zeroes all coefficients of receiver.
Definition: floatarray.C:658
int giveRank() const
Returns domain rank in a group of collaborating processes (0..groupSize-1)
Definition: engngm.h:1058
virtual Interface * giveInterface(InterfaceType t)
Interface requesting service.
Definition: femcmpnn.h:179
void zero()
Zeroes all coefficient of receiver.
Definition: floatmatrix.C:1326
virtual int read(int *data, int count)
Reads count integer values into array pointed by data.
Definition: processcomm.h:91
The Communicator and corresponding buffers (represented by this class) are separated in order to allo...
Definition: communicator.h:60
const char * __InternalStateTypeToString(InternalStateType _value)
Definition: cltypes.C:298
Abstract base class representing the "problem" under consideration.
Definition: engngm.h:181
int giveSize() const
Definition: intarray.h:203
int giveSize() const
Returns the size of receiver.
Definition: floatarray.h:218
Node * giveNode(int n)
Service for accessing particular domain node.
Definition: domain.h:371
the oofem namespace is to define a context or scope in which all oofem names are defined.
bool initCommMap
Communication init flag.
int giveNumber() const
Definition: femcmpnn.h:107
DofManager * giveDofManager(int n)
Service for accessing particular domain dof manager.
Definition: domain.C:314
The base class for all recovery models, which perform nodal averaging or projection processes for int...
virtual void SPRNodalRecoveryMI_giveDofMansDeterminedByPatch(IntArray &answer, int pap)=0
DofManager is local, there are no contribution from other domains to this DofManager.
Definition: dofmanager.h:81
Class representing integration point in finite element program.
Definition: gausspoint.h:93
#define OOFEM_WARNING(...)
Definition: error.h:62
bool hasElement(int elem) const
Return True if given element is contained.
Definition: set.C:218
InternalStateType valType
Determines the type of recovered values.
Class representing solution step.
Definition: timestep.h:80
virtual int computeGlobalCoordinates(FloatArray &answer, const FloatArray &lcoords)
Computes the global coordinates from given element&#39;s local coordinates.
Definition: element.C:1207
const IntArray & giveElementList()
Returns list of elements within set.
Definition: set.C:138
DofManager is shared by neighboring partitions, it is necessary to sum contributions from all contrib...
Definition: dofmanager.h:82
dofManagerParallelMode giveParallelMode() const
Return dofManagerParallelMode of receiver.
Definition: dofmanager.h:512
void resize(int s)
Resizes receiver towards requested size.
Definition: floatarray.C:631

This page is part of the OOFEM documentation. Copyright (c) 2011 Borek Patzak
Project e-mail: info@oofem.org
Generated at Tue Jan 2 2018 20:07:31 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011