OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
vtkexportmodule.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 /* COMPONENTS in TENSORS like stress or strain
36  * x y z
37  * x 1 6 5
38  * y 6 2 4
39  * z 5 4 3
40  *
41  * PARAVIEW - stresses and strains in global c.s., damage tensor in local c.s.
42  * x y z
43  * x 0 1 2
44  * y 3 4 5
45  * z 6 7 8
46  *
47  */
48 
49 
50 #include "vtkexportmodule.h"
51 #include "timestep.h"
52 #include "gausspoint.h"
53 #include "engngm.h"
54 #include "node.h"
55 #include "materialinterface.h"
56 #include "mathfem.h"
57 #include "cltypes.h"
58 #include "element.h"
59 #include "material.h"
60 #include "classfactory.h"
61 #include "crosssection.h"
62 #include "dof.h"
63 
64 #include <vector>
65 
66 namespace oofem {
68 
69 VTKExportModule :: VTKExportModule(int n, EngngModel *e) : ExportModule(n, e), internalVarsToExport(), primaryVarsToExport()
70 {
71  smoother = NULL;
72 }
73 
74 
76 {
77  if ( this->smoother ) {
78  delete this->smoother;
79  }
80 }
81 
82 
85 {
86  IRResultType result; // Required by IR_GIVE_FIELD macro
87  int val;
88 
92 
96 
98 }
99 
100 
101 void
102 VTKExportModule :: doOutput(TimeStep *tStep, bool forcedOutput)
103 {
104  if ( !( testTimeStepOutput(tStep) || forcedOutput ) ) {
105  return;
106  }
107 
108  FILE *stream = this->giveOutputStream(tStep);
109 
110  fprintf(stream, "# vtk DataFile Version 2.0\n");
111  fprintf( stream, "Output for time %f\n", tStep->giveTargetTime() );
112  fprintf(stream, "ASCII\n");
113 
114  fprintf(stream, "DATASET UNSTRUCTURED_GRID\n");
115 
116 
117  Domain *d = emodel->giveDomain(1);
118  FloatArray *coords;
119  int i, inode, nnodes = d->giveNumberOfDofManagers();
120  this->giveSmoother(); // make sure smoother is created
121 
122  // output points
123 
124  fprintf(stream, "POINTS %d double\n", nnodes);
125  int ireg = -1;
126  int regionDofMans;
127  IntArray map( d->giveNumberOfDofManagers() );
128 
129  // asemble local->global region map
130  this->initRegionNodeNumbering(map, regionDofMans, 0, d, ireg, 1);
131 
132  OOFEM_LOG_DEBUG("vktexportModule: %d %d\n", nnodes, regionDofMans);
133  for ( inode = 1; inode <= regionDofMans; inode++ ) {
134  coords = d->giveNode( map.at(inode) )->giveCoordinates();
135  for ( i = 1; i <= coords->giveSize(); i++ ) {
136  fprintf( stream, "%e ", coords->at(i) );
137  }
138 
139  for ( i = coords->giveSize() + 1; i <= 3; i++ ) {
140  fprintf(stream, "%e ", 0.0);
141  }
142 
143  fprintf(stream, "\n");
144  }
145 
146  int elemToProcess = 0;
147  int ncells, celllistsize = 0;
148  for ( auto &elem : d->giveElements() ) {
149  if ( elem->giveParallelMode() != Element_local ) {
150  continue;
151  }
152 
153  elemToProcess++;
154  // element composed from same-type cells asumed
155  ncells = this->giveNumberOfElementCells( elem.get() );
156  celllistsize += ncells + ncells *this->giveNumberOfNodesPerCell( this->giveCellType ( elem.get() ) );
157  }
158 
159  int nelemNodes;
160  int vtkCellType;
161  IntArray cellNodes;
162  // output cells
163  fprintf(stream, "\nCELLS %d %d\n", elemToProcess, celllistsize);
164 
165  IntArray regionNodalNumbers(nnodes);
166 
167  // assemble global->local map
168  this->initRegionNodeNumbering(regionNodalNumbers, regionDofMans, 0, d, ireg, 0);
169  for ( auto &elem : d->giveElements() ) {
170  if ( elem->giveParallelMode() != Element_local ) {
171  continue;
172  }
173 
174  vtkCellType = this->giveCellType(elem.get());
175 
176  nelemNodes = this->giveNumberOfNodesPerCell(vtkCellType); //elem->giveNumberOfNodes(); // It HAS to be the same size as giveNumberOfNodesPerCell, otherwise the file will be incorrect.
177  this->giveElementCell(cellNodes, elem.get(), 0);
178  fprintf(stream, "%d ", nelemNodes);
179  for ( i = 1; i <= nelemNodes; i++ ) {
180  fprintf(stream, "%d ", regionNodalNumbers.at( cellNodes.at(i) ) - 1);
181  }
182 
183  fprintf(stream, "\n");
184  }
185 
186  // output cell types
187  fprintf(stream, "\nCELL_TYPES %d\n", elemToProcess);
188  for ( auto &elem : d->giveElements() ) {
189  if ( elem->giveParallelMode() != Element_local ) {
190  continue;
191  }
192 
193  vtkCellType = this->giveCellType(elem.get());
194  fprintf(stream, "%d\n", vtkCellType);
195  }
196 
197  // output cell data (Material ID ...)
198  if ( cellVarsToExport.giveSize() ) {
199  exportCellVars(stream, elemToProcess, tStep);
200  }
201 
203  fprintf( stream, "\n\nPOINT_DATA %d\n", this->giveTotalRBRNumberOfNodes(d) );
204  }
205 
206  this->exportPrimaryVars(stream, tStep);
207  this->exportIntVars(stream, tStep);
208 
209  fclose(stream);
210 }
211 
212 void
214 {
215  if ( this->smoother ) {
216  delete this->smoother;
217  this->smoother = NULL;
218  }
220 }
221 
222 
223 void
225 { }
226 
227 
228 FILE *
230 {
231  std :: string fileName;
232  FILE *answer;
233  fileName = this->giveOutputBaseFileName(tStep) + ".vtk";
234  if ( ( answer = fopen(fileName.c_str(), "w") ) == NULL ) {
235  OOFEM_ERROR("failed to open file %s", fileName.c_str());
236  }
237  return answer;
238 }
239 
240 int
242 {
243  Element_Geometry_Type elemGT = elem->giveGeometryType();
244  int vtkCellType = 0;
245  if ( elemGT == EGT_point ) {
246  vtkCellType = 1;
247  } else if ( elemGT == EGT_line_1 ) {
248  vtkCellType = 3;
249  } else if ( elemGT == EGT_line_2 ) {
250  vtkCellType = 21;
251  } else if ( elemGT == EGT_triangle_1 ) {
252  vtkCellType = 5;
253  } else if ( elemGT == EGT_triangle_2 ) {
254  vtkCellType = 22;
255  } else if ( elemGT == EGT_tetra_1 ) {
256  vtkCellType = 10;
257  } else if ( elemGT == EGT_tetra_2 ) {
258  vtkCellType = 24;
259  } else if ( elemGT == EGT_quad_1 ) {
260  vtkCellType = 9;
261  } else if ( elemGT == EGT_quad_2 ) {
262  vtkCellType = 23;
263  } else if ( elemGT == EGT_hexa_1 ) {
264  vtkCellType = 12;
265  } else if ( elemGT == EGT_hexa_2 ) {
266  vtkCellType = 25;
267  } else if ( elemGT == EGT_wedge_1 ) {
268  vtkCellType = 13;
269  } else if ( elemGT == EGT_wedge_2 ) {
270  vtkCellType = 26;
271  } else {
272  OOFEM_ERROR("unsupported element gemetry type");
273  }
274 
275  return vtkCellType;
276 }
277 
278 int
280 {
281  switch ( cellType ) {
282  case 1:
283  return 1;
284 
285  case 3:
286  return 2;
287 
288  case 5:
289  case 21:
290  return 3;
291 
292  case 9:
293  case 10:
294  return 4;
295 
296  case 14:
297  return 5;
298 
299  case 13:
300  case 22:
301  return 6;
302 
303  case 12:
304  case 23:
305  return 8;
306 
307  case 24:
308  return 10;
309 
310  case 25:
311  return 20;
312 
313  default:
314  OOFEM_ERROR("unsupported cell type ID");
315  }
316 
317  return 0; // to make compiler happy
318 }
319 
320 
321 void
323 {
324  Element_Geometry_Type elemGT = elem->giveGeometryType();
325  int i, nelemNodes;
326 
327  if ( ( elemGT == EGT_point ) ||
328  ( elemGT == EGT_line_1 ) || ( elemGT == EGT_line_2 ) ||
329  ( elemGT == EGT_triangle_1 ) || ( elemGT == EGT_triangle_2 ) ||
330  ( elemGT == EGT_tetra_1 ) || ( elemGT == EGT_tetra_2 ) ||
331  ( elemGT == EGT_quad_1 ) || ( elemGT == EGT_quad_2 ) ||
332  ( elemGT == EGT_hexa_1 ) || ( elemGT == EGT_wedge_1 ) ) {
333  nelemNodes = elem->giveNumberOfNodes();
334  answer.resize(nelemNodes);
335  for ( i = 1; i <= nelemNodes; i++ ) {
336  answer.at(i) = elem->giveNode(i)->giveNumber();
337  }
338  } else if ( elemGT == EGT_hexa_2 ) {
339  int HexaQuadNodeMapping [] = {
340  5, 8, 7, 6, 1, 4, 3, 2, 16, 15, 14, 13, 12, 11, 10, 9, 17, 20, 19, 18
341  };
342  nelemNodes = elem->giveNumberOfNodes();
343  answer.resize(nelemNodes);
344  for ( i = 1; i <= nelemNodes; i++ ) {
345  answer.at(i) = elem->giveNode(HexaQuadNodeMapping [ i - 1 ])->giveNumber();
346  }
347  } else if ( elemGT == EGT_wedge_2 ) {
348  int WedgeQuadNodeMapping [] = {
349  4, 6, 5, 1, 3, 2, 12, 11, 10, 9, 8, 7, 13, 15, 14
350  };
351  nelemNodes = elem->giveNumberOfNodes();
352  answer.resize(nelemNodes);
353  for ( i = 1; i <= nelemNodes; i++ ) {
354  answer.at(i) = elem->giveNode(WedgeQuadNodeMapping [ i - 1 ])->giveNumber();
355  }
356  } else {
357  OOFEM_ERROR("unsupported element geometry type");
358  }
359 }
360 
361 
362 int
364 {
365  Element_Geometry_Type elemGT = elem->giveGeometryType();
366 
367  if ( ( elemGT == EGT_point ) ||
368  ( elemGT == EGT_line_1 ) || ( elemGT == EGT_line_2 ) ||
369  ( elemGT == EGT_triangle_1 ) || ( elemGT == EGT_triangle_2 ) ||
370  ( elemGT == EGT_tetra_1 ) || ( elemGT == EGT_tetra_2 ) ||
371  ( elemGT == EGT_quad_1 ) || ( elemGT == EGT_quad_2 ) ||
372  ( elemGT == EGT_hexa_1 ) || ( elemGT == EGT_hexa_2 ) ||
373  ( elemGT == EGT_wedge_1 ) || ( elemGT == EGT_wedge_2 ) ) {
374  return 1;
375  } else {
376  OOFEM_ERROR("unsupported element geometry type");
377  }
378 
379  return 0;
380 }
381 
382 //keyword "vars" in OOFEM input file
383 void
385 {
386  // should be performed over regions
387 
388  int i, n = internalVarsToExport.giveSize();
389  //int nnodes;
390  //Domain *d = emodel->giveDomain(1);
391  InternalStateType type;
392 
393  if ( n == 0 ) {
394  return;
395  }
396 
397  for ( i = 1; i <= n; i++ ) {
400  this->exportIntVarAs(type, iType, stream, tStep);
401  }
402 }
403 
404 void
405 VTKExportModule :: exportCellVars(FILE *stream, int elemToProcess, TimeStep *tStep)
406 {
407  int pos;
408  InternalStateType type;
409  Domain *d = emodel->giveDomain(1);
410  FloatMatrix mtrx(3, 3);
411  FloatArray temp, vec;
412  double gptot;
413 
414  fprintf(stream, "\nCELL_DATA %d\n", elemToProcess);
415  for ( int i = 1; i <= cellVarsToExport.giveSize(); i++ ) {
416  type = ( InternalStateType ) cellVarsToExport.at(i);
417  switch ( type ) {
418  case IST_MaterialNumber:
419  case IST_ElementNumber:
420  fprintf( stream, "SCALARS %s int\nLOOKUP_TABLE default\n", __InternalStateTypeToString(type) );
421  for ( auto &elem : d->giveElements() ) {
422  if ( elem->giveParallelMode() != Element_local ) {
423  continue;
424  }
425 
426  if ( type == IST_MaterialNumber || type == IST_CrossSectionNumber ) {
427  OOFEM_WARNING("Material numbers are deprecated, outputing cross section number instead...");
428  fprintf( stream, "%d\n", elem->giveCrossSection()->giveNumber() );
429  } else if ( type == IST_ElementNumber ) {
430  fprintf( stream, "%d\n", elem->giveNumber() );
431  } else {
432  OOFEM_ERROR("Unsupported Cell variable %s\n", __InternalStateTypeToString(type));
433  }
434  }
435 
436  break;
437 
438  case IST_MaterialOrientation_x:
439  case IST_MaterialOrientation_y:
440  case IST_MaterialOrientation_z:
441  if ( type == IST_MaterialOrientation_x ) {
442  pos = 1;
443  } else if ( type == IST_MaterialOrientation_y ) {
444  pos = 2;
445  } else {
446  pos = 3;
447  }
448 
449  fprintf( stream, "VECTORS %s double\n", __InternalStateTypeToString(type) );
450  for ( auto &elem : d->giveElements() ) {
451  if ( !elem->giveLocalCoordinateSystem(mtrx) ) {
452  mtrx.resize(3, 3);
453  mtrx.zero();
454  }
455 
456  fprintf( stream, "%f %f %f\n", mtrx.at(1, pos), mtrx.at(2, pos), mtrx.at(3, pos) );
457  }
458 
459  break;
460  default:
462  switch ( vt ) {
463  case ISVT_TENSOR_S3: // These could be written as tensors as well, if one wants to.
464  case ISVT_TENSOR_S3E:
465  case ISVT_VECTOR:
466  case ISVT_SCALAR:
467  if ( vt == ISVT_SCALAR ) {
468  fprintf( stream, "SCALARS %s double\nLOOKUP_TABLE default\n", __InternalStateTypeToString(type) );
469  } else {
470  fprintf( stream, "VECTORS %s double\nLOOKUP_TABLE default\n", __InternalStateTypeToString(type) );
471  }
472  for ( auto &elem : d->giveElements() ) {
473  if ( elem->giveParallelMode() != Element_local ) {
474  continue;
475  }
476 
477  gptot = 0;
478  vec.clear();
479  for ( GaussPoint *gp: *elem->giveDefaultIntegrationRulePtr() ) {
480  elem->giveIPValue(temp, gp, type, tStep);
481  gptot += gp->giveWeight();
482  vec.add(gp->giveWeight(), temp);
483  }
484  vec.times(1 / gptot);
485  for ( int j = 1; j <= vec.giveSize(); ++j ) {
486  fprintf( stream, "%e ", vec.at(j) );
487  }
488  fprintf(stream, "\n");
489  }
490  break;
491 #if 0 // Hardly even worth the effort...
492  case ISVT_TENSOR_G:
493  for ( int indx = 1; indx < 9; ++indx ) {
494  fprintf(stream, "SCALARS %s_%d double 1\n", __InternalStateTypeToString(valID), indx);
495 
496  for ( ielem = 1; ielem <= nelem; ielem++ ) {
497  elem = d->giveElement(ielem);
498  elem->giveIPValue(vec, elem->giveDefaultIntegrationRulePtr()->getIntegrationPoint(1), type, tStep);
499  fprintf( stream, "%e ", vec.at(indx) );
500  }
501  }
502 #endif
503  default:
504  OOFEM_ERROR("Quantity %s not handled yet.", __InternalStateTypeToString(type));
505  }
506  }
507 
508  fprintf(stream, "\n\n");
509  }
510 }
511 
512 
513 int
515 //
516 // Returns total number of nodes with region multiplicity
517 // (RBR = Region by Region)
518 // The nodes on region boundaries are for each region.
519 // We need unique node numbers for each region, to prevent
520 // vtk from smoothing the nodal values at region boundaries.
521 //
522 {
523  int rbrnodes = 0, nnodes = d->giveNumberOfDofManagers();
524  std :: vector< char > map(nnodes);
525  //char map[nnodes];
526  int elemnodes;
527 
528  for ( int j = 0; j < nnodes; j++ ) {
529  map [ j ] = 0;
530  }
531 
532  for ( auto &elem : d->giveElements() ) {
533  if ( elem->giveParallelMode() != Element_local ) {
534  continue;
535  }
536 
537  elemnodes = elem->giveNumberOfNodes();
538  for ( int ielemnode = 1; ielemnode <= elemnodes; ielemnode++ ) {
539  map [ elem->giveNode(ielemnode)->giveNumber() - 1 ] = 1;
540  }
541  }
542 
543  for ( int j = 0; j < nnodes; j++ ) {
544  rbrnodes += map [ j ];
545  }
546 
547  return rbrnodes;
548 }
549 
550 
551 int
552 VTKExportModule :: initRegionNodeNumbering(IntArray &regionNodalNumbers, int &regionDofMans,
553  int offset, Domain *domain, int reg, int mode)
554 {
555  // if mode == 0 then regionNodalNumbers is array with mapping from global numbering to local region numbering.
556  // The i-th value contains the corresponding local region number (or zero, if global numbar is not in region).
557 
558  // if mode == 1 then regionNodalNumbers is array with mapping from local to global numbering.
559  // The i-th value contains the corresponding global node number.
560 
561 
562  int nnodes = domain->giveNumberOfDofManagers();
563  int elemNodes;
564  int currOffset = offset + 1;
565 
566  regionNodalNumbers.resize(nnodes);
567  regionNodalNumbers.zero();
568  regionDofMans = 0;
569 
570  for ( auto &element : domain->giveElements() ) {
571 
572  if ( element->giveParallelMode() != Element_local ) {
573  continue;
574  }
575 
576  elemNodes = element->giveNumberOfNodes();
577  // elemSides = element->giveNumberOfSides();
578 
579  // determine local region node numbering
580  for ( int elementNode = 1; elementNode <= elemNodes; elementNode++ ) {
581  int node = element->giveNode(elementNode)->giveNumber();
582  if ( regionNodalNumbers.at(node) == 0 ) { // assign new number
583  /* mark for assignement. This is done later, as it allows to preserve
584  * natural node numbering.
585  */
586  regionNodalNumbers.at(node) = 1;
587  regionDofMans++;
588  }
589  }
590  }
591 
592  if ( mode == 1 ) {
593  IntArray answer(nnodes);
594  for ( int i = 1; i <= nnodes; i++ ) {
595  if ( regionNodalNumbers.at(i) ) {
596  regionNodalNumbers.at(i) = currOffset++;
597  answer.at( regionNodalNumbers.at(i) ) = i;
598  }
599  }
600 
601  regionNodalNumbers = answer;
602  } else {
603  for ( int i = 1; i <= nnodes; i++ ) {
604  if ( regionNodalNumbers.at(i) ) {
605  regionNodalNumbers.at(i) = currOffset++;
606  }
607  }
608  }
609 
610  return 1;
611 }
612 
613 //keyword "vars" in OOFEM input file
614 void
616 {
617  Domain *d = emodel->giveDomain(1);
618  int ireg;
619  int nnodes = d->giveNumberOfDofManagers(), inode;
620  int j, jsize;
621  FloatArray iVal(3);
622  FloatMatrix t(3, 3);
623  const FloatArray *val = NULL;
624 
625 
626  // create a new set containing all elements
627  Set elemSet(0, d);
628  elemSet.addAllElements();
629 
630  this->giveSmoother();
631 
632  int nindx = giveInternalStateTypeSize(type);
633 
634  for ( int indx = 1; indx <= nindx; indx++ ) {
635  // print header
636  if ( type == ISVT_SCALAR ) {
637  fprintf( stream, "SCALARS %s double 1\n", __InternalStateTypeToString(valID) );
638  } else if ( type == ISVT_VECTOR ) {
639  fprintf( stream, "VECTORS %s double\n", __InternalStateTypeToString(valID) );
640  } else if ( ( type == ISVT_TENSOR_S3 ) || ( type == ISVT_TENSOR_S3E ) ) {
641  fprintf( stream, "TENSORS %s double\n", __InternalStateTypeToString(valID) );
642  } else if ( type == ISVT_TENSOR_G ) {
643  fprintf(stream, "SCALARS %s_%d double 1\n", __InternalStateTypeToString(valID), indx);
644  } else {
645  fprintf( stderr, "VTKExportModule :: exportIntVarAs: unsupported variable type %s\n", __InternalStateTypeToString(valID) );
646  }
647 
648  if ( ( type == ISVT_SCALAR ) || ( type == ISVT_TENSOR_G ) ) {
649  fprintf(stream, "LOOKUP_TABLE default\n");
650  }
651 
652  if ( !( ( valID == IST_DisplacementVector ) || ( valID == IST_MaterialInterfaceVal ) ) ) {
653  this->smoother->recoverValues(elemSet, valID, tStep);
654  }
655 
656  IntArray regionNodalNumbers(nnodes);
657  int regionDofMans = 0, offset = 0;
658  ireg = -1;
659  int defaultSize = 0;
660 
661  this->initRegionNodeNumbering(regionNodalNumbers, regionDofMans, offset, d, ireg, 1);
662  if ( !( ( valID == IST_DisplacementVector ) || ( valID == IST_MaterialInterfaceVal ) ) ) {
663  // assemble local->global map
664  defaultSize = giveInternalStateTypeSize(type);
665  } else {
666  regionDofMans = nnodes;
667  }
668 
669  for ( inode = 1; inode <= regionDofMans; inode++ ) {
670  if ( valID == IST_DisplacementVector ) {
671  iVal.resize(3);
672  val = & iVal;
673  for ( j = 1; j <= 3; j++ ) {
674  iVal.at(j) = d->giveNode( regionNodalNumbers.at(inode) )->giveUpdatedCoordinate(j, tStep, 1.0) -
675  d->giveNode( regionNodalNumbers.at(inode) )->giveCoordinate(j);
676  }
677  } else if ( valID == IST_MaterialInterfaceVal ) {
679  if ( mi ) {
680  iVal.resize(1);
681  val = & iVal;
682  iVal.at(1) = mi->giveNodalScalarRepresentation( regionNodalNumbers.at(inode) );
683  }
684  } else {
685  this->smoother->giveNodalVector( val, regionNodalNumbers.at(inode) );
686  }
687 
688  if ( val == NULL ) {
689  iVal.resize(defaultSize);
690  iVal.zero();
691  val = & iVal;
692  //OOFEM_ERROR("internal error: invalid dofman data");
693  }
694  }
695 
696 
697  if ( type == ISVT_SCALAR ) {
698  if ( val->giveSize() ) {
699  fprintf( stream, "%e ", val->at(1) );
700  } else {
701  fprintf(stream, "%e ", 0.0);
702  }
703  } else if ( type == ISVT_VECTOR ) {
704  jsize = min( 3, val->giveSize() );
705  for ( j = 1; j <= jsize; j++ ) {
706  fprintf( stream, "%e ", val->at(j) );
707  }
708 
709  for ( j = jsize + 1; j <= 3; j++ ) {
710  fprintf(stream, "0.0 ");
711  }
712  } else if ( type == ISVT_TENSOR_S3 ) {
713  t.zero();
714  for ( int ii = 1; ii <= 6; ii++ ) {
715  if ( ii == 1 ) {
716  t.at(1, 1) = val->at(ii);
717  } else if ( ii == 2 ) {
718  t.at(2, 2) = val->at(ii);
719  } else if ( ii == 3 ) {
720  t.at(3, 3) = val->at(ii);
721  } else if ( ii == 4 ) {
722  t.at(2, 3) = val->at(ii);
723  t.at(3, 2) = val->at(ii);
724  } else if ( ii == 5 ) {
725  t.at(1, 3) = val->at(ii);
726  t.at(3, 1) = val->at(ii);
727  } else if ( ii == 6 ) {
728  t.at(1, 2) = val->at(ii);
729  t.at(2, 1) = val->at(ii);
730  }
731  }
732 
733  for ( int ii = 1; ii <= 3; ii++ ) {
734  for ( int jj = 1; jj <= 3; jj++ ) {
735  fprintf( stream, "%e ", t.at(ii, jj) );
736  }
737 
738  fprintf(stream, "\n");
739  }
740  } else if ( type == ISVT_TENSOR_G ) { // export general tensor values as scalars
741  fprintf( stream, "%e ", val->at(indx) );
742  }
743 
744  fprintf(stream, "\n");
745  }
746 }
747 
748 
751 {
752  Domain *d = emodel->giveDomain(1);
753 
754  if ( this->smoother == NULL ) {
756  }
757 
758  return this->smoother;
759 }
760 
761 
762 //keyword "primvars" in OOFEM input file
763 void
765 {
766  for ( auto &primvar : primaryVarsToExport ) {
767  UnknownType type = ( UnknownType ) primvar;
768  this->exportPrimVarAs(type, stream, tStep);
769  }
770 }
771 
772 //keyword "primvars" in OOFEM input file
773 void
775 {
776  Domain *d = emodel->giveDomain(1);
777  int ireg;
778  int nnodes = d->giveNumberOfDofManagers();
779  int j, jsize;
780  FloatArray iVal, iValLCS;
781  IntArray dofIDMask;
783  int nScalarComp = 1;
784 
785  if ( ( valID == DisplacementVector ) || ( valID == EigenVector ) || ( valID == VelocityVector ) ) {
786  type = ISVT_VECTOR;
787  } else if ( ( valID == FluxVector ) || ( valID == PressureVector ) || ( valID == Temperature ) || ( valID == Humidity )) {
788  type = ISVT_SCALAR;
789  //nScalarComp = d->giveNumberOfDefaultNodeDofs();
790  } else {
791  OOFEM_ERROR("unsupported UnknownType (%s)", __UnknownTypeToString(valID) );
792  }
793 
794  // print header
795  if ( type == ISVT_SCALAR ) {
796  fprintf(stream, "SCALARS %s double %d\n", __UnknownTypeToString(valID), nScalarComp);
797  } else if ( type == ISVT_VECTOR ) {
798  fprintf( stream, "VECTORS %s double\n", __UnknownTypeToString(valID) );
799  } else {
800  fprintf(stderr, "exportPrimVarAs: unsupported variable type\n");
801  }
802 
803  if ( type == ISVT_SCALAR ) {
804  fprintf(stream, "LOOKUP_TABLE default\n");
805  }
806 
807  DofIDItem id;
808 
809  IntArray regionNodalNumbers(nnodes);
810  int regionDofMans = 0, offset = 0;
811  ireg = -1;
812 
813 
814  // assemble local->global map
815  this->initRegionNodeNumbering(regionNodalNumbers, regionDofMans, offset, d, ireg, 1);
816 
817  // Used for special nodes/elements with mixed number of dofs.
818  this->giveSmoother();
819 
820  for ( int inode = 1; inode <= regionDofMans; inode++ ) {
821  DofManager *dman = d->giveNode( regionNodalNumbers.at(inode) );
822 
823  if ( ( valID == DisplacementVector ) || ( valID == EigenVector ) || ( valID == VelocityVector ) ) {
824  iVal.resize(3);
825  iVal.zero();
826 
827  for ( Dof *dof: *dman ) {
828  id = dof->giveDofID();
829  if ( ( id == V_u ) || ( id == D_u ) ) {
830  iVal.at(1) = dof->giveUnknown(VM_Total, tStep);
831  } else if ( ( id == V_v ) || ( id == D_v ) ) {
832  iVal.at(2) = dof->giveUnknown(VM_Total, tStep);
833  } else if ( ( id == V_w ) || ( id == D_w ) ) {
834  iVal.at(3) = dof->giveUnknown(VM_Total, tStep);
835  }
836  }
837  } else if ( (valID == FluxVector) || (valID == Humidity) ) {
838  iVal.resize(1);
839 
840  for ( Dof *dof: *dman ) {
841  id = dof->giveDofID();
842  if ( id == C_1 ) {
843  iVal.at(1) = dof->giveUnknown(VM_Total, tStep);
844  }
845  }
846  } else if ( valID == Temperature ) {
847  iVal.resize(1);
848 
849  for ( Dof *dof: *dman ) {
850  id = dof->giveDofID();
851  if ( id == T_f ) {
852  iVal.at(1) = dof->giveUnknown(VM_Total, tStep);
853  }
854  }
855  } else if ( valID == PressureVector ) {
856  dofIDMask = {P_f};
857  this->getDofManPrimaryVariable(iVal, dman, dofIDMask, VM_Total, tStep, IST_Pressure);
858  } else {
859  OOFEM_ERROR("unsupported unknownType (%s)", __UnknownTypeToString(valID) );
860  }
861 
862  if ( type == ISVT_SCALAR ) {
863  if ( iVal.giveSize() ) {
864  for ( j = 1; j <= nScalarComp; j++ ) {
865  fprintf( stream, "%e ", iVal.at(j) );
866  }
867  } else {
868  fprintf(stream, "%e ", 0.0);
869  }
870  } else if ( type == ISVT_VECTOR ) {
871  jsize = min( 3, iVal.giveSize() );
872  //rotate back from nodal CS to global CS if applies
873  if ( d->giveNode( dman->giveNumber() )->hasLocalCS() ) {
874  iVal.resize(3);
875  iValLCS = iVal;
876  iVal.beTProductOf(* d->giveNode( dman->giveNumber() )->giveLocalCoordinateTriplet(), iValLCS);
877  }
878 
879  for ( j = 1; j <= jsize; j++ ) {
880  fprintf( stream, "%e ", iVal.at(j) );
881  }
882 
883  for ( j = jsize + 1; j <= 3; j++ ) {
884  fprintf(stream, "0.0 ");
885  }
886  }
887 
888  fprintf(stream, "\n");
889  }
890 
891  fprintf(stream, "\n");
892 }
893 
894 void
897 {
898  int size = dofIDMask.giveSize();
899  const FloatArray *recoveredVal;
900  answer.resize(size);
901  // all values zero by default
902  answer.zero();
903 
904 
905 
906  for ( int j = 1; j <= size; j++ ) {
907  if ( dman->hasDofID( ( DofIDItem ) dofIDMask.at(j) ) ) {
908  // primary variable available directly in dof manager
909  answer.at(j) = dman->giveDofWithID( dofIDMask.at(j) )->giveUnknown(VM_Total, tStep);
910  } else if ( iType != IST_Undefined ) {
911  // ok primary variable not directly available
912  // but equivalent InternalStateType provided
913  // in this case use smoother to recover nodal value
914 
915  // create a new set containing all elements
916  Set elemSet( 0, dman->giveDomain() );
917  elemSet.addAllElements();
918 
919  this->giveSmoother()->recoverValues(elemSet, iType, tStep);
920  this->giveSmoother()->giveNodalVector( recoveredVal, dman->giveNumber() );
921  // here we have a lack of information about how to convert recoveredVal to response
922  // if the size is compatible we accept it, otherwise an error is thrown
923  if ( size == recoveredVal->giveSize() ) {
924  answer.at(j) = recoveredVal->at(j);
925  } else {
926  OOFEM_WARNING("recovered variable size mismatch for %d", iType);
927  answer.at(j) = 0.0;
928  }
929  }
930  }
931 }
932 } // end namespace oofem
InternalStateType
Type representing the physical meaning of element or constitutive model internal variable.
IntArray cellVarsToExport
List of cell data to export.
bool testTimeStepOutput(TimeStep *tStep)
Tests if given time step output is required.
Definition: exportmodule.C:148
NodalRecoveryModel * createNodalRecoveryModel(NodalRecoveryModel::NodalRecoveryModelType type, Domain *d)
Creates new instance of nodal recovery model corresponding to given type.
Definition: classfactory.C:153
virtual int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
Returns the integration point corresponding value in full form.
Definition: element.C:1257
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
Class and object Domain.
Definition: domain.h:115
Element_Geometry_Type
Enumerative type used to classify element geometry Possible values are: EGT_point - point in space EG...
int giveNumberOfDofManagers() const
Returns number of dof managers in domain.
Definition: domain.h:432
FILE * giveOutputStream(TimeStep *tStep)
Returns the output stream for given solution step.
#define _IFT_VTKExportModule_stype
void zero()
Sets all component to zero.
Definition: intarray.C:52
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
ValueModeType
Type representing the mode of UnknownType or CharType, or similar types.
Definition: valuemodetype.h:78
void clear()
Clears receiver (zero size).
Definition: floatarray.h:206
virtual MaterialInterface * giveMaterialInterface(int n)
Returns material interface representation for given domain.
Definition: engngm.h:351
IntArray internalVarsToExport
List of InternalStateType values, identifying the selected vars for export.
virtual void initialize()
Definition: exportmodule.C:86
double giveTargetTime()
Returns target time.
Definition: timestep.h:146
void exportCellVars(FILE *stream, int elemToProcess, TimeStep *tStep)
Export variables defined on cells.
IntArray primaryVarsToExport
List of primary unknowns to export.
Abstract base class for all finite elements.
Definition: element.h:145
InternalStateValueType
Determines the type of internal variable.
symmetric 3x3 tensor, packed with off diagonal components multiplied by 2 (engineering strain vector...
Base class for dof managers.
Definition: dofmanager.h:113
Represents export output module - a base class for all output modules.
Definition: exportmodule.h:71
#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
const char * __UnknownTypeToString(UnknownType _value)
Definition: cltypes.C:302
int giveInternalStateTypeSize(InternalStateValueType valType)
Definition: cltypes.C:217
void exportIntVarAs(InternalStateType valID, InternalStateValueType type, FILE *stream, TimeStep *tStep)
Exports single variable.
#define _IFT_VTKExportModule_primvars
virtual int giveNumberOfNodes() const
Returns number of nodes of receiver.
Definition: element.h:662
#define _IFT_VTKExportModule_vars
virtual ~VTKExportModule()
Destructor.
virtual void initialize()
int giveTotalRBRNumberOfNodes(Domain *d)
Computes total number of nodes (summed Region by Region, nodes on region boundaries are added multipl...
void getDofManPrimaryVariable(FloatArray &answer, DofManager *dman, IntArray &dofIDMask, ValueModeType mode, TimeStep *tStep, InternalStateType iType)
Returns the value of Primary variable at given dof manager.
Element * giveElement(int n)
Service for accessing particular domain fe element.
Definition: domain.C:160
int giveCellType(Element *tStep)
Returns corresponding element cell_type.
int giveNodalVector(const FloatArray *&ptr, int node)
Returns vector of recovered values for given node and region.
#define OOFEM_ERROR(...)
Definition: error.h:61
DofIDItem
Type representing particular dof type.
Definition: dofiditem.h:86
EngngModel * emodel
Problem pointer.
Definition: exportmodule.h:77
#define _IFT_VTKExportModule_cellvars
UnknownType
Type representing particular unknown (its physical meaning).
Definition: unknowntype.h:55
Abstract base class representing (moving) material interfaces.
Set of elements, boundaries, edges and/or nodes.
Definition: set.h:66
void giveElementCell(IntArray &answer, Element *elem, int cell)
Returns the element cell geometry.
NodalRecoveryModel::NodalRecoveryModelType stype
Smoother type.
void beTProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Receiver becomes the result of the product of aMatrix^T and anArray.
Definition: floatarray.C:708
double at(int i, int j) const
Coefficient access function.
Definition: floatmatrix.h:176
void resize(int n)
Checks size of receiver towards requested bounds.
Definition: intarray.C:124
void exportIntVars(FILE *stream, TimeStep *tStep)
Export internal variables.
Symmetric 3x3 tensor.
Class representing vector of real numbers.
Definition: floatarray.h:82
bool hasDofID(DofIDItem id) const
Checks if receiver contains dof with given ID.
Definition: dofmanager.C:166
Element is local, there are no contributions from other domains to this element.
Definition: element.h:101
Implementation of matrix containing floating point numbers.
Definition: floatmatrix.h:94
void exportPrimVarAs(UnknownType valID, FILE *stream, TimeStep *tStep)
Exports single variable.
IRResultType
Type defining the return values of InputRecord reading operations.
Definition: irresulttype.h:47
Represents VTK (Visualization Toolkit) export module.
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
Definition: exportmodule.C:58
int giveNumberOfElementCells(Element *)
Returns the number of elements vtk cells.
void resize(int rows, int cols)
Checks size of receiver towards requested bounds.
Definition: floatmatrix.C:1358
virtual void terminate()
Terminates the receiver.
virtual int recoverValues(Set elementSet, InternalStateType type, TimeStep *tStep)=0
Recovers the nodal values for all regions.
Class representing the general Input Record.
Definition: inputrecord.h:101
Dof * giveDofWithID(int dofID) const
Returns DOF with given dofID; issues error if not present.
Definition: dofmanager.C:119
void exportPrimaryVars(FILE *stream, TimeStep *tStep)
Export primary variables.
void zero()
Zeroes all coefficients of receiver.
Definition: floatarray.C:658
void addAllElements()
Initialize the element set to contain all elements in the receiver domain.
Definition: set.C:212
virtual double giveNodalScalarRepresentation(int)=0
Returns scalar value representation of material Interface at given point.
void times(double s)
Multiplies receiver with scalar.
Definition: floatarray.C:818
ClassFactory & classFactory
Definition: classfactory.C:59
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
std::vector< std::unique_ptr< Element > > & giveElements()
Definition: domain.h:279
const char * __InternalStateTypeToString(InternalStateType _value)
Definition: cltypes.C:298
int giveNumberOfNodesPerCell(int cellType)
Returns number of nodes corresponding to cell type.
Abstract base class representing the "problem" under consideration.
Definition: engngm.h:181
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:78
InternalStateValueType giveInternalStateValueType(InternalStateType type)
Definition: cltypes.C:77
int giveSize() const
Definition: intarray.h:203
int giveSize() const
Returns the size of receiver.
Definition: floatarray.h:218
virtual Element_Geometry_Type giveGeometryType() const
Returns the element geometry type.
Definition: element.C:1529
Node * giveNode(int n)
Service for accessing particular domain node.
Definition: domain.h:371
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
int giveNumber() const
Definition: femcmpnn.h:107
The base class for all recovery models, which perform nodal averaging or projection processes for int...
NodalRecoveryModel * smoother
Smoother.
Node * giveNode(int i) const
Returns reference to the i-th node of element.
Definition: element.h:610
std::string giveOutputBaseFileName(TimeStep *tStep)
Gives the appropriate name (minus specific file extension).
Definition: exportmodule.C:125
Class representing integration point in finite element program.
Definition: gausspoint.h:93
#define OOFEM_WARNING(...)
Definition: error.h:62
virtual void doOutput(TimeStep *tStep, bool forcedOutput=false)
Writes the output.
int initRegionNodeNumbering(IntArray &regionNodalNumbers, int &regionDofMans, int offset, Domain *domain, int reg, int mode)
Assembles the region node map.
Class representing solution step.
Definition: timestep.h:80
NodalRecoveryModel * giveSmoother()
Returns the internal smoother.
REGISTER_ExportModule(ErrorCheckingExportModule)
void add(const FloatArray &src)
Adds array src to receiver.
Definition: floatarray.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:32 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011