OOFEM 3.0
Loading...
Searching...
No Matches
incrementallinearstatic.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 "oofemcfg.h"
37#include "timestep.h"
38#include "dof.h"
39#include "domain.h"
40#include "sparsemtrx.h"
41#include "dictionary.h"
42#include "verbose.h"
43#include "classfactory.h"
44#include "datastream.h"
45#include "contextioerr.h"
46#include "dofmanager.h"
47#include "activebc.h"
49
50/*
51#include "set.h"
52#include "element.h"
53#include "node.h"
54*/
55
56#include "boundarycondition.h"
57
58#include <vector>
59#include <set>
60
61namespace oofem {
63
64IncrementalLinearStatic :: IncrementalLinearStatic(int i, EngngModel *_master) : StructuralEngngModel(i, _master),
66{
67 ndomains = 1;
69}
70
71
72IncrementalLinearStatic :: ~IncrementalLinearStatic()
73{}
74
75
76NumericalMethod *IncrementalLinearStatic :: giveNumericalMethod(MetaStep *mStep)
77
78{
79 if ( !nMethod ) {
80 nMethod = classFactory.createSparseLinSolver(solverType, this->giveDomain(1), this);
81 if ( !nMethod ) {
82 OOFEM_ERROR("linear solver creation failed for lstype %d", solverType);
83 }
84 }
85
86 return nMethod.get();
87}
88
89
90void IncrementalLinearStatic :: initializeFrom(InputRecord &ir)
91{
93 if ( discreteTimes.giveSize() > 0 ) {
94 numberOfSteps = discreteTimes.giveSize();
96 fixedSteps = false;
97 } else {
98 deltaT = 1.0;
102 fixedSteps = true;
103 }
105
106 int val = 0;
109
110 val = 0;
113
114
116
117 if(suppressOutput) {
118 printf("Suppressing output.\n");
119 }
120 else {
121
122 if ( ( outputStream = fopen(this->dataOutputFileName.c_str(), "w") ) == NULL ) {
123 OOFEM_ERROR("Can't open output file %s", this->dataOutputFileName.c_str());
124 }
125
126 fprintf(outputStream, "%s", PRG_HEADER);
127 fprintf(outputStream, "\nStarting analysis on: %s\n", ctime(& this->startTime) );
128 fprintf(outputStream, "%s\n", simulationDescription.c_str());
129 }
130
131 //StructuralEngngModel::initializeFrom (ir);
132}
133
134
135double IncrementalLinearStatic :: giveDiscreteTime(int iStep)
136{
137 if ( this->fixedSteps ) {
138 return this->deltaT * iStep;
139 } else {
140 if ( ( iStep > 0 ) && ( iStep <= discreteTimes.giveSize() ) ) {
141 return ( discreteTimes.at(iStep) );
142 }
143 }
144
145 OOFEM_ERROR("invalid iStep");
146}
147
148
149TimeStep *IncrementalLinearStatic :: giveNextStep()
150{
151 if ( !currentStep ) {
152 currentStep = std::make_unique<TimeStep>(giveNumberOfTimeStepWhenIcApply(), this, 0, 0., this->giveDiscreteTime(1), 0);
153 }
154
155 previousStep = std :: move(currentStep);
156 double dt = this->giveDiscreteTime(previousStep->giveNumber()+1) - previousStep->giveTargetTime();
157 currentStep = std::make_unique<TimeStep>(*previousStep, dt);
158 return currentStep.get();
159}
160
161void IncrementalLinearStatic :: solveYourself()
162{
163 this->giveDiscreteTime(1); // ensures numberOfSteps defined
164 StructuralEngngModel :: solveYourself();
165}
166
167void IncrementalLinearStatic :: solveYourselfAt(TimeStep *tStep)
168{
169 Domain *d = this->giveDomain(1);
170 // Creates system of governing eq's and solves them at given time step
171
172
173 // >>> beginning PH
174 // The following piece of code updates assignment of boundary conditions to dofs
175 // (this allows to have multiple boundary conditions assigned to one dof
176 // which can be arbitrarily turned on and off in time)
177 // Almost the entire section has been copied from domain.C
178 std :: vector< std :: map< int, int > > dof_bc( d->giveNumberOfDofManagers() );
179
180 for ( int i = 1; i <= d->giveNumberOfBoundaryConditions(); ++i ) {
181 GeneralBoundaryCondition *gbc = d->giveBc(i);
182
183 if ( gbc->isImposed(tStep) ){
184
185 if ( gbc->giveSetNumber() > 0 ) {
186 // Loop over nodes in set and store the bc number in each dof.
187 Set *set = d->giveSet( gbc->giveSetNumber() );
188 ActiveBoundaryCondition *active_bc = dynamic_cast< ActiveBoundaryCondition * >(gbc);
189 BoundaryCondition *bc = dynamic_cast< BoundaryCondition * >(gbc);
190 if ( bc || ( active_bc && active_bc->requiresActiveDofs() ) ) {
191 const IntArray &appliedDofs = gbc->giveDofIDs();
192 const IntArray &nodes = set->giveNodeList();
193 for ( int inode = 1; inode <= nodes.giveSize(); ++inode ) {
194 for ( int idof = 1; idof <= appliedDofs.giveSize(); ++idof ) {
195
196 if ( dof_bc [ nodes.at(inode) - 1 ].find( appliedDofs.at(idof) ) == dof_bc [ nodes.at(inode) - 1 ].end() ) {
197 // is empty
198 dof_bc [ nodes.at(inode) - 1 ] [ appliedDofs.at(idof) ] = i;
199
200 DofManager * dofman = d->giveDofManager( nodes.at(inode) );
201 Dof * dof = dofman->giveDofWithID( appliedDofs.at(idof) );
202
203 dof->setBcId(i);
204
205 } else {
206 // another bc has been already prescribed at this time step to this dof
207 OOFEM_WARNING("More than one boundary condition assigned at time %f to node %d dof %d. Considering boundary condition %d", tStep->giveTargetTime(), nodes.at(inode), appliedDofs.at(idof), dof_bc [ nodes.at(inode) - 1 ] [appliedDofs.at(idof)] );
208
209
210 }
211 }
212 }
213 }
214 }
215 }
216 }
217
218 // to get proper number of equations
220 // <<< end PH
221
222
223
224 // Initiates the total displacement to zero.
225 if ( tStep->isTheFirstStep() ) {
226 for ( auto &dofman : d->giveDofManagers() ) {
227 for ( Dof *dof: *dofman ) {
228 dof->updateUnknownsDictionary(tStep->givePreviousStep(), VM_Total, 0.);
229 dof->updateUnknownsDictionary(tStep, VM_Total, 0.);
230 }
231 }
232
233 for ( auto &bc : d->giveBcs() ) {
235
236 if ( ( abc = dynamic_cast< ActiveBoundaryCondition * >(bc.get()) ) ) {
237 int ndman = abc->giveNumberOfInternalDofManagers();
238 for ( int i = 1; i <= ndman; i++ ) {
239 DofManager *dofman = abc->giveInternalDofManager(i);
240 for ( Dof *dof: *dofman ) {
241 dof->updateUnknownsDictionary(tStep->givePreviousStep(), VM_Total, 0.);
242 dof->updateUnknownsDictionary(tStep, VM_Total, 0.);
243 }
244 }
245 }
246 }
247 }
248
249 // Apply dirichlet b.c's on total values
250 for ( auto &dofman : d->giveDofManagers() ) {
251 for ( Dof *dof: *dofman ) {
252 double tot = dof->giveUnknown( VM_Total, tStep->givePreviousStep() );
253 if ( dof->hasBc(tStep) ) {
254 tot += dof->giveBcValue(VM_Incremental, tStep);
255 }
256
257 dof->updateUnknownsDictionary(tStep, VM_Total, tot);
258 }
259 }
260
262
263#ifdef VERBOSE
264 OOFEM_LOG_RELEVANT("Solving [step number %8d, time %15e, equations %d]\n", tStep->giveNumber(), tStep->giveTargetTime(), neq);
265#endif
266
267 if ( neq == 0 ) { // Allows for fully prescribed/empty problems.
268 return;
269 }
270
273
274#ifdef VERBOSE
275 OOFEM_LOG_INFO("Assembling load\n");
276#endif
277 // Assembling the element part of load vector
278 internalLoadVector.resize(neq);
279 internalLoadVector.zero();
281 VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(1) );
282
283 loadVector.resize(neq);
284 loadVector.zero();
286 VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(1) );
287
290
291
292#ifdef VERBOSE
293 OOFEM_LOG_INFO("Assembling stiffness matrix\n");
294#endif
295 stiffnessMatrix = classFactory.createSparseMtrx(sparseMtrxType);
296 if ( !stiffnessMatrix ) {
297 OOFEM_ERROR("sparse matrix creation failed");
298 }
299
300 stiffnessMatrix->buildInternalStructure( this, 1, EModelDefaultEquationNumbering() );
301 stiffnessMatrix->zero();
302 this->assemble( *stiffnessMatrix, tStep, TangentAssembler(TangentStiffness),
304
305#ifdef VERBOSE
306 OOFEM_LOG_INFO("Solving ...\n");
307#endif
310 if ( s!= CR_CONVERGED) {
311 OOFEM_ERROR("No success in solving system.");
312 }
313 tStep->convergedReason = s;
314}
315
316
317double IncrementalLinearStatic :: giveUnknownComponent(ValueModeType mode, TimeStep *tStep, Domain *d, Dof *dof)
318{
319 if ( this->requiresUnknownsDictionaryUpdate() ) {
320 int hash = this->giveUnknownDictHashIndx(mode, tStep);
321 if ( dof->giveUnknowns()->includes(hash) ) {
322 return dof->giveUnknowns()->at(hash);
323 } else {
324 OOFEM_ERROR("Dof unknowns dictionary does not contain unknown of value mode (%s)", __ValueModeTypeToString(mode) );
325 }
326 } else {
327 OOFEM_ERROR("Only the mode requiresUnknownsDictionaryUpdate() is supported");
328 }
329
330 // return 0.;
331}
332
333
334int IncrementalLinearStatic :: giveUnknownDictHashIndx(ValueModeType mode, TimeStep *tStep)
335{
336 return tStep->giveNumber() % 2;
337}
338
339
340void IncrementalLinearStatic :: updateDofUnknownsDictionary(DofManager *inode, TimeStep *tStep)
341{
342 // update DOF unknowns dictionary, where
343 // unknowns are hold instead of keeping them in global unknowns
344 // vectors in engng instances
345 // this is necessary, because during solution equation numbers for
346 // particular DOFs may changed, and it is necessary to keep them
347 // in DOF level.
348
349 double val;
350 for ( Dof *dof: *inode ) {
351 // skip slave DOFs (only master (primary) DOFs have to be updated).
352 if ( !dof->isPrimaryDof() ) {
353 continue;
354 }
355 val = dof->giveUnknown(VM_Total, tStep);
356 if ( !dof->hasBc(tStep) ) {
357 val += this->incrementOfDisplacementVector.at( dof->__giveEquationNumber() );
358 }
359
360 dof->updateUnknownsDictionary(tStep->givePreviousStep(), VM_Total, val);
361 dof->updateUnknownsDictionary(tStep, VM_Total, val);
362 }
363}
364
365
366void IncrementalLinearStatic :: saveContext(DataStream &stream, ContextMode mode)
367{
368 StructuralEngngModel :: saveContext(stream, mode);
369}
370
371
372void IncrementalLinearStatic :: restoreContext(DataStream &stream, ContextMode mode)
373{
374 StructuralEngngModel :: restoreContext(stream, mode);
375}
376} // end namespace oofem
#define REGISTER_EngngModel(class)
virtual bool requiresActiveDofs()
Definition activebc.h:151
Dof * giveDofWithID(int dofID) const
Definition dofmanager.C:127
virtual void giveUnknowns(FloatArray &masterUnknowns, ValueModeType mode, TimeStep *tStep)
Definition dof.C:159
virtual void setBcId(int bcId)
Overwrites the boundary condition id (0-inactive BC), intended for specific purposes such as coupling...
Definition dof.h:382
int giveNumberOfBoundaryConditions() const
Returns number of boundary conditions in domain.
Definition domain.h:469
Set * giveSet(int n)
Definition domain.C:366
std ::vector< std ::unique_ptr< DofManager > > & giveDofManagers()
Definition domain.h:427
int giveNumberOfDofManagers() const
Returns number of dof managers in domain.
Definition domain.h:461
std ::vector< std ::unique_ptr< GeneralBoundaryCondition > > & giveBcs()
Definition domain.h:349
DofManager * giveDofManager(int n)
Definition domain.C:317
GeneralBoundaryCondition * giveBc(int n)
Definition domain.C:246
int giveNumberOfTimeStepWhenIcApply()
Returns the time step number, when initial conditions should apply.
Definition engngm.h:787
virtual int giveNumberOfDomainEquations(int di, const UnknownNumberingScheme &num)
Definition engngm.C:452
std::string dataOutputFileName
Path to output stream.
Definition engngm.h:248
std::string simulationDescription
Definition engngm.h:339
std ::unique_ptr< TimeStep > previousStep
Previous time step.
Definition engngm.h:243
MetaStep * giveCurrentMetaStep()
Returns current meta step.
Definition engngm.C:1900
int ndomains
Number of receiver domains.
Definition engngm.h:215
int numberOfSteps
Total number of time steps.
Definition engngm.h:219
Domain * giveDomain(int n)
Definition engngm.C:1936
std ::unique_ptr< TimeStep > currentStep
Current time step.
Definition engngm.h:241
time_t startTime
Solution start time.
Definition engngm.h:271
virtual int forceEquationNumbering(int i)
Definition engngm.C:469
bool suppressOutput
Flag for suppressing output to file.
Definition engngm.h:337
FILE * outputStream
Output stream.
Definition engngm.h:252
int updateSharedDofManagers(FloatArray &answer, const UnknownNumberingScheme &s, int ExchangeTag)
Definition engngm.C:2162
void assembleVector(FloatArray &answer, TimeStep *tStep, const VectorAssembler &va, ValueModeType mode, const UnknownNumberingScheme &s, Domain *domain, FloatArray *eNorms=NULL)
Definition engngm.C:1106
virtual int giveNumberOfInternalDofManagers()
Gives the number of internal dof managers.
virtual const IntArray & giveDofIDs() const
virtual bool isImposed(TimeStep *tStep)
virtual DofManager * giveInternalDofManager(int i)
Gives an internal dof manager from receiver.
int giveUnknownDictHashIndx(ValueModeType mode, TimeStep *tStep) override
NumericalMethod * giveNumericalMethod(MetaStep *mStep) override
Returns reference to receiver's numerical method.
std ::unique_ptr< SparseMtrx > stiffnessMatrix
std ::unique_ptr< SparseLinearSystemNM > nMethod
Numerical method used to solve the problem.
virtual bool hasField(InputFieldType id)=0
Returns true if record contains field identified by idString keyword.
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
const IntArray & giveNodeList()
Definition set.C:168
StructuralEngngModel(int i, EngngModel *master=nullptr)
Creates new StructuralEngngModel with number i, associated to domain d.
ConvergedReason convergedReason
Status of solution step (Converged,.
Definition timestep.h:120
double giveTargetTime()
Returns target time.
Definition timestep.h:164
int giveNumber()
Returns receiver's number.
Definition timestep.h:144
TimeStep * givePreviousStep()
Returns pointer to previous solution step.
Definition timestep.C:132
bool isTheFirstStep()
Definition timestep.C:148
#define _IFT_EngngModel_nsteps
Definition engngm.h:78
#define _IFT_EngngModel_suppressOutput
Definition engngm.h:94
#define _IFT_EngngModel_lstype
Definition engngm.h:91
#define _IFT_EngngModel_smtype
Definition engngm.h:92
#define OOFEM_WARNING(...)
Definition error.h:80
#define OOFEM_ERROR(...)
Definition error.h:79
#define _IFT_IncrementalLinearStatic_endoftimeofinterest
#define _IFT_IncrementalLinearStatic_deltat
#define _IFT_IncrementalLinearStatic_prescribedtimes
#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_RELEVANT(...)
Definition logger.h:142
long ContextMode
Definition contextmode.h:43
FloatArrayF< N > assemble(const FloatArrayF< M > &x, int const (&c)[M])
Assemble components into zero matrix.
ClassFactory & classFactory
OOFEM_EXPORT const char * PRG_HEADER
Definition oofemcfg.C:22

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