OOFEM 3.0
Loading...
Searching...
No Matches
vtkxfemexportmodule.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
35#include "vtkxfemexportmodule.h"
36#include "element.h"
37#include "gausspoint.h"
38#include "timestep.h"
39#include "engngm.h"
40#include "node.h"
41#include "dof.h"
42#include "materialinterface.h"
43#include "mathfem.h"
44#include "cltypes.h"
45#include "material.h"
46#include "classfactory.h"
47#include "crosssection.h"
49
50#include "xfem/xfemmanager.h"
51#include "xfem/enrichmentitem.h"
52
53#include <string>
54#include <sstream>
55#include <ctime>
56
57#ifdef __VTK_MODULE
58 #include <vtkPoints.h>
59 #include <vtkPointData.h>
60 #include <vtkDoubleArray.h>
61 #include <vtkCellArray.h>
62 #include <vtkCellData.h>
63 #include <vtkXMLUnstructuredGridWriter.h>
64 #include <vtkXMLPUnstructuredGridWriter.h>
65 #include <vtkUnstructuredGrid.h>
66 #include <vtkSmartPointer.h>
67#endif
68
69namespace oofem {
71
72
73
74//
75// VTKXMLXFemExport module
76//
77
79
81
82void
87
88
89std::string
91{
92 return this->giveOutputBaseFileName(tStep) + ".vtu";
93}
94
95
96std::ofstream
98{
99 std::string fileName = giveOutputFileName(tStep);
100 std::ofstream streamF;
101
102 if ( pythonExport ) {
103 streamF = std::ofstream(NULL_DEVICE);//do not write anything
104 } else {
105 streamF = std::ofstream(fileName);
106 }
107
108 if ( !streamF.good() ) {
109 OOFEM_ERROR("failed to open file %s", fileName.c_str() );
110 }
111
112 streamF.fill('0');//zero padding
113 return streamF;
114}
115
116void
118{
119 Domain *d = emodel->giveDomain(1);
120 FloatArray answer;
121 //IntArray& mapG2L = vtkPiece.getMapG2L();
122 IntArray& mapL2G = vtkPiece.getMapL2G();
123
124 // Export of XFEM related quantities
125 if ( d->hasXfemManager() ) {
126 XfemManager *xFemMan = d->giveXfemManager();
127 vtkPiece.setNumberOfInternalVarsToExport(xFemMan->vtkExportFields, mapL2G.giveSize() );
128 XFEMStateType xfemstype = ( XFEMStateType ) xFemMan->vtkExportFields [ field - 1 ];
129
130 for ( int nodeIndx = 1; nodeIndx <= mapL2G.giveSize(); nodeIndx++ ) {
131 Node *node = d->giveNode(mapL2G.at(nodeIndx) );
132 getNodalVariableFromXFEMST(answer, node, tStep, xfemstype, region, xFemMan->giveEnrichmentItem(enrItIndex) );
133 vtkPiece.setInternalXFEMVarInNode(field, enrItIndex, nodeIndx, answer);
134 }
135 }
136}
137
138void
140{
141 // Recovers nodal values from XFEM state variables (e.g. levelset function)
142 // Should return an array with proper size supported by VTK (1, 3 or 9)
143 // This could be moved into EnrichmentItem such that VTKExport doesn't need to know anything about XFEM
144
145 const FloatArray *val = NULL;
146 FloatArray valueArray;
147
148 Domain *d = emodel->giveDomain(1);
149 XfemManager *xFemMan = d->giveXfemManager();
150 InternalStateValueType valType = xFemMan->giveXFEMStateValueType(xfemstype);
151
152
153 // The xfem level set function is defined in the nodes and recovery of nodal values is trivial.
154 if ( xfemstype == XFEMST_LevelSetPhi ) {
155 valueArray.resize(1);
156 val = & valueArray;
157 ei->evalLevelSetNormalInNode(valueArray.at(1), node->giveNumber(), node->giveCoordinates() );
158 } else if ( xfemstype == XFEMST_LevelSetGamma ) {
159 valueArray.resize(1);
160 val = & valueArray;
161 ei->evalLevelSetTangInNode(valueArray.at(1), node->giveNumber(), node->giveCoordinates() );
162 } else if ( xfemstype == XFEMST_NodeEnrMarker ) {
163 valueArray.resize(1);
164 val = & valueArray;
165 ei->evalNodeEnrMarkerInNode(valueArray.at(1), node->giveNumber() );
166 } else {
167 //OOFEM_WARNING("invalid data in node %d", inode);
168 }
169
171 int ncomponents = giveInternalStateTypeSize(valType);
172 answer.resize(ncomponents);
173 int valSize = val->giveSize(); // size of recovered quantity
174
175 // check if valSize corresponds to the expected size otherwise pad with zeros
176 if ( valType == ISVT_SCALAR ) {
177 answer.at(1) = valSize ? val->at(1) : 0.0;
178 } else if ( valType == ISVT_VECTOR ) {
179 answer = * val;
180 answer.resizeWithValues(3);
181 } else if ( valType == ISVT_TENSOR_S3 || valType == ISVT_TENSOR_S3E || valType == ISVT_TENSOR_G ) {
182 this->makeFullTensorForm(answer, * val, valType);
183 } else {
184 OOFEM_ERROR("ISVT_UNDEFINED encountered")
185 }
186}
187
188
189bool
190VTKXMLXFemExportModule::writeXFEMVars(ExportRegion &vtkPiece, int field, int enrItIndex)
191{
192 Domain *d = emodel->giveDomain(1);
193 XfemManager *xFemMan = d->giveXfemManager();
194 FloatArray valueArray;
195
196 if ( !vtkPiece.giveNumberOfCells() ) {
197 return false;
198 }
199
200 XFEMStateType xfemstype = ( XFEMStateType ) xFemMan->vtkExportFields.at(field);
201 const char *namePart = __XFEMStateTypeToString(xfemstype);
202 InternalStateValueType valType = xFemMan->giveXFEMStateValueType(xfemstype);
203 int ncomponents = giveInternalStateTypeSize(valType);
204 ( void ) ncomponents; //silence the warning
205
206 int numNodes = vtkPiece.giveNumberOfNodes();
207
208 // Header
209 char name [ 100 ]; // Must I define a fixed size? /JB
210 sprintf(name, "%s_%d ", namePart, xFemMan->giveEnrichmentItem(enrItIndex)->giveNumber() );
211
212#ifdef __VTK_MODULE
213 vtkSmartPointer< vtkDoubleArray >varArray = vtkSmartPointer< vtkDoubleArray >::New();
214 varArray->SetName(name);
215 varArray->SetNumberOfComponents(ncomponents);
216 varArray->SetNumberOfTuples(numNodes);
217 for ( int inode = 1; inode <= numNodes; inode++ ) {
218 valueArray = vtkPiece.giveInternalXFEMVarInNode(field, enrItIndex, inode);
219 for ( int i = 1; i <= ncomponents; ++i ) {
220 varArray->SetComponent(inode - 1, i - 1, valueArray.at(i) );
221 }
222 }
223
224 this->writeVTKPointData(name, varArray);
225#else
226 this->fileStream << "<DataArray type=\"Float64\" Name=\"" << name << "\" NumberOfComponents=\"" << ncomponents << "\" format=\"ascii\"> ";
227 for ( int inode = 1; inode <= numNodes; inode++ ) {
228 valueArray = vtkPiece.giveInternalXFEMVarInNode(field, enrItIndex, inode);
229 this->writeVTKPointData(valueArray);
230 }
231 this->fileStream << "</DataArray>\n";
232#endif
233 return true;
234}
235
236void
237VTKXMLXFemExportModule::giveDataHeaders(std::string &pointHeader, std::string &cellHeader)
238{
239 std::string scalars, vectors, tensors;
240
241 Domain *d = emodel->giveDomain(1);
242 XfemManager *xFemMan = d->giveXfemManager();
243 int nEnrIt = xFemMan->giveNumberOfEnrichmentItems();
244 for ( int field = 1; field <= xFemMan->vtkExportFields.giveSize(); field++ ) {
245 for ( int enrItIndex = 1; enrItIndex <= nEnrIt; enrItIndex++ ) {
246 XFEMStateType xfemstype = ( XFEMStateType ) xFemMan->vtkExportFields.at(field);
247 const char *namePart = __XFEMStateTypeToString(xfemstype);
248
249 // Header
250 char name [ 100 ]; // Must I define a fixed size? /JB
251 sprintf(name, "%s_%d ", namePart, xFemMan->giveEnrichmentItem(enrItIndex)->giveNumber() );
252 scalars += name;
253 scalars.append(" ");
254 }
255 }
256 // print header
257 pointHeader = "<PointData Scalars=\"" + scalars + "\" "
258 + "Vectors=\"" + vectors + "\" "
259 + "Tensors=\"" + tensors + "\" >\n";
260
261}
262
263
264void
266{
267 if ( !( testTimeStepOutput(tStep) || forcedOutput ) ) {
268 return;
269 }
270
271 Domain *d = emodel->giveDomain(1);
272 //XfemManager *xFemMan = d->giveXfemManager();
273#ifdef __VTK_MODULE
274 this->fileStream = vtkSmartPointer< vtkUnstructuredGrid >::New();
275 this->nodes = vtkSmartPointer< vtkPoints >::New();
276 this->elemNodeArray = vtkSmartPointer< vtkIdList >::New();
277
278#else
279 this->fileStream = this->giveOutputStream(tStep);
280 struct tm *current;
281 time_t now;
282 time(& now);
283 current = localtime(& now);
284
285#endif
286 // Write output: VTK header
287#ifndef __VTK_MODULE
288 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";
289 this->fileStream << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n";
290 this->fileStream << "<UnstructuredGrid>\n";
291#endif
292
293 /* Loop over pieces ///@todo: this feature has been broken but not checked if it currently works /JB
294 * Start default pieces containing all single cell elements. Elements built up from several vtk
295 * cells (composite elements) are exported as individual pieces after the default ones.
296 */
297 int nPiecesToExport = this->giveNumberOfRegions(); //old name: region, meaning: sets
298 int anyPieceNonEmpty = 0;
299
300 // Export of XFEM related quantities
301
302 if ( d->hasXfemManager() ) {
303 XfemManager *xFemMan = d->giveXfemManager();
304 int nEnrIt = xFemMan->giveNumberOfEnrichmentItems();
305
306 for ( int pieceNum = 1; pieceNum <= nPiecesToExport; pieceNum++ ) {
307 // Fills a data struct (VTKPiece) with all the necessary data.
308 Set* region = this->giveRegionSet(pieceNum);
309 this->setupVTKPiece(this->defaultVTKPiece, tStep, *region);
310 if (this->defaultVTKPiece.giveNumberOfNodes() > 0) {
311 this->writeVTKPieceProlog(this->defaultVTKPiece, tStep);
312 this->defaultVTKPiece.setNumberOfInternalVarsToExport(xFemMan->vtkExportFields, this->defaultVTKPiece.getMapL2G().giveSize() );
313
314 std::string pointHeader, cellHeader;
315 this->giveDataHeaders(pointHeader, cellHeader);
316 this->fileStream << pointHeader.c_str();
317
318 for ( int field = 1; field <= xFemMan->vtkExportFields.giveSize(); field++ ) {
319 //XFEMStateType xfemstype = ( XFEMStateType ) xFemMan->vtkExportFields [ field - 1 ];
320
321 for ( int enrItIndex = 1; enrItIndex <= nEnrIt; enrItIndex++ ) {
322 // Fills a data struct (VTKPiece) with all the necessary data.
323 //this->setupVTKPiece(this->defaultVTKPiece, tStep, *region);
324 this->exportIntVars2(this->defaultVTKPiece, *region, field, enrItIndex, internalVarsToExport, *smoother, tStep);
325 // Write the VTK piece to file.
326 anyPieceNonEmpty +=this->writeXFEMVars(this->defaultVTKPiece, field, enrItIndex);
327 }
328 }
329
330 this->fileStream << "</PointData>\n";
331 this->writeVTKPieceEpilog(this->defaultVTKPiece, tStep);
332 this->defaultVTKPiece.clear();
333 }
334 }
335
336 /*
337 * Output all composite elements - one piece per composite element
338 * Each element is responsible of setting up a VTKPiece which can then be exported
339 */
340 for ( int pieceNum = 1; pieceNum <= nPiecesToExport; pieceNum++ ) {
341 const IntArray &elements = this->giveRegionSet(pieceNum)->giveElementList();
342 for ( int i = 1; i <= elements.giveSize(); i++ ) {
343 Element *el = d->giveElement(elements.at(i) );
344 if ( this->isElementComposite(el) ) {
345 if ( el->giveParallelMode() != Element_local ) {
346 continue;
347 }
348#ifndef __VTK_MODULE
349 //this->exportCompositeElement(this->defaultVTKPiece, el, tStep);
350 this->exportCompositeElement(this->defaultVTKPieces, el, tStep);
351 for ( int j = 0; j < ( int ) this->defaultVTKPieces.size(); j++ ) {
352 this->writeVTKPieceProlog(this->defaultVTKPieces[j], tStep);
353 std::string pointHeader, cellHeader;
354 this->giveDataHeaders(pointHeader, cellHeader);
355 this->fileStream << pointHeader.c_str();
356
357 for ( int field = 1; field <= xFemMan->vtkExportFields.giveSize(); field++ ) {
358 for ( int enrItIndex = 1; enrItIndex <= nEnrIt; enrItIndex++ ) {
359 anyPieceNonEmpty += this->writeXFEMVars(this->defaultVTKPieces [ j ], field, enrItIndex);
360 }
361 }
362 this->fileStream << "</PointData>\n";
363 this->writeVTKPieceEpilog(this->defaultVTKPieces[j], tStep);
364 }
365#else
366 // No support for binary export yet
367#endif
368 }
369 } // end loop over composite elements
370 }
371 }
372
373#ifndef __VTK_MODULE
374 if ( anyPieceNonEmpty == 0 ) {
375 // write empty piece, Otherwise ParaView complains if the whole vtu file is without <Piece></Piece>
376 this->fileStream << "<Piece NumberOfPoints=\"0\" NumberOfCells=\"0\">\n";
377 this->fileStream << "<Cells>\n<DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\"> </DataArray>\n</Cells>\n";
378 this->fileStream << "</Piece>\n";
379 }
380#endif
381
382 // Finalize the output:
383 std::string fname = giveOutputFileName(tStep);
384#ifdef __VTK_MODULE
385
386 #if 0
387 // Code fragment intended for future support of composite elements in binary format
388 // Doesn't as well as I would want it to, interface to VTK is to limited to control this.
389 // * The PVTU-file is written by every process (seems to be impossible to avoid).
390 // * Part files are renamed and time step and everything else is cut off => name collisions
391 vtkSmartPointer< vtkXMLPUnstructuredGridWriter >writer = vtkSmartPointer< vtkXMLPUnstructuredGridWriter >::New();
392 writer->SetTimeStep(tStep->giveNumber() - 1);
393 writer->SetNumberOfPieces(this->emodel->giveNumberOfProcesses() );
394 writer->SetStartPiece(this->emodel->giveRank() );
395 writer->SetEndPiece(this->emodel->giveRank() );
396
397
398 #else
399 vtkSmartPointer< vtkXMLUnstructuredGridWriter >writer = vtkSmartPointer< vtkXMLUnstructuredGridWriter >::New();
400 #endif
401
402 writer->SetFileName(fname.c_str() );
403 //writer->SetInput(this->fileStream); // VTK 4
404 writer->SetInputData(this->fileStream); // VTK 6
405
406 // Optional - set the mode. The default is binary.
407 //writer->SetDataModeToBinary();
408 writer->SetDataModeToAscii();
409 writer->Write();
410#else
411 this->fileStream << "</UnstructuredGrid>\n</VTKFile>";
412 if(this->fileStream){
413 this->fileStream.close();
414 }
415#endif
416}
417
418} // end namespace oofem
#define REGISTER_ExportModule(class)
const FloatArray & giveCoordinates() const
Definition dofmanager.h:390
Element * giveElement(int n)
Definition domain.C:165
Node * giveNode(int n)
Definition domain.h:398
XfemManager * giveXfemManager()
Definition domain.C:378
bool hasXfemManager()
Definition domain.C:389
elementParallelMode giveParallelMode() const
Definition element.h:1139
bool evalNodeEnrMarkerInNode(double &oNodeEnrMarker, int iNodeInd) const
bool evalLevelSetTangInNode(double &oLevelSet, int iNodeInd, const FloatArray &iGlobalCoord) const
bool evalLevelSetNormalInNode(double &oLevelSet, int iNodeInd, const FloatArray &iGlobalCoord) const
double timeScale
Scaling time in output, e.g. conversion from seconds to hours.
std::string giveOutputBaseFileName(TimeStep *tStep)
virtual void initializeFrom(InputRecord &ir)
Initializes receiver according to object description stored in input record.
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 setInternalXFEMVarInNode(int varNum, int eiNum, int nodeNum, FloatArray valueArray)
FloatArray & giveInternalXFEMVarInNode(int varNum, int eiNum, int nodeNum)
void setNumberOfInternalVarsToExport(const IntArray &ists, 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 resizeWithValues(Index s, std::size_t allocChunk=0)
Definition floatarray.C:103
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
double giveTargetTime()
Returns target time.
Definition timestep.h:164
int giveNumber()
Returns receiver's number.
Definition timestep.h:144
bool isElementComposite(Element *elem)
static void makeFullTensorForm(FloatArray &answer, const FloatArray &reducedForm, InternalStateValueType vtype)
Gives the full form of given symmetrically stored tensors, missing components are filled with zeros.
virtual void setupVTKPiece(ExportRegion &vtkPiece, TimeStep *tStep, Set &region)
IntArray internalVarsToExport
List of InternalStateType values, identifying the selected vars for export.
std::unique_ptr< NodalRecoveryModel > smoother
Smoother.
void exportCompositeElement(ExportRegion &vtkPiece, Element *el, TimeStep *tStep)
void writeVTKPointData(FloatArray &valueArray)
std::vector< ExportRegion > defaultVTKPieces
bool writeVTKPieceProlog(ExportRegion &vtkPiece, TimeStep *tStep)
bool writeVTKPieceEpilog(ExportRegion &vtkPiece, TimeStep *tStep)
std::string giveOutputFileName(TimeStep *tStep)
Returns the filename for the given time step.
virtual ~VTKXMLXFemExportModule()
Destructor.
void initializeFrom(InputRecord &ir) override
Initializes receiver according to object description stored in input record.
VTKXMLXFemExportModule(int n, EngngModel *e)
Constructor. Creates empty Output Manager. By default all components are selected.
void getNodalVariableFromXFEMST(FloatArray &answer, Node *node, TimeStep *tStep, XFEMStateType xfemstype, Set &region, EnrichmentItem *ei)
void giveDataHeaders(std::string &pointHeader, std::string &cellHeader) override
std::ofstream giveOutputStream(TimeStep *tStep)
Returns the output stream for given solution step.
bool writeXFEMVars(ExportRegion &vtkPiece, int field, int enrItIndex)
void doOutput(TimeStep *tStep, bool forcedOutput=false) override
void exportIntVars2(ExportRegion &vtkPiece, Set &region, int field, int enrItIndex, IntArray &internalVarsToExport, NodalRecoveryModel &smoother, TimeStep *tStep)
IntArray vtkExportFields
InternalStateValueType giveXFEMStateValueType(XFEMStateType type)
Definition xfemmanager.C:88
EnrichmentItem * giveEnrichmentItem(int n)
int giveNumberOfEnrichmentItems() const
#define OOFEM_ERROR(...)
Definition error.h:79
@ Element_local
Element is local, there are no contributions from other domains to this element.
Definition element.h:88
const char * __XFEMStateTypeToString(XFEMStateType _value)
Definition cltypes.C:350
int giveInternalStateTypeSize(InternalStateValueType valType)
Definition cltypes.C:229
XFEMStateType
Definition xfemmanager.h:92
InternalStateValueType
Determines the type of internal variable.
@ ISVT_TENSOR_S3E
symmetric 3x3 tensor, packed with off diagonal components multiplied by 2 (engineering strain vector,...
@ ISVT_SCALAR
Scalar.
@ ISVT_TENSOR_S3
Symmetric 3x3 tensor.
@ ISVT_VECTOR
Vector.
@ ISVT_TENSOR_G
General tensor.
#define NULL_DEVICE

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