OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
stationarytransportproblem.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 
36 #include "nummet.h"
37 #include "timestep.h"
38 #include "element.h"
39 #include "dof.h"
40 #include "maskedprimaryfield.h"
41 #include "intvarfield.h"
42 #include "verbose.h"
43 #include "transportelement.h"
44 #include "classfactory.h"
45 #include "datastream.h"
46 #include "contextioerr.h"
47 #include "nrsolver.h"
48 #include "unknownnumberingscheme.h"
50 
51 namespace oofem {
52 REGISTER_EngngModel(StationaryTransportProblem);
53 
55 {
56  ndomains = 1;
57  nMethod = NULL;
58 }
59 
61 {
62  delete nMethod;
63 }
64 
66 {
67  if ( nMethod ) {
68  return nMethod;
69  }
70 
71  nMethod = new NRSolver(this->giveDomain(1), this);
72  return nMethod;
73 }
74 
77 {
78  IRResultType result; // Required by IR_GIVE_FIELD macro
79 
80  result = EngngModel :: initializeFrom(ir);
81  if ( result != IRRT_OK ) return result;
82 
83  int val = SMT_Skyline;
85  this->sparseMtrxType = ( SparseMtrxType ) val;
86 
89 
90  // read field export flag
91  IntArray exportFields;
93  if ( exportFields.giveSize() ) {
94  FieldManager *fm = this->giveContext()->giveFieldManager();
95  for ( int i = 1; i <= exportFields.giveSize(); i++ ) {
96  if ( exportFields.at(i) == FT_Temperature ) {
97  FieldPtr _temperatureField( new MaskedPrimaryField ( ( FieldType ) exportFields.at(i), this->UnknownsField.get(), {T_f} ) );
98  fm->registerField( _temperatureField, ( FieldType ) exportFields.at(i) );
99  } else if ( exportFields.at(i) == FT_HumidityConcentration ) {
100  FieldPtr _concentrationField( new MaskedPrimaryField ( ( FieldType ) exportFields.at(i), this->UnknownsField.get(), {C_1} ) );
101  fm->registerField( _concentrationField, ( FieldType ) exportFields.at(i) );
102  }
103  }
104  }
105 
106  if ( !UnknownsField ) { // can exist from nonstationary transport problem
107  //UnknownsField.reset( new DofDistributedPrimaryField(this, 1, FT_TransportProblemUnknowns, 0) );
108  UnknownsField.reset( new PrimaryField(this, 1, FT_TransportProblemUnknowns, 0) );
109  }
110 
111  return IRRT_OK;
112 }
113 
114 
115 
117 {
118 #ifdef DEBUG
119  if ( dof->__giveEquationNumber() == 0 ) {
120  OOFEM_ERROR("invalid equation number");
121  }
122 #endif
123  if (mode == VM_TotalIntrinsic) mode = VM_Total;
124  return UnknownsField->giveUnknownValue(dof, mode, tStep);
125 }
126 
127 
129 {
130  /* Note: the current implementation uses MaskedPrimaryField, that is automatically updated with the model progress,
131  so the returned field always refers to active solution step.
132  */
133 
134  if ( tStep != this->giveCurrentStep() ) {
135  OOFEM_ERROR("Unable to return field representation for non-current time step");
136  }
137  if ( key == FT_Temperature ) {
138  FieldPtr _ptr ( new MaskedPrimaryField ( key, this->UnknownsField.get(), {T_f} ) );
139  return _ptr;
140  } else if ( key == FT_HumidityConcentration ) {
141  FieldPtr _ptr ( new MaskedPrimaryField ( key, this->UnknownsField.get(), {C_1} ) );
142  return _ptr;
143  } else {
144  return FieldPtr();
145  }
146 }
147 
148 
149 
151 {
152  int istep = this->giveNumberOfFirstStep();
153  StateCounterType counter = 1;
154 
155  if ( currentStep ) {
156  istep = currentStep->giveNumber() + 1;
157  counter = currentStep->giveSolutionStateCounter() + 1;
158  }
159 
160  previousStep = std :: move(currentStep);
161  currentStep.reset( new TimeStep(istep, this, 1, ( double ) istep, 0., counter) );
162  return currentStep.get();
163 }
164 
165 
167 {
168 
169 
170  //
171  // creates system of governing eq's and solves them at given time step
172  //
173  // first assemble problem at current time step
174  UnknownsField->advanceSolution(tStep);
176 
177  if ( tStep->giveNumber() == 1 ) {
178  // allocate space for solution vector
179  FloatArray *solutionVector = UnknownsField->giveSolutionVector(tStep);
180  solutionVector->resize(neq);
181  solutionVector->zero();
182 
184  if ( conductivityMatrix == NULL ) {
185  OOFEM_ERROR("sparse matrix creation failed");
186  }
187 
188  conductivityMatrix->buildInternalStructure( this, 1, EModelDefaultEquationNumbering() );
189  if ( this->keepTangent ) {
190  this->conductivityMatrix->zero();
191  this->assemble( *conductivityMatrix, tStep, TangentAssembler(TangentStiffness),
193  }
194  }
195 
196  Domain *domain = this->giveDomain(1);
197  // update element state according to given ic
198  for ( auto &elem : domain->giveElements() ) {
199  TransportElement *element = static_cast< TransportElement * >( elem.get() );
200  element->updateInternalState(tStep);
201  element->updateYourself(tStep);
202  }
203 
204 
205  internalForces.resize(neq);
206 
207 #ifdef VERBOSE
208  OOFEM_LOG_INFO("Assembling external forces\n");
209 #endif
210  FloatArray externalForces(neq);
211  externalForces.zero();
212  this->assembleVector( externalForces, tStep, ExternalForceAssembler(), VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(1) );
214 
215  // set-up numerical method
216  this->giveNumericalMethod( this->giveCurrentMetaStep() );
217 #ifdef VERBOSE
218  OOFEM_LOG_INFO("Solving for %d unknowns\n", neq);
219 #endif
220 
221  FloatArray incrementOfSolution;
222  double loadLevel;
223  int currentIterations;
224  this->nMethod->solve(*this->conductivityMatrix,
225  externalForces,
226  NULL,
227  *UnknownsField->giveSolutionVector(tStep),
228  incrementOfSolution,
229  this->internalForces,
230  this->eNorm,
231  loadLevel, // Only relevant for incrementalBCLoadVector
233  currentIterations,
234  tStep);
235 
236  //nMethod->solve( *conductivityMatrix, rhsVector, *UnknownsField->giveSolutionVector(tStep) );
237 }
238 
239 void
241 {
242  this->updateInternalState(tStep);
244 }
245 
246 void
248 {
249  if ( cmpn == InternalRhs ) {
250  this->internalForces.zero();
251  this->assembleVector(this->internalForces, tStep, InternalForceAssembler(), VM_Total,
252  EModelDefaultEquationNumbering(), this->giveDomain(1), & this->eNorm);
254  return;
255  } else if ( cmpn == NonLinearLhs ) {
256  if ( !this->keepTangent ) {
257  // Optimization for linear problems, we can keep the old matrix (which could save its factorization)
258  this->conductivityMatrix->zero();
259  this->assemble( *conductivityMatrix, tStep, TangentAssembler(TangentStiffness),
261  }
262  return;
263  } else {
264  OOFEM_ERROR("Unknown component");
265  }
266 }
267 
270 {
271  contextIOResultType iores;
272 
273  if ( ( iores = EngngModel :: saveContext(stream, mode) ) != CIO_OK ) {
274  THROW_CIOERR(iores);
275  }
276 
277  if ( ( iores = UnknownsField->saveContext(stream, mode) ) != CIO_OK ) {
278  THROW_CIOERR(iores);
279  }
280 
281  return CIO_OK;
282 }
283 
284 
285 
288 {
289  contextIOResultType iores;
290 
291  if ( ( iores = EngngModel :: restoreContext(stream, mode) ) != CIO_OK ) {
292  THROW_CIOERR(iores);
293  }
294 
295  if ( ( iores = UnknownsField->restoreContext(stream, mode) ) != CIO_OK ) {
296  THROW_CIOERR(iores);
297  }
298 
299  return CIO_OK;
300 }
301 
302 
303 int
305 {
306  Domain *domain = this->giveDomain(1);
307 
308  // check for proper element type
309  for ( auto &elem : domain->giveElements() ) {
310  if ( !dynamic_cast< TransportElement * >( elem.get() ) ) {
311  OOFEM_WARNING("Element %d has no TransportElement base", elem->giveLabel());
312  return 0;
313  }
314  }
315 
317 }
318 
319 
320 void
322 {
324  this->giveNumericalMethod( this->giveCurrentMetaStep() )->setDomain( this->giveDomain(1) );
325 }
326 
327 
328 void
330 {
332  for ( auto &domain: domainList ) {
333  for ( auto &elem : domain->giveElements() ) {
334  elem->updateInternalState(tStep);
335  }
336  }
337 }
338 
339 } // end namespace oofem
virtual void updateInternalState(TimeStep *tStep)
Updates IP values on elements.
The representation of EngngModel default unknown numbering.
#define _IFT_StationaryTransportProblem_keepTangent
std::unique_ptr< TimeStep > currentStep
Current time step.
Definition: engngm.h:231
std::shared_ptr< Field > FieldPtr
Definition: field.h:72
Class and object Domain.
Definition: domain.h:115
SparseNonLinearSystemNM * nMethod
Numerical method used to solve the problem.
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
Abstract class representing subset of DOFs (identified by DofId mask) of primary field.
FieldType
Physical type of field.
Definition: field.h:60
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description in input reader.
Definition: engngm.C:262
Class representing meta step.
Definition: metastep.h:62
This class implements Newton-Raphson Method, derived from abstract NumericalMethod class for solving ...
Definition: nrsolver.h:95
SparseMtrx * createSparseMtrx(SparseMtrxType type)
Creates new instance of sparse matrix corresponding to given keyword.
Definition: classfactory.C:105
Abstract class representing field of primary variables (those, which are unknown and are typically as...
Definition: primaryfield.h:104
The purpose of DataStream abstract class is to allow to store/restore context to different streams...
Definition: datastream.h:54
std::vector< std::unique_ptr< Domain > > domainList
List of problem domains.
Definition: engngm.h:207
std::unique_ptr< TimeStep > previousStep
Previous time step.
Definition: engngm.h:233
ValueModeType
Type representing the mode of UnknownType or CharType, or similar types.
Definition: valuemodetype.h:78
long StateCounterType
StateCounterType type used to indicate solution state.
This base class is an abstraction for numerical algorithm.
Definition: nummet.h:80
StationaryTransportProblem(int i, EngngModel *_master)
Constructor.
Implementation for assembling tangent matrices in standard monolithic FE-problems.
virtual void updateYourself(TimeStep *tStep)
Updates element state after equilibrium in time step has been reached.
Definition: element.C:779
virtual bool hasField(InputFieldType id)=0
Returns true if record contains field identified by idString keyword.
virtual int checkConsistency()
Allows programmer to test some receiver&#39;s internal data, before computation begins.
virtual void solveYourselfAt(TimeStep *tStep)
Solves problem for given time step.
virtual int __giveEquationNumber() const =0
Returns equation number of receiver, usually assigned by emodel.
FieldManager * giveFieldManager()
Definition: engngm.h:131
REGISTER_EngngModel(ProblemSequence)
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 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
#define OOFEM_LOG_INFO(...)
Definition: logger.h:127
int giveNumber()
Returns receiver&#39;s number.
Definition: timestep.h:129
std::unique_ptr< SparseMtrx > conductivityMatrix
virtual void updateComponent(TimeStep *tStep, NumericalCmpn cmpn, Domain *d)
Updates components mapped to numerical method if necessary during solution process.
virtual contextIOResultType saveContext(DataStream &stream, ContextMode mode)
Stores the state of model to output stream.
NumericalCmpn
Type representing numerical component.
Definition: numericalcmpn.h:46
virtual contextIOResultType restoreContext(DataStream &stream, ContextMode mode)
Restores the state of model from output stream.
#define _IFT_EngngModel_smtype
Definition: engngm.h:82
#define OOFEM_ERROR(...)
Definition: error.h:61
virtual NumericalMethod * giveNumericalMethod(MetaStep *mStep)
Returns reference to receiver&#39;s numerical method.
EngngModelContext * giveContext()
Context requesting service.
Definition: engngm.h:1078
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.
The reference incremental load vector is defined as totalLoadVector assembled at given time...
Implementation for assembling external forces vectors in standard monolithic FE-problems.
This abstract class represent a general base element class for transport problems.
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description in input reader.
virtual void updateYourself(TimeStep *tStep)
Updates internal state after finishing time step.
Definition: engngm.C:612
virtual int giveNumberOfFirstStep(bool force=false)
Returns number of first time step used by receiver.
Definition: engngm.h:730
virtual contextIOResultType saveContext(DataStream &stream, ContextMode mode)
Stores the state of model to output stream.
Definition: engngm.C:1527
std::unique_ptr< PrimaryField > UnknownsField
This field stores solution vector. For fixed size of problem, the PrimaryField is used...
Initializes the variable VERBOSE, in order to get a few intermediate messages on screen: beginning an...
void registerField(FieldPtr eField, FieldType key)
Registers the given field (the receiver is not assumed to own given field).
Definition: fieldmanager.C:42
Class representing vector of real numbers.
Definition: floatarray.h:82
virtual int checkConsistency()
Allows programmer to test some receiver&#39;s internal data, before computation begins.
Definition: engngm.h:995
virtual TimeStep * giveNextStep()
Returns next time step (next to current step) of receiver.
IRResultType
Type defining the return values of InputRecord reading operations.
Definition: irresulttype.h:47
Class representing the general Input Record.
Definition: inputrecord.h:101
void zero()
Zeroes all coefficients of receiver.
Definition: floatarray.C:658
virtual void updateDomainLinks()
Updates domain links after the domains of receiver have changed.
virtual double giveUnknownComponent(ValueModeType mode, TimeStep *tStep, Domain *d, Dof *dof)
Returns requested unknown.
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
virtual void updateYourself(TimeStep *tStep)
Updates internal state after finishing time step.
#define _IFT_StationaryTransportProblem_exportfields
std::vector< std::unique_ptr< Element > > & giveElements()
Definition: domain.h:279
virtual FieldPtr giveField(FieldType key, TimeStep *)
Returns the smart pointer to requested field, Null otherwise.
Abstract base class representing the "problem" under consideration.
Definition: engngm.h:181
virtual void setDomain(Domain *d)
Definition: nummet.h:114
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:78
virtual TimeStep * giveCurrentStep(bool force=false)
Returns current time step.
Definition: engngm.h:683
int giveSize() const
Definition: intarray.h:203
virtual void updateDomainLinks()
Updates domain links after the domains of receiver have changed.
Definition: engngm.C:1521
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
Abstract class Dof represents Degree Of Freedom in finite element mesh.
Definition: dof.h:93
Symmetric skyline.
virtual void updateInternalState(TimeStep *tStep)
Updates element state after equilibrium in time step has been reached.
#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
virtual NM_Status solve(SparseMtrx &K, FloatArray &R, FloatArray *R0, FloatArray &X, FloatArray &dX, FloatArray &F, const FloatArray &internalForcesEBENorm, double &s, referenceLoadInputModeType rlm, int &nite, TimeStep *tStep)=0
Solves the given sparse linear system of equations .
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:31 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011