OOFEM 3.0
Loading...
Searching...
No Matches
linearstability.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
35// please activate or de-activate next line
36//#define LIN_STAB_COMPATIBILITY_MODE
37
38#include "oofemcfg.h"
40#include "timestep.h"
41#include "element.h"
42#include "contextioerr.h"
43#include "floatmatrix.h"
44#include "verbose.h"
45#include "floatarray.h"
46#include "classfactory.h"
47#include "datastream.h"
48#include "exportmodulemanager.h"
49#include "dofmanager.h"
50#include "dof.h"
52#include "outputmanager.h"
54
55
56#ifdef __OOFEG
57 #include "oofeggraphiccontext.h"
58#endif
59
60namespace oofem {
62
63LinearStability :: LinearStability(int i, EngngModel *master) : StructuralEngngModel(i, master),
65 rtolv(1e-6),
67{
68 numberOfSteps = 1;
69 ndomains = 1;
70}
71
72
73NumericalMethod *LinearStability :: giveNumericalMethod(MetaStep *mStep)
74{
75 if ( !nMethod ) {
76 nMethod = classFactory.createGeneralizedEigenValueSolver(solverType, this->giveDomain(1), this);
77 if ( !nMethod ) {
78 OOFEM_ERROR("solver creation failed");
79 }
80 }
81
82 return nMethod.get();
83}
84
85
86SparseLinearSystemNM *LinearStability :: giveNumericalMethodForLinStaticProblem(TimeStep *tStep)
87{
88 if ( !nMethodLS ) {
89 nMethodLS = classFactory.createSparseLinSolver(ST_Direct, this->giveDomain(1), this);
90 if ( !nMethodLS ) {
91 OOFEM_ERROR("solver creation failed");
92 }
93 }
94
95 return nMethodLS.get();
96}
97
98
99void
100LinearStability :: initializeFrom(InputRecord &ir)
101{
102 //StructuralEngngModel::instanciateFrom(ir);
104 // numberOfSteps set artifficially to numberOfRequiredEigenValues
105 // in order to allow
106 // use restoreContext function for different eigenValues
108 this->field = std::make_unique<EigenVectorPrimaryField>(this, 1, FT_Displacements, numberOfRequiredEigenValues + 1); // +1 for eq. solution
109
111 if ( rtolv < 1.e-12 ) {
112 rtolv = 1.e-12;
113 } else if ( rtolv > 0.01 ) {
114 rtolv = 0.01;
115 }
116
117 int val = 0;
120
121 nMetaSteps = 0;
122
124
125 if (suppressOutput) {
126 printf("Suppressing output.\n");
127 } else {
128 if ( ( outputStream = fopen(this->dataOutputFileName.c_str(), "w") ) == NULL ) {
129 OOFEM_ERROR("Can't open output file %s", this->dataOutputFileName.c_str());
130 }
131
132 fprintf(outputStream, "%s", PRG_HEADER);
133 fprintf(outputStream, "\nStarting analysis on: %s\n", ctime(& this->startTime) );
134 fprintf(outputStream, "%s\n", simulationDescription.c_str());
135 }
136}
137
138
139int LinearStability :: giveUnknownDictHashIndx(ValueModeType mode, TimeStep *tStep)
140{
141 return tStep->giveNumber() % (this->numberOfRequiredEigenValues + 1); // +1 for eq. solution
142}
143
144
145double LinearStability :: giveUnknownComponent(ValueModeType mode, TimeStep *tStep, Domain *d, Dof *dof)
146{
147 return field->giveUnknownValue(dof, mode, tStep);
148}
149
150
151TimeStep *LinearStability :: giveNextStep()
152{
153 int istep = giveNumberOfFirstStep();
154 StateCounterType counter = 1;
155
156 if ( currentStep ) {
157 istep = currentStep->giveNumber() + 1;
158 counter = currentStep->giveSolutionStateCounter() + 1;
159 }
160
161 previousStep = std :: move(currentStep);
162 currentStep = std::make_unique<TimeStep>(istep, this, 1, 0., 0., counter);
163
164 return currentStep.get();
165}
166
167
168void LinearStability :: solveYourself()
169{
170 this->timer.startTimer(EngngModelTimer :: EMTT_AnalysisTimer);
171 // update state according to new meta step
172 this->giveNextStep();
173 this->updateAttributes( this->giveCurrentMetaStep() );
174 this->solveYourselfAt( this->giveCurrentStep() );
175 this->terminate( this->giveCurrentStep() );
176}
177
178
179void LinearStability :: solveYourselfAt(TimeStep *tStep)
180{
181 tStep->setNumber(0);
182 tStep->setTime(0.0);
183
184 // creates system of governing eq's and solves them at given time step
185 this->giveNumericalMethod( this->giveMetaStep( tStep->giveMetaStepNumber() ) );
187
188 // first assemble problem at current time step
189 if ( !stiffnessMatrix ) {
190 //
191 // first step - solve linear static problem
192 //
193 stiffnessMatrix = classFactory.createSparseMtrx(SMT_Skyline);
194 stiffnessMatrix->buildInternalStructure( this, 1, EModelDefaultEquationNumbering() );
195 }
196
197#ifndef LIN_STAB_COMPATIBILITY_MODE
198 OOFEM_LOG_INFO("Assembling stiffness matrix\n");
199 stiffnessMatrix->zero();
200 this->assemble( *stiffnessMatrix, tStep, TangentAssembler(TangentStiffness),
202#endif
203
204 OOFEM_LOG_INFO("Assembling load\n");
206 FloatArray displacementVector(neq), loadVector(neq);
207
208 // Internal forces first, negated;
209 field->update(VM_Total, tStep, displacementVector, EModelDefaultEquationNumbering());
210 this->assembleVector( loadVector, tStep, InternalForceAssembler(), VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(1) );
211 loadVector.negated();
212
213 this->assembleVector( loadVector, tStep, ExternalForceAssembler(), VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(1) );
215
216 OOFEM_LOG_INFO("Solving linear static problem\n");
217 nMethodLS->solve(*stiffnessMatrix, loadVector, displacementVector);
218 // Initial displacements are stored at position 0; this is a bit of a hack. In the future, a cleaner approach of handling fields could be suitable,
219 // but currently, it all converges down to the same giveUnknownComponent, so this is the easisest approach.
220 field->update(VM_Total, tStep, displacementVector, EModelDefaultEquationNumbering());
221 // terminate linear static computation (necessary, in order to compute stresses in elements).
222 // Recompute for updated state:
223 this->assembleVector( loadVector, tStep, InternalForceAssembler(), VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(1) );
224 this->terminateLinStatic( tStep );
225
226 // Normal forces already known, proceed with linear stability
227 stiffnessMatrix->zero();
228 if ( !initialStressMatrix ) {
230 } else {
231 initialStressMatrix->zero();
232 }
233
234 OOFEM_LOG_INFO("Assembling stiffness matrix\n");
235 this->assemble( *stiffnessMatrix, tStep, TangentAssembler(TangentStiffness),
237
238 OOFEM_LOG_INFO("Assembling initial stress matrix\n");
241 initialStressMatrix->times(-1.0);
242
243 //stiffnessMatrix->printYourself();
244 //initialStressMatrix->printYourself();
245
248 eigVal.zero();
249
250 OOFEM_LOG_INFO("Solving ...\n");
252 this->field->updateAll(eigVec, EModelDefaultEquationNumbering());
253}
254
255
256void LinearStability :: updateYourself(TimeStep *tStep)
257{ }
258
259
260void
261LinearStability :: terminateLinStatic(TimeStep *tStep)
262{
263 Domain *domain = this->giveDomain(1);
264
265 for ( auto &dman : domain->giveDofManagers() ) {
266 dman->updateYourself(tStep);
267 }
268
269# ifdef VERBOSE
270 VERBOSE_PRINT0("Updated nodes ", domain->giveNumberOfDofManagers())
271# endif
272
273 for ( auto &elem : domain->giveElements() ) {
274 elem->updateInternalState(tStep);
275 elem->updateYourself(tStep);
276 }
277
278# ifdef VERBOSE
279 VERBOSE_PRINT0("Updated Elements ", domain->giveNumberOfElements())
280# endif
281
282#if 0
283 // save context if required
284 // default - save only if ALWAYS is set ( see cltypes.h )
285
286 if ((domain->giveContextOutputMode() == COM_Always ) ||
287 (domain->giveContextOutputMode() == COM_Required )) {
288 this->saveContext(NULL);
289 } else if (domain->giveContextOutputMode() == COM_UserDefined ) {
290 if (tStep->giveNumber()%domain->giveContextOutputStep() == 0)
291 this->saveContext(NULL);
292 }
293#endif
294}
295
296
297void LinearStability :: doStepOutput(TimeStep *tStep)
298{
299 if ( !suppressOutput ) {
300 this->printOutputAt(this->giveOutputStream(), tStep);
301 fflush( this->giveOutputStream() );
302 }
303
304 Domain *domain = this->giveDomain(1);
305 // i = 0 represents the linear solution, which is followed by the eigen vectors starting at i = 1
306 for ( int i = 0; i <= numberOfRequiredEigenValues; i++ ) {
307 TimeStep step = *tStep;
308 step.setTime( ( double ) i );
309 step.setNumber(i);
310
311 for ( auto &dman : domain->giveDofManagers() ) {
312 dman->updateYourself(&step);
313 }
314
315 exportModuleManager.doOutput(&step);
316 }
317}
318
319
320void LinearStability :: printOutputAt(FILE *file, TimeStep *tStep)
321{
322 Domain *domain = this->giveDomain(1);
323 if ( !domain->giveOutputManager()->testTimeStepOutput(tStep) ) {
324 return;
325 }
326
327 fprintf(file, "\nLinear Stability:");
328 fprintf(file, "\nEigen Values are:\n-----------------\n");
329
330 for ( int i = 1; i <= numberOfRequiredEigenValues; i++ ) {
331 fprintf(file, "%15.8e ", eigVal.at(i) );
332 if ( ( i % 5 ) == 0 ) {
333 fprintf(file, "\n");
334 }
335 }
336
337 fprintf(file, "\n\n");
338
339 for ( int i = 0; i <= numberOfRequiredEigenValues; i++ ) {
340 TimeStep step = *tStep;
341 step.setTime( ( double ) i );
342 step.setNumber(i);
343
344 if ( i == 0 ) {
345 fprintf(file, "\nLinear solution\n\n");
346 } else {
347 fprintf(file, "\nEigen vector no. %d, corresponding eigen value is %15.8e\n\n", i, eigVal.at(i));
348 }
349
350 for ( auto &dman : domain->giveDofManagers() ) {
351 dman->updateYourself(&step);
352 dman->printOutputAt(file, &step);
353 }
354
355 if ( i == 0 ) {
356 for ( auto &elem : domain->giveElements() ) {
357 elem->printOutputAt(file, &step);
358 }
359 this->printReactionForces(&step, 1., file);
360 }
361 }
362}
363
364
365void LinearStability :: setActiveVector(int activeVector)
366{
367 this->giveCurrentStep()->setTime( ( double ) activeVector );
368 this->giveCurrentStep()->setNumber( ( double ) activeVector );
369}
370
371
372void LinearStability :: saveContext(DataStream &stream, ContextMode mode)
373{
374 StructuralEngngModel :: saveContext(stream, mode);
375
376 field->saveContext(stream);
377
379 if ( ( iores = eigVal.storeYourself(stream) ) != CIO_OK ) {
380 THROW_CIOERR(iores);
381 }
382}
383
384
385void LinearStability :: restoreContext(DataStream &stream, ContextMode mode)
386{
387 StructuralEngngModel :: restoreContext(stream, mode);
388
389 field->restoreContext(stream);
390
392 if ( ( iores = eigVal.restoreYourself(stream) ) != CIO_OK ) {
393 THROW_CIOERR(iores);
394 }
395}
396
397
398} // end namespace oofem
#define REGISTER_EngngModel(class)
OutputManager * giveOutputManager()
Definition domain.C:1544
int giveNumberOfElements() const
Returns number of elements in domain.
Definition domain.h:463
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< Element > > & giveElements()
Definition domain.h:294
virtual TimeStep * giveCurrentStep(bool force=false)
Definition engngm.h:717
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
FILE * giveOutputStream()
Returns file descriptor of output file.
Definition engngm.C:1994
time_t startTime
Solution start time.
Definition engngm.h:271
MetaStep * giveMetaStep(int i)
Returns the i-th meta step.
Definition engngm.h:773
EngngModelTimer timer
E-model timer.
Definition engngm.h:279
int nMetaSteps
Number of meta steps.
Definition engngm.h:235
ExportModuleManager exportModuleManager
Export module manager.
Definition engngm.h:260
EngngModel * master
Master e-model; if defined receiver is in maintained (slave) mode.
Definition engngm.h:274
bool suppressOutput
Flag for suppressing output to file.
Definition engngm.h:337
FILE * outputStream
Output stream.
Definition engngm.h:252
virtual int giveNumberOfFirstStep(bool force=false)
Definition engngm.h:763
virtual void updateAttributes(MetaStep *mStep)
Definition engngm.C:669
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 bool hasField(InputFieldType id)=0
Returns true if record contains field identified by idString keyword.
std ::unique_ptr< EigenVectorPrimaryField > field
SparseLinearSystemNM * giveNumericalMethodForLinStaticProblem(TimeStep *tStep)
void solveYourselfAt(TimeStep *tStep) override
GenEigvalSolverType solverType
Numerical method used to solve the problem.
NumericalMethod * giveNumericalMethod(MetaStep *mStep) override
Returns reference to receiver's numerical method.
std ::unique_ptr< SparseLinearSystemNM > nMethodLS
Numerical method used to solve the static problem.
std ::unique_ptr< SparseMtrx > initialStressMatrix
TimeStep * giveNextStep() override
Returns next time step (next to current step) of receiver.
void terminateLinStatic(TimeStep *tStep)
std ::unique_ptr< SparseGeneralEigenValueSystemNM > nMethod
void printOutputAt(FILE *file, TimeStep *tStep) override
std ::unique_ptr< SparseMtrx > stiffnessMatrix
void saveContext(DataStream &stream, ContextMode mode) override
int testTimeStepOutput(TimeStep *)
void terminate(TimeStep *tStep) override
void printReactionForces(TimeStep *tStep, int id, FILE *out)
StructuralEngngModel(int i, EngngModel *master=nullptr)
Creates new StructuralEngngModel with number i, associated to domain d.
int giveMetaStepNumber()
Returns receiver's meta step number.
Definition timestep.h:150
void setNumber(int i)
Set receiver's number.
Definition timestep.h:146
int giveNumber()
Returns receiver's number.
Definition timestep.h:144
void setTime(double newt)
Sets target and intrinsic time to be equal.
Definition timestep.h:172
#define THROW_CIOERR(e)
#define _IFT_EngngModel_suppressOutput
Definition engngm.h:94
#define OOFEM_ERROR(...)
Definition error.h:79
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Definition inputrecord.h:75
#define IR_GIVE_FIELD(__ir, __value, __id)
Definition inputrecord.h:67
#define _IFT_LinearStability_nroot
#define _IFT_LinearStability_stype
#define _IFT_LinearStability_rtolv
#define OOFEM_LOG_INFO(...)
Definition logger.h:143
long ContextMode
Definition contextmode.h:43
FloatArrayF< N > assemble(const FloatArrayF< M > &x, int const (&c)[M])
Assemble components into zero matrix.
long StateCounterType
StateCounterType type used to indicate solution state.
@ COM_Required
If required (for backtracking computation).
@ COM_Always
Enable for post-processing.
@ COM_UserDefined
Input attribute of domain (each n-th step).
@ SMT_Skyline
Symmetric skyline.
ClassFactory & classFactory
OOFEM_EXPORT const char * PRG_HEADER
Definition oofemcfg.C:22
#define VERBOSE_PRINT0(str, number)
Definition verbose.h:56

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