OOFEM 3.0
Loading...
Searching...
No Matches
vtkxmllatticeexportmodule.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 - 2025 Borek Patzak
14 *
15 *
16 *
17 * Czech Technical University, Faculty of Civil Engineering,
18 * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19 *
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License as published by the Free Software Foundation; either
23 * version 2.1 of the License, or (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * Lesser General Public License for more details.
29 *
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library; if not, write to the Free Software
32 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 */
34
36#include "element.h"
37#include "gausspoint.h"
38#include "timestep.h"
39#include "engngm.h"
40#include "node.h"
41#include "materialinterface.h"
42#include "mathfem.h"
43#include "cltypes.h"
44#include "material.h"
45#include "classfactory.h"
46#include "crosssection.h"
47#include "dof.h"
48
49#ifdef __SM_MODULE
54#endif
55
56#ifdef __TM_MODULE
58#endif
59
60
61namespace oofem {
68
69
72
73
74void
81
82std::string
84{
85 return this->giveOutputBaseFileName(tStep) + ".cross.vtu";
86}
87
88std::ofstream
90{
91 std::string fileName = giveOutputFileNameCross(tStep);
92 std::ofstream streamC;
93
94 if ( pythonExport ) {
95 streamC = std::ofstream(NULL_DEVICE);//do not write anything
96 } else {
97 streamC = std::ofstream(fileName);
98 }
99
100 if ( !streamC.good() ) {
101 OOFEM_ERROR("failed to open file %s", fileName.c_str() );
102 }
103
104 streamC.fill('0');//zero padding
105 return streamC;
106}
107
108void
110 answer.resize(3);
111 answer.zero();
112 int counter = 1;
113 for ( int x = -1; x < 2; x++ ) {
114 for ( int y = -1; y < 2; y++ ) {
115 for ( int z = -1; z < 2; z++ ) {
116 if ( !( z == 0 && y == 0 && x == 0 ) ) {
117 if ( counter == location ) {
118 answer(0) = x;
119 answer(1) = y;
120 answer(2) = z;
121 }
122 counter++;
123 }
124 }
125 }
126 }
127
128 return;
129}
130
131void
133{
134 // Stores all neccessary data (of a region) in a VTKPiece so it can be exported later.
135
136 Domain *d = emodel->giveDomain(1);
137 Element *elem;
138
139 int nnodes = d->giveNumberOfDofManagers();
140
141 // Assemble local->global and global->local region map and get number of
142 // single cells to process, the composite cells exported individually.
143 this->initRegionNodeNumbering(vtkPiece, d, tStep, region);
144 const IntArray& mapG2L = vtkPiece.getMapG2L();
145 const IntArray& mapL2G = vtkPiece.getMapL2G();
146 const int numNodes = vtkPiece.giveNumberOfNodes();
147 const int numRegionEl = vtkPiece.giveNumberOfCells();
148
149
150
151 if ( numNodes > 0 && numRegionEl > 0 ) {
152 // Export nodes as vtk vertices
153 vtkPiece.setNumberOfNodes(numNodes);
154 for ( int inode = 1; inode <= numNodes; inode++ ) {
155 if ( mapL2G.at(inode) <= nnodes && mapL2G.at(inode) != 0 ) { //DofManagers in domain (input file)
156 const auto &coords = d->giveNode(mapL2G.at(inode) )->giveCoordinates();
157 vtkPiece.setNodeCoords(inode, coords);
158 } else if ( mapL2G.at(inode) > nnodes && mapL2G.at(inode) <= numNodes && mapL2G.at(inode) != 0 ) { //extra image nodes
159 FloatArray helpArray(3);
160 helpArray.at(1) = uniqueNodeTable.at(mapL2G.at(inode), 1);
161 helpArray.at(2) = uniqueNodeTable.at(mapL2G.at(inode), 2);
162 helpArray.at(3) = uniqueNodeTable.at(mapL2G.at(inode), 3);
163 vtkPiece.setNodeCoords(inode, helpArray);
164 } else {
165 FloatArray helpArray(3);
166 helpArray.zero();
167 vtkPiece.setNodeCoords(inode, helpArray);
168 }
169 }
170
171
172 //-------------------------------------------
173 // Export all the cell data for the piece
174 //-------------------------------------------
175 IntArray cellNodes;
176 vtkPiece.setNumberOfCells(numRegionEl);
177
178 int offset = 0;
179 int cellNum = 0;
180 IntArray elems = region.giveElementList();
181 int helpCounter = 0;
182 for ( int ei = 1; ei <= elems.giveSize(); ei++ ) {
183 int elNum = elems.at(ei);
184 elem = d->giveElement(elNum);
185
186 // Skip elements that:
187 // are inactivated or of composite type ( these are exported individually later)
188 if ( this->isElementComposite(elem) || !elem->isActivated(tStep) ) {
189 continue;
190 }
191
192 if ( elem->giveParallelMode() != Element_local ) {
193 continue;
194 }
195
196 cellNum++;
197
198 // Set the connectivity
199#ifdef __SM_MODULE
200 if ( dynamic_cast< Lattice3dBoundary * >( elem ) || dynamic_cast< LatticeLink3dBoundary * >( elem ) || dynamic_cast< Lattice2dBoundary * >( elem ) ) {
201 cellNodes.resize(2);
202 IntArray loc = elem->giveLocation();
203 for ( int ielnode = 1; ielnode <= 2; ielnode++ ) {
204 if ( loc.at(ielnode) != 0 ) {
205 helpCounter++;
206 cellNodes.at(ielnode) = regionToUniqueMap.at(nnodes + helpCounter);
207 } else {
208 cellNodes.at(ielnode) = elem->giveNode(ielnode)->giveNumber();
209 }
210 }
211 } else { //Standard case
212#endif
213 this->giveElementCell(cellNodes, elem);
214#ifdef __SM_MODULE
215 }
216#endif
217 // Map from global to local node numbers for the current piece
218 int numElNodes = cellNodes.giveSize();
219
220
221 IntArray connectivity(numElNodes);
222 for ( int i = 1; i <= numElNodes; i++ ) {
223 connectivity.at(i) = mapG2L.at(cellNodes.at(i) );
224 }
225
226 vtkPiece.setConnectivity(cellNum, connectivity);
227
228 vtkPiece.setCellType(cellNum, this->giveCellType(elem) ); // VTK cell type
229
230 offset += numElNodes;
231 vtkPiece.setOffset(cellNum, offset);
232 }
233 } // end of default piece for simple geometry elements
234}
235
236
237void
239{
240 // Stores all neccessary data (of a region) in a VTKPiece so it can be exported later.
241
242 Domain *domain = emodel->giveDomain(1);
243
244 IntArray elements = region.giveElementList();
245 int numberOfElements = elements.giveSize();
246
247 //Loop over the elements and get crossSectionNodes
248 int numberOfCrossSectionNodes = 0;
249
250 IntArray crossSectionTable;
251 crossSectionTable.resize(numberOfElements);
252 int numberOfNodes = 0;
253 for ( int ie = 1; ie <= numberOfElements; ie++ ) {
254 #ifdef __SM_MODULE
255 if ( dynamic_cast< LatticeStructuralElement * >( domain->giveElement(elements.at(ie) ) ) ) {
256 numberOfCrossSectionNodes = ( static_cast< LatticeStructuralElement * >( domain->giveElement(elements.at(ie) ) ) )->giveNumberOfCrossSectionNodes();
257 } else
258 #endif
259 #ifdef __TM_MODULE
260 if ( dynamic_cast< LatticeTransportElement * >( domain->giveElement(elements.at(ie) ) ) ) {
261 numberOfCrossSectionNodes = ( static_cast< LatticeTransportElement * >( domain->giveElement(elements.at(ie) ) ) )->giveNumberOfCrossSectionNodes();
262 } else
263 #endif
264 {
265 OOFEM_ERROR("Unknown element type\n");
266 }
267
268 crossSectionTable.at(ie) = numberOfCrossSectionNodes;
269 numberOfNodes += numberOfCrossSectionNodes;
270 }
271
272 FloatMatrix nodeTable;
273 nodeTable.resize(numberOfNodes, 3);
274
275 FloatArray crossSectionCoordinates;
276 FloatArray coords(3);
277
278 //Store node coordinates in table
279 int nodeCounter = 0;
280 for ( int ie = 1; ie <= elements.giveSize(); ie++ ) {
281 #ifdef __SM_MODULE
282 if ( dynamic_cast< LatticeStructuralElement * >( domain->giveElement(elements.at(ie) ) ) ) {
283 numberOfCrossSectionNodes = ( static_cast< LatticeStructuralElement * >( domain->giveElement(elements.at(ie) ) ) )->giveNumberOfCrossSectionNodes();
284 ( static_cast< LatticeStructuralElement * >( domain->giveElement(elements.at(ie) ) ) )->giveCrossSectionCoordinates(crossSectionCoordinates);
285 } else
286 #endif
287 #ifdef __TM_MODULE
288 if ( dynamic_cast< LatticeTransportElement * >( domain->giveElement(elements.at(ie) ) ) ) {
289 numberOfCrossSectionNodes = ( static_cast< LatticeTransportElement * >( domain->giveElement(elements.at(ie) ) ) )->giveNumberOfCrossSectionNodes();
290 ( static_cast< LatticeTransportElement * >( domain->giveElement(elements.at(ie) ) ) )->giveCrossSectionCoordinates(crossSectionCoordinates);
291 } else
292 #endif
293 {
294 OOFEM_ERROR("Unknown element type\n");
295 }
296
297 for ( int is = 0; is < numberOfCrossSectionNodes; is++ ) {
298 nodeCounter++;
299 nodeTable.at(nodeCounter, 1) = crossSectionCoordinates.at(3 * is + 1);
300 nodeTable.at(nodeCounter, 2) = crossSectionCoordinates.at(3 * is + 2);
301 nodeTable.at(nodeCounter, 3) = crossSectionCoordinates.at(3 * is + 3);
302 }
303 }
304
305 if ( numberOfNodes > 0 && numberOfElements > 0 ) {
306 // Export nodes as vtk vertices
307 vtkPieceCross.setNumberOfNodes(numberOfNodes);
308 for ( int inode = 1; inode <= numberOfNodes; inode++ ) {
309 coords.at(1) = nodeTable.at(inode, 1);
310 coords.at(2) = nodeTable.at(inode, 2);
311 coords.at(3) = nodeTable.at(inode, 3);
312 vtkPieceCross.setNodeCoords(inode, coords);
313 }
314 }
315
316
317 //-------------------------------------------
318 // Export all the cell data for the piece
319 //-------------------------------------------
320 IntArray connectivity;
321 vtkPieceCross.setNumberOfCells(numberOfElements);
322 int numElNodes;
323
324 int offset = 0;
325 for ( int ei = 1; ei <= numberOfElements; ei++ ) {
326 numElNodes = crossSectionTable.at(ei);
327
328 connectivity.resize(numElNodes);
329 for ( int i = 1; i <= numElNodes; i++ ) {
330 connectivity.at(i) = offset + i;
331 }
332 vtkPieceCross.setConnectivity(ei, connectivity);
333
334 vtkPieceCross.setCellType(ei, 7);
335 offset += numElNodes;
336 vtkPieceCross.setOffset(ei, offset);
337 }
338
339 this->exportCellVars(vtkPieceCross, region, cellVarsToExport, tStep);
340}
341
342
343void
345{
346 this->doOutputNormal(tStep, forcedOutput);
348 this->doOutputCross(tStep, forcedOutput);
349 }
350 this->defaultVTKPiece.clear();
351
352}
353
354
355void
357{
358 if ( !( testTimeStepOutput(tStep) || forcedOutput ) ) {
359 return;
360 }
361
362 this->fileStreamCross = this->giveOutputStreamCross(tStep);
363 struct tm *current;
364 time_t now;
365 time(& now);
366 current = localtime(& now);
367
368 this->fileStreamCross << "<!-- TimeStep " << tStep->giveTargetTime() * timeScale << " Computed " << current->tm_year + 1900 << "-" << setw(2) << current->tm_mon + 1 << "-" << setw(2) << current->tm_mday << " at " << current->tm_hour << ":" << current->tm_min << ":" << setw(2) << current->tm_sec << " -->\n";
369 this->fileStreamCross << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n";
370 this->fileStreamCross << "<UnstructuredGrid>\n";
371
372 int nPiecesToExport = this->giveNumberOfRegions(); //old name: region, meaning: sets
373 int anyPieceNonEmpty = 0;
374
375 for ( int pieceNum = 1; pieceNum <= nPiecesToExport; pieceNum++ ) {
376 Set* region = this->giveRegionSet(pieceNum);
377 // Fills a data struct (VTKPiece) with all the necessary data.
378 this->setupVTKPieceCross(this->defaultVTKPieceCross, tStep, *region);
379
380 // Write the VTK piece to file.
381 anyPieceNonEmpty += this->writeVTKPieceCross(this->defaultVTKPieceCross, tStep);
382 this->defaultVTKPieceCross.clear();
383 }
384
385
386 if ( anyPieceNonEmpty == 0 ) {
387 // write empty piece, Otherwise ParaView complains if the whole vtu file is without <Piece></Piece>
388 this->fileStreamCross << "<Piece NumberOfPoints=\"0\" NumberOfCells=\"0\">\n";
389 this->fileStreamCross << "<Cells>\n<DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\"> </DataArray>\n</Cells>\n";
390 this->fileStreamCross << "</Piece>\n";
391 }
392
393 this->fileStreamCross << "</UnstructuredGrid>\n</VTKFile>";
394 this->fileStreamCross.close();
395}
396
397
398void
400{
401 if ( !( testTimeStepOutput(tStep) || forcedOutput ) ) {
402 return;
403 }
404
405 this->fileStream = this->giveOutputStream(tStep);
406 struct tm *current;
407 time_t now;
408 time(& now);
409 current = localtime(& now);
410
411 this->fileStream << "<!-- TimeStep " << tStep->giveTargetTime() * timeScale << " Computed " << current->tm_year + 1900 << "-" << setw(2) << current->tm_mon + 1 << "-" << setw(2) << current->tm_mday << " at " << current->tm_hour << ":" << current->tm_min << ":" << setw(2) << current->tm_sec << " -->\n";
412
413 this->fileStream << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n";
414 this->fileStream << "<UnstructuredGrid>\n";
415
416 this->giveSmoother(); // make sure smoother is created, Necessary? If it doesn't exist it is created /JB
417
418 int nPiecesToExport = this->giveNumberOfRegions(); //old name: region, meaning: sets
419 int anyPieceNonEmpty = 0;
420
423
424 for ( int pieceNum = 1; pieceNum <= nPiecesToExport; pieceNum++ ) {
425 // Fills a data struct (VTKPiece) with all the necessary data.
426 Set *region = this->giveRegionSet(pieceNum);
427 this->setupVTKPiece(this->defaultVTKPiece, tStep, *region);
428 this->writeVTKPieceProlog(this->defaultVTKPiece, tStep);
429 // Export primary, internal and XFEM variables as nodal quantities
431 this->exportIntVars(this->defaultVTKPiece, *region, internalVarsToExport, *smoother, tStep);
432 //const IntArray &elements = region.giveElementList();
433 this->exportCellVars(this->defaultVTKPiece, *region, cellVarsToExport, tStep);
434 // Write the VTK piece to file.
435 anyPieceNonEmpty += this->writeVTKPieceVariables(this->defaultVTKPiece, tStep);
436 this->writeVTKPieceEpilog(this->defaultVTKPiece, tStep);
437 }
438
439 /*
440 * Output all composite elements - one piece per composite element
441 * Each element is responsible of setting up a VTKPiece which can then be exported
442 */
443 Domain *d = emodel->giveDomain(1);
444
445 for ( int pieceNum = 1; pieceNum <= nPiecesToExport; pieceNum++ ) {
446 const IntArray &elements = this->giveRegionSet(pieceNum)->giveElementList();
447 for ( int i = 1; i <= elements.giveSize(); i++ ) {
448 Element *el = d->giveElement(elements.at(i) );
449 if ( this->isElementComposite(el) ) {
450 if ( el->giveParallelMode() != Element_local ) {
451 continue;
452 }
453
454 //this->exportCompositeElement(this->defaultVTKPiece, el, tStep);
455 this->exportCompositeElement(this->defaultVTKPieces, el, tStep);
456
457 for ( int j = 0; j < ( int ) this->defaultVTKPieces.size(); j++ ) {
458 this->writeVTKPieceProlog(this->defaultVTKPieces[j], tStep);
459 anyPieceNonEmpty += this->writeVTKPieceVariables(this->defaultVTKPieces [ j ], tStep);
460 this->writeVTKPieceEpilog(this->defaultVTKPieces[j], tStep);
461 }
462 }
463 }
464 } // end loop over composite elements
465
466 if ( anyPieceNonEmpty == 0 ) {
467 // write empty piece, Otherwise ParaView complains if the whole vtu file is without <Piece></Piece>
468 this->fileStream << "<Piece NumberOfPoints=\"0\" NumberOfCells=\"0\">\n";
469 this->fileStream << "<Cells>\n<DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\"> </DataArray>\n</Cells>\n";
470 this->fileStream << "</Piece>\n";
471 }
472
473 this->fileStream << "</UnstructuredGrid>\n</VTKFile>";
474 this->fileStream.close();
475}
476
477
478
479
480int
482{
483 int nnodes = domain->giveNumberOfDofManagers();
484 int elementNode, node;
485 int currOffset = 1;
486 Element *element;
487
488 int regionDofMans = 0;
489 int regionSingleCells = 0;
490
491 IntArray elements = region.giveElementList();
492
493 int extraNodes = 0.;
494 for ( int ie = 1; ie <= elements.giveSize(); ie++ ) {
495 element = domain->giveElement(elements.at(ie) );
496
497#ifdef __SM_MODULE
498 if ( dynamic_cast< Lattice3dBoundary * >( element ) || dynamic_cast< LatticeLink3dBoundary * >( element ) || dynamic_cast< Lattice2dBoundary * >( element ) ) {
499 IntArray loc = element->giveLocation();
500 for ( int ielnode = 1; ielnode <= 2; ielnode++ ) {
501 if ( loc.at(ielnode) != 0 ) {
502 extraNodes++;
503 }
504 }
505 }
506#endif
507 }
508 IntArray& regionG2LNodalNumbers = vtkPiece.getMapG2L();
509 IntArray& regionL2GNodalNumbers = vtkPiece.getMapL2G();
510
511 regionG2LNodalNumbers.resize(nnodes + extraNodes);
512 regionG2LNodalNumbers.zero();
513
514 periodicMap.resize(nnodes + extraNodes);
515 regionToUniqueMap.resize(nnodes + extraNodes);
516 locationMap.resize(nnodes + extraNodes);
517
518 uniqueNodeTable.resize(nnodes + extraNodes, 3);
519 uniqueNodeTable.zero();
520
521 int totalNodes = 0;
522 int uniqueNodes = 0;
523
524 for ( int ie = 1; ie <= elements.giveSize(); ie++ ) {
525 int ielem = elements.at(ie);
526 element = domain->giveElement(ielem);
527
528 if ( this->isElementComposite(element) ) {
529 continue; // composite cells exported individually
530 }
531
532 if ( !element->isActivated(tStep) ) { //skip inactivated elements
533 continue;
534 }
535
536 if ( element->giveParallelMode() != Element_local ) {
537 continue;
538 }
539
540 regionSingleCells++;
541 elemNodes = element->giveNumberOfNodes();
542
543#ifdef __SM_MODULE
544 if ( dynamic_cast< Lattice3dBoundary * >( element ) || dynamic_cast< LatticeLink3dBoundary * >( element ) || dynamic_cast< Lattice2dBoundary * >( element ) ) {
545 elemNodes = 2;
546 }
547#endif
548
549 for ( elementNode = 1; elementNode <= elemNodes; elementNode++ ) {
550#ifdef __SM_MODULE
551 if ( dynamic_cast< Lattice3dBoundary * >( element ) || dynamic_cast< LatticeLink3dBoundary * >( element ) || dynamic_cast< Lattice2dBoundary * >( element ) ) { //beam elements - only unique nodes
552 IntArray loc = element->giveLocation();
553 FloatArray nodeCoords;
554 if ( loc.at(elementNode) != 0 ) { //boundary element with mirrored node
555 totalNodes++;
556 regionDofMans++;
557 regionG2LNodalNumbers.at(nnodes + totalNodes) = 1;
558 node = element->giveNode(elementNode)->giveNumber();
559 if ( regionG2LNodalNumbers.at(node) == 0 ) { // assign new number
560 /* mark for assignment. This is done later, as it allows to preserve
561 * natural node numbering.
562 */
563 regionG2LNodalNumbers.at(node) = 1;
564 regionDofMans++;
565 }
566 if ( regionG2LNodalNumbers.at(nnodes) == 0 ) {
567 regionG2LNodalNumbers.at(nnodes) = 1;
568 regionDofMans++;
569 }
570
571 periodicMap.at(nnodes + totalNodes) = node;
572 locationMap.at(nnodes + totalNodes) = loc.at(elementNode);
573
574 element->recalculateCoordinates(elementNode, nodeCoords);
575
576 //get only the unique nodes
577 int repeatFlag = 0;
578 for ( int j = nnodes + 1; j <= nnodes + uniqueNodes; j++ ) {
579 double dx = fabs(uniqueNodeTable.at(j, 1) - nodeCoords.at(1) );
580 double dy = fabs(uniqueNodeTable.at(j, 2) - nodeCoords.at(2) );
581 double dz = fabs(uniqueNodeTable.at(j, 3) - nodeCoords.at(3) );
582 if ( dx < 1e-9 && dy < 1e-9 && dz < 1e-9 ) {//node already present
583 repeatFlag++;
584 regionToUniqueMap.at(nnodes + totalNodes) = j;
585 }
586 }
587
588 if ( repeatFlag == 0 ) {//new unique node
589 uniqueNodes++;
590 uniqueNodeTable.at(nnodes + uniqueNodes, 1) = nodeCoords.at(1);
591 uniqueNodeTable.at(nnodes + uniqueNodes, 2) = nodeCoords.at(2);
592 uniqueNodeTable.at(nnodes + uniqueNodes, 3) = nodeCoords.at(3);
593 regionToUniqueMap.at(nnodes + totalNodes) = nnodes + uniqueNodes;
594 }
595 }
596 } else { //regular element
597#endif
598 node = element->giveNode(elementNode)->giveNumber();
599 if ( regionG2LNodalNumbers.at(node) == 0 ) { // assign new number
600 /* mark for assignment. This is done later, as it allows to preserve
601 * natural node numbering.
602 */
603 regionG2LNodalNumbers.at(node) = 1;
604 regionDofMans++;
605 }
606#ifdef __SM_MODULE
607 }
608#endif
609 }
610 }
611
612 uniqueNodeTable.resizeWithData(nnodes + uniqueNodes, 3);
613 regionDofMans = nnodes + uniqueNodes;
614 vtkPiece.setNumberOfNodes(regionDofMans);
615 vtkPiece.setNumberOfCells(regionSingleCells);
616
617 regionG2LNodalNumbers.resizeWithValues(regionDofMans);
618 regionL2GNodalNumbers.resize(regionDofMans);
619
620 for ( int i = 1; i <= regionDofMans; i++ ) {
621 if ( regionG2LNodalNumbers.at(i) ) {
622 regionG2LNodalNumbers.at(i) = currOffset++;
623 regionL2GNodalNumbers.at(regionG2LNodalNumbers.at(i) ) = i;
624 }
625 }
626 return 1;
627}
628
629
630void
632{
633 Domain *d = emodel->giveDomain(1);
634 int nnodes = d->giveNumberOfDofManagers();
635 FloatArray valueArray;
636 smoother.clear(); // Makes sure primary smoother is up-to-date with potentially new mesh.
637
638 //const IntArray& mapG2L = vtkPiece.getMapG2L();
639 const IntArray& mapL2G = vtkPiece.getMapL2G();
640
642
643 //Get the macroscopic field (deformation gradients, curvatures etc.)
644 DofManager *controlNode = d->giveNode(nnodes); //assuming the control node is last
645 IntArray dofIdArray;
646 controlNode->giveCompleteMasterDofIDArray(dofIdArray);
647
648 FloatArray macroField(controlNode->giveNumberOfDofs() );
649 for ( int j = 1; j <= controlNode->giveNumberOfDofs(); j++ ) {
650 macroField.at(j) = controlNode->giveDofWithID(dofIdArray.at(j) )->giveUnknown(VM_Total, tStep);
651 }
652
653 //Get unit cell size
654 const auto unitCellSize = controlNode->giveCoordinates();
655
656 for ( int i = 1, n = primaryVarsToExport.giveSize(); i <= n; i++ ) {
658
659 for ( int inode = 1; inode <= mapL2G.giveSize(); inode++ ) {
660 if ( inode <= nnodes && mapL2G.at(inode) <= nnodes && mapL2G.at(inode) != 0 ) { //no special treatment for master nodes
661 DofManager *dman = d->giveNode(mapL2G.at(inode) );
662
663 this->getNodalVariableFromPrimaryField(valueArray, dman, tStep, type, region, smoother);
664 vtkPiece.setPrimaryVarInNode(type, inode, std::move(valueArray) );
665 } else { //special treatment for image nodes
666 //find the periodic node, enough to find the first occurrence
667 int pos = 0;
668 if ( mapL2G.at(inode) != 0 ) {
669 pos = regionToUniqueMap.findFirstIndexOf(mapL2G.at(inode) );
670 }
671 if ( pos ) {
672 DofManager *dman = d->giveNode(periodicMap.at(pos) );
673 IntArray switches;
674 giveSwitches(switches, locationMap.at(pos) );
675 //get the master unknown
676 FloatArray helpArray;
677 this->getNodalVariableFromPrimaryField(helpArray, dman, tStep, type, region, smoother);
678 //recalculate the image unknown
679 if ( type == DisplacementVector ) {
680 if ( dofIdArray.giveSize() == 3 && dofIdArray.at(1) == E_xx && dofIdArray.at(2) == E_yy && dofIdArray.at(3) == G_xy ) { //Macroscale: 2D solid using Voigt notation
681 valueArray.resize(helpArray.giveSize() );
682 valueArray.at(1) = helpArray.at(1) + unitCellSize.at(1) * switches.at(1) * macroField.at(1);
683 valueArray.at(2) = helpArray.at(2) + unitCellSize.at(2) * switches.at(2) * macroField.at(2) + unitCellSize.at(1) * switches.at(1) * macroField.at(3);
684 valueArray.at(3) = helpArray.at(3);
685 } else if ( dofIdArray.giveSize() == 1 && dofIdArray.at(1) == E_xx ) { //Macroscale: 3D truss. 1 DOF: EXX
686 valueArray.resize(helpArray.giveSize() );
687 valueArray.at(1) = helpArray.at(1) + unitCellSize.at(1) * switches.at(1) * macroField.at(1);
688 valueArray.at(2) = helpArray.at(2);
689 valueArray.at(3) = helpArray.at(3);
690 } else if ( dofIdArray.giveSize() == 6 && dofIdArray.at(1) == E_xx && dofIdArray.at(2) == E_yy && dofIdArray.at(3) == E_zz && dofIdArray.at(4) == G_yz && dofIdArray.at(5) == G_xz && dofIdArray.at(6) == G_xy ) { //Macroscale: 3D solid using Voigt notation
691 valueArray.resize(helpArray.giveSize() );
692 valueArray.at(1) = helpArray.at(1) + unitCellSize.at(1) * switches.at(1) * macroField.at(1) +
693 unitCellSize.at(3) * switches.at(3) * macroField.at(5) + unitCellSize.at(2) * switches.at(2) * macroField.at(6);
694 valueArray.at(2) = helpArray.at(2) + unitCellSize.at(2) * switches.at(2) * macroField.at(2) +
695 unitCellSize.at(3) * switches.at(3) * macroField.at(4);
696 valueArray.at(3) = helpArray.at(3) + unitCellSize.at(3) * switches.at(3) * macroField.at(3);
697 } else {
698 OOFEM_ERROR("Unknown periodic element type\n");
699 }
700 }
701 } else {
702 valueArray.resize(3);
703 }
704 vtkPiece.setPrimaryVarInNode(type, inode, std::move(valueArray) );
705 }
706 }
707 }
708}
709
710
711void
713{
714 Domain *d = emodel->giveDomain(1);
715 int nnodes = d->giveNumberOfDofManagers();
716 InternalStateType isType;
717 FloatArray answer;
718
719 smoother.clear(); // Makes sure smoother is up-to-date with potentially new mesh.
720 //const IntArray& mapG2L = vtkPiece.getMapG2L();
721 const IntArray& mapL2G = vtkPiece.getMapL2G();
722 // Export of Internal State Type fields
724 for ( int field = 1; field <= internalVarsToExport.giveSize(); field++ ) {
725 isType = ( InternalStateType ) internalVarsToExport.at(field);
726
727 for ( int nodeNum = 1; nodeNum <= mapL2G.giveSize(); nodeNum++ ) {
728 if ( nodeNum <= nnodes && mapL2G.at(nodeNum) <= nnodes && mapL2G.at(nodeNum) != 0 ) { //no special treatment for master nodes
729 Node *node = d->giveNode(mapL2G.at(nodeNum) );
730 this->getNodalVariableFromIS(answer, node, tStep, isType, region, smoother);
731 vtkPiece.setInternalVarInNode(isType, nodeNum, answer);
732 } else { //special treatment for image nodes
733 //find the periodic node, enough to find the first occurrence
734 int pos = 0;
735 if ( mapL2G.at(nodeNum) != 0 ) {
736 pos = regionToUniqueMap.findFirstIndexOf(mapL2G.at(nodeNum) );
737 }
738
739 if ( pos ) {
740 Node *node = d->giveNode(periodicMap.at(pos) );
741 this->getNodalVariableFromIS(answer, node, tStep, isType, region, smoother);
742 vtkPiece.setInternalVarInNode(isType, nodeNum, answer);
743 } else { //fill with zeroes
745 int ncomponents = giveInternalStateTypeSize(valType);
746 answer.resize(ncomponents);
747
748 if ( isType == IST_BeamForceMomentTensor ) {
749 answer.resize(6);
750 }
751
752 answer.zero();
753 vtkPiece.setInternalVarInNode(isType, nodeNum, answer);
754 }
755 }
756 }
757 }
758}
759
760
761bool
763{
764 if ( !vtkPieceCross.giveNumberOfCells() ) {
765 return false;
766 }
767
768 // Write output: node coords
769 int numNodes = vtkPieceCross.giveNumberOfNodes();
770 int numEl = vtkPieceCross.giveNumberOfCells();
771 FloatArray coords;
772
773 this->fileStreamCross << "<Piece NumberOfPoints=\"" << numNodes << "\" NumberOfCells=\"" << numEl << "\">\n";
774 this->fileStreamCross << "<Points>\n <DataArray type=\"Float64\" NumberOfComponents=\"3\" format=\"ascii\"> ";
775
776 for ( int inode = 1; inode <= numNodes; inode++ ) {
777 coords = vtkPieceCross.giveNodeCoords(inode);
779 for ( int i = 1; i <= coords.giveSize(); i++ ) {
780 this->fileStreamCross << scientific << coords.at(i) << " ";
781 }
782
783 for ( int i = coords.giveSize() + 1; i <= 3; i++ ) {
784 this->fileStreamCross << scientific << 0.0 << " ";
785 }
786 }
787
788 this->fileStreamCross << "</DataArray>\n</Points>\n";
789 this->fileStreamCross << "<Cells>\n";
790 this->fileStreamCross << " <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\"> ";
791
792 IntArray cellNodes;
793 for ( int ielem = 1; ielem <= numEl; ielem++ ) {
794 cellNodes = vtkPieceCross.giveCellConnectivity(ielem);
795
796 for ( int i = 1; i <= cellNodes.giveSize(); i++ ) {
797 this->fileStreamCross << cellNodes.at(i) - 1 << " ";
798 }
799 this->fileStreamCross << " ";
800 }
801
802 this->fileStreamCross << "</DataArray>\n";
803
804 // output the offsets (index of individual element data in connectivity array)
805 this->fileStreamCross << " <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\"> ";
806
807 for ( int ielem = 1; ielem <= numEl; ielem++ ) {
808 this->fileStreamCross << vtkPieceCross.giveCellOffset(ielem) << " ";
809 }
810
811 this->fileStreamCross << "</DataArray>\n";
812
813
814 // output cell (element) types
815 this->fileStreamCross << " <DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\"> ";
816 for ( int ielem = 1; ielem <= numEl; ielem++ ) {
817 this->fileStreamCross << vtkPieceCross.giveCellType(ielem) << " ";
818 }
819
820 this->fileStreamCross << "</DataArray>\n";
821 this->fileStreamCross << "</Cells>\n";
822
823
825 std::string pointHeader, cellHeader;
826 this->giveDataHeaders(pointHeader, cellHeader);
827
828 this->fileStreamCross << pointHeader.c_str();
829 this->fileStreamCross << "</PointData>\n";
830 this->fileStreamCross << cellHeader.c_str();
831
832 this->writeCellVarsCross(vtkPieceCross);
833
834 this->fileStreamCross << "</CellData>\n";
835 this->fileStreamCross << "</Piece>\n";
836
837 vtkPieceCross.clear();
838 return true;
839}
840
841void
843{
844 FloatArray valueArray;
845 int numCells = vtkPiece.giveNumberOfCells();
846 for ( int i = 1; i <= cellVarsToExport.giveSize(); i++ ) {
849 int ncomponents = giveInternalStateTypeSize(valType);
850 const char *name = __InternalStateTypeToString(type);
851 ( void ) name; //silence the warning
852
853 this->fileStreamCross << " <DataArray type=\"Float64\" Name=\"" << name << "\" NumberOfComponents=\"" << ncomponents << "\" format=\"ascii\"> ";
854 valueArray.resize(ncomponents);
855 for ( int ielem = 1; ielem <= numCells; ielem++ ) {
856 valueArray = vtkPiece.giveCellVar(type, ielem);
857 for ( int i = 1; i <= valueArray.giveSize(); i++ ) {
858 this->fileStreamCross << valueArray.at(i) << " ";
859 }
860 }
861 this->fileStreamCross << "</DataArray>\n";
862
863#ifdef _PYBIND_BINDINGS
864#if 0
865 if ( pythonExport ) {
866 py::list vals;
867 for ( int ielem = 1; ielem <= numCells; ielem++ ) {
868 valueArray = vtkPiece.giveCellVar(i, ielem);
869 vals.append(valueArray);
870 }
871 this->Py_CellVars [ name ] = vals;
872 }
873#endif
874#endif
875 }//end of for
876}
877} // end namespace oofem
#define REGISTER_ExportModule(class)
int giveNumberOfDofs() const
Definition dofmanager.C:287
void giveCompleteMasterDofIDArray(IntArray &dofIDArray) const
Definition dofmanager.C:257
const FloatArray & giveCoordinates() const
Definition dofmanager.h:390
Dof * giveDofWithID(int dofID) const
Definition dofmanager.C:127
virtual double giveUnknown(ValueModeType mode, TimeStep *tStep)=0
int giveNumberOfDofManagers() const
Returns number of dof managers in domain.
Definition domain.h:461
Element * giveElement(int n)
Definition domain.C:165
Node * giveNode(int n)
Definition domain.h:398
Node * giveNode(int i) const
Definition element.h:629
virtual const IntArray giveLocation()
Definition element.h:1223
virtual bool isActivated(TimeStep *tStep)
Definition element.C:838
virtual int giveNumberOfNodes() const
Definition element.h:703
elementParallelMode giveParallelMode() const
Definition element.h:1139
virtual void recalculateCoordinates(int nodeNumber, FloatArray &coords)
Definition element.h:1224
double timeScale
Scaling time in output, e.g. conversion from seconds to hours.
std::string giveOutputBaseFileName(TimeStep *tStep)
bool pythonExport
Output is carried out as a python list instead of writing files.
Set * giveRegionSet(int i)
Returns element set.
int giveNumberOfRegions()
Returns number of regions (aka regionSets).
EngngModel * emodel
Problem pointer.
bool testTimeStepOutput(TimeStep *tStep)
Stores all neccessary data (of a region) in a VTKPiece so it can be exported later.
IntArray & getMapL2G()
void setInternalVarInNode(InternalStateType type, int nodeNum, FloatArray valueArray)
void setCellType(int cellNum, int type)
FloatArray & giveCellVar(InternalStateType type, int cellNum)
void setNumberOfInternalVarsToExport(const IntArray &ists, int numNodes)
FloatArray & giveNodeCoords(int nodeNum)
void setNumberOfPrimaryVarsToExport(const IntArray &primVars, int numNodes)
void setConnectivity(int cellNum, IntArray &nodes)
void setPrimaryVarInNode(UnknownType type, int nodeNum, FloatArray valueArray)
IntArray & getMapG2L()
void setOffset(int cellNum, int offset)
IntArray & giveCellConnectivity(int cellNum)
void setNumberOfCells(int numCells)
int giveCellType(int cellNum)
int giveCellOffset(int cellNum)
void setNodeCoords(int nodeNum, const FloatArray &coords)
void setNumberOfNodes(int numNodes)
int giveNumber() const
Definition femcmpnn.h:104
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
double at(std::size_t i, std::size_t j) const
void resizeWithValues(int n, int allocChunk=0)
Definition intarray.C:64
void resize(int n)
Definition intarray.C:73
void zero()
Sets all component to zero.
Definition intarray.C:52
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
const IntArray & giveElementList()
Definition set.C:158
double giveTargetTime()
Returns target time.
Definition timestep.h:164
bool isElementComposite(Element *elem)
void exportCellVars(ExportRegion &piece, Set &region, IntArray &cellVarsToExport, TimeStep *tStep)
Exports cell variables (typically internal variables).
void giveElementCell(IntArray &answer, Element *elem)
void getNodalVariableFromIS(FloatArray &answer, Node *node, TimeStep *tStep, InternalStateType type, Set &region, NodalRecoveryModel &smoother)
int giveCellType(Element *element)
void getNodalVariableFromPrimaryField(FloatArray &answer, DofManager *dman, TimeStep *tStep, UnknownType type, Set &region, NodalRecoveryModel &smoother)
virtual void giveDataHeaders(std::string &pointHeader, std::string &cellHeader)
IntArray internalVarsToExport
List of InternalStateType values, identifying the selected vars for export.
void initializeFrom(InputRecord &ir) override
Initializes receiver according to object description stored in input record.
std::unique_ptr< NodalRecoveryModel > smoother
Smoother.
IntArray primaryVarsToExport
List of primary unknowns to export.
NodalRecoveryModel * givePrimVarSmoother()
Returns the smoother for primary variables (nodal averaging).
std::ofstream giveOutputStream(TimeStep *tStep)
Returns the output stream for given solution step.
void exportCompositeElement(ExportRegion &vtkPiece, Element *el, TimeStep *tStep)
IntArray cellVarsToExport
List of cell data to export.
bool writeVTKPieceVariables(ExportRegion &vtkPiece, TimeStep *tStep)
std::vector< ExportRegion > defaultVTKPieces
bool writeVTKPieceProlog(ExportRegion &vtkPiece, TimeStep *tStep)
NodalRecoveryModel * giveSmoother()
Returns the internal smoother.
bool writeVTKPieceEpilog(ExportRegion &vtkPiece, TimeStep *tStep)
std::unique_ptr< NodalRecoveryModel > primVarSmoother
Smoother for primary variables.
void initializeFrom(InputRecord &ir) override
Initializes receiver according to object description stored in input record.
bool writeVTKPieceCross(ExportRegion &vtkPiece, TimeStep *tStep)
void doOutputCross(TimeStep *tStep, bool forcedOutput=false)
void giveSwitches(IntArray &answer, int location)
void doOutputNormal(TimeStep *tStep, bool forcedOutput=false)
std::string giveOutputFileNameCross(TimeStep *tStep)
void doOutput(TimeStep *tStep, bool forcedOutput=false) override
std::ofstream giveOutputStreamCross(TimeStep *tStep)
int initRegionNodeNumbering(ExportRegion &piece, Domain *domain, TimeStep *tStep, Set &region) override
void setupVTKPieceCross(ExportRegion &vtkPiece, TimeStep *tStep, Set &region)
void writeCellVarsCross(ExportRegion &vtkPiece)
void exportPrimaryVars(ExportRegion &piece, Set &region, IntArray &primaryVarsToExport, NodalRecoveryModel &smoother, TimeStep *tStep) override
void setupVTKPiece(ExportRegion &vtkPiece, TimeStep *tStep, Set &region) override
void exportIntVars(ExportRegion &piece, Set &region, IntArray &internalVarsToExport, NodalRecoveryModel &smoother, TimeStep *tStep) override
VTKXMLLatticeExportModule(int n, EngngModel *e)
Constructor. Creates empty Output Manager. By default all components are selected.
#define OOFEM_ERROR(...)
Definition error.h:79
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Definition inputrecord.h:75
const char * __InternalStateTypeToString(InternalStateType _value)
Definition cltypes.C:309
@ Element_local
Element is local, there are no contributions from other domains to this element.
Definition element.h:88
int giveInternalStateTypeSize(InternalStateValueType valType)
Definition cltypes.C:229
InternalStateValueType
Determines the type of internal variable.
InternalStateValueType giveInternalStateValueType(InternalStateType type)
Definition cltypes.C:75
#define NULL_DEVICE
#define _IFT_VTKXMLLatticeExportModule_cross

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011