OOFEM 3.0
Loading...
Searching...
No Matches
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 - 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 "dofmanager.h"
39#include "engngm.h"
40#include "classfactory.h"
41
42#ifdef __MPI_PARALLEL_MODE
43 #include "problemcomm.h"
44 #include "processcomm.h"
45 #include "communicator.h"
46#endif
47
48namespace oofem {
49REGISTER_NodalRecoveryModel(NodalAveragingRecoveryModel, NodalRecoveryModel :: NRM_NodalAveraging);
50
51NodalAveragingRecoveryModel :: NodalAveragingRecoveryModel(Domain *d) : NodalRecoveryModel(d)
52{ }
53
54NodalAveragingRecoveryModel :: ~NodalAveragingRecoveryModel()
55{ }
56
57int
58NodalAveragingRecoveryModel :: recoverValues(Set elementSet, InternalStateType type, TimeStep *tStep)
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 __MPI_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 * >
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 __MPI_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 __MPI_PARALLEL_MODE
164
165void
166NodalAveragingRecoveryModel :: initCommMaps()
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
179void
180NodalAveragingRecoveryModel :: exchangeDofManValues(FloatArray &lhs, IntArray &regionDofMansConnectivity,
181 IntArray &regionNodalNumbers, int regionValSize)
182{
183 parallelStruct ls( &lhs, &regionDofMansConnectivity, &regionNodalNumbers, regionValSize);
184
185 // exchange data for shared nodes
186 communicator->packAllData(this, & ls, & NodalAveragingRecoveryModel :: packSharedDofManData);
187 communicator->initExchange(789);
188 communicator->unpackAllData(this, & ls, & NodalAveragingRecoveryModel :: unpackSharedDofManData);
189 communicator->finishExchange();
190}
191
192int
193NodalAveragingRecoveryModel :: packSharedDofManData(parallelStruct *s, ProcessCommunicator &processComm)
194{
195 int result = 1;
197 const IntArray &toSendMap = processComm.giveToSendMap();
198
199 for ( int inode : toSendMap ) {
200 // toSendMap contains all shared dofmans with remote partition
201 // one has to check, if particular shared node value is available for given region
202 int indx = s->regionNodalNumbers->at( inode );
203 if ( indx ) {
204 // pack "1" to indicate that for given shared node this is a valid contribution
205 result &= pcbuff->write(1);
206 result &= pcbuff->write( s->regionDofMansConnectivity->at(indx) );
207 int eq = ( indx - 1 ) * s->regionValSize;
208 for ( int j = 1; j <= s->regionValSize; j++ ) {
209 result &= pcbuff->write( s->lhs->at(eq + j) );
210 }
211 } else {
212 // ok shared node is not in active region (determined by s->regionNodalNumbers)
213 result &= pcbuff->write(0);
214 }
215 }
216
217 return result;
218}
219
220int
221NodalAveragingRecoveryModel :: unpackSharedDofManData(parallelStruct *s, ProcessCommunicator &processComm)
222{
223 int result = 1;
224 int flag, intValue;
225 const IntArray &toRecvMap = processComm.giveToRecvMap();
227
228 for ( int inode : toRecvMap ) {
229 int indx = s->regionNodalNumbers->at( inode );
230 // toRecvMap contains all shared dofmans with remote partition
231 // one has to check, if particular shared node received contribution is available for given region
232 result &= pcbuff->read(flag);
233 if ( flag ) {
234 // "1" to indicates that for given shared node this is a valid contribution
235 result &= pcbuff->read(intValue);
236 // now check if we have a valid number
237 if ( indx ) {
238 s->regionDofMansConnectivity->at(indx) += intValue;
239 }
240
241 int eq = ( indx - 1 ) * s->regionValSize;
242 for ( int j = 1; j <= s->regionValSize; j++ ) {
243 double value;
244 result &= pcbuff->read(value);
245 if ( indx ) {
246 s->lhs->at(eq + j) += value;
247 }
248 }
249 }
250 }
251
252 return result;
253}
254
255#endif
256} // end namespace oofem
#define REGISTER_NodalRecoveryModel(class, type)
elementParallelMode giveParallelMode() const
Definition element.h:1139
virtual int giveNumberOfDofManagers() const
Definition element.h:695
DofManager * giveDofManager(int i) const
Definition element.C:553
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 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
virtual void NodalAveragingRecoveryMI_computeNodalValue(FloatArray &answer, int node, InternalStateType type, TimeStep *tStep)=0
void exchangeDofManValues(FloatArray &lhs, IntArray &, IntArray &, int)
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()
const IntArray & giveElementList()
Definition set.C:158
StateCounterType giveSolutionStateCounter()
Definition timestep.h:211
#define OOFEM_WARNING(...)
Definition error.h:80
#define OOFEM_LOG_INFO(...)
Definition logger.h:143
#define OOFEM_LOG_RELEVANT(...)
Definition logger.h:142
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
@ CBT_dynamic
@ NodalAveragingRecoveryModelInterfaceType

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