OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
dofmanager.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 "dofmanager.h"
36 #include "masterdof.h"
37 #include "simpleslavedof.h"
38 #include "timestep.h"
39 #include "load.h"
40 #include "floatarray.h"
41 #include "floatmatrix.h"
42 #include "intarray.h"
43 #include "classfactory.h"
44 #include "datastream.h"
45 #include "contextioerr.h"
46 #include "mathfem.h"
47 #include "dynamicinputrecord.h"
48 #include "domain.h"
49 #include "unknownnumberingscheme.h"
51 #include "engngm.h"
52 
53 namespace oofem {
54 DofManager :: DofManager(int n, Domain *aDomain) :
55  FEMComponent(n, aDomain), dofArray(), loadArray(), partitions()
56 {
57  isBoundaryFlag = false;
58  hasSlaveDofs = false;
59  dofidmask = NULL;
60  dofTypemap = NULL;
61  dofMastermap = NULL;
62  dofBCmap = NULL;
63  dofICmap = NULL;
65 }
66 
67 
69 {
70  for ( Dof *dof: dofArray ) {
71  delete dof;
72  }
73 
74  delete dofidmask;
75  delete dofTypemap;
76  delete dofMastermap;
77  delete dofBCmap;
78  delete dofICmap;
79 }
80 
81 
83 // Returns the list containing the number of every nodal loads that act on
84 // the receiver. If this list does not exist yet, constructs it. This list
85 // is not to be confused with the load vector.
86 {
87  return & loadArray;
88 }
89 
90 
92 {
93  this->loadArray = la;
94 }
95 
96 
98 {
99  if ( load->giveBCGeoType() != NodalLoadBGT ) {
100  OOFEM_ERROR("incompatible load type applied");
101  }
102 
103  answer.clear();
104  if ( type != ExternalForcesVector ) {
105  return;
106  }
107 
108  if ( load->giveDofIDs().giveSize() == 0 ) {
109  load->computeComponentArrayAt(answer, tStep, mode);
110  } else {
111  answer.resize(this->giveNumberOfDofs());
112  FloatArray tmp;
113  load->computeComponentArrayAt(tmp, tStep, mode);
114  answer.assemble(tmp, load->giveDofIDs());
115  }
116 }
117 
118 
120 // Returns the degree of freedom of the receiver with 'dofID'.
121 {
122  auto pos = this->findDofWithDofId( ( DofIDItem ) dofID );
123 
124 #ifdef DEBUG
125  if ( pos == this->end() ) {
126  OOFEM_ERROR("dof with given DofID does not exists");
127  }
128 #endif
129 
130  return *pos;
131 }
132 
133 
135 // appends a Dof to the end position in dofArray
136 // because dofArray is not resizeable, the data need
137 // to be copied out of the dofArray, dofArray deleted
138 // and again constructed with new Dof
139 {
140 #ifdef DEBUG
141  // check if dofID of DOF to be added not already present
142  if ( this->findDofWithDofId( dof->giveDofID() ) != this->end() ) {
143  OOFEM_ERROR("DOF with dofID %d already present (dofman %d)", dof->giveDofID(), this->number);
144  }
145 #endif
146 
147  this->dofArray.push_back(dof);
148 }
149 
150 
152 {
153  int i = 0;
154  for ( Dof *dof: *this ) {
155  if ( dof->giveDofID() == id ) {
156  delete dof;
157  this->dofArray.erase( i + this->begin() );
158  return;
159  }
160  i++;
161  }
162  OOFEM_WARNING("no DOF with dofID %d found", id);
163 }
164 
165 
167 {
168  for ( Dof *dof: *this ) {
169  if ( dof->giveDofID() == id ) {
170  return true;
171  }
172  }
173  return false;
174 }
175 
176 
177 void DofManager :: giveLocationArray(const IntArray &dofIDArry, IntArray &locationArray, const UnknownNumberingScheme &s) const
178 {
179  if ( !hasSlaveDofs ) {
180  int size;
181  // prevents some size problem when connecting different elements with
182  // different number of dofs
183  size = dofIDArry.giveSize();
184  locationArray.resize(size);
185  for ( int i = 1; i <= size; i++ ) {
186  auto pos = this->findDofWithDofId( ( DofIDItem ) dofIDArry.at(i) );
187  if ( pos == this->end() ) {
188  OOFEM_ERROR("incompatible dof (%d) requested", dofIDArry.at(i));
189  }
190 
191  locationArray.at(i) = s.giveDofEquationNumber( *pos );
192  }
193  } else {
194  IntArray mstrEqNmbrs;
195  locationArray.clear();
196 
197  for ( int dofid: dofIDArry ) {
198  auto pos = this->findDofWithDofId( ( DofIDItem ) dofid );
199  if ( pos == this->end() ) {
200  OOFEM_ERROR("incompatible dof (%d) requested", dofid);
201  }
202  (*pos)->giveEquationNumbers(mstrEqNmbrs, s);
203  locationArray.followedBy(mstrEqNmbrs);
204  }
205  }
206 }
207 
208 
209 void DofManager :: giveMasterDofIDArray(const IntArray &dofIDArry, IntArray &masterDofIDs) const
210 {
211  if ( !hasSlaveDofs ) {
212  masterDofIDs = dofIDArry;
213  } else {
214  IntArray temp;
215  masterDofIDs.clear();
216 
217  for ( int dofid: dofIDArry ) {
218  auto pos = this->findDofWithDofId( ( DofIDItem ) dofid );
219  if ( pos == this->end() ) {
220  OOFEM_ERROR("incompatible dof (%d) requested", dofid);
221  }
222  (*pos)->giveDofIDs(temp);
223  masterDofIDs.followedBy(temp);
224  }
225  }
226 }
227 
228 
230 {
231  if ( !hasSlaveDofs ) {
232  // prevents some size problem when connecting different elements with
233  // different number of dofs
234  locationArray.resizeWithValues(0, this->giveNumberOfDofs());
235  for ( Dof *dof: *this ) {
236  locationArray.followedBy( s.giveDofEquationNumber( dof ) );
237  }
238  } else {
239  IntArray temp;
240  locationArray.resize(0);
241  for ( Dof *dof: *this ) {
242  dof->giveEquationNumbers(temp, s);
243  locationArray.followedBy(temp);
244  }
245  }
246 }
247 
248 
250 {
251  if ( !hasSlaveDofs ) {
252  dofIDArray.resizeWithValues(0, this->giveNumberOfDofs());
253  for ( Dof *dof: *this ) {
254  dofIDArray.followedBy( dof->giveDofID() );
255  }
256  } else {
257  IntArray temp;
258  for ( Dof *dof: *this ) {
259  dof->giveDofIDs(temp);
260  dofIDArray.followedBy(temp);
261  }
262  }
263 }
264 
265 
266 std :: vector< Dof* > :: const_iterator DofManager :: findDofWithDofId(DofIDItem dofID) const
267 {
268  int i = 0;
269  for ( Dof *dof: *this ) {
270  if ( dof->giveDofID() == dofID ) {
271  return this->begin() + i;
272  }
273  i++;
274  }
275  return this->end();
276 }
277 
278 
280 // Returns the number of degrees of freedom of the receiver.
281 {
282  return (int)dofArray.size();
283 }
284 
285 
287 {
288  for ( Dof *dof: *this ) {
289  delete dof;
290  }
291  this->dofArray.assign(_ndofs, NULL);
292 }
293 
294 
296 {
297  for ( Dof *dof: *this ) {
298  dof->askNewEquationNumber(tStep);
299  }
300 }
301 
302 
304 {
305  if ( !hasSlaveDofs ) {
306  return dofIDArray.giveSize();
307  }
308 
309  int answer = 0;
310 
311  for ( int dofid: dofIDArray ) {
312  auto pos = this->findDofWithDofId((DofIDItem)dofid);
313 #ifdef DEBUG
314  if ( pos == this->end() ) {
315  OOFEM_ERROR("Dof with ID %d doesn't exist", dofid);
316  }
317 #endif
318  answer += (*pos)->giveNumberOfPrimaryMasterDofs();
319  }
320 
321  return answer;
322 }
323 
324 
327 {
328  IRResultType result; // Required by IR_GIVE_FIELD macro
329 
330  delete dofidmask;
331  dofidmask = NULL;
332  delete dofTypemap;
333  dofTypemap = NULL;
334  delete dofMastermap;
335  dofMastermap = NULL;
336  delete dofBCmap;
337  dofBCmap = NULL;
338  delete dofICmap;
339  dofICmap = NULL;
340 
341  IntArray dofIDArry;
342  IntArray ic, masterMask, dofTypeMask;
343 
344  loadArray.clear();
346 
348  int dummy;
349  IR_GIVE_OPTIONAL_FIELD(ir, dummy, "ndofs");
350 
351  if ( ir->hasField(_IFT_DofManager_dofidmask) ) {
353  this->dofidmask = new IntArray(dofIDArry);
354  } else {
355  dofIDArry = domain->giveDefaultNodeDofIDArry();
356  }
357 
358  mBC.clear();
360 
361  ic.clear();
363 
364  // reads master mask - in this array are numbers of master dofManagers
365  // to which are connected dofs in receiver.
366  // if master mask index is zero then dof is created as master (i.e., having own equation number)
367  // othervise slave dof connected to master DofManager is created.
368  // by default if masterMask is not specifyed, all dofs are created as masters.
369  dofTypeMask.clear(); // termitovo
371 
372  // read boundary flag
374  isBoundaryFlag = true;
375  }
376 
377 
378  partitions.clear();
380 
383  } else if ( ir->hasField(_IFT_DofManager_remoteflag) ) {
385  } else if ( ir->hasField(_IFT_DofManager_nullflag) ) {
387  } else {
389  }
390 
391  // in parallel mode, slaves are allowed, because ((Dr. Rypl promissed)
392  // masters have to be in same partition as slaves. They can be again Remote copies.
393 
394 
395  bool hasIc = ic.giveSize() != 0;
396  bool hasBc = mBC.giveSize() != 0;
397  bool hasTypeinfo = dofTypeMask.giveSize() != 0;
398 
400  if ( ( hasIc || hasBc || hasTypeinfo ) && !this->dofidmask ) {
401  this->dofidmask = new IntArray(dofIDArry);
402  }
403 
404  // check sizes
405  if ( hasBc ) {
406  if ( mBC.giveSize() != dofIDArry.giveSize() ) {
407  OOFEM_ERROR("bc size mismatch. Size is %d and need %d", mBC.giveSize(), dofIDArry.giveSize());
408  }
409  this->dofBCmap = new std :: map< int, int >();
410  for ( int i = 1; i <= mBC.giveSize(); ++i ) {
411  if ( mBC.at(i) > 0 ) {
412  ( * this->dofBCmap ) [ dofIDArry.at(i) ] = mBC.at(i);
413  }
414  }
415  }
416 
417  if ( hasIc ) {
418  if ( ic.giveSize() != dofIDArry.giveSize() ) {
419  OOFEM_ERROR("ic size mismatch. Size is %d and need %d", ic.giveSize(), dofIDArry.giveSize());
420  }
421  this->dofICmap = new std :: map< int, int >();
422  for ( int i = 1; i <= ic.giveSize(); ++i ) {
423  if ( ic.at(i) > 0 ) {
424  ( * this->dofICmap ) [ dofIDArry.at(i) ] = ic.at(i);
425  }
426  }
427  }
428 
429  if ( hasTypeinfo ) {
430  if ( dofTypeMask.giveSize() != dofIDArry.giveSize() ) {
431  OOFEM_ERROR("dofTypeMask size mismatch. Size is %d and need %d", dofTypeMask.giveSize(), dofIDArry.giveSize());
432  }
433  this->dofTypemap = new std :: map< int, int >();
434  for ( int i = 1; i <= dofTypeMask.giveSize(); ++i ) {
435  if ( dofTypeMask.at(i) != DT_master ) {
436  ( * this->dofTypemap ) [ dofIDArry.at(i) ] = dofTypeMask.at(i);
437  }
438  }
439  // For simple slave dofs:
440  if ( dofTypeMask.contains(DT_simpleSlave) ) {
441  IR_GIVE_FIELD(ir, masterMask, _IFT_DofManager_mastermask);
442  if ( masterMask.giveSize() != dofIDArry.giveSize() ) {
443  OOFEM_ERROR("mastermask size mismatch");
444  }
445  this->dofMastermap = new std :: map< int, int >();
446  for ( int i = 1; i <= masterMask.giveSize(); ++i ) {
447  if ( masterMask.at(i) > 0 ) {
448  ( * this->dofMastermap ) [ dofIDArry.at(i) ] = masterMask.at(i);
449  }
450  }
451  }
452  }
453 
454  return IRRT_OK;
455 }
456 
457 
459 {
461 
462  IntArray mbc, dofids;
463  // Ignore here mBC and dofidmask as they may not correspod to actual state.
464  // They just decribe the state at init, but after some dofs may have been
465  // added dynamically (xfem, subdivision, etc).
466  for ( Dof *dof: *this ) {
467  dofids.followedBy(dof->giveDofID(),3);
468  if (dof->giveBcId()) mbc.followedBy(dof->giveBcId(),3);
469  else mbc.followedBy(0,3);
470  }
471  input.setField(mbc, _IFT_DofManager_bc);
472  input.setField(dofids, _IFT_DofManager_dofidmask);
473 
474 
475  if ( this->dofTypemap ) {
476  IntArray typeMask( this->dofidmask->giveSize() );
477  for ( int i = 1; i <= dofidmask->giveSize(); ++i ) {
478  typeMask.at(i) = ( * this->dofTypemap ) [ dofidmask->at(i) ];
479  }
480  input.setField(typeMask, _IFT_DofManager_doftypemask);
481  }
482 
483  if ( this->dofMastermap ) {
484  IntArray masterMask( this->dofidmask->giveSize() );
485  for ( int i = 1; i <= dofidmask->giveSize(); ++i ) {
486  masterMask.at(i) = ( * this->dofMastermap ) [ dofidmask->at(i) ];
487  }
488  input.setField(masterMask, _IFT_DofManager_mastermask);
489  }
490 
491  if ( isBoundaryFlag ) {
493  }
494 
495 
496  if ( this->partitions.giveSize() > 0 ) {
498  }
499 
500  if ( parallel_mode == DofManager_shared ) {
502  } else if ( parallel_mode == DofManager_remote ) {
504  } else if ( parallel_mode == DofManager_null ) {
506  }
507 }
508 
509 
510 void DofManager :: printOutputAt(FILE *stream, TimeStep *tStep)
511 {
512  EngngModel *emodel = this->giveDomain()->giveEngngModel();
513 
514  fprintf( stream, "%-8s%8d (%8d):\n", this->giveClassName(), this->giveLabel(), this->giveNumber() );
515  for ( Dof *dof: *this ) {
516  emodel->printDofOutputAt(stream, dof, tStep);
517  }
518 }
519 
520 
522 // Prints the receiver on screen.
523 {
524  printf("DofManager %d\n", number);
525  for ( Dof *dof: *this ) {
526  dof->printYourself();
527  }
528 
530  printf("\n");
531 }
532 
533 
535 // Updates the receiver at end of step.
536 {
537  for ( Dof *dof: *this ) {
538  dof->updateYourself(tStep);
539  }
540 }
541 
542 
544 //
545 // saves full node context (saves state variables, that completely describe
546 // current state)
547 //
548 {
549  int _val;
550  contextIOResultType iores;
551 
552  if ( ( iores = FEMComponent :: saveContext(stream, mode, obj) ) != CIO_OK ) {
553  THROW_CIOERR(iores);
554  }
555 
556  if ( mode & CM_Definition ) {
557  if ( !stream.write(this->giveNumberOfDofs()) ) {
559  }
560 
561  for ( auto &dof : *this ) {
562  _val = dof->giveDofType();
563  if ( !stream.write(_val) ) {
565  }
566  _val = dof->giveDofID();
567  if ( !stream.write(_val) ) {
569  }
570  if ( ( iores = dof->saveContext(stream, mode, obj) ) != CIO_OK ) {
571  THROW_CIOERR(iores);
572  }
573  }
574 
575  if ( ( iores = loadArray.storeYourself(stream) ) != CIO_OK ) {
576  THROW_CIOERR(iores);
577  }
578 
579  if ( !stream.write(isBoundaryFlag) ) {
581  }
582 
583  if ( !stream.write(hasSlaveDofs) ) {
585  }
586 
587  if ( !stream.write(globalNumber) ) {
589  }
590 
591  _val = parallel_mode;
592  if ( !stream.write(_val) ) {
594  }
595 
596  if ( ( iores = partitions.storeYourself(stream) ) != CIO_OK ) {
597  THROW_CIOERR(iores);
598  }
599  } else {
600  for ( auto &dof : *this ) {
601  if ( ( iores = dof->saveContext(stream, mode, obj) ) != CIO_OK ) {
602  THROW_CIOERR(iores);
603  }
604  }
605  }
606 
607  return CIO_OK;
608 }
609 
610 
612 //
613 // restores full node context (saves state variables, that completely describe
614 // current state)
615 //
616 {
617  contextIOResultType iores;
618 
619  if ( ( iores = FEMComponent :: restoreContext(stream, mode, obj) ) != CIO_OK ) {
620  THROW_CIOERR(iores);
621  }
622 
623  if ( mode & CM_Definition ) {
624  int _numberOfDofs;
625  if ( !stream.read(_numberOfDofs) ) {
627  }
628 
629  // allocate new ones
630  for ( auto &d: dofArray) { delete d; }
631  dofArray.clear();
632 
633  for ( int i = 0; i < _numberOfDofs; i++ ) {
634  int dtype, dofid;
635  if ( !stream.read(dtype) ) {
637  }
638  if ( !stream.read(dofid) ) {
640  }
641  Dof *dof = classFactory.createDof( ( dofType ) dtype, (DofIDItem)dofid, this );
642  if ( ( iores = dof->restoreContext(stream, mode, obj) ) != CIO_OK ) {
643  THROW_CIOERR(iores);
644  }
645  this->appendDof(dof);
646  }
647 
648  if ( ( iores = loadArray.restoreYourself(stream) ) != CIO_OK ) {
649  THROW_CIOERR(iores);
650  }
651 
652  if ( !stream.read(isBoundaryFlag) ) {
654  }
655 
656  if ( !stream.read(hasSlaveDofs) ) {
658  }
659 
660  if ( !stream.read(globalNumber) ) {
662  }
663 
664  int _val;
665  if ( !stream.read(_val) ) {
667  }
668 
670  if ( ( iores = partitions.restoreYourself(stream) ) != CIO_OK ) {
671  THROW_CIOERR(iores);
672  }
673  } else {
674  for ( auto &dof : this->dofArray ) {
675  if ( ( iores = dof->restoreContext(stream, mode, obj) ) != CIO_OK ) {
676  THROW_CIOERR(iores);
677  }
678  }
679  }
680 
681  return CIO_OK;
682 }
683 
684 
685 void DofManager :: giveUnknownVector(FloatArray &answer, const IntArray &dofIDArry, ValueModeType mode, TimeStep *tStep, bool padding)
686 {
687  answer.resize( dofIDArry.giveSize() );
688  if ( dofIDArry.giveSize() == 0 ) return;
689 
690  int k = 0;
691  for ( auto &dofid: dofIDArry ) {
692  auto pos = this->findDofWithDofId( ( DofIDItem ) dofid );
693  if ( pos == this->end() ) {
694  if ( padding ) {
695  answer.at(++k) = 0.;
696  }
697  continue;
698  }
699  answer.at(++k) = (*pos)->giveUnknown(mode, tStep);
700  }
701  answer.resizeWithValues(k);
702 
703  // Transform to global c.s.
704  FloatMatrix L2G;
705  if ( this->computeL2GTransformation(L2G, dofIDArry) ) {
706  answer.rotatedWith(L2G, 'n');
707  }
708 }
709 
710 
711 void DofManager :: giveUnknownVector(FloatArray &answer, const IntArray &dofIDArry,
712  PrimaryField &field, ValueModeType mode, TimeStep *tStep, bool padding)
713 {
714  answer.resize( dofIDArry.giveSize() );
715 
716  int k = 0;
717  for ( auto &dofid: dofIDArry ) {
718  auto pos = this->findDofWithDofId( ( DofIDItem ) dofid );
719  if ( pos == this->end() ) {
720  if ( padding ) {
721  answer.at(++k) = 0.;
722  }
723  continue;
724  }
725  answer.at(++k) = (*pos)->giveUnknown(field, mode, tStep);
726  }
727  answer.resizeWithValues(k);
728 
729  // Transform to global c.s.
730  FloatMatrix L2G;
731  if ( this->computeL2GTransformation(L2G, dofIDArry) ) {
732  answer.rotatedWith(L2G, 'n');
733  }
734 }
735 
736 
738 {
739  int i = 1;
740  answer.resize(this->giveNumberOfDofs());
741  for ( Dof *dof: *this ) {
742  answer.at(i) = dof->giveUnknown(mode, tStep);
743  i++;
744  }
745 }
746 
747 
749  ValueModeType mode, TimeStep *tStep)
750 {
751  answer.resize(dofIDArry.giveSize());
752 
753  int j = 1;
754  for ( int dofid: dofIDArry ) {
755  answer.at(j++) = this->giveDofWithID( dofid )->giveBcValue(mode, tStep);
756  }
757 
758  // Transform to global c.s.
759  FloatMatrix L2G;
760  if ( this->computeL2GTransformation(L2G, dofIDArry) ) {
761  answer.rotatedWith(L2G, 'n');
762  }
763 }
764 
765 
767 {
768  int k = 1;
769  FloatArray localVector(3);
770  IntArray dofIDArry(3);
771 
772  // This is a bit cumbersome. I first construct the local vector, which might have a odd order, e.g [D_w, D_u], which is later added to the global vector "answer"
773  // I also store the dof id's, so that I can construct the local 2 global transformation afterwards (if its necessary). / Mikael
774  for ( Dof *d: *this ) {
775  double val = d->giveUnknown(mode, tStep);
776  if ( ut == DisplacementVector || ut == EigenVector ) { // Just treat eigenvectors as displacement vectors (they are redundant)
777  if ( d->giveDofID() == D_u ) {
778  dofIDArry.at(k) = D_u;
779  localVector.at(k) = val;
780  k++;
781  } else if ( d->giveDofID() == D_v ) {
782  dofIDArry.at(k) = D_v;
783  localVector.at(k) = val;
784  k++;
785  } else if ( d->giveDofID() == D_w ) {
786  dofIDArry.at(k) = D_w;
787  localVector.at(k) = val;
788  k++;
789  }
790  } else if ( ut == VelocityVector ) {
791  if ( d->giveDofID() == V_u ) {
792  dofIDArry.at(k) = V_u;
793  localVector.at(k) = val;
794  k++;
795  } else if ( d->giveDofID() == V_v ) {
796  dofIDArry.at(k) = V_v;
797  localVector.at(k) = val;
798  k++;
799  } else if ( d->giveDofID() == V_w ) {
800  dofIDArry.at(k) = V_w;
801  localVector.at(k) = val;
802  k++;
803  }
804  } else {
805  OOFEM_ERROR("Can't produce vector for unknown type: %d", ut);
806  }
807  }
808 
809  FloatMatrix L2G;
810  if ( this->computeL2GTransformation(L2G, dofIDArry) ) {
811  // Transform to global c.s.
812  answer.beProductOf(L2G, localVector);
813  } else {
814  // No local c.s, just copy the values to respective index;
815  answer.resize(3);
816  answer.zero();
817  for ( int i = 1; i <= k; i++ ) {
818  if ( dofIDArry.at(i) == D_u || dofIDArry.at(i) == V_u ) {
819  answer.at(1) = localVector.at(i);
820  } else if ( dofIDArry.at(i) == D_v || dofIDArry.at(i) == V_v ) {
821  answer.at(2) = localVector.at(i);
822  } else if ( dofIDArry.at(i) == D_w || dofIDArry.at(i) == V_w ) {
823  answer.at(3) = localVector.at(i);
824  }
825  }
826  }
827 }
828 
829 
831 {
832  for ( Dof *dof: *this ) {
833  if ( !dof->isPrimaryDof() ) {
834  return true;
835  }
836  }
837 
838  return false;
839 }
840 
841 
843 {
844  IntArray _dof_masters;
845  bool answer = false;
846 
847  masters.clear();
848  for ( Dof *dof: *this ) {
849  if ( !dof->isPrimaryDof() ) {
850  answer = true;
851  dof->giveMasterDofManArray(_dof_masters);
852  for ( int j = 1; j <= _dof_masters.giveSize(); j++ ) {
853  masters.insertSortedOnce(_dof_masters.at(j), 2);
854  }
855  }
856  }
857 
858  return answer;
859 }
860 
861 
863 {
864  hasSlaveDofs = false;
865  for ( Dof *dof: *this ) {
866  if ( !dof->isPrimaryDof() ) {
867  hasSlaveDofs = true;
868  continue;
869  }
870  }
871 }
872 
873 
875 // computes transformation matrix of receiver.
876 // transformation should include transformation from global cs to nodal cs,
877 // as well as further necessary transformations (for example in case
878 // rigid arms this must include transformation to master dofs).
879 {
880  FloatMatrix L2G, M2L;
881 
882  bool hasL2G = computeL2GTransformation(L2G, dofMask);
883  bool hasM2L = computeM2LTransformation(M2L, dofMask);
884 
885  if ( !hasL2G && !hasM2L ) {
886  answer.clear();
887  return false;
888  } else if ( hasL2G && hasM2L ) {
889  answer.beProductOf(L2G, M2L);
890  } else if ( hasL2G ) {
891  answer = L2G;
892  } else {
893  answer = M2L;
894  }
895  return true;
896 }
897 
898 
900 {
901  return false;
902 }
903 
904 
906 {
907  if ( !this->hasAnySlaveDofs() ) {
908  return false;
909  }
910 
911  FloatArray mstrContrs;
912 
913  if ( dofIDArry.isEmpty() ) {
915  int cols = 0;
916  for ( Dof *dof: *this ) {
917  cols += dof->giveNumberOfPrimaryMasterDofs();
918  }
919  answer.resize( this->giveNumberOfDofs(), cols );
920  answer.zero();
921 
922  int k = 1, i = 1;
923  for ( Dof *dof: *this ) {
924  dof->computeDofTransformation(mstrContrs);
925  answer.copySubVectorRow(mstrContrs, i, k);
926  k += mstrContrs.giveSize();
927  i++;
928  }
929  } else {
930  answer.resize( dofIDArry.giveSize(), giveNumberOfPrimaryMasterDofs(dofIDArry) );
931  answer.zero();
932 
933  int k = 1;
934  for ( int i = 1; i <= dofIDArry.giveSize(); i++ ) {
935  this->giveDofWithID(dofIDArry.at(i))->computeDofTransformation(mstrContrs);
936  answer.copySubVectorRow(mstrContrs, i, k);
937  k += mstrContrs.giveSize();
938  }
939  }
940  return true;
941 }
942 
943 
945 {
946  return this->hasAnySlaveDofs();
947 }
948 
949 
951 {
952  //update masterNode numbering
953  if ( this->dofMastermap ) {
954  for ( auto & mapper: *this->dofMastermap ) {
955  mapper.second = f( mapper.second, ERS_DofManager );
956  }
957  }
958 
959  for ( Dof *dof: *this ) {
960  dof->updateLocalNumbering(f);
961  }
962 }
963 
964 
966 {
967  // more optimized version can be made requiring sorted partition list of receiver
968  int size = _p.giveSize();
969  for ( int i = 1; i <= size; i++ ) {
970  partitions.insertOnce( _p.at(i) );
971  }
972 }
973 
974 
976 {
977  int n = partitions.giveSize();
978  int myrank = this->giveDomain()->giveEngngModel()->giveRank();
979  if ( partitions.findFirstIndexOf(myrank) ) {
980  return n;
981  } else {
982  return n + 1;
983  }
984 }
985 
986 
988 {
989  if ( parallel_mode == DofManager_local ) {
990  return true;
991  }
992 
993  if ( parallel_mode == DofManager_shared ) {
994  // determine if problem is the lowest one sharing the dofman; if yes the receiver is responsible to
995  // deliver number
996  int n = partitions.giveSize();
997  int myrank = this->giveDomain()->giveEngngModel()->giveRank();
998  int minrank = myrank;
999 
1000  for ( int j = 1; j <= n; j++ ) {
1001  minrank = min( minrank, partitions.at(j) );
1002  }
1003 
1004  if ( minrank == myrank ) {
1005  return true;
1006  }
1007  }
1008 
1009  return false;
1010 }
1011 
1012 } // end namespace oofem
bool contains(int value) const
Definition: intarray.h:283
#define _IFT_DofManager_nullflag
Definition: dofmanager.h:63
void setField(int item, InputFieldType id)
contextIOResultType storeYourself(DataStream &stream) const
Stores array to output stream.
Definition: intarray.C:289
int number
Component number.
Definition: femcmpnn.h:80
DofManager in active domain is shared only by remote elements (these are only introduced for nonlocal...
Definition: dofmanager.h:88
void printYourself() const
Prints receiver on stdout.
Definition: intarray.C:225
Class and object Domain.
Definition: domain.h:115
#define _IFT_DofManager_mastermask
Definition: dofmanager.h:56
DofManager(int n, Domain *aDomain)
Constructor.
Definition: dofmanager.C:54
#define _IFT_DofManager_ic
Definition: dofmanager.h:55
Domain * domain
Link to domain object, useful for communicating with other FEM components.
Definition: femcmpnn.h:82
virtual bool giveMasterDofMans(IntArray &masters)
Returns true if the receiver is linked (its slave DOFs depend on master values) to some other dof man...
Definition: dofmanager.C:842
virtual void computeLoadVector(FloatArray &answer, Load *load, CharType type, TimeStep *tStep, ValueModeType mode)
Computes the load vector for given load.
Definition: dofmanager.C:97
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
bool isEmpty() const
Checks if receiver is empty (i.e., zero sized).
Definition: intarray.h:208
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
virtual void printYourself()
Prints receiver state on stdout. Useful for debugging.
Definition: dofmanager.C:521
virtual void postInitialize()
Performs post-initialization such like checking if there are any slave dofs etc.
Definition: dofmanager.C:862
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.
#define _IFT_DofManager_boundaryflag
Definition: dofmanager.h:58
virtual void giveInputRecord(DynamicInputRecord &input)
Setups the input record string of receiver.
Definition: dofmanager.C:458
void clear()
Clears receiver (zero size).
Definition: floatarray.h:206
std::map< int, int > * dofMastermap
Map from DofIDItem to master node.
Definition: dofmanager.h:147
bool insertSortedOnce(int value, int allocChunk=0)
Inserts given value into a receiver, which is assumed to be sorted.
Definition: intarray.C:360
virtual double giveUnknown(ValueModeType mode, TimeStep *tStep)=0
The key method of class Dof.
EngngModel * giveEngngModel()
Returns engineering model to which receiver is associated.
Definition: domain.C:433
std::vector< Dof * > dofArray
Array of DOFs.
Definition: dofmanager.h:117
dofType
Dof Type, determines the type of DOF created.
Definition: doftype.h:48
const IntArray & giveDefaultNodeDofIDArry()
Returns default DofID array which defines physical meaning of particular DOFs.
Definition: domain.C:1004
virtual bool hasField(InputFieldType id)=0
Returns true if record contains field identified by idString keyword.
#define _IFT_DofManager_dofidmask
Definition: dofmanager.h:52
virtual contextIOResultType saveContext(DataStream &stream, ContextMode mode, void *obj=NULL)
Stores receiver state to output stream.
Definition: femcmpnn.C:51
General IO error.
virtual void printDofOutputAt(FILE *stream, Dof *iDof, TimeStep *tStep)
DOF printing routine.
Definition: engngm.C:798
virtual void computeComponentArrayAt(FloatArray &answer, TimeStep *tStep, ValueModeType mode)
Computes boundary condition value - its components values at given time.
Definition: load.C:82
virtual void printOutputAt(FILE *file, TimeStep *tStep)
Prints output of receiver to stream, for given time step.
Definition: dofmanager.C:510
std::map< int, int > * dofICmap
Map from DofIDItem to ic (to be removed).
Definition: dofmanager.h:151
virtual void printYourself()
Prints the receiver state on stdout.
Definition: dof.C:107
virtual bool hasAnySlaveDofs()
Definition: dofmanager.C:830
virtual void giveInputRecord(DynamicInputRecord &input)
Setups the input record string of receiver.
Definition: femcmpnn.C:77
virtual void giveEquationNumbers(IntArray &masterEqNumbers, const UnknownNumberingScheme &s)
Returns equation number of receiver.
Definition: dof.C:61
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.
int givePartitionsConnectivitySize()
Returns number of partitions sharing given receiver (=number of shared partitions + local one)...
Definition: dofmanager.C:975
#define THROW_CIOERR(e)
Definition: contextioerr.h:61
dofManagerParallelMode
In parallel mode, this type indicates the mode of DofManager.
Definition: dofmanager.h:80
void rotatedWith(FloatMatrix &r, char mode)
Returns the receiver a rotated according the change-of-base matrix r.
Definition: floatarray.C:799
virtual int giveDofEquationNumber(Dof *dof) const =0
Returns the equation number for corresponding DOF.
#define _IFT_DofManager_bc
Definition: dofmanager.h:54
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
Definition: dofmanager.C:326
virtual int write(const int *data, int count)=0
Writes count integer values from array pointed by data.
Concentrated nodal load.
Definition: bcgeomtype.h:42
virtual void updateLocalNumbering(EntityRenumberingFunctor &f)
Local renumbering support.
Definition: dof.h:315
void giveUnknownVector(FloatArray &answer, const IntArray &dofMask, ValueModeType mode, TimeStep *tStep, bool padding=false)
Assembles the vector of unknowns in global c.s for given dofs of receiver.
Definition: dofmanager.C:685
virtual int giveBcId()=0
Returns the id of associated boundary condition, if there is any.
#define _IFT_DofManager_remoteflag
Definition: dofmanager.h:62
bool hasSlaveDofs
Flag indicating whether receiver has slave DOFs.
Definition: dofmanager.h:126
bool computeM2GTransformation(FloatMatrix &answer, const IntArray &dofIDArry)
Computes receiver transformation matrix from global CS to dofManager specific coordinate system; ...
Definition: dofmanager.C:874
int giveNumberOfDofs() const
Definition: dofmanager.C:279
int globalNumber
In parallel mode, globalNumber contains globally unique DoFManager number.
Definition: dofmanager.h:132
void giveUnknownVectorOfType(FloatArray &answer, UnknownType ut, ValueModeType mode, TimeStep *tStep)
Constructs the requested vector by assembling e.g.
Definition: dofmanager.C:766
void insertOnce(int p)
Insert once (does not make any assumption about receiver state or ordering, quite inefficient)...
Definition: intarray.C:412
#define OOFEM_ERROR(...)
Definition: error.h:61
virtual bool requiresTransformation()
Indicates, whether dofManager requires the transformation.
Definition: dofmanager.C:944
void clear()
Clears the array (zero size).
Definition: intarray.h:177
int giveLabel() const
Definition: dofmanager.h:502
DofIDItem
Type representing particular dof type.
Definition: dofiditem.h:86
void copySubVectorRow(const FloatArray &src, int sr, int sc)
Copy (set) given vector to receiver row sr, starting at column sc.
Definition: floatmatrix.C:677
UnknownType
Type representing particular unknown (its physical meaning).
Definition: unknowntype.h:55
void giveMasterDofIDArray(const IntArray &dofIDArry, IntArray &masterDofIDs) const
Returns master dof ID array of receiver.
Definition: dofmanager.C:209
Abstract base class allowing to control the way, how equations are assigned to individual DOFs...
DofIDItem giveDofID() const
Returns DofID value of receiver, which determines type of of unknown connected to receiver (e...
Definition: dof.h:276
void setLoadArray(IntArray &load)
Sets the array of applied loadings of the receiver.
Definition: dofmanager.C:91
virtual bool isPrimaryDof()
Tests if receiver is primary DOF.
Definition: dof.h:287
virtual void giveMasterDofManArray(IntArray &answer)
Definition: dof.C:183
IntArray partitions
List of partition sharing the shared dof manager or remote partition containing remote dofmanager cou...
Definition: dofmanager.h:140
void resizeWithValues(int n, int allocChunk=0)
Checks size of receiver towards requested bounds.
Definition: intarray.C:115
#define _IFT_DofManager_doftypemask
Definition: dofmanager.h:57
void askNewEquationNumbers(TimeStep *tStep)
Renumbers all contained DOFs.
Definition: dofmanager.C:295
void giveCompleteMasterDofIDArray(IntArray &dofIDArray) const
Returns the full dof ID array of receiver.
Definition: dofmanager.C:249
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Receiver becomes the result of the product of aMatrix and anArray.
Definition: floatarray.C:676
void resizeWithValues(int s, int allocChunk=0)
Checks size of receiver towards requested bounds.
Definition: floatarray.C:615
void resize(int n)
Checks size of receiver towards requested bounds.
Definition: intarray.C:124
void giveCompleteUnknownVector(FloatArray &answer, ValueModeType mode, TimeStep *tStep)
Assembles the complete unknown vector in node.
Definition: dofmanager.C:737
contextIOResultType restoreYourself(DataStream &stream)
Restores array from image on stream.
Definition: intarray.C:305
IntArray loadArray
List of applied loads.
Definition: dofmanager.h:119
void appendDof(Dof *dof)
Adds the given Dof into the receiver.
Definition: dofmanager.C:134
virtual bool computeL2GTransformation(FloatMatrix &answer, const IntArray &dofIDArry)
Computes transformation matrix from global c.s.
Definition: dofmanager.C:899
Class representing vector of real numbers.
Definition: floatarray.h:82
void setNumberOfDofs(int _ndofs)
Sets number of dofs of the receiver; Deallocates existing DOFs; Resizes the dofArray accordingly...
Definition: dofmanager.C:286
Dof * createDof(dofType type, DofIDItem dofid, DofManager *dman)
Creates new instance of DOF corresponding to given keyword.
Definition: classfactory.C:115
virtual contextIOResultType saveContext(DataStream &stream, ContextMode mode, void *obj=NULL)
Stores receiver state to output stream.
Definition: dofmanager.C:543
bool hasDofID(DofIDItem id) const
Checks if receiver contains dof with given ID.
Definition: dofmanager.C:166
dofManagerParallelMode parallel_mode
Definition: dofmanager.h:134
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
void givePrescribedUnknownVector(FloatArray &answer, const IntArray &dofMask, ValueModeType mode, TimeStep *tStep)
Assembles the vector of prescribed unknowns in nodal c.s for given dofs of receiver.
Definition: dofmanager.C:748
virtual const char * giveClassName() const =0
void giveCompleteLocationArray(IntArray &locationArray, const UnknownNumberingScheme &s) const
Returns full location array of receiver containing equation numbers of all dofs of receiver...
Definition: dofmanager.C:229
void assemble(const FloatArray &fe, const IntArray &loc)
Assembles the array fe (typically, the load vector of a finite element) into the receiver, using loc as location array.
Definition: floatarray.C:551
CharType
Definition: chartype.h:87
void resize(int rows, int cols)
Checks size of receiver towards requested bounds.
Definition: floatmatrix.C:1358
Class representing the general Input Record.
Definition: inputrecord.h:101
std::vector< Dof * >::const_iterator findDofWithDofId(DofIDItem dofID) const
Finds index of DOF with required physical meaning of receiver.
Definition: dofmanager.C:266
bool isBoundaryFlag
Indicates if dofManager is boundary (true boundary or on boundary between regions) or interior...
Definition: dofmanager.h:124
std::vector< Dof * >::iterator begin()
Definition: dofmanager.h:157
virtual contextIOResultType restoreContext(DataStream &stream, ContextMode mode, void *obj=NULL)
Restores the receiver state previously written in stream.
Definition: dof.C:148
void mergePartitionList(IntArray &_p)
Merges receiver partition list with given lists.
Definition: dofmanager.C:965
Dof * giveDofWithID(int dofID) const
Returns DOF with given dofID; issues error if not present.
Definition: dofmanager.C:119
void followedBy(const IntArray &b, int allocChunk=0)
Appends array b at the end of receiver.
Definition: intarray.C:145
std::map< int, int > * dofBCmap
Map from DofIDItem to bc (to be removed).
Definition: dofmanager.h:149
virtual double giveBcValue(ValueModeType mode, TimeStep *tStep)
Returns value of boundary condition of dof if it is prescribed.
Definition: dof.C:120
void zero()
Zeroes all coefficients of receiver.
Definition: floatarray.C:658
virtual bcGeomType giveBCGeoType() const
Returns geometry character of boundary condition.
int giveRank() const
Returns domain rank in a group of collaborating processes (0..groupSize-1)
Definition: engngm.h:1058
std::map< int, int > * dofTypemap
Map from DofIDItem to dofType.
Definition: dofmanager.h:145
Class representing the a dynamic Input Record.
virtual void computeDofTransformation(FloatArray &masterContribs)
Computes dof transformation array, which describes the dependence of receiver value on values of mast...
Definition: dof.C:176
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
#define CM_Definition
Definition: contextmode.h:47
IntArray * giveLoadArray()
Returns the array containing applied loadings of the receiver.
Definition: dofmanager.C:82
void zero()
Zeroes all coefficient of receiver.
Definition: floatmatrix.C:1326
Domain * giveDomain() const
Definition: femcmpnn.h:100
int min(int i, int j)
Returns smaller value from two given decimals.
Definition: mathfem.h:59
#define _IFT_DofManager_sharedflag
Definition: dofmanager.h:61
virtual contextIOResultType restoreContext(DataStream &stream, ContextMode mode, void *obj=NULL)
Restores the receiver state previously written in stream.
Definition: femcmpnn.C:64
Load is base abstract class for all loads.
Definition: load.h:61
Abstract base class representing the "problem" under consideration.
Definition: engngm.h:181
virtual int giveNumberOfPrimaryMasterDofs()
Definition: dof.h:252
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
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
Assigns to the receiver product of .
Definition: floatmatrix.C:337
int giveSize() const
Definition: intarray.h:203
virtual void updateYourself(TimeStep *tStep)
Updates receiver after finishing time step.
Definition: dof.h:336
int giveSize() const
Returns the size of receiver.
Definition: floatarray.h:218
virtual ~DofManager()
Destructor.
Definition: dofmanager.C:68
the oofem namespace is to define a context or scope in which all oofem names are defined.
int giveNumberOfPrimaryMasterDofs(const IntArray &dofIDArray) const
Returns the number of primary dofs on which receiver dofs (given in dofArray) depend on...
Definition: dofmanager.C:303
std::vector< Dof * >::iterator end()
Definition: dofmanager.h:158
void clear()
Sets size of receiver to be an empty matrix. It will have zero rows and zero columns size...
Definition: floatmatrix.h:516
bool isLocal()
Returns true if receiver is locally maintained.
Definition: dofmanager.C:987
#define IR_GIVE_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:69
#define _IFT_DofManager_load
Definition: dofmanager.h:53
Abstract class Dof represents Degree Of Freedom in finite element mesh.
Definition: dof.h:93
int giveNumber() const
Definition: femcmpnn.h:107
virtual void giveDofIDs(IntArray &masterDofIDs)
As giveEquationNumbers but for dof IDs.
Definition: dof.C:67
void giveLocationArray(const IntArray &dofIDArry, IntArray &locationArray, const UnknownNumberingScheme &s) const
Returns location array (array containing for each requested dof related equation number) for given nu...
Definition: dofmanager.C:177
DofManager is local, there are no contribution from other domains to this DofManager.
Definition: dofmanager.h:81
virtual void updateYourself(TimeStep *tStep)
Updates receiver after equilibrium in time step has been reached.
Definition: dofmanager.C:534
virtual contextIOResultType restoreContext(DataStream &stream, ContextMode mode, void *obj=NULL)
Restores the receiver state previously written in stream.
Definition: dofmanager.C:611
void removeDof(DofIDItem id)
Removes Dof with given id from dofArray.
Definition: dofmanager.C:151
#define OOFEM_WARNING(...)
Definition: error.h:62
#define _IFT_DofManager_partitions
Definition: dofmanager.h:60
Class representing solution step.
Definition: timestep.h:80
The top abstract class of all classes constituting the finite element mesh.
Definition: femcmpnn.h:76
DofManager is shared by neighboring partitions, it is necessary to sum contributions from all contrib...
Definition: dofmanager.h:82
virtual int askNewEquationNumber(TimeStep *tStep)=0
Asks EngngModel for new equation number.
virtual void updateLocalNumbering(EntityRenumberingFunctor &f)
Local renumbering support.
Definition: dofmanager.C:950
int findFirstIndexOf(int value) const
Finds index of first occurrence of given value in array.
Definition: intarray.C:331
IntArray * dofidmask
List of additional dof ids to include.
Definition: dofmanager.h:143
virtual bool computeM2LTransformation(FloatMatrix &answer, const IntArray &dofIDArry)
Computes transformation matrix from local DOFs to master DOFs; .
Definition: dofmanager.C:905
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:28 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011