OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
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 - 2013 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 #include "../sm/EngineeringModels/incrementallinearstatic.h"
36 #include "timestep.h"
37 #include "dof.h"
38 #include "domain.h"
39 #include "sparsemtrx.h"
40 #include "dictionary.h"
41 #include "verbose.h"
42 #include "classfactory.h"
43 #include "datastream.h"
44 #include "contextioerr.h"
45 #include "dofmanager.h"
46 #include "activebc.h"
47 #include "unknownnumberingscheme.h"
48 
49 /*
50 #include "set.h"
51 #include "element.h"
52 #include "node.h"
53 */
54 
55 #include "boundarycondition.h"
56 
57 #include <vector>
58 #include <set>
59 
60 namespace oofem {
61 REGISTER_EngngModel(IncrementalLinearStatic);
62 
64  loadVector(), internalLoadVector(), incrementOfDisplacementVector(), discreteTimes()
65 {
66  ndomains = 1;
68 }
69 
70 
72 {}
73 
74 
76 
77 {
78  if ( !nMethod ) {
79  nMethod.reset( classFactory.createSparseLinSolver(solverType, this->giveDomain(1), this) );
80  if ( !nMethod ) {
81  OOFEM_ERROR("linear solver creation failed for lstype %d", solverType);
82  }
83  }
84 
85  return nMethod.get();
86 }
87 
88 
90 {
91  IRResultType result;
92 
94  if ( discreteTimes.giveSize() > 0 ) {
97  fixedSteps = false;
98  } else {
99  deltaT = 1.0;
103  fixedSteps = true;
104  }
106 
107  int val = 0;
109  solverType = ( LinSystSolverType ) val;
110 
111  val = 0;
113  sparseMtrxType = ( SparseMtrxType ) val;
114 
115 
117 
118  if(suppressOutput) {
119  printf("Suppressing output.\n");
120  }
121  else {
122 
123  if ( ( outputStream = fopen(this->dataOutputFileName.c_str(), "w") ) == NULL ) {
124  OOFEM_ERROR("Can't open output file %s", this->dataOutputFileName.c_str());
125  }
126 
127  fprintf(outputStream, "%s", PRG_HEADER);
128  fprintf(outputStream, "\nStarting analysis on: %s\n", ctime(& this->startTime) );
129  fprintf(outputStream, "%s\n", simulationDescription.c_str());
130  }
131 
132  //StructuralEngngModel::initializeFrom (ir);
133  return IRRT_OK;
134 }
135 
136 
138 {
139  if ( this->fixedSteps ) {
140  return this->deltaT * iStep;
141  } else {
142  if ( ( iStep > 0 ) && ( iStep <= discreteTimes.giveSize() ) ) {
143  return ( discreteTimes.at(iStep) );
144  }
145  }
146 
147  OOFEM_ERROR("invalid iStep");
148  return 0.0;
149 }
150 
151 
153 {
154  if ( !currentStep ) {
155  currentStep.reset( new TimeStep(giveNumberOfTimeStepWhenIcApply(), this, 0, 0., this->giveDiscreteTime(1), 0) );
156  }
157 
158  previousStep = std :: move(currentStep);
159  double dt = this->giveDiscreteTime(previousStep->giveNumber()+1) - previousStep->giveTargetTime();
160  currentStep.reset( new TimeStep(*previousStep, dt) );
161  return currentStep.get();
162 }
163 
165 {
166  this->giveDiscreteTime(1); // ensures numberOfSteps defined
168 }
169 
171 {
172  Domain *d = this->giveDomain(1);
173  // Creates system of governing eq's and solves them at given time step
174 
175 
176  // >>> beginning PH
177  // The following piece of code updates assignment of boundary conditions to dofs
178  // (this allows to have multiple boundary conditions assigned to one dof
179  // which can be arbitrarily turned on and off in time)
180  // Almost the entire section has been copied from domain.C
181  std :: vector< std :: map< int, int > > dof_bc( d->giveNumberOfDofManagers() );
182 
183  for ( int i = 1; i <= d->giveNumberOfBoundaryConditions(); ++i ) {
184  GeneralBoundaryCondition *gbc = d->giveBc(i);
185 
186  if ( gbc->isImposed(tStep) ){
187 
188  if ( gbc->giveSetNumber() > 0 ) {
189  // Loop over nodes in set and store the bc number in each dof.
190  Set *set = d->giveSet( gbc->giveSetNumber() );
191  ActiveBoundaryCondition *active_bc = dynamic_cast< ActiveBoundaryCondition * >(gbc);
192  BoundaryCondition *bc = dynamic_cast< BoundaryCondition * >(gbc);
193  if ( bc || ( active_bc && active_bc->requiresActiveDofs() ) ) {
194  const IntArray &appliedDofs = gbc->giveDofIDs();
195  const IntArray &nodes = set->giveNodeList();
196  for ( int inode = 1; inode <= nodes.giveSize(); ++inode ) {
197  for ( int idof = 1; idof <= appliedDofs.giveSize(); ++idof ) {
198 
199  if ( dof_bc [ nodes.at(inode) - 1 ].find( appliedDofs.at(idof) ) == dof_bc [ nodes.at(inode) - 1 ].end() ) {
200  // is empty
201  dof_bc [ nodes.at(inode) - 1 ] [ appliedDofs.at(idof) ] = i;
202 
203  DofManager * dofman = d->giveDofManager( nodes.at(inode) );
204  Dof * dof = dofman->giveDofWithID( appliedDofs.at(idof) );
205 
206  dof->setBcId(i);
207 
208  } else {
209  // another bc has been already prescribed at this time step to this dof
210  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)] );
211 
212 
213  }
214  }
215  }
216  }
217  }
218  }
219  }
220 
221  // to get proper number of equations
222  this->forceEquationNumbering();
223  // <<< end PH
224 
225 
226 
227  // Initiates the total displacement to zero.
228  if ( tStep->isTheFirstStep() ) {
229  for ( auto &dofman : d->giveDofManagers() ) {
230  for ( Dof *dof: *dofman ) {
231  dof->updateUnknownsDictionary(tStep->givePreviousStep(), VM_Total, 0.);
232  dof->updateUnknownsDictionary(tStep, VM_Total, 0.);
233  }
234  }
235 
236  for ( auto &bc : d->giveBcs() ) {
238 
239  if ( ( abc = dynamic_cast< ActiveBoundaryCondition * >(bc.get()) ) ) {
240  int ndman = abc->giveNumberOfInternalDofManagers();
241  for ( int i = 1; i <= ndman; i++ ) {
242  DofManager *dofman = abc->giveInternalDofManager(i);
243  for ( Dof *dof: *dofman ) {
244  dof->updateUnknownsDictionary(tStep->givePreviousStep(), VM_Total, 0.);
245  dof->updateUnknownsDictionary(tStep, VM_Total, 0.);
246  }
247  }
248  }
249  }
250  }
251 
252  // Apply dirichlet b.c's on total values
253  for ( auto &dofman : d->giveDofManagers() ) {
254  for ( Dof *dof: *dofman ) {
255  double tot = dof->giveUnknown( VM_Total, tStep->givePreviousStep() );
256  if ( dof->hasBc(tStep) ) {
257  tot += dof->giveBcValue(VM_Incremental, tStep);
258  }
259 
260  dof->updateUnknownsDictionary(tStep, VM_Total, tot);
261  }
262  }
263 
265 
266 #ifdef VERBOSE
267  OOFEM_LOG_RELEVANT("Solving [step number %8d, time %15e, equations %d]\n", tStep->giveNumber(), tStep->giveTargetTime(), neq);
268 #endif
269 
270  if ( neq == 0 ) { // Allows for fully prescribed/empty problems.
271  return;
272  }
273 
276 
277 #ifdef VERBOSE
278  OOFEM_LOG_INFO("Assembling load\n");
279 #endif
280  // Assembling the element part of load vector
284  VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(1) );
285 
286  loadVector.resize(neq);
287  loadVector.zero();
289  VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(1) );
290 
293 
294 
295 #ifdef VERBOSE
296  OOFEM_LOG_INFO("Assembling stiffness matrix\n");
297 #endif
299  if ( !stiffnessMatrix ) {
300  OOFEM_ERROR("sparse matrix creation failed");
301  }
302 
303  stiffnessMatrix->buildInternalStructure( this, 1, EModelDefaultEquationNumbering() );
304  stiffnessMatrix->zero();
305  this->assemble( *stiffnessMatrix, tStep, TangentAssembler(TangentStiffness),
307 
308 #ifdef VERBOSE
309  OOFEM_LOG_INFO("Solving ...\n");
310 #endif
311  this->giveNumericalMethod( this->giveCurrentMetaStep() );
313  if ( !( s & NM_Success ) ) {
314  OOFEM_ERROR("No success in solving system.");
315  }
316 }
317 
318 
320 {
321  if ( this->requiresUnknownsDictionaryUpdate() ) {
322  int hash = this->giveUnknownDictHashIndx(mode, tStep);
323  if ( dof->giveUnknowns()->includes(hash) ) {
324  return dof->giveUnknowns()->at(hash);
325  } else {
326  OOFEM_ERROR("Dof unknowns dictionary does not contain unknown of value mode (%s)", __ValueModeTypeToString(mode) );
327  }
328  } else {
329  OOFEM_ERROR("Only the mode requiresUnknownsDictionaryUpdate() is supported");
330  }
331 
332  return 0.;
333 }
334 
335 
337 {
338  return tStep->giveNumber() % 2;
339 }
340 
341 
343 {
344  // update DOF unknowns dictionary, where
345  // unknowns are hold instead of keeping them in global unknowns
346  // vectors in engng instances
347  // this is necessary, because during solution equation numbers for
348  // particular DOFs may changed, and it is necessary to keep them
349  // in DOF level.
350 
351  double val;
352  for ( Dof *dof: *inode ) {
353  // skip slave DOFs (only master (primary) DOFs have to be updated).
354  if ( !dof->isPrimaryDof() ) {
355  continue;
356  }
357  val = dof->giveUnknown(VM_Total, tStep);
358  if ( !dof->hasBc(tStep) ) {
359  val += this->incrementOfDisplacementVector.at( dof->__giveEquationNumber() );
360  }
361 
362  dof->updateUnknownsDictionary(tStep->givePreviousStep(), VM_Total, val);
363  dof->updateUnknownsDictionary(tStep, VM_Total, val);
364  }
365 }
366 
367 
369 {
370  contextIOResultType iores;
371 
372  if ( ( iores = StructuralEngngModel :: saveContext(stream, mode) ) != CIO_OK ) {
373  THROW_CIOERR(iores);
374  }
375 
376  return CIO_OK;
377 }
378 
379 
381 {
382  contextIOResultType iores;
383 
384  if ( ( iores = StructuralEngngModel :: restoreContext(stream, mode) ) != CIO_OK ) {
385  THROW_CIOERR(iores);
386  }
387 
388  return CIO_OK;
389 }
390 } // end namespace oofem
LinSystSolverType
The values of this type should be related not to specific solvers, but more to specific packages that...
virtual bool isImposed(TimeStep *tStep)
Returns nonzero if receiver representing BC is imposed at given time, otherwise returns zero...
The representation of EngngModel default unknown numbering.
void subtract(const FloatArray &src)
Subtracts array src to receiver.
Definition: floatarray.C:258
std::unique_ptr< SparseMtrx > stiffnessMatrix
FILE * outputStream
Output stream.
Definition: engngm.h:242
#define NM_Success
Numerical method exited with success.
Definition: nmstatus.h:47
std::unique_ptr< TimeStep > currentStep
Current time step.
Definition: engngm.h:231
std::string simulationDescription
Definition: engngm.h:316
Class and object Domain.
Definition: domain.h:115
Implementation for assembling internal forces vectors in standard monolithic, nonlinear FE-problems...
virtual int giveNumberOfDomainEquations(int di, const UnknownNumberingScheme &num)
Returns number of equations for given domain in active (current time step) time step.
Definition: engngm.C:391
virtual bool requiresActiveDofs()
Checks to see if active boundary condition requires special DOFs.
Definition: activebc.h:152
std::string dataOutputFileName
Path to output stream.
Definition: engngm.h:238
int giveNumberOfDofManagers() const
Returns number of dof managers in domain.
Definition: domain.h:432
Class representing meta step.
Definition: metastep.h:62
SparseMtrx * createSparseMtrx(SparseMtrxType type)
Creates new instance of sparse matrix corresponding to given keyword.
Definition: classfactory.C:105
int giveNumberOfBoundaryConditions() const
Returns number of boundary conditions in domain.
Definition: domain.h:440
IncrementalLinearStatic(int i, EngngModel *_master=NULL)
The purpose of DataStream abstract class is to allow to store/restore context to different streams...
Definition: datastream.h:54
std::unique_ptr< TimeStep > previousStep
Previous time step.
Definition: engngm.h:233
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
virtual NumericalMethod * giveNumericalMethod(MetaStep *mStep)
Returns reference to receiver&#39;s numerical method.
ValueModeType
Type representing the mode of UnknownType or CharType, or similar types.
Definition: valuemodetype.h:78
virtual const IntArray & giveDofIDs() const
Array with default dofs which b.c.
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description in input reader.
#define _IFT_IncrementalLinearStatic_deltat
This base class is an abstraction for numerical algorithm.
Definition: nummet.h:80
virtual contextIOResultType saveContext(DataStream &stream, ContextMode mode)
Stores the state of model to output stream.
virtual DofManager * giveInternalDofManager(int i)
Gives an internal dof manager from receiver.
Implementation for assembling tangent matrices in standard monolithic FE-problems.
virtual bool hasField(InputFieldType id)=0
Returns true if record contains field identified by idString keyword.
time_t startTime
Solution start time.
Definition: engngm.h:259
double giveTargetTime()
Returns target time.
Definition: timestep.h:146
Base class for dof managers.
Definition: dofmanager.h:113
std::vector< std::unique_ptr< DofManager > > & giveDofManagers()
Definition: domain.h:400
virtual void solveYourself()
Starts solution process.
Definition: engngm.C:501
virtual contextIOResultType restoreContext(DataStream &stream, ContextMode mode)
Restores the state of model from output stream.
std::unique_ptr< SparseLinearSystemNM > nMethod
Numerical method used to solve the problem.
REGISTER_EngngModel(ProblemSequence)
unsigned long NM_Status
Mask defining NumMetod Status; which can be asked after finishing computation by Numerical Method...
Definition: nmstatus.h:44
Class implementing an array of integers.
Definition: intarray.h:61
int & at(int i)
Coefficient access function.
Definition: intarray.h:103
#define THROW_CIOERR(e)
Definition: contextioerr.h:61
virtual void giveUnknowns(FloatArray &masterUnknowns, ValueModeType mode, TimeStep *tStep)
The key method of class Dof.
Definition: dof.C:162
virtual int giveNumberOfInternalDofManagers()
Gives the number of internal dof managers.
#define OOFEM_LOG_RELEVANT(...)
Definition: logger.h:126
virtual void setBcId(int bcId)
Overwrites the boundary condition id (0-inactive BC), intended for specific purposes such as coupling...
Definition: dof.h:382
GeneralBoundaryCondition * giveBc(int n)
Service for accessing particular domain bc.
Definition: domain.C:243
bool isTheFirstStep()
Check if receiver is first step.
Definition: timestep.C:134
virtual void assemble(SparseMtrx &answer, TimeStep *tStep, const MatrixAssembler &ma, const UnknownNumberingScheme &s, Domain *domain)
Assembles characteristic matrix of required type into given sparse matrix.
Definition: engngm.C:803
MetaStep * giveCurrentMetaStep()
Returns current meta step.
Definition: engngm.C:1684
std::vector< std::unique_ptr< GeneralBoundaryCondition > > & giveBcs()
Definition: domain.h:322
int giveSetNumber()
Gives the set number which boundary condition is applied to.
Class implementing Dirichlet boundary condition on DOF (primary boundary condition).
#define OOFEM_LOG_INFO(...)
Definition: logger.h:127
int giveNumber()
Returns receiver&#39;s number.
Definition: timestep.h:129
#define _IFT_IncrementalLinearStatic_prescribedtimes
double giveDiscreteTime(int iStep)
This function returns time valid for iStep time step, used in integration of structure response...
#define _IFT_EngngModel_smtype
Definition: engngm.h:82
#define OOFEM_ERROR(...)
Definition: error.h:61
virtual void solveYourselfAt(TimeStep *tStep)
Solves problem for given time step.
int numberOfSteps
Total number of time steps.
Definition: engngm.h:209
int ndomains
Number of receiver domains.
Definition: engngm.h:205
int updateSharedDofManagers(FloatArray &answer, const UnknownNumberingScheme &s, int ExchangeTag)
Exchanges necessary remote DofManagers data.
Definition: engngm.C:1957
SparseMtrxType
Enumerative type used to identify the sparse matrix type.
Implementation for assembling external forces vectors in standard monolithic FE-problems.
Set of elements, boundaries, edges and/or nodes.
Definition: set.h:66
virtual double giveUnknownComponent(ValueModeType mode, TimeStep *tStep, Domain *d, Dof *dof)
Returns requested unknown.
#define _IFT_EngngModel_suppressOutput
Definition: engngm.h:84
Set * giveSet(int n)
Service for accessing particular domain set.
Definition: domain.C:363
Abstract base class for all active boundary conditions.
Definition: activebc.h:63
Abstract base class for all boundary conditions of problem.
#define _IFT_EngngModel_nsteps
Definition: engngm.h:68
TimeStep * givePreviousStep()
Returns pointer to previous solution step.
Definition: timestep.C:114
virtual TimeStep * giveNextStep()
Returns next time step (next to current step) of receiver.
virtual contextIOResultType saveContext(DataStream &stream, ContextMode mode)
Stores the state of model to output stream.
Definition: engngm.C:1527
virtual int forceEquationNumbering()
Forces equation renumbering on all domains associated to engng model.
Definition: engngm.C:473
Initializes the variable VERBOSE, in order to get a few intermediate messages on screen: beginning an...
SparseLinearSystemNM * createSparseLinSolver(LinSystSolverType st, Domain *d, EngngModel *m)
Creates new instance of SparseLinearSystemNM corresponding to given type.
Definition: classfactory.C:120
#define _IFT_EngngModel_lstype
Definition: engngm.h:81
IRResultType
Type defining the return values of InputRecord reading operations.
Definition: irresulttype.h:47
virtual int requiresUnknownsDictionaryUpdate()
Indicates if EngngModel requires Dofs dictionaries to be updated.
int giveNumberOfTimeStepWhenIcApply()
Returns the time step number, when initial conditions should apply.
Definition: engngm.h:754
Class representing the general Input Record.
Definition: inputrecord.h:101
Dof * giveDofWithID(int dofID) const
Returns DOF with given dofID; issues error if not present.
Definition: dofmanager.C:119
void zero()
Zeroes all coefficients of receiver.
Definition: floatarray.C:658
ClassFactory & classFactory
Definition: classfactory.C:59
long ContextMode
Context mode (mask), defining the type of information written/read to/from context.
Definition: contextmode.h:43
bool suppressOutput
Flag for suppressing output to file.
Definition: engngm.h:314
This class implements extension of EngngModel for structural models.
#define _IFT_IncrementalLinearStatic_endoftimeofinterest
virtual int giveUnknownDictHashIndx(ValueModeType mode, TimeStep *tStep)
This method is responsible for computing unique dictionary id (ie hash value) from given valueModeTyp...
Abstract base class representing the "problem" under consideration.
Definition: engngm.h:181
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:78
virtual void updateDofUnknownsDictionary(DofManager *, TimeStep *)
Updates necessary values in Dofs unknown dictionaries.
int giveSize() const
Definition: intarray.h:203
int giveSize() const
Returns the size of receiver.
Definition: floatarray.h:218
virtual contextIOResultType restoreContext(DataStream &stream, ContextMode mode)
Restores the state of model from output stream.
Definition: engngm.C:1592
the oofem namespace is to define a context or scope in which all oofem names are defined.
Domain * giveDomain(int n)
Service for accessing particular problem domain.
Definition: engngm.C:1720
#define IR_GIVE_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:69
Abstract class Dof represents Degree Of Freedom in finite element mesh.
Definition: dof.h:93
DofManager * giveDofManager(int n)
Service for accessing particular domain dof manager.
Definition: domain.C:314
virtual void solveYourself()
Starts solution process.
#define OOFEM_WARNING(...)
Definition: error.h:62
void assembleVector(FloatArray &answer, TimeStep *tStep, const VectorAssembler &va, ValueModeType mode, const UnknownNumberingScheme &s, Domain *domain, FloatArray *eNorms=NULL)
Assembles characteristic vector of required type from dofManagers, element, and active boundary condi...
Definition: engngm.C:986
Class representing solution step.
Definition: timestep.h:80
const char * __ValueModeTypeToString(ValueModeType _value)
Definition: cltypes.C:322
void resize(int s)
Resizes receiver towards requested size.
Definition: floatarray.C:631

This page is part of the OOFEM documentation. Copyright (c) 2011 Borek Patzak
Project e-mail: info@oofem.org
Generated at Tue Jan 2 2018 20:07:29 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011