OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
nldeidynamic.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/nldeidynamic.h"
36 #include "timestep.h"
37 #include "dofmanager.h"
38 #include "element.h"
39 #include "dof.h"
40 #include "verbose.h"
41 #include "outputmanager.h"
42 #include "mathfem.h"
43 #include "datastream.h"
44 #include "contextioerr.h"
45 #include "sparsemtrx.h"
46 #include "classfactory.h"
47 #include "unknownnumberingscheme.h"
48 
49 #ifdef __PARALLEL_MODE
50  #include "problemcomm.h"
51  #include "processcomm.h"
52 #endif
53 
54 namespace oofem {
55 #define ZERO_REL_MASS 1.E-6
56 
57 REGISTER_EngngModel(NlDEIDynamic);
58 
59 NlDEIDynamic :: NlDEIDynamic(int i, EngngModel *_master) : StructuralEngngModel(i, _master), massMatrix(), loadVector(),
60  previousIncrementOfDisplacementVector(), displacementVector(),
61  velocityVector(), accelerationVector(), internalForces(),
62  nMethod(NULL)
63 {
64  ndomains = 1;
65  initFlag = 1;
66 }
67 
68 
70 { }
71 
73 {
74  if ( nMethod ) {
75  return nMethod;
76  }
77 
79 
80  return nMethod;
81 }
82 
85 {
86  IRResultType result; // Required by IR_GIVE_FIELD macro
87 
89  if ( result != IRRT_OK ) {
90  return result;
91  }
92 
93  IR_GIVE_FIELD(ir, dumpingCoef, _IFT_NlDEIDynamic_dumpcoef); // C = dumpingCoef * M
95 
96  drFlag = 0;
98  if ( drFlag ) {
101  }
102 
103 #ifdef __PARALLEL_MODE
105  communicator = new NodeCommunicator(this, commBuff, this->giveRank(),
106  this->giveNumberOfProcesses());
107 
109  nonlocalExt = 1;
111  this->giveNumberOfProcesses());
112  }
113 
114 #endif
115 
116  return IRRT_OK;
117 }
118 
119 
121 // Returns unknown quantity like displacement, velocity of equation eq.
122 // This function translates this request to numerical method language.
123 {
124  int eq = dof->__giveEquationNumber();
125 #ifdef DEBUG
126  if ( eq == 0 ) {
127  OOFEM_ERROR("invalid equation number");
128  }
129 #endif
130 
131  if ( tStep != this->giveCurrentStep() ) {
132  OOFEM_ERROR("unknown time step encountered");
133  return 0.;
134  }
135 
136  switch ( mode ) {
137  case VM_Total:
138  return displacementVector.at(eq);
139 
140  case VM_Incremental:
142 
143  case VM_Velocity:
144  return velocityVector.at(eq);
145 
146  case VM_Acceleration:
147  return accelerationVector.at(eq);
148 
149  default:
150  OOFEM_ERROR("Unknown is of undefined type for this problem");
151  }
152 
153  return 0.;
154 }
155 
157 {
158  int istep = 0;
159  double totalTime = 0;
160  StateCounterType counter = 1;
161 
162  if ( currentStep ) {
163  totalTime = currentStep->giveTargetTime() + deltaT;
164  istep = currentStep->giveNumber() + 1;
165  counter = currentStep->giveSolutionStateCounter() + 1;
166  }
167 
168  previousStep = std :: move(currentStep);
169  currentStep.reset( new TimeStep(istep, this, 1, totalTime, deltaT, counter) );
170 
171  return currentStep.get();
172 }
173 
174 
175 
177 {
178  if ( this->isParallel() ) {
179  #ifdef __VERBOSE_PARALLEL
180  // Force equation numbering before setting up comm maps.
182  OOFEM_LOG_INFO("[process rank %d] neq is %d\n", this->giveRank(), neq);
183  #endif
184 
185  this->initializeCommMaps();
186  }
187 
189 }
190 
192 {
193  //
194  // Creates system of governing eq's and solves them at given time step.
195  //
196 
197  Domain *domain = this->giveDomain(1);
199  int nman = domain->giveNumberOfDofManagers();
200 
201  DofManager *node;
202 
203  int i, k, j, jj;
204  double coeff, maxDt, maxOm = 0.;
205  double prevIncrOfDisplacement, incrOfDisplacement;
206 
207  if ( initFlag ) {
208 #ifdef VERBOSE
209  OOFEM_LOG_DEBUG("Assembling mass matrix\n");
210 #endif
211 
212  //
213  // Assemble mass matrix.
214  //
215  this->computeMassMtrx(massMatrix, maxOm, tStep);
216 
217  if ( drFlag ) {
218  // If dynamic relaxation: Assemble amplitude load vector.
219  loadRefVector.resize(neq);
221 
222  this->computeLoadVector(loadRefVector, VM_Total, tStep);
223 
224 #ifdef __PARALLEL_MODE
225  // Compute the processor part of load vector norm pMp
226  this->pMp = 0.0;
227  double my_pMp = 0.0, coeff = 1.0;
228  int eqNum, ndofman = domain->giveNumberOfDofManagers();
229  dofManagerParallelMode dofmanmode;
230  DofManager *dman;
231  for ( int dm = 1; dm <= ndofman; dm++ ) {
232  dman = domain->giveDofManager(dm);
233  dofmanmode = dman->giveParallelMode();
234 
235  // Skip all remote and null dofmanagers
236  coeff = 1.0;
237  if ( ( dofmanmode == DofManager_remote ) || ( ( dofmanmode == DofManager_null ) ) ) {
238  continue;
239  } else if ( dofmanmode == DofManager_shared ) {
240  coeff = 1. / dman->givePartitionsConnectivitySize();
241  }
242 
243  // For shared nodes we add locally an average = 1/givePartitionsConnectivitySize()*contribution,
244  for ( Dof *dof: *dman ) {
245  if ( dof->isPrimaryDof() && ( eqNum = dof->__giveEquationNumber() ) ) {
246  my_pMp += coeff * loadRefVector.at(eqNum) * loadRefVector.at(eqNum) / massMatrix.at(eqNum);
247  }
248  }
249  }
250 
251  // Sum up the contributions from processors.
252  MPI_Allreduce(& my_pMp, & pMp, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
253 #else
254  this->pMp = 0.0;
255  for ( i = 1; i <= neq; i++ ) {
256  pMp += loadRefVector.at(i) * loadRefVector.at(i) / massMatrix.at(i);
257  }
258 #endif
259  // Solve for rate of loading process (parameter "c") (undamped system assumed),
260  if ( dumpingCoef < 1.e-3 ) {
261  c = 3.0 * this->pyEstimate / pMp / Tau / Tau;
262  } else {
264  ( -3.0 / 2.0 + dumpingCoef * Tau + 2.0 * exp(-dumpingCoef * Tau) - 0.5 * exp(-2.0 * dumpingCoef * Tau) );
265  }
266  }
267 
268  initFlag = 0;
269  }
270 
271 
272  if ( tStep->isTheFirstStep() ) {
273  //
274  // Special init step - Compute displacements at tstep 0.
275  //
280  velocityVector.resize(neq);
284 
285  for ( j = 1; j <= nman; j++ ) {
286  node = domain->giveDofManager(j);
287 
288  for ( Dof *dof: *node ) {
289  // Ask for initial values obtained from
290  // bc (boundary conditions) and ic (initial conditions)
291  // all dofs are expected to be DisplacementVector type.
292  if ( !dof->isPrimaryDof() ) {
293  continue;
294  }
295 
296  jj = dof->__giveEquationNumber();
297  if ( jj ) {
298  displacementVector.at(jj) = dof->giveUnknown(VM_Total, tStep);
299  velocityVector.at(jj) = dof->giveUnknown(VM_Velocity, tStep);
300  accelerationVector.at(jj) = dof->giveUnknown(VM_Acceleration, tStep);
301  }
302  }
303  }
304 
305  //
306  // Set-up numerical model.
307  //
308 
309  // Try to determine the best deltaT,
310  maxDt = 2.0 / sqrt(maxOm);
311  if ( deltaT > maxDt ) {
312  // Print reduced time step increment and minimum period Tmin
313  OOFEM_LOG_RELEVANT("deltaT reduced to %e, Tmin is %e\n", maxDt, maxDt * M_PI);
314  deltaT = maxDt;
315  tStep->setTimeIncrement(deltaT);
316  }
317 
318  for ( j = 1; j <= neq; j++ ) {
321  }
322 #ifdef VERBOSE
323  OOFEM_LOG_RELEVANT( "\n\nSolving [Step number %8d, Time %15e]\n", tStep->giveNumber(), tStep->giveTargetTime() );
324 #endif
325  return;
326  } // end of init step
327 
328 #ifdef VERBOSE
329  OOFEM_LOG_DEBUG("Assembling right hand side\n");
330 #endif
331 
333 
334  // Update solution state counter
335  tStep->incrementStateCounter();
336 
337  // Compute internal forces.
338  this->giveInternalForces(internalForces, false, 1, tStep);
339 
340  if ( !drFlag ) {
341  //
342  // Assembling the element part of load vector.
343  //
344  this->computeLoadVector(loadVector, VM_Total, tStep);
345  //
346  // Assembling additional parts of right hand side.
347  //
349  } else {
350  // Dynamic relaxation
351  // compute load factor
352  pt = 0.0;
353 
354 #ifdef __PARALLEL_MODE
355  double my_pt = 0.0, coeff = 1.0;
356  int eqNum, ndofman = domain->giveNumberOfDofManagers();
357  dofManagerParallelMode dofmanmode;
358  DofManager *dman;
359  for ( int dm = 1; dm <= ndofman; dm++ ) {
360  dman = domain->giveDofManager(dm);
361  dofmanmode = dman->giveParallelMode();
362  // skip all remote and null dofmanagers
363  coeff = 1.0;
364  if ( ( dofmanmode == DofManager_remote ) || ( dofmanmode == DofManager_null ) ) {
365  continue;
366  } else if ( dofmanmode == DofManager_shared ) {
367  coeff = 1. / dman->givePartitionsConnectivitySize();
368  }
369 
370  // For shared nodes we add locally an average= 1/givePartitionsConnectivitySize()*contribution.
371  for ( Dof *dof: *dman ) {
372  if ( dof->isPrimaryDof() && ( eqNum = dof->__giveEquationNumber() ) ) {
373  my_pt += coeff * internalForces.at(eqNum) * loadRefVector.at(eqNum) / massMatrix.at(eqNum);
374  }
375  }
376  }
377 
378  // Sum up the contributions from processors.
379  MPI_Allreduce(& my_pt, & pt, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
380 #else
381  for ( k = 1; k <= neq; k++ ) {
382  pt += internalForces.at(k) * loadRefVector.at(k) / massMatrix.at(k);
383  }
384 
385 #endif
386  pt = pt / pMp;
387  if ( dumpingCoef < 1.e-3 ) {
388  pt += c * ( Tau - tStep->giveTargetTime() ) / Tau;
389  } else {
390  pt += c * ( 1.0 - exp( dumpingCoef * ( tStep->giveTargetTime() - Tau ) ) ) / dumpingCoef / Tau;
391  }
392 
394  for ( k = 1; k <= neq; k++ ) {
396  }
397 
398 
399  // Compute relative error.
400  double err = 0.0;
401 #ifdef __PARALLEL_MODE
402  double my_err = 0.0;
403 
404  for ( int dm = 1; dm <= ndofman; dm++ ) {
405  dman = domain->giveDofManager(dm);
406  dofmanmode = dman->giveParallelMode();
407  // Skip all remote and null dofmanagers.
408  coeff = 1.0;
409  if ( ( dofmanmode == DofManager_remote ) || ( dofmanmode == DofManager_null ) ) {
410  continue;
411  } else if ( dofmanmode == DofManager_shared ) {
412  coeff = 1. / dman->givePartitionsConnectivitySize();
413  }
414 
415  // For shared nodes we add locally an average= 1/givePartitionsConnectivitySize()*contribution.
416  for ( Dof *dof: *dman ) {
417  if ( dof->isPrimaryDof() && ( eqNum = dof->__giveEquationNumber() ) ) {
418  my_err += coeff * loadVector.at(eqNum) * loadVector.at(eqNum) / massMatrix.at(eqNum);
419  }
420  }
421  }
422 
423  // Sum up the contributions from processors.
424  MPI_Allreduce(& my_err, & err, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
425 
426 #else
427  for ( k = 1; k <= neq; k++ ) {
428  err = loadVector.at(k) * loadVector.at(k) / massMatrix.at(k);
429  }
430 
431 #endif
432  err = err / ( pMp * pt * pt );
433  OOFEM_LOG_RELEVANT("Relative error is %e, loadlevel is %e\n", err, pt);
434  }
435 
436  for ( j = 1; j <= neq; j++ ) {
437  coeff = massMatrix.at(j);
438  loadVector.at(j) +=
439  coeff * ( ( 1. / ( deltaT * deltaT ) ) - dumpingCoef * 1. / ( 2. * deltaT ) ) *
441  }
442 
443  //
444  // Set-up numerical model
445  //
446  /* it is not necesary to call numerical method
447  * approach used here is not good, but effective enough
448  * inverse of diagonal mass matrix is done here
449  */
450  //
451  // call numerical model to solve arised problem - done localy here
452  //
453 #ifdef VERBOSE
454  OOFEM_LOG_RELEVANT( "\n\nSolving [Step number %8d, Time %15e]\n", tStep->giveNumber(), tStep->giveTargetTime() );
455 #endif
456 
457  // NM_Status s = nMethod->solve(*massMatrix, loadVector, displacementVector);
458  // if ( !(s & NM_Success) ) {
459  // OOFEM_ERROR("No success in solving system. Ma=f");
460  // }
461 
462 
463  for ( i = 1; i <= neq; i++ ) {
464  prevIncrOfDisplacement = previousIncrementOfDisplacementVector.at(i);
465  incrOfDisplacement = loadVector.at(i) /
466  ( massMatrix.at(i) * ( 1. / ( deltaT * deltaT ) + dumpingCoef / ( 2. * deltaT ) ) );
467 
468  accelerationVector.at(i) = ( incrOfDisplacement - prevIncrOfDisplacement ) / ( deltaT * deltaT );
469  velocityVector.at(i) = ( incrOfDisplacement + prevIncrOfDisplacement ) / ( 2. * deltaT );
470  previousIncrementOfDisplacementVector.at(i) = incrOfDisplacement;
471  }
472 }
473 
474 
476 {
477  // Updates internal state to reached one
478  // all internal variables are directly updated by
479  // numerical method - void function here
480 
481  // this->updateInternalState(tStep);
483 }
484 
485 
486 void
488 {
490  answer.zero();
491 
492  //
493  // Assemble the nodal part of load vector.
494  //
495  this->assembleVector( answer, tStep, ExternalForceAssembler(), mode,
497 
498  //
499  // Exchange contributions.
500  //
502 }
503 
504 
505 void
507 {
508  Domain *domain = this->giveDomain(1);
509  int nelem = domain->giveNumberOfElements();
511  int i, j, jj, n;
512  double maxOmi, maxOmEl;
513  FloatMatrix charMtrx, charMtrx2, R;
514  IntArray loc;
515  Element *element;
517 
518 #ifndef LOCAL_ZERO_MASS_REPLACEMENT
519  FloatArray diagonalStiffMtrx;
520 #endif
521 
522  maxOm = 0.;
523  massMatrix.resize(neq);
524  massMatrix.zero();
525  for ( i = 1; i <= nelem; i++ ) {
526  element = domain->giveElement(i);
527 
528  // skip remote elements (these are used as mirrors of remote elements on other domains
529  // when nonlocal constitutive models are used. They introduction is necessary to
530  // allow local averaging on domains without fine grain communication between domains).
531  if ( element->giveParallelMode() == Element_remote ) {
532  continue;
533  }
534 
535  element->giveLocationArray(loc, en);
536  element->giveCharacteristicMatrix(charMtrx, LumpedMassMatrix, tStep);
537  if ( charMtrx.isNotEmpty() ) {
539  if ( element->giveRotationMatrix(R) ) {
540  charMtrx.rotatedWith(R);
541  }
542  }
543 
544 #ifdef LOCAL_ZERO_MASS_REPLACEMENT
545  element->giveCharacteristicMatrix(charMtrx2, TangentStiffnessMatrix, tStep);
546  if ( charMtrx2.isNotEmpty() ) {
548  if ( R.isNotEmpty() ) {
549  charMtrx2.rotatedWith(R);
550  }
551  }
552 #endif
553 
554 #ifdef DEBUG
555  if ( loc.giveSize() != charMtrx.giveNumberOfRows() ) {
556  OOFEM_ERROR("dimension mismatch");
557  }
558 #endif
559 
560  n = loc.giveSize();
561 
562 #ifdef LOCAL_ZERO_MASS_REPLACEMENT
563  maxOmEl = 0.;
564 
565  double maxElmass = -1.0;
566  for ( j = 1; j <= n; j++ ) {
567  maxElmass = max( maxElmass, charMtrx.at(j, j) );
568  }
569 
570  if ( maxElmass <= 0.0 ) {
571  OOFEM_WARNING("Element (%d) with zero (or negative) lumped mass encountered\n", i);
572  } else {
573 
574  if (charMtrx2.isNotEmpty() ) {
575  // in case stifness matrix defined, we can generate artificial mass
576  // in those DOFs without mass
577  for ( j = 1; j <= n; j++ ) {
578  if ( charMtrx.at(j, j) > maxElmass * ZERO_REL_MASS ) {
579  maxOmi = charMtrx2.at(j, j) / charMtrx.at(j, j);
580  maxOmEl = ( maxOmEl > maxOmi ) ? ( maxOmEl ) : ( maxOmi );
581  }
582  }
583 
584  maxOm = ( maxOm > maxOmEl ) ? ( maxOm ) : ( maxOmEl );
585 
586  for ( j = 1; j <= n; j++ ) {
587  jj = loc.at(j);
588  if ( ( jj ) && ( charMtrx.at(j, j) <= maxElmass * ZERO_REL_MASS ) ) {
589  charMtrx.at(j, j) = charMtrx2.at(j, j) / maxOmEl;
590  }
591  }
592  }
593  }
594 #endif
595 
596  for ( j = 1; j <= n; j++ ) {
597  jj = loc.at(j);
598  if ( jj ) {
599  massMatrix.at(jj) += charMtrx.at(j, j);
600  }
601  }
602  }
603 
604 #ifndef LOCAL_ZERO_MASS_REPLACEMENT
605  // If init step - find minimun period of vibration in order to
606  // determine maximal admisible time step
607  // global variant
608  for ( i = 1; i <= nelem; i++ ) {
609  element = domain->giveElement(i);
610  element->giveLocationArray(loc, en);
611  element->giveCharacteristicMatrix(charMtrx, TangentStiffnessMatrix, tStep);
612  if ( charMtrx.isNotEmpty() ) {
614  if ( element->giveRotationMatrix(R) ) {
615  charMtrx.rotatedWith(R);
616  }
617  }
618 
619  n = loc.giveSize();
620  for ( j = 1; j <= n; j++ ) {
621  jj = loc.at(j);
622  if ( jj ) {
623  diagonalStiffMtrx.at(jj) += charMtrx.at(j, j);
624  }
625  }
626  }
627 
628  // Find find global minimun period of vibration
629  double maxElmass = -1.0;
630  for ( j = 1; j <= n; j++ ) {
631  maxElmass = max( maxElmass, charMtrx.at(j, j) );
632  }
633 
634  if ( maxElmass <= 0.0 ) {
635  OOFEM_ERROR("Element with zero (or negative) lumped mass encountered");
636  }
637 
638  for ( j = 1; j <= neq; j++ ) {
639  if ( massMatrix.at(j) > maxElmass * ZERO_REL_MASS ) {
640  maxOmi = diagonalStiffMtrx.at(j) / massMatrix.at(j);
641  maxOm = ( maxOm > maxOmi ) ? ( maxOm ) : ( maxOmi );
642  }
643  }
644 
645  // Set ZERO MASS members in massMatrix to value which corresponds to global maxOm.
646  for ( i = 1; i <= neq; i++ ) {
647  if ( massMatrix.at(i) <= maxElmass * ZERO_REL_MASS ) {
648  massMatrix.at(i) = diagonalStiffMtrx.at(i) / maxOm;
649  }
650  }
651 #endif
652 
654 
655 #ifdef __PARALLEL_MODE
656  // Determine maxOm over all processes.
657  #ifdef __USE_MPI
658  double globalMaxOm;
659 
660  #ifdef __VERBOSE_PARALLEL
661  VERBOSEPARALLEL_PRINT( "NlDEIDynamic :: computeMassMtrx", "Reduce of maxOm started", this->giveRank() );
662  #endif
663 
664  int result = MPI_Allreduce(& maxOm, & globalMaxOm, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
665 
666  #ifdef __VERBOSE_PARALLEL
667  VERBOSEPARALLEL_PRINT( "NlDEIDynamic :: computeMassMtrx", "Reduce of maxOm finished", this->giveRank() );
668  #endif
669 
670  if ( result != MPI_SUCCESS ) {
671  OOFEM_ERROR("MPI_Allreduce failed");
672  }
673 
674  maxOm = globalMaxOm;
675  #else
676 WARNING: NOT SUPPORTED MESSAGE PARSING LIBRARY
677  #endif
678 
679 #endif
680 }
681 
682 int
683 NlDEIDynamic :: estimateMaxPackSize(IntArray &commMap, DataStream &buff, int packUnpackType)
684 {
685  int count = 0, pcount = 0;
686  Domain *domain = this->giveDomain(1);
687 
688  if ( packUnpackType == 0 ) {
689  for ( int inod: commMap ) {
690  DofManager *dman = domain->giveDofManager( inod );
691  for ( Dof *dof: *dman ) {
692  if ( dof->isPrimaryDof() && ( dof->__giveEquationNumber() ) ) {
693  count++;
694  } else {
695  pcount++;
696  }
697  }
698  }
699 
700  return ( buff.givePackSizeOfDouble(1) * max(count, pcount) );
701  } else if ( packUnpackType == 1 ) {
702  for ( int inod: commMap ) {
703  count += domain->giveElement( inod )->estimatePackSize(buff);
704  }
705 
706  return count;
707  }
708 
709  return 0;
710 }
711 
713 {
714  contextIOResultType iores;
715 
716  if ( ( iores = StructuralEngngModel :: saveContext(stream, mode) ) != CIO_OK ) {
717  THROW_CIOERR(iores);
718  }
719 
720  if ( ( iores = previousIncrementOfDisplacementVector.storeYourself(stream) ) != CIO_OK ) {
721  THROW_CIOERR(iores);
722  }
723 
724  if ( ( iores = displacementVector.storeYourself(stream) ) != CIO_OK ) {
725  THROW_CIOERR(iores);
726  }
727 
728  if ( ( iores = velocityVector.storeYourself(stream) ) != CIO_OK ) {
729  THROW_CIOERR(iores);
730  }
731 
732  if ( ( iores = accelerationVector.storeYourself(stream) ) != CIO_OK ) {
733  THROW_CIOERR(iores);
734  }
735 
736  if ( !stream.write(deltaT) ) {
738  }
739 
740  return CIO_OK;
741 }
742 
743 
745 {
746  contextIOResultType iores;
747 
748  if ( ( iores = StructuralEngngModel :: restoreContext(stream, mode) ) != CIO_OK ) {
749  THROW_CIOERR(iores);
750  }
751 
752  if ( ( iores = previousIncrementOfDisplacementVector.restoreYourself(stream) ) != CIO_OK ) {
753  THROW_CIOERR(iores);
754  }
755 
756  if ( ( iores = displacementVector.restoreYourself(stream) ) != CIO_OK ) {
757  THROW_CIOERR(iores);
758  }
759 
760  if ( ( iores = velocityVector.restoreYourself(stream) ) != CIO_OK ) {
761  THROW_CIOERR(iores);
762  }
763 
764  if ( ( iores = accelerationVector.restoreYourself(stream) ) != CIO_OK ) {
765  THROW_CIOERR(iores);
766  }
767 
768  if ( !stream.read(deltaT) ) {
770  }
771 
772  return CIO_OK;
773 }
774 
775 
776 void
777 NlDEIDynamic :: printDofOutputAt(FILE *stream, Dof *iDof, TimeStep *tStep)
778 {
779  static char dofchar[] = "dva";
780  static ValueModeType dofmodes[] = {
781  VM_Total, VM_Velocity, VM_Acceleration
782  };
783 
784  iDof->printMultipleOutputAt(stream, tStep, dofchar, dofmodes, 3);
785 }
786 
787 
788 void
790 {
791  if ( !this->giveDomain(1)->giveOutputManager()->testTimeStepOutput(tStep) ) {
792  return; // do not print even Solution step header
793  }
794 
795  fprintf(file, "\n\nOutput for time %.3e, solution step number %d\n", tStep->giveTargetTime(), tStep->giveNumber() );
796  if ( drFlag ) {
797  fprintf(file, "Reached load level : %e\n\n", this->pt);
798  }
799 
800  this->giveDomain(1)->giveOutputManager()->doDofManOutput(file, tStep);
801  this->giveDomain(1)->giveOutputManager()->doElementOutput(file, tStep);
802  this->printReactionForces(tStep, 1, file);
803 }
804 } // end namespace oofem
#define _IFT_NlDEIDynamic_deltat
Definition: nldeidynamic.h:50
FloatArray loadRefVector
Reference load vector.
Definition: nldeidynamic.h:112
The representation of EngngModel default unknown numbering.
void computeMassMtrx(FloatArray &mass, double &maxOm, TimeStep *tStep)
Assembles the diagonal mass matrix of receiver.
Definition: nldeidynamic.C:506
void subtract(const FloatArray &src)
Subtracts array src to receiver.
Definition: floatarray.C:258
virtual void solveYourself()
Starts solution process.
Definition: nldeidynamic.C:176
virtual void printOutputAt(FILE *file, TimeStep *tStep)
Prints output of receiver to output domain stream, for given time step.
Definition: nldeidynamic.C:789
FloatArray internalForces
Vector of real nodal forces.
Definition: nldeidynamic.h:100
virtual void updateYourself(TimeStep *tStep)
Updates internal state after finishing time step.
Definition: nldeidynamic.C:475
DofManager in active domain is shared only by remote elements (these are only introduced for nonlocal...
Definition: dofmanager.h:88
virtual void solveYourselfAt(TimeStep *tStep)
Solves problem for given time step.
Definition: nldeidynamic.C:191
std::unique_ptr< TimeStep > currentStep
Current time step.
Definition: engngm.h:231
virtual NumericalMethod * giveNumericalMethod(MetaStep *mStep)
Returns reference to receiver&#39;s numerical method.
Definition: nldeidynamic.C:72
Class and object Domain.
Definition: domain.h:115
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 IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description in input reader.
Definition: engngm.C:262
int giveNumberOfDofManagers() const
Returns number of dof managers in domain.
Definition: domain.h:432
Class representing meta step.
Definition: metastep.h:62
The purpose of DataStream abstract class is to allow to store/restore context to different streams...
Definition: datastream.h:54
contextIOResultType storeYourself(DataStream &stream) const
Definition: floatarray.C:872
std::unique_ptr< TimeStep > previousStep
Previous time step.
Definition: engngm.h:233
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
int max(int i, int j)
Returns bigger value form two given decimals.
Definition: mathfem.h:71
ValueModeType
Type representing the mode of UnknownType or CharType, or similar types.
Definition: valuemodetype.h:78
int nonlocalExt
Flag indicating if nonlocal extension active, which will cause data to be sent between shared element...
Definition: engngm.h:280
long StateCounterType
StateCounterType type used to indicate solution state.
virtual void printDofOutputAt(FILE *stream, Dof *iDof, TimeStep *tStep)
DOF printing routine.
Definition: nldeidynamic.C:777
This base class is an abstraction for numerical algorithm.
Definition: nummet.h:80
virtual bool hasField(InputFieldType id)=0
Returns true if record contains field identified by idString keyword.
double giveTargetTime()
Returns target time.
Definition: timestep.h:146
bool isParallel() const
Returns true if receiver in parallel mode.
Definition: engngm.h:1056
void incrementStateCounter()
Updates solution state counter.
Definition: timestep.h:190
void setTimeIncrement(double newDt)
Sets solution step time increment.
Definition: timestep.h:152
Abstract base class for all finite elements.
Definition: element.h:145
double c
Parameter determining rate of the loading process.
Definition: nldeidynamic.h:114
Base class for dof managers.
Definition: dofmanager.h:113
int giveNumberOfProcesses() const
Returns the number of collaborating processes.
Definition: engngm.h:1060
General IO error.
virtual void solveYourself()
Starts solution process.
Definition: engngm.C:501
virtual int __giveEquationNumber() const =0
Returns equation number of receiver, usually assigned by emodel.
int giveNumberOfElements() const
Returns number of elements in domain.
Definition: domain.h:434
virtual void giveCharacteristicMatrix(FloatMatrix &answer, CharType type, TimeStep *tStep)
Computes characteristic matrix of receiver of requested type in given time step.
Definition: element.C:569
virtual ~NlDEIDynamic()
Definition: nldeidynamic.C:69
virtual void printMultipleOutputAt(FILE *File, TimeStep *tStep, char *ch, ValueModeType *mode, int nite)
Prints Dof output (it prints value of unknown related to dof at given timeStep).
Definition: dof.C:92
REGISTER_EngngModel(ProblemSequence)
#define OOFEM_LOG_DEBUG(...)
Definition: logger.h:128
Class implementing an array of integers.
Definition: intarray.h:61
int & at(int i)
Coefficient access function.
Definition: intarray.h:103
virtual int read(int *data, int count)=0
Reads count integer values into array pointed by data.
#define _IFT_NlDEIDynamic_drflag
Definition: nldeidynamic.h:51
int givePartitionsConnectivitySize()
Returns number of partitions sharing given receiver (=number of shared partitions + local one)...
Definition: dofmanager.C:975
virtual void giveInternalForces(FloatArray &answer, bool normFlag, int di, TimeStep *tStep)
Evaluates the nodal representation of internal forces by assembling contributions from individual ele...
#define THROW_CIOERR(e)
Definition: contextioerr.h:61
void printReactionForces(TimeStep *tStep, int id, FILE *out)
Computes and prints reaction forces, computed from nodal internal forces.
dofManagerParallelMode
In parallel mode, this type indicates the mode of DofManager.
Definition: dofmanager.h:80
#define OOFEM_LOG_RELEVANT(...)
Definition: logger.h:126
FloatArray previousIncrementOfDisplacementVector
Vector storing displacement increments.
Definition: nldeidynamic.h:96
bool isTheFirstStep()
Check if receiver is first step.
Definition: timestep.C:134
virtual int write(const int *data, int count)=0
Writes count integer values from array pointed by data.
#define _IFT_NlDEIDynamic_py
Definition: nldeidynamic.h:53
bool isNotEmpty() const
Tests for empty matrix.
Definition: floatmatrix.h:162
#define _IFT_NlDEIDynamic_dumpcoef
Definition: nldeidynamic.h:49
LinSystSolverType solverType
Definition: nldeidynamic.h:125
ProblemCommunicator * nonlocCommunicator
NonLocal Communicator. Necessary when nonlocal constitutive models are used.
Definition: engngm.h:306
int giveNumber()
Returns receiver&#39;s number.
Definition: timestep.h:129
#define OOFEM_LOG_INFO(...)
Definition: logger.h:127
double pyEstimate
Estimate of loadRefVector^T*displacementVector(Tau).
Definition: nldeidynamic.h:120
double deltaT
Time step.
Definition: nldeidynamic.h:104
Element * giveElement(int n)
Service for accessing particular domain fe element.
Definition: domain.C:160
#define M_PI
Definition: mathfem.h:52
void doElementOutput(FILE *, TimeStep *)
Does the element output.
#define OOFEM_ERROR(...)
Definition: error.h:61
double pt
Load level.
Definition: nldeidynamic.h:116
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
Implementation for assembling external forces vectors in standard monolithic FE-problems.
#define VERBOSEPARALLEL_PRINT(service, str, rank)
Definition: parallel.h:50
void giveLocationArray(IntArray &locationArray, const UnknownNumberingScheme &s, IntArray *dofIds=NULL) const
Returns the location array (array of code numbers) of receiver for given numbering scheme...
Definition: element.C:390
void rotatedWith(const FloatMatrix &r, char mode= 'n')
Returns the receiver &#39;a&#39; transformed using give transformation matrix r.
Definition: floatmatrix.C:1557
contextIOResultType restoreYourself(DataStream &stream)
Definition: floatarray.C:895
#define _IFT_NlDEIDynamic_tau
Definition: nldeidynamic.h:52
ProblemCommunicator * communicator
Communicator.
Definition: engngm.h:303
FloatArray displacementVector
Displacement, velocity and acceleration vectors.
Definition: nldeidynamic.h:98
virtual bool giveRotationMatrix(FloatMatrix &answer)
Transformation matrices updates rotation matrix between element-local and primary DOFs...
Definition: element.C:259
CommunicatorBuff * commBuff
Common Communicator buffer.
Definition: engngm.h:301
SparseLinearSystemNM * nMethod
Definition: nldeidynamic.h:127
double at(int i, int j) const
Coefficient access function.
Definition: floatmatrix.h:176
void computeLoadVector(FloatArray &answer, ValueModeType mode, TimeStep *tStep)
Assembles the load vector.
Definition: nldeidynamic.C:487
#define ZERO_REL_MASS
Definition: nldeidynamic.C:55
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description in input reader.
Definition: nldeidynamic.C:84
virtual void updateYourself(TimeStep *tStep)
Updates internal state after finishing time step.
virtual contextIOResultType saveContext(DataStream &stream, ContextMode mode)
Stores the state of model to output stream.
Definition: engngm.C:1527
virtual double giveUnknownComponent(ValueModeType type, TimeStep *tStep, Domain *d, Dof *dof)
Returns requested unknown.
Definition: nldeidynamic.C:120
Initializes the variable VERBOSE, in order to get a few intermediate messages on screen: beginning an...
FloatArray accelerationVector
Definition: nldeidynamic.h:98
Class representing vector of real numbers.
Definition: floatarray.h:82
int estimatePackSize(DataStream &buff)
Estimates the necessary pack size to hold all packed data of receiver.
Definition: element.C:1575
SparseLinearSystemNM * createSparseLinSolver(LinSystSolverType st, Domain *d, EngngModel *m)
Creates new instance of SparseLinearSystemNM corresponding to given type.
Definition: classfactory.C:120
elementParallelMode giveParallelMode() const
Return elementParallelMode of receiver.
Definition: element.h:1069
Implementation of matrix containing floating point numbers.
Definition: floatmatrix.h:94
IRResultType
Type defining the return values of InputRecord reading operations.
Definition: irresulttype.h:47
virtual int givePackSizeOfDouble(int count)=0
virtual contextIOResultType restoreContext(DataStream &stream, ContextMode mode)
Restores the state of model from output stream.
Definition: nldeidynamic.C:744
double Tau
End of time interval.
Definition: nldeidynamic.h:118
Class representing the general Input Record.
Definition: inputrecord.h:101
FloatArray velocityVector
Definition: nldeidynamic.h:98
void zero()
Zeroes all coefficients of receiver.
Definition: floatarray.C:658
virtual int estimateMaxPackSize(IntArray &commMap, DataStream &buff, int packUnpackType)
Determines the space necessary for send/receive buffer.
Definition: nldeidynamic.C:683
int giveRank() const
Returns domain rank in a group of collaborating processes (0..groupSize-1)
Definition: engngm.h:1058
void initializeCommMaps(bool forceInit=false)
Definition: engngm.C:1942
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
Element in active domain is only mirror of some remote element.
Definition: element.h:102
FloatArray massMatrix
Mass matrix.
Definition: nldeidynamic.h:92
double dumpingCoef
Dumping coefficient (C = dumpingCoef * MassMtrx).
Definition: nldeidynamic.h:102
OutputManager * giveOutputManager()
Returns domain output manager.
Definition: domain.C:1436
This class implements extension of EngngModel for structural models.
The Communicator and corresponding buffers (represented by this class) are separated in order to allo...
Definition: communicator.h:60
NlDEIDynamic(int i, EngngModel *_master=NULL)
Definition: nldeidynamic.C:59
Abstract base class representing the "problem" under consideration.
Definition: engngm.h:181
DofManager in active domain is only mirror of some remote DofManager.
Definition: dofmanager.h:85
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:78
int initFlag
Flag indicating the need for initialization.
Definition: nldeidynamic.h:106
virtual TimeStep * giveCurrentStep(bool force=false)
Returns current time step.
Definition: engngm.h:683
int giveSize() const
Definition: intarray.h:203
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.
FloatArray loadVector
Load vector.
Definition: nldeidynamic.h:94
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
void doDofManOutput(FILE *, TimeStep *)
Does the dofmanager output.
Definition: outputmanager.C:78
#define _IFT_NlDEIDynamic_nonlocalext
Definition: nldeidynamic.h:54
int giveNumberOfRows() const
Returns number of rows of receiver.
Definition: floatmatrix.h:156
#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 contextIOResultType saveContext(DataStream &stream, ContextMode mode)
Stores the state of model to output stream.
Definition: nldeidynamic.C:712
int drFlag
Flag indicating whether dynamic relaxation takes place.
Definition: nldeidynamic.h:110
DofManager is shared by neighboring partitions, it is necessary to sum contributions from all contrib...
Definition: dofmanager.h:82
dofManagerParallelMode giveParallelMode() const
Return dofManagerParallelMode of receiver.
Definition: dofmanager.h:512
double pMp
Product of p^tM^(-1)p; where p is reference load vector.
Definition: nldeidynamic.h:122
void add(const FloatArray &src)
Adds array src to receiver.
Definition: floatarray.C:156
virtual TimeStep * giveNextStep()
Returns next time step (next to current step) of receiver.
Definition: nldeidynamic.C:156
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:30 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011