OOFEM 3.0
Loading...
Searching...
No Matches
directerrorindicatorrc.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 "errorestimator.h"
37#include "domain.h"
38#include "element.h"
39#include "dofmanager.h"
40#include "engngm.h"
41#include "connectivitytable.h"
42#include "mathfem.h"
43#include "timestep.h"
44
45#ifdef __MPI_PARALLEL_MODE
46 #include "problemcomm.h"
47#endif
48
49namespace oofem {
50DirectErrorIndicatorRC :: DirectErrorIndicatorRC(int n, ErrorEstimator *e) : RemeshingCriteria(n, e)
51{
52 stateCounter = -1;
53#ifdef __MPI_PARALLEL_MODE
55#endif
56}
57
58DirectErrorIndicatorRC :: ~DirectErrorIndicatorRC()
59{
60}
61
62void
63DirectErrorIndicatorRC :: giveNodeChar(int inode, TimeStep *tStep, double &indicatorVal, double &currDensity)
64{
65 currDensity = this->giveDofManDensity(inode);
66 indicatorVal = this->giveDofManIndicator(inode, tStep);
67}
68
69
70double
71DirectErrorIndicatorRC :: giveDofManDensity(int num)
72{
73#ifdef __MPI_PARALLEL_MODE
74 Domain *d = this->giveDomain();
75 if ( d->giveDofManager(num)->isShared() ) {
76 return this->sharedDofManDensities [ num ];
77 } else {
78 return this->giveLocalDofManDensity(num);
79 }
80
81#else
82 return this->giveLocalDofManDensity(num);
83
84#endif
85}
86
87double
88DirectErrorIndicatorRC :: giveLocalDofManDensity(int num)
89{
90 int isize;
91 double currDensity = 0.0;
92 const IntArray *con;
93 Domain *d = this->giveDomain();
95
96 con = ct->giveDofManConnectivityArray(num);
97 isize = con->giveSize();
98
99 for ( int i = 1; i <= isize; i++ ) {
100 // ask for indicator variable value and determine current mesh density
101 Element *element = d->giveElement( con->at(i) );
102
103 if ( i == 1 ) {
104 currDensity = element->computeMeanSize();
105 } else {
106 currDensity = max( currDensity, element->computeMeanSize() );
107 }
108 }
109
110 return currDensity;
111}
112
113
114double
115DirectErrorIndicatorRC :: giveDofManIndicator(int num, TimeStep *tStep)
116{
117#ifdef __MPI_PARALLEL_MODE
118 Domain *d = this->giveDomain();
119 if ( d->giveDofManager(num)->isShared() ) {
120 return this->sharedDofManIndicatorVals [ num ];
121 } else {
122 return this->giveLocalDofManIndicator(num, tStep);
123 }
124
125#else
126 return this->giveLocalDofManIndicator(num, tStep);
127
128#endif
129}
130
131double
132DirectErrorIndicatorRC :: giveLocalDofManIndicator(int inode, TimeStep *tStep)
133{
134 int isize;
135 const IntArray *con;
136 Domain *d = this->giveDomain();
138 double indicatorVal = 0.0;
139
140 con = ct->giveDofManConnectivityArray(inode);
141 isize = con->giveSize();
142
143 for ( int i = 1; i <= isize; i++ ) {
144 // ask for indicator variable value and determine current mesh density
145 Element *element = d->giveElement( con->at(i) );
146
147 if ( i == 1 ) {
148 indicatorVal = ee->giveElementError(indicatorET, element, tStep);
149 } else {
150 indicatorVal = max( indicatorVal, ee->giveElementError(indicatorET, element, tStep) );
151 }
152 }
153
154 return indicatorVal;
155}
156
157
158
159int
160DirectErrorIndicatorRC :: estimateMeshDensities(TimeStep *tStep)
161{
162 Domain *d = this->giveDomain();
163 int inode, nnodes = d->giveNumberOfDofManagers();
164 double indicatorVal, currDensity, proposedDensity;
165
166 if ( stateCounter == tStep->giveSolutionStateCounter() ) {
167 return 1;
168 }
169
170#ifdef __MPI_PARALLEL_MODE
171 if ( initCommMap ) {
172 communicator->setUpCommunicationMaps(d->giveEngngModel(), true, true);
173 OOFEM_LOG_INFO("DirectErrorIndicatorRC :: estimateMeshDensities: initialized comm maps\n");
174 initCommMap = false;
175 }
176
177
179 this->exchangeDofManIndicatorVals(tStep);
180#endif
181
183 this->nodalDensities.resize(nnodes);
184
185 for ( inode = 1; inode <= nnodes; inode++ ) {
186 this->giveNodeChar(inode, tStep, indicatorVal, currDensity);
187
188 if ( indicatorVal < minIndicatorLimit ) {
189 this->nodalDensities.at(inode) = zeroIndicatorDensity; //currDensity;
190 } else if ( indicatorVal >= maxIndicatorLimit ) {
191 this->nodalDensities.at(inode) = proposedDensity = maxIndicatorDensity;
192
193 if ( proposedDensity < ( currDensity * this->remeshingDensityRatioToggle ) ) {
195 OOFEM_LOG_DEBUG("DirectEI: remeshing required for node %d, den %e, required_dens %e\n", inode, currDensity, proposedDensity);
196 }
197 } else {
198 // evaluate the required size
199 proposedDensity = minIndicatorDensity +
201 //proposedDensity = min (currDensity, proposedDensity);
202 this->nodalDensities.at(inode) = proposedDensity;
203
204 if ( proposedDensity < ( currDensity * this->remeshingDensityRatioToggle ) ) {
205 OOFEM_LOG_DEBUG("DirectEI: remeshing required for node %d, den %e, required_dens %e\n", inode, currDensity, proposedDensity);
207 }
208 }
209 }
210
211#ifdef __MPI_PARALLEL_MODE
212 // exchange strategies between nodes to ensure consistency
213 int myStrategy = this->currStrategy, globalStrategy;
214 MPI_Allreduce(& myStrategy, & globalStrategy, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
215 this->currStrategy = ( RemeshingStrategy ) globalStrategy;
216#endif
217
218 // remember time stamp
220 return 1;
221}
222
223
224double
225DirectErrorIndicatorRC :: giveRequiredDofManDensity(int num, TimeStep *tStep, int relative)
226{
227 this->estimateMeshDensities(tStep);
228 if ( relative ) {
229 double currDens;
230 currDens = this->giveDofManDensity(num);
231 return this->nodalDensities.at(num) / currDens;
232 } else {
233 return this->nodalDensities.at(num);
234 }
235}
236
237
238void
257
259DirectErrorIndicatorRC :: giveRemeshingStrategy(TimeStep *tStep)
260{
261 this->estimateMeshDensities(tStep);
262 return this->currStrategy;
263}
264
265void
266DirectErrorIndicatorRC :: reinitialize()
267{
268 stateCounter = -1;
269#ifdef __MPI_PARALLEL_MODE
271 initCommMap = true;
272#endif
273}
274
275
276void
277DirectErrorIndicatorRC :: setDomain(Domain *d)
278{
279 RemeshingCriteria :: setDomain(d);
280#ifdef __MPI_PARALLEL_MODE
282 initCommMap = true;
283#endif
284}
285
286
287#ifdef __MPI_PARALLEL_MODE
288void
289DirectErrorIndicatorRC :: exchangeDofManDensities()
290{
291 Domain *domain = this->giveDomain();
292
293 if ( this->dofManDensityExchangeFlag ) {
295 sharedDofManDensities.clear();
296 int size = domain->giveNumberOfDofManagers();
297 for ( int i = 1; i <= size; i++ ) {
298 if ( domain->giveDofManager(i)->giveParallelMode() == DofManager_shared ) {
300 }
301 }
302
303 // exchange them
304 communicator->packAllData(this, & DirectErrorIndicatorRC :: packSharedDofManLocalDensities);
305 communicator->initExchange(999);
306 communicator->unpackAllData(this, & DirectErrorIndicatorRC :: unpackSharedDofManLocalDensities);
307 communicator->finishExchange();
308
309 this->dofManDensityExchangeFlag = false;
310 } // if (this->dofManDensityExchangeFlag)
311}
312
313int
314DirectErrorIndicatorRC :: packSharedDofManLocalDensities(ProcessCommunicator &processComm)
315{
316 int result = 1;
318 const IntArray &toSendMap = processComm.giveToSendMap();
319
320 for ( int inode : toSendMap ) {
321 result &= pcbuff->write(this->sharedDofManDensities [ inode ]);
322 }
323
324 return result;
325}
326
327int
328DirectErrorIndicatorRC :: unpackSharedDofManLocalDensities(ProcessCommunicator &processComm)
329{
330 int result = 1;
331 const IntArray &toRecvMap = processComm.giveToRecvMap();
333 double value;
334
335 for ( int inode : toRecvMap ) {
336 result &= pcbuff->read(value);
337 this->sharedDofManDensities [ inode ] = max(value, this->sharedDofManDensities [ inode ]);
338 #ifdef __VERBOSE_PARALLEL
339 OOFEM_LOG_INFO("unpackSharedDofManLocalDensities: node %d[%d], value %f\n", inode, domain->giveDofManager( inode )->giveGlobalNumber(), this->sharedDofManDensities [ inode ]);
340 #endif
341 }
342
343 return result;
344}
345
346
347
348
349void
350DirectErrorIndicatorRC :: exchangeDofManIndicatorVals(TimeStep *tStep)
351{
352 Domain *domain = this->giveDomain();
353
356 int size = domain->giveNumberOfDofManagers();
357 for ( int i = 1; i <= size; i++ ) {
358 if ( domain->giveDofManager(i)->giveParallelMode() == DofManager_shared ) {
360 }
361 }
362
363 // exchange them
364 communicator->packAllData(this, & DirectErrorIndicatorRC :: packSharedDofManLocalIndicatorVals);
365 communicator->initExchange(999);
366 communicator->unpackAllData(this, & DirectErrorIndicatorRC :: unpackSharedDofManLocalIndicatorVals);
367 communicator->finishExchange();
368}
369
370int
371DirectErrorIndicatorRC :: packSharedDofManLocalIndicatorVals(ProcessCommunicator &processComm)
372{
373 int result = 1;
375 const IntArray &toSendMap = processComm.giveToSendMap();
376
377 for ( int inode : toSendMap ) {
378 result &= pcbuff->write(this->sharedDofManIndicatorVals [ inode ]);
379 }
380
381 return result;
382}
383
384int
385DirectErrorIndicatorRC :: unpackSharedDofManLocalIndicatorVals(ProcessCommunicator &processComm)
386{
387 int result = 1;
388 const IntArray &toRecvMap = processComm.giveToRecvMap();
390
391 for ( int inode : toRecvMap ) {
392 double value;
393 result &= pcbuff->read(value);
394 this->sharedDofManIndicatorVals [ inode ] = max(value, this->sharedDofManIndicatorVals [ inode ]);
395 #ifdef __VERBOSE_PARALLEL
396 OOFEM_LOG_INFO("unpackSharedDofManLocalIndicatorVals: node %d[%d], value %f\n", inode, domain->giveDofManager( inode )->giveGlobalNumber(), this->sharedDofManIndicatorVals [ inode ]);
397 #endif
398 }
399
400 return result;
401}
402
403
404#endif
405} // end namespace oofem
const IntArray * giveDofManConnectivityArray(int dofman)
double giveLocalDofManIndicator(int num, TimeStep *tStep)
StateCounterType stateCounter
Actual values (densities) state counter.
double zeroIndicatorDensity
Default mesh density for Indicator value < minIndicatorLimit.
void exchangeDofManIndicatorVals(TimeStep *tStep)
std ::map< int, double > sharedDofManDensities
double giveDofManIndicator(int num, TimeStep *tStep)
double giveDofManDensity(int num) override
std ::map< int, double > sharedDofManIndicatorVals
void giveNodeChar(int inode, TimeStep *tStep, double &indicatorVal, double &currDensity)
int estimateMeshDensities(TimeStep *tStep) override
bool isShared()
Returns true if receiver is shared.
Definition dofmanager.h:552
ConnectivityTable * giveConnectivityTable()
Definition domain.C:1240
int giveNumberOfDofManagers() const
Returns number of dof managers in domain.
Definition domain.h:461
DofManager * giveDofManager(int n)
Definition domain.C:317
Element * giveElement(int n)
Definition domain.C:165
EngngModel * giveEngngModel()
Definition domain.C:419
double computeMeanSize()
Definition element.C:1100
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
Domain * giveDomain() const
Definition femcmpnn.h:97
Domain * domain
Link to domain object, useful for communicating with other FEM components.
Definition femcmpnn.h:79
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
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()
bool initCommMap
Communication init flag.
RemeshingCriteria(int n, ErrorEstimator *e)
Constructor.
ProblemCommunicator * communicator
Communicator.
CommunicatorBuff * commBuff
Common Communicator buffer.
StateCounterType giveSolutionStateCounter()
Definition timestep.h:211
#define _IFT_DirectErrorIndicatorRC_mindens
#define _IFT_DirectErrorIndicatorRC_remeshingdensityratio
#define _IFT_DirectErrorIndicatorRC_maxdens
#define _IFT_DirectErrorIndicatorRC_maxlim
#define _IFT_DirectErrorIndicatorRC_minlim
#define _IFT_DirectErrorIndicatorRC_defdens
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Definition inputrecord.h:75
#define IR_GIVE_FIELD(__ir, __value, __id)
Definition inputrecord.h:67
#define OOFEM_LOG_INFO(...)
Definition logger.h:143
#define OOFEM_LOG_DEBUG(...)
Definition logger.h:144
FloatArrayF< N > max(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
@ DofManager_shared
Definition dofmanager.h:68
@ CBT_dynamic
RemeshingStrategy
Type representing the remeshing strategy.
@ RemeshingFromCurrentState_RS
@ NoRemeshing_RS

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