OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
nodalaveragingrecoverymodel.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 
36 #include "timestep.h"
37 #include "element.h"
38 #include "dofmanager.h"
39 #include "engngm.h"
40 #include "classfactory.h"
41 
42 #ifdef __PARALLEL_MODE
43  #include "problemcomm.h"
44  #include "processcomm.h"
45  #include "communicator.h"
46 #endif
47 
48 namespace oofem {
50 
52 { }
53 
55 { }
56 
57 int
59 {
60  int nnodes = domain->giveNumberOfDofManagers();
61  IntArray regionNodalNumbers(nnodes);
62  IntArray regionDofMansConnectivity;
63  FloatArray lhs, val;
64 
65 
66  if ( ( this->valType == type ) && ( this->stateCounter == tStep->giveSolutionStateCounter() ) ) {
67  return 1;
68  }
69 
70 #ifdef __PARALLEL_MODE
71  bool parallel = this->domain->giveEngngModel()->isParallel();
72  if ( parallel ) {
73  this->initCommMaps();
74  }
75 #endif
76 
77  // clear nodal table
78  this->clear();
79 
80  int regionValSize = 0;
81  int regionDofMans;
82 
83  // loop over elements and determine local region node numbering and determine and check nodal values size
84  if ( this->initRegionNodeNumbering(regionNodalNumbers, regionDofMans, elementSet) == 0 ) {
85  return 0;
86  }
87 
88  regionDofMansConnectivity.resize(regionDofMans);
89  regionDofMansConnectivity.zero();
90 
91  IntArray elements = elementSet.giveElementList();
92  // assemble element contributions
93  for ( int i = 1; i <= elements.giveSize(); i++ ) {
94  int ielem = elements.at(i);
96  Element *element = domain->giveElement(ielem);
97 
98  if ( element->giveParallelMode() != Element_local ) {
99  continue;
100  }
101 
102  // If an element doesn't implement the interface, it is ignored.
103  if ( ( interface = static_cast< NodalAveragingRecoveryModelInterface * >
104  ( element->giveInterface(NodalAveragingRecoveryModelInterfaceType) ) ) == NULL ) {
105  //abort();
106  continue;
107  }
108 
109  int elemNodes = element->giveNumberOfDofManagers();
110  // ask element contributions
111  for ( int elementNode = 1; elementNode <= elemNodes; elementNode++ ) {
112  int node = element->giveDofManager(elementNode)->giveNumber();
113  interface->NodalAveragingRecoveryMI_computeNodalValue(val, elementNode, type, tStep);
114  // if the element cannot evaluate this variable, it is ignored
115  if ( val.giveSize() == 0 ) {
116  continue;
117  } else if ( regionValSize == 0 ) {
118  regionValSize = val.giveSize();
119  lhs.resize(regionDofMans * regionValSize);
120  lhs.zero();
121  } else if ( val.giveSize() != regionValSize ) {
122  OOFEM_LOG_RELEVANT("NodalAveragingRecoveryModel :: size mismatch for InternalStateType %s, ignoring all elements that doesn't use the size %d\n", __InternalStateTypeToString(type), regionValSize);
123  continue;
124  }
125  int eq = ( regionNodalNumbers.at(node) - 1 ) * regionValSize;
126  for ( int j = 1; j <= regionValSize; j++ ) {
127  lhs.at(eq + j) += val.at(j);
128  }
129 
130  regionDofMansConnectivity.at( regionNodalNumbers.at(node) )++;
131  }
132  } // end assemble element contributions
133 
134 #ifdef __PARALLEL_MODE
135  if ( parallel ) {
136  this->exchangeDofManValues(lhs, regionDofMansConnectivity, regionNodalNumbers, regionValSize);
137  }
138 #endif
139 
140  // solve for recovered values of active region
141  for ( int inode = 1; inode <= nnodes; inode++ ) {
142  if ( regionNodalNumbers.at(inode) ) {
143  int eq = ( regionNodalNumbers.at(inode) - 1 ) * regionValSize;
144  for ( int i = 1; i <= regionValSize; i++ ) {
145  if ( regionDofMansConnectivity.at( regionNodalNumbers.at(inode) ) > 0 ) {
146  lhs.at(eq + i) /= regionDofMansConnectivity.at( regionNodalNumbers.at(inode) );
147  } else {
148  OOFEM_WARNING("values of dofmanager %d undetermined", inode);
149  lhs.at(eq + i) = 0.0;
150  }
151  }
152  }
153  }
154 
155  // update recovered values
156  this->updateRegionRecoveredValues(regionNodalNumbers, regionValSize, lhs);
157 
158  this->valType = type;
159  this->stateCounter = tStep->giveSolutionStateCounter();
160  return 1;
161 }
162 
163 #ifdef __PARALLEL_MODE
164 
165 void
167 {
168  if ( initCommMap ) {
169  EngngModel *emodel = domain->giveEngngModel();
171  communicator = new NodeCommunicator(emodel, commBuff, emodel->giveRank(),
172  emodel->giveNumberOfProcesses());
173  communicator->setUpCommunicationMaps(domain->giveEngngModel(), true, true);
174  OOFEM_LOG_INFO("NodalAveragingRecoveryModel :: initCommMaps: initialized comm maps\n");
175  initCommMap = false;
176  }
177 }
178 
179 void
181  IntArray &regionNodalNumbers, int regionValSize)
182 {
183  parallelStruct ls( &lhs, &regionDofMansConnectivity, &regionNodalNumbers, regionValSize);
184 
185  // exchange data for shared nodes
190 }
191 
192 int
194 {
195  int result = 1, size;
197  IntArray const *toSendMap = processComm.giveToSendMap();
198 
199  size = toSendMap->giveSize();
200  for ( int i = 1; i <= size; i++ ) {
201  // toSendMap contains all shared dofmans with remote partition
202  // one has to check, if particular shared node value is available for given region
203  int indx = s->regionNodalNumbers->at( toSendMap->at(i) );
204  if ( indx ) {
205  // pack "1" to indicate that for given shared node this is a valid contribution
206  result &= pcbuff->write(1);
207  result &= pcbuff->write( s->regionDofMansConnectivity->at(indx) );
208  int eq = ( indx - 1 ) * s->regionValSize;
209  for ( int j = 1; j <= s->regionValSize; j++ ) {
210  result &= pcbuff->write( s->lhs->at(eq + j) );
211  }
212  } else {
213  // ok shared node is not in active region (determined by s->regionNodalNumbers)
214  result &= pcbuff->write(0);
215  }
216  }
217 
218  return result;
219 }
220 
221 int
223 {
224  int result = 1;
225  int size, flag, intValue;
226  IntArray const *toRecvMap = processComm.giveToRecvMap();
228  double value;
229 
230  size = toRecvMap->giveSize();
231  for ( int i = 1; i <= size; i++ ) {
232  int indx = s->regionNodalNumbers->at( toRecvMap->at(i) );
233  // toRecvMap contains all shared dofmans with remote partition
234  // one has to check, if particular shared node received contribution is available for given region
235  result &= pcbuff->read(flag);
236  if ( flag ) {
237  // "1" to indicates that for given shared node this is a valid contribution
238  result &= pcbuff->read(intValue);
239  // now check if we have a valid number
240  if ( indx ) {
241  s->regionDofMansConnectivity->at(indx) += intValue;
242  }
243 
244  int eq = ( indx - 1 ) * s->regionValSize;
245  for ( int j = 1; j <= s->regionValSize; j++ ) {
246  result &= pcbuff->read(value);
247  if ( indx ) {
248  s->lhs->at(eq + j) += value;
249  }
250  }
251  }
252  }
253 
254  return result;
255 }
256 
257 #endif
258 } // end namespace oofem
InternalStateType
Type representing the physical meaning of element or constitutive model internal variable.
The element interface required by NodalAvergagingRecoveryModel.
int initExchange(int tag)
Initializes data exchange with all problems.
Definition: communicator.C:104
Class and object Domain.
Definition: domain.h:115
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
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
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
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.
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 int giveNumberOfDofManagers() const
Definition: element.h:656
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 recoverValues(Set elementSet, InternalStateType type, TimeStep *tStep)
Recovers the nodal values for all regions.
#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
virtual void NodalAveragingRecoveryMI_computeNodalValue(FloatArray &answer, int node, InternalStateType type, TimeStep *tStep)=0
Computes the element value in given node.
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
Class representing process communicator for engineering model.
Definition: processcomm.h:176
CommunicatorBuff * commBuff
Common Communicator buffer.
void resize(int n)
Checks size of receiver towards requested bounds.
Definition: intarray.C:124
int unpackSharedDofManData(parallelStruct *s, ProcessCommunicator &processComm)
ProblemCommunicator * communicator
Communicator.
StateCounterType stateCounter
Time stamp of recovered values.
virtual int clear()
Clears the receiver&#39;s nodal table.
void exchangeDofManValues(FloatArray &lhs, IntArray &, IntArray &, int)
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
int packSharedDofManData(parallelStruct *s, ProcessCommunicator &processComm)
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
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
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.
int giveNumber() const
Definition: femcmpnn.h:107
The base class for all recovery models, which perform nodal averaging or projection processes for int...
Helper structure to pass required arguments to packing/unpacking functions needed in parallel mode...
#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:30 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011