OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
zznodalrecoverymodel.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 "zznodalrecoverymodel.h"
36 #include "timestep.h"
37 #include "element.h"
38 #include "dofmanager.h"
39 #include "gausspoint.h"
40 #include "integrationrule.h"
41 #include "feinterpol.h"
42 #include "mathfem.h"
43 #include "feinterpol.h"
44 #include "error.h"
45 #include "engngm.h"
46 #include "classfactory.h"
47 
48 #include <sstream>
49 #include <set>
50 
51 #ifdef __PARALLEL_MODE
52  #include "problemcomm.h"
53  #include "communicator.h"
54 #endif
55 
56 #define ZZNRM_ZERO_VALUE 1.e-12
57 
58 namespace oofem {
60 
62 { }
63 
65 { }
66 
67 int
69 {
70  int nnodes = domain->giveNumberOfDofManagers();
71  IntArray regionNodalNumbers(nnodes);
72  // following variable is for better error reporting only
73  std :: set< int >unresolvedDofMans;
74  // IntArray loc;
75  FloatArray lhs, nn, sol;
76  FloatMatrix rhs, nsig;
77 
78 
79  if ( this->valType == type && this->stateCounter == tStep->giveSolutionStateCounter() ) {
80  return 1;
81  }
82 
83 #ifdef __PARALLEL_MODE
84  if ( this->domain->giveEngngModel()->isParallel() ) {
85  this->initCommMaps();
86  }
87 #endif
88 
89  // clear nodal table
90  this->clear();
91 
92  int elemNodes;
93  int regionValSize;
94  int regionDofMans;
95 
96  // loop over elements and determine local region node numbering and determine and check nodal values size
97  if ( this->initRegionNodeNumbering(regionNodalNumbers, regionDofMans, elementSet) == 0 ) {
98  return 0;
99  }
100 
101  regionValSize = 0;
102  lhs.resize(regionDofMans);
103  lhs.zero();
104  IntArray elements = elementSet.giveElementList();
105  // assemble element contributions
106  for ( int i = 1; i <= elements.giveSize(); i++ ) {
107  int ielem = elements.at(i);
109  Element *element = domain->giveElement(ielem);
110 
111  if ( element->giveParallelMode() != Element_local ) {
112  continue;
113  }
114 
115  // If an element doesn't implement the interface, it is ignored.
116  if ( ( interface = static_cast< ZZNodalRecoveryModelInterface * >( element->giveInterface(ZZNodalRecoveryModelInterfaceType) ) ) == NULL ) {
117  //abort();
118  continue;
119  }
120 
121 
122  // ask element contributions
123  if (!interface->ZZNodalRecoveryMI_computeNValProduct(nsig, type, tStep)) {
124  // skip element contribution if value type recognized by element
125  continue;
126  }
127  interface->ZZNodalRecoveryMI_computeNNMatrix(nn, type);
128 
129  // assemble contributions
130  elemNodes = element->giveNumberOfDofManagers();
131 
132  if ( regionValSize == 0 ) {
133  regionValSize = nsig.giveNumberOfColumns();
134  rhs.resize(regionDofMans, regionValSize);
135  rhs.zero();
136  if ( regionValSize == 0 ) {
137  OOFEM_LOG_RELEVANT( "ZZNodalRecoveryModel :: unknown size of InternalStateType %s\n", __InternalStateTypeToString(type) );
138  }
139  } else if ( regionValSize != nsig.giveNumberOfColumns() ) {
140  nsig.resize(regionDofMans, regionValSize);
141  nsig.zero();
142  OOFEM_LOG_RELEVANT( "ZZNodalRecoveryModel :: changing size of for InternalStateType %s. New sized results ignored (this shouldn't happen).\n", __InternalStateTypeToString(type) );
143  }
144 
145  //loc.resize ((elemNodes+elemSides)*regionValSize);
146  int eq = 1;
147  for ( int elementNode = 1; elementNode <= elemNodes; elementNode++ ) {
148  int node = element->giveDofManager(elementNode)->giveNumber();
149  lhs.at( regionNodalNumbers.at(node) ) += nn.at(eq);
150  for ( int j = 1; j <= regionValSize; j++ ) {
151  rhs.at(regionNodalNumbers.at(node), j) += nsig.at(eq, j);
152  }
153 
154  eq++;
155  }
156  } // end assemble element contributions
157 
158 #ifdef __PARALLEL_MODE
159  if ( this->domain->giveEngngModel()->isParallel() ) {
160  this->exchangeDofManValues(lhs, rhs, regionNodalNumbers);
161  }
162 #endif
163 
164  sol.resize(regionDofMans * regionValSize);
165  sol.zero();
166 
167  bool missingDofManContribution = false;
168  unresolvedDofMans.clear();
169  // solve for recovered values of active region
170  for ( int i = 1; i <= regionDofMans; i++ ) {
171  int eq = ( i - 1 ) * regionValSize;
172  for ( int j = 1; j <= regionValSize; j++ ) {
173  // rhs will be overriden by recovered values
174  if ( fabs( lhs.at(i) ) > ZZNRM_ZERO_VALUE ) {
175  sol.at(eq + j) = rhs.at(i, j) / lhs.at(i);
176  } else {
177  missingDofManContribution = true;
178  unresolvedDofMans.insert( regionNodalNumbers.at(i) );
179  sol.at(eq + j) = 0.0;
180  }
181  }
182  }
183 
184  // update recovered values
185  this->updateRegionRecoveredValues(regionNodalNumbers, regionValSize, sol);
186 
187  if ( missingDofManContribution ) {
188  std :: ostringstream msg;
189  int i = 0;
190  for ( int dman: unresolvedDofMans ) {
191  msg << this->domain->giveDofManager(dman)->giveLabel() << ' ';
192  if ( ++i > 20 ) {
193  break;
194  }
195  }
196  if ( i > 20 ) {
197  msg << "...";
198  }
199  OOFEM_WARNING("some values of some dofmanagers undetermined (in global numbers) \n[%s]", msg.str().c_str() );
200  }
201 
202 
203  this->valType = type;
204  this->stateCounter = tStep->giveSolutionStateCounter();
205  return 1;
206 }
207 
208 
209 bool
211  TimeStep *tStep)
212 { // evaluates N^T sigma over element volume
213  // N(nsigma, nsigma*nnodes)
214  // Definition : sigmaVector = N * nodalSigmaVector
215  FloatArray stressVector, n;
216  FEInterpolation *interpol = element->giveInterpolation();
217  IntegrationRule *iRule = element->giveDefaultIntegrationRulePtr();
218  bool success = true;
219 
220  answer.clear();
221  for ( GaussPoint *gp: *iRule ) {
222  double dV = element->computeVolumeAround(gp);
223  //this-> computeStressVector(stressVector, gp, tStep);
224  if ( !element->giveIPValue(stressVector, gp, type, tStep) ) {
225  success = false;
226  continue;
227  }
228 
229  interpol->evalN( n, gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(element) );
230  answer.plusDyadUnsym(n, stressVector, dV);
231 
232  // help.beTProductOf(n,stressVector);
233  // answer.add(help.times(dV));
234  }
235  return success;
236 }
237 
238 void
240 {
241  //
242  // Returns NTN matrix (lumped) for Zienkiewicz-Zhu
243  // The size of N mtrx is (nstresses, nnodes*nstreses)
244  // Definition : sigmaVector = N * nodalSigmaVector
245  //
246  double volume = 0.0;
247  FloatMatrix fullAnswer;
248  FloatArray n;
249  FEInterpolation *interpol = element->giveInterpolation();
250  IntegrationRule *iRule = element->giveDefaultIntegrationRulePtr();
251 
252  if ( !interpol ) {
253  OOFEM_ERROR( "Element %d not providing interpolation", element->giveNumber() );
254  }
255 
256  int size = element->giveNumberOfDofManagers();
257  fullAnswer.resize(size, size);
258  fullAnswer.zero();
259  double pok = 0.0;
260 
261  for ( GaussPoint *gp: *iRule ) {
262  double dV = element->computeVolumeAround(gp);
263  interpol->evalN( n, gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(element) );
264  fullAnswer.plusDyadSymmUpper(n, dV);
265  pok += ( n.at(1) * dV );
266  volume += dV;
267  }
268 
269 
270  fullAnswer.symmetrized();
271  answer.resize(size);
272  for ( int i = 1; i <= size; i++ ) {
273  double sum = 0.0;
274  for ( int j = 1; j <= size; j++ ) {
275  sum += fullAnswer.at(i, j);
276  }
277 
278  answer.at(i) = sum;
279  }
280 }
281 
282 
283 #ifdef __PARALLEL_MODE
284 
285 void
287 {
288  #ifdef __PARALLEL_MODE
289  if ( initCommMap ) {
290  EngngModel *emodel = domain->giveEngngModel();
292  communicator = new NodeCommunicator(emodel, commBuff, emodel->giveRank(),
293  emodel->giveNumberOfProcesses());
294  communicator->setUpCommunicationMaps(domain->giveEngngModel(), true, true);
295  OOFEM_LOG_INFO("ZZNodalRecoveryModel :: initCommMaps: initialized comm maps");
296  initCommMap = false;
297  }
298 
299  #endif
300 }
301 
302 void
304 {
305  parallelStruct ls( &lhs, &rhs, &rn);
306 
307  // exchange data for shared nodes
312 }
313 
314 int
316 {
317  int result = 1, indx, nc, size;
319  IntArray const *toSendMap = processComm.giveToSendMap();
320  nc = s->rhs->giveNumberOfColumns();
321 
322  size = toSendMap->giveSize();
323  for ( int i = 1; i <= size; i++ ) {
324  // toSendMap contains all shared dofmans with remote partition
325  // one has to check, if particular shared node value is available for given region
326  indx = s->regionNodalNumbers->at( toSendMap->at(i) );
327  if ( indx ) {
328  // pack "1" to indicate that for given shared node this is a valid contribution
329  result &= pcbuff->write(1);
330  result &= pcbuff->write( s->lhs->at(indx) );
331  for ( int j = 1; j <= nc; j++ ) {
332  result &= pcbuff->write( s->rhs->at(indx, j) );
333  }
334 
335  //printf("[%d] ZZ: Sending data for shred node %d[%d]\n", domain->giveEngngModel()->giveRank(),
336  // toSendMap->at(i), domain->giveDofManager(toSendMap->at(i))->giveGlobalNumber());
337  } else {
338  // ok shared node is not in active region (determined by s->regionNodalNumbers)
339  result &= pcbuff->write(0);
340  }
341  }
342 
343  return result;
344 }
345 
346 int
348 {
349  int result = 1;
350  int nc, indx, size, flag;
351  IntArray const *toRecvMap = processComm.giveToRecvMap();
353  double value;
354  nc = s->rhs->giveNumberOfColumns();
355 
356  size = toRecvMap->giveSize();
357  for ( int i = 1; i <= size; i++ ) {
358  indx = s->regionNodalNumbers->at( toRecvMap->at(i) );
359  // toRecvMap contains all shared dofmans with remote partition
360  // one has to check, if particular shared node received contribution is available for given region
361  result &= pcbuff->read(flag);
362  if ( flag ) {
363  // "1" to indicates that for given shared node this is a valid contribution
364  result &= pcbuff->read(value);
365  // now check if we have a valid number
366  if ( indx ) {
367  s->lhs->at(indx) += value;
368  }
369 
370  for ( int j = 1; j <= nc; j++ ) {
371  result &= pcbuff->read(value);
372  if ( indx ) {
373  s->rhs->at(indx, j) += value;
374  }
375  }
376 
377  //if (indx) printf("[%d] ZZ: Receiving data for shred node %d[%d]\n", domain->giveEngngModel()->giveRank(),
378  // toRecvMap->at(i), domain->giveDofManager(toRecvMap->at(i))->giveGlobalNumber());
379  }
380  }
381 
382  return result;
383 }
384 
385 #endif
386 } // end namespace oofem
InternalStateType
Type representing the physical meaning of element or constitutive model internal variable.
int giveNumberOfColumns() const
Returns number of columns of receiver.
Definition: floatmatrix.h:158
int initExchange(int tag)
Initializes data exchange with all problems.
Definition: communicator.C:104
virtual void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)=0
Evaluates the array of interpolation functions (shape functions) at given point.
Class and object Domain.
Definition: domain.h:115
#define ZZNRM_ZERO_VALUE
int initRegionNodeNumbering(IntArray &regionNodalNumbers, int &regionDofMans, Set &region)
Determine local region node numbering and determine and check nodal values size.
int giveNumberOfDofManagers() const
Returns number of dof managers in domain.
Definition: domain.h:432
The element interface required by ZZNodalRecoveryModel.
int packAllData(T *ptr, int(T::*packFunc)(ProcessCommunicator &))
Pack all problemCommunicators data to their send buffers.
Definition: communicator.h:223
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
int packSharedDofManData(parallelStruct *s, ProcessCommunicator &processComm)
EngngModel * giveEngngModel()
Returns engineering model to which receiver is associated.
Definition: domain.C:433
bool isParallel() const
Returns true if receiver in parallel mode.
Definition: engngm.h:1056
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.
void plusDyadUnsym(const FloatArray &a, const FloatArray &b, double dV)
Adds to the receiver the product .
Definition: floatmatrix.C:811
The ProcessCommunicator and corresponding buffers (represented by this class) are separated in order ...
Definition: processcomm.h:64
Helper structure to pass required arguments to packing/unpacking functions needed in parallel mode...
Class implementing an array of integers.
Definition: intarray.h:61
int & at(int i)
Coefficient access function.
Definition: intarray.h:103
virtual int recoverValues(Set elementSet, InternalStateType type, TimeStep *tStep)
Recovers the nodal values for all regions.
virtual int giveNumberOfDofManagers() const
Definition: element.h:656
Abstract base class representing integration rule.
int finishExchange()
Finishes the exchange.
Definition: communicator.C:115
#define OOFEM_LOG_RELEVANT(...)
Definition: logger.h:126
REGISTER_NodalRecoveryModel(NodalAveragingRecoveryModel, NodalRecoveryModel::NRM_NodalAveraging)
const IntArray * giveToSendMap()
Returns receiver to send map.
Definition: processcomm.h:223
int unpackSharedDofManData(parallelStruct *s, ProcessCommunicator &processComm)
Class representing a general abstraction for finite element interpolation class.
Definition: feinterpol.h:132
#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
int giveLabel() const
Definition: dofmanager.h:502
virtual bool ZZNodalRecoveryMI_computeNValProduct(FloatMatrix &answer, InternalStateType type, TimeStep *tStep)
Computes the element contribution to , where is quantity to be recovered (for example stress or stra...
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
Wrapper around element definition to provide FEICellGeometry interface.
Definition: feinterpol.h:95
Class representing process communicator for engineering model.
Definition: processcomm.h:176
CommunicatorBuff * commBuff
Common Communicator buffer.
double at(int i, int j) const
Coefficient access function.
Definition: floatmatrix.h:176
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
void plusDyadSymmUpper(const FloatArray &a, double dV)
Adds to the receiver the dyadic product .
Definition: floatmatrix.C:756
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
void exchangeDofManValues(FloatArray &lhs, FloatMatrix &rhs, IntArray &rn)
virtual void ZZNodalRecoveryMI_computeNNMatrix(FloatArray &answer, InternalStateType type)
Computes the element contribution to term.
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 ~ZZNodalRecoveryModel()
Destructor.
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
the oofem namespace is to define a context or scope in which all oofem names are defined.
DofManager * giveDofManager(int i) const
Definition: element.C:514
bool initCommMap
Communication init flag.
void clear()
Sets size of receiver to be an empty matrix. It will have zero rows and zero columns size...
Definition: floatmatrix.h:516
ZZNodalRecoveryModel(Domain *d)
Constructor.
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...
void symmetrized()
Initializes the lower half of the receiver according to the upper half.
Definition: floatmatrix.C:1576
Class representing integration point in finite element program.
Definition: gausspoint.h:93
#define OOFEM_WARNING(...)
Definition: error.h:62
InternalStateType valType
Determines the type of recovered values.
Class representing solution step.
Definition: timestep.h:80
const IntArray & giveElementList()
Returns list of elements within set.
Definition: set.C:138
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:32 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011