OOFEM 3.0
Loading...
Searching...
No Matches
dofdistributedprimaryfield.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 "dofmanager.h"
37#include "dof.h"
38#include "domain.h"
39#include "timestep.h"
40#include "floatarray.h"
41#include "engngm.h"
42#include "set.h"
43#include "boundarycondition.h"
44#include "initialcondition.h"
45#include "element.h"
46#include "activebc.h"
47
48
49namespace oofem {
50DofDistributedPrimaryField :: DofDistributedPrimaryField(EngngModel *a, int idomain,
51 FieldType ft, int nHist, double alpha) :
52 PrimaryField(a, idomain, ft, nHist),
53 alpha(alpha)
54{ }
55
56DofDistributedPrimaryField :: ~DofDistributedPrimaryField()
57{ }
58
59double
60DofDistributedPrimaryField :: giveUnknownValue(Dof *dof, ValueModeType mode, TimeStep *tStep)
61{
62 if ( mode == VM_Total ) {
63 return dof->giveUnknownsDictionaryValue(tStep, mode);
64 } else {
65 double val1 = dof->giveUnknownsDictionaryValue(tStep, VM_Total);
66 double val0 = dof->giveUnknownsDictionaryValue(tStep->givePreviousStep(), VM_Total);
67 if ( mode == VM_Velocity ) {
68 return (val1 - val0) / tStep->giveTimeIncrement();
69 } else if ( mode == VM_Intermediate || mode == VM_TotalIntrinsic ) {
70 return this->alpha * val1 + (1-this->alpha) * val0;
71 } else if ( mode == VM_Incremental ) {
72 return val1 - val0;
73 } else {
74 OOFEM_ERROR("Unknown value mode requested");
75 }
76 }
77
78 return 0.;
79}
80
81void
82DofDistributedPrimaryField :: initialize(ValueModeType mode, TimeStep *tStep, FloatArray &answer, const UnknownNumberingScheme &s)
83{
84 Domain *d = emodel->giveDomain(domainIndx);
85 int neq = emodel->giveNumberOfDomainEquations(domainIndx, s);
86
87 answer.resize(neq);
88 answer.zero();
89
90 for ( auto &node : d->giveDofManagers() ) {
91 for ( Dof *dof: *node ) {
92 if ( !dof->isPrimaryDof() ) continue;
93 int eqNum = dof->giveEquationNumber(s);
94 if ( eqNum ) {
95 answer.at(eqNum) = dof->giveUnknownsDictionaryValue(tStep, mode);
96 }
97 }
98 }
99
100 for ( auto &elem : d->giveElements() ) {
101 int ndman = elem->giveNumberOfInternalDofManagers();
102 for ( int i = 1; i <= ndman; i++ ) {
103 for ( auto &dof : *elem->giveInternalDofManager(i) ) {
104 if ( !dof->isPrimaryDof() ) continue;
105 int eqNum = dof->giveEquationNumber(s);
106 if ( eqNum > 0 ) {
107 answer.at(eqNum) = dof->giveUnknownsDictionaryValue(tStep, mode);
108 }
109 }
110 }
111 }
112
113 for ( auto &bc : d->giveBcs() ) {
114 int ndman = bc->giveNumberOfInternalDofManagers();
115 for ( int i = 1; i <= ndman; i++ ) {
116 for ( auto &dof : *bc->giveInternalDofManager(i) ) {
117 if ( !dof->isPrimaryDof() ) continue;
118 int eqNum = dof->giveEquationNumber(s);
119 if ( eqNum > 0 ) {
120 answer.at(eqNum) = dof->giveUnknownsDictionaryValue(tStep, mode);
121 }
122 }
123 }
124 }
125}
126
127
128void
129DofDistributedPrimaryField :: update(ValueModeType mode, TimeStep *tStep, const FloatArray &vectorToStore, const UnknownNumberingScheme &s)
130{
131 Domain *d = emodel->giveDomain(domainIndx);
132
133 auto set_values = [&mode, &tStep, &vectorToStore, &s](DofManager &dman) {
134 for ( Dof *dof: dman ) {
135 if ( !dof->isPrimaryDof() ) continue;
136 int eqNum = dof->giveEquationNumber(s);
137 if ( eqNum > 0 ) {
138 dof->updateUnknownsDictionary(tStep, VM_Total, vectorToStore.at(eqNum));
139 }
140 }
141 };
142
143 for ( auto &node : d->giveDofManagers() ) {
144 set_values(*node);
145 }
146
147 for ( auto &elem : d->giveElements() ) {
148 int ndman = elem->giveNumberOfInternalDofManagers();
149 for ( int i = 1; i <= ndman; i++ ) {
150 set_values(*elem->giveInternalDofManager(i));
151 }
152 }
153
154 for ( auto &bc : d->giveBcs() ) {
155 int ndman = bc->giveNumberOfInternalDofManagers();
156 for ( int i = 1; i <= ndman; i++ ) {
157 set_values(*bc->giveInternalDofManager(i));
158 }
159 }
160}
161
162
163void
164DofDistributedPrimaryField :: applyDefaultInitialCondition()
165{
166 Domain *d = emodel->giveDomain(domainIndx);
167 TimeStep *tStep = emodel->giveSolutionStepWhenIcApply();
168 // Copy over the old dictionary values to the new step as the initial guess:
169 for ( auto &dman : d->giveDofManagers() ) {
170 if ( dman->isNull() ) continue;
171 for ( auto &dof : *dman ) {
172 dof->updateUnknownsDictionary(tStep, VM_Total, 0.);
173 int icid = dof->giveIcId();
174 if ( icid > 0 && dof->isPrimaryDof() ) {
175 InitialCondition *ic = d->giveIc(icid);
176 if ( ic->hasConditionOn(VM_Total) ) {
177 FloatArray c = dman->giveCoordinates();
178 double val = ic->give(VM_Total, c);
179 dof->updateUnknownsDictionary(tStep, VM_Total, val);
180 }
181 }
182 }
183 }
184
185 for ( auto &elem : d->giveElements() ) {
186 if ( elem->giveParallelMode() == Element_remote ) continue;
187 int ndman = elem->giveNumberOfInternalDofManagers();
188 for ( int i = 1; i <= ndman; i++ ) {
189 for ( auto &dof : *elem->giveInternalDofManager(i) ) {
190 dof->updateUnknownsDictionary(tStep, VM_Total, 0.);
191 }
192 }
193 }
194
195 for ( auto &bc : d->giveBcs() ) {
196 int ndman = bc->giveNumberOfInternalDofManagers();
197 for ( int i = 1; i <= ndman; i++ ) {
198 if ( bc->giveInternalDofManager(i)->isNull() ) continue;
199 for ( auto &dof : *bc->giveInternalDofManager(i) ) {
200 dof->updateUnknownsDictionary(tStep, VM_Total, 0.);
201 }
202 }
203 }
204
205 // Apply ICs that use sets.
206 for ( auto &ic : d->giveIcs() ) {
207 this->applyInitialCondition(*ic);
208 }
209}
210
211void
212DofDistributedPrimaryField :: applyInitialCondition(InitialCondition &ic)
213{
214 if ( ic.giveSetNumber() == 0 ) {
215 return;
216 }
217
218 Domain *d = ic.giveDomain();
219 Set *set = d->giveSet(ic.giveSetNumber());
220 TimeStep *tStep = emodel->giveSolutionStepWhenIcApply();
221 //TimeStep *prev = tStep->givePreviousStep();
222
223 // We have to set initial value, and velocity, for this particular primary field.
224 for ( int inode : set->giveNodeList() ) {
225 DofManager *dman = d->giveDofManager(inode);
226 if ( dman->isNull() ) continue;
227 double tot0 = 0;
228 if ( ic.hasConditionOn(VM_Total) ) {
229 FloatArray c = dman->giveCoordinates();
230 tot0 = ic.give(VM_Total, c);
231 }
232#if 0
233 Not relevant for this time discretization
234 double tot1 = 0.
235 if ( ic.hasConditionOn(VM_Incremental) ) {
236 tot1 = tot0 - ic.give(VM_Incremental);
237 } else if ( ic.hasConditionOn(VM_Velocity) ) {
238 tot1 = tot0 - ic.give(VM_Velocity) * tStep->giveTimeIncrement();
239 } else {
240 tot1 = tot0;
241 }
242#endif
243 for ( int dofid : ic.giveDofIDs() ) {
244 if ( dman->findDofWithDofId((DofIDItem)dofid) != dman->end() ) {
245 Dof *dof = dman->giveDofWithID(dofid);
246 //dof->updateUnknownsDictionary(tStep, VM_Total, tot1);
247 dof->updateUnknownsDictionary(tStep, VM_Total, tot0);
248 }
249 }
250 }
251}
252
253
254void
255DofDistributedPrimaryField :: applyBoundaryCondition(TimeStep *tStep)
256{
257 Domain *d = emodel->giveDomain(domainIndx);
258 for ( auto &dman : d->giveDofManagers() ) {
259 if ( dman->isNull() ) continue;
260 for ( auto &dof : *dman ) {
261 if ( dof->hasBc(tStep) && dof->isPrimaryDof() ) {
262 int bcid = dof->giveBcId();
263 double val = static_cast< BoundaryCondition* >(d->giveBc(bcid))->give(dof, VM_Total, tStep->giveTargetTime());
264 dof->updateUnknownsDictionary(tStep, VM_Total, val);
265 }
266 }
267 }
268
269 for ( auto &bc : d->giveBcs() ) {
270 if ( bc->isImposed(tStep) ) {
271 BoundaryCondition *dbc = dynamic_cast< BoundaryCondition* >(bc.get());
272 ActiveBoundaryCondition *abc = dynamic_cast< ActiveBoundaryCondition* >(bc.get());
273 if ( dbc && dbc->isImposed(tStep) ) {
274 this->applyBoundaryCondition(*dbc, tStep);
275 } else if ( abc ) {
276 for ( int i = 1; i <= abc->giveNumberOfInternalDofManagers(); i++ ) {
277 if ( abc->giveInternalDofManager(i)->isNull() ) continue;
278 for ( auto &dof : *abc->giveInternalDofManager(i) ) {
279 if ( dof->isPrimaryDof() && abc->hasBc(dof, tStep) ) {
280 dof->updateUnknownsDictionary( tStep, VM_Total, abc->giveBcValue(dof, VM_Total, tStep) );
281 }
282 }
283 }
284 }
285 }
286 }
287}
288
289
290void
291DofDistributedPrimaryField :: applyBoundaryCondition(BoundaryCondition &bc, TimeStep *tStep)
292{
293 if ( bc.giveSetNumber() == 0 ) {
294 return;
295 }
296
297 Domain *d = bc.giveDomain();
298 Set *set = d->giveSet(bc.giveSetNumber());
299 for ( int inode : set->giveNodeList() ) {
300 DofManager *dman = d->giveDofManager(inode);
301 if ( dman->isNull() ) continue;
302 for ( auto &dofid : bc.giveDofIDs() ) {
303 if ( !dman->hasDofID((DofIDItem)dofid) ) {
304 continue;
305 }
306 Dof *dof = dman->giveDofWithID(dofid);
307 if ( dof->isPrimaryDof() ) {
308 dof->updateUnknownsDictionary( tStep, VM_Total, bc.give(dof, VM_Total, tStep->giveTargetTime()) );
309 }
310 }
311 }
312}
313
314
315void
316DofDistributedPrimaryField :: setInitialGuess(DofManager &dman, TimeStep *tStep, TimeStep *prev)
317{
318 for ( auto &dof : dman ) {
319 double val = dof->giveUnknownsDictionaryValue( prev, VM_Total );
320 dof->updateUnknownsDictionary( tStep, VM_Total, val );
321 }
322}
323
324void
325DofDistributedPrimaryField :: advanceSolution(TimeStep *tStep)
326{
327 // Copy over the old dictionary values to the new step as the initial guess:
328 Domain *d = emodel->giveDomain(1);
329 TimeStep *prev = tStep->givePreviousStep();
330 for ( auto &dman : d->giveDofManagers() ) {
331 if ( dman->isNull() ) continue;
332 this->setInitialGuess(*dman, tStep, prev);
333 }
334
335 for ( auto &elem : d->giveElements() ) {
336 if ( elem->giveParallelMode() == Element_remote ) continue;
337 int ndman = elem->giveNumberOfInternalDofManagers();
338 for ( int i = 1; i <= ndman; i++ ) {
339 this->setInitialGuess(*elem->giveInternalDofManager(i), tStep, prev);
340 }
341 }
342
343 for ( auto &bc : d->giveBcs() ) {
344 int ndman = bc->giveNumberOfInternalDofManagers();
345 for ( int i = 1; i <= ndman; i++ ) {
346 if ( bc->giveInternalDofManager(i)->isNull() ) continue;
347 this->setInitialGuess(*bc->giveInternalDofManager(i), tStep, prev);
348 }
349 }
350
351 // Apply dirichlet b.c.s
352 this->applyBoundaryCondition(tStep);
353}
354
355} // end namespace oofem
#define OOFEM_ERROR(...)
Definition error.h:79
FieldType
Physical type of field.
Definition field.h:64

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