00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <WriterVTK.hpp>
00021 #include <Mesh.hpp>
00022
00023 #include <FieldOfScalarFunction.hpp>
00024
00025 #include <ScalarFunctionBase.hpp>
00026
00027 #include <FEMFunctionBase.hpp>
00028
00029 #include <Mesh.hpp>
00030
00031 #include <Structured3DMesh.hpp>
00032
00033 #include <MeshOfTetrahedra.hpp>
00034 #include <MeshOfHexahedra.hpp>
00035
00036 #include <SpectralMesh.hpp>
00037
00038 #include <OctreeMesh.hpp>
00039
00040 #include <SurfaceMeshOfTriangles.hpp>
00041 #include <SurfaceMeshOfQuadrangles.hpp>
00042
00043 #include <XMLWriter.hpp>
00044
00045 #include <Vector.hpp>
00046
00047 #include <EndianConverter.hpp>
00048 #include <fstream>
00049
00050 class BinarySerializerVTK
00051 {
00052 std::vector<char> __data;
00053
00054 template <typename T>
00055 struct DataTypeTraits {
00056 typedef T DataType;
00057 };
00058
00059 template <typename T>
00060 void __add(T data)
00061 {
00062 littleEndianize(data);
00063 for (size_t i=0; i<sizeof(T); ++i) {
00064 __data.push_back(reinterpret_cast<char*>(&data)[i]);
00065 }
00066 }
00067
00068 public:
00069 size_t offset() const
00070 {
00071 return __data.size();
00072 }
00073
00074 friend std::ostream& operator<<(std::ostream& os,
00075 const BinarySerializerVTK& serializer)
00076 {
00077 os.write(&serializer.__data[0], serializer.__data.size());
00078 return os;
00079 }
00080
00081 template <typename T>
00082 void add(const Vector<T>& values)
00083 {
00084 typedef typename DataTypeTraits<T>::DataType DataType;
00085
00086 int size = values.size()*sizeof(DataType);
00087 this->__add(size);
00088 for (size_t i=0; i<values.size(); ++i) {
00089 DataType v = values[i];
00090 this->__add(v);
00091 }
00092 }
00093
00094 BinarySerializerVTK()
00095 {
00096 ;
00097 }
00098 };
00099
00100 template <>
00101 struct BinarySerializerVTK::DataTypeTraits<real_t>
00102 {
00103 typedef double DataType;
00104 };
00105
00106 BinarySerializerVTK serializer;
00107
00108
00109
00110 template <typename CellType>
00111 struct WriterVTK::Traits {};
00112
00113 template <>
00114 struct WriterVTK::Traits<Triangle>
00115 {
00116 enum {
00117 VTKType = 5
00118 };
00119 };
00120
00121 template <>
00122 struct WriterVTK::Traits<Quadrangle>
00123 {
00124 enum {
00125 VTKType = 9
00126 };
00127 };
00128
00129 template <>
00130 struct WriterVTK::Traits<Tetrahedron>
00131 {
00132 enum {
00133 VTKType = 10
00134 };
00135 };
00136
00137 template <>
00138 struct WriterVTK::Traits<Hexahedron>
00139 {
00140 enum {
00141 VTKType = 12
00142 };
00143 };
00144
00145 template <>
00146 struct WriterVTK::Traits<CartesianHexahedron>
00147 {
00148 enum {
00149 VTKType = 12
00150 };
00151 };
00152
00153 void WriterVTK::
00154 __fillCrossedComponent(const FieldOfScalarFunction& field,
00155 Vector<real_t>& values) const
00156 {
00157 const size_t numberOfComponents = field.numberOfComponents();
00158 ASSERT(values.size() == __mesh->numberOfVertices()*numberOfComponents);
00159
00160 switch (__mesh->type()) {
00161 case Mesh::cartesianHexahedraMesh: {
00162 const Structured3DMesh& mesh = dynamic_cast<const Structured3DMesh&>(*__mesh);
00163 for (size_t l = 0; l<numberOfComponents; ++l) {
00164 const ScalarFunctionBase& function = *field.function(l);
00165
00166 switch (function.type()) {
00167 case ScalarFunctionBase::femfunction: {
00168 const FEMFunctionBase& fem
00169 = static_cast<const FEMFunctionBase&>(function);
00170
00171 if ((fem.discretizationType() == ScalarDiscretizationTypeBase::lagrangianFEM1)
00172 and (fem.baseMesh() == __mesh)) {
00173 size_t position = 0;
00174 for (size_t k=0; k<mesh.shape().nz(); ++k)
00175 for (size_t j=0; j<mesh.shape().ny(); ++j)
00176 for (size_t i=0; i<mesh.shape().nx(); ++i) {
00177 const size_t pointNumber = mesh.shape()(i,j,k);
00178 values[position*numberOfComponents+l] = fem[pointNumber];
00179 position++;
00180 }
00181 break;
00182 }
00183 }
00184 default: {
00185 size_t position = 0;
00186 for (size_t k=0; k<mesh.shape().nz(); ++k)
00187 for (size_t j=0; j<mesh.shape().ny(); ++j)
00188 for (size_t i=0; i<mesh.shape().nx(); ++i) {
00189 const Vertex& x = mesh.vertex(i,j,k);
00190 values[position*numberOfComponents+l] = function(x);
00191 position++;
00192 }
00193 }
00194 }
00195 }
00196 break;
00197 }
00198 default: {
00199 for (size_t i = 0; i<numberOfComponents; ++i) {
00200 const ScalarFunctionBase& function = *field.function(i);
00201
00202 switch (function.type()) {
00203 case ScalarFunctionBase::femfunction: {
00204 const FEMFunctionBase& fem
00205 = static_cast<const FEMFunctionBase&>(function);
00206 if ((fem.baseMesh() == __mesh) and
00207 ((fem.discretizationType() == ScalarDiscretizationTypeBase::lagrangianFEM1))) {
00208 for (size_t j=0; j<fem.values().size(); ++j) {
00209 values[numberOfComponents*j+i] = fem[j];
00210 }
00211 break;
00212 }
00213 }
00214 default: {
00215 for (size_t j=0; j<__mesh->numberOfVertices(); ++j) {
00216 const TinyVector<3,real_t>& x = __mesh->vertex(j);
00217 values[numberOfComponents*j+i] = function(x);
00218 }
00219 }
00220 }
00221 }
00222 }
00223 }
00224 }
00225
00226 template <typename MeshType>
00227 void WriterVTK::
00228 __proceed() const
00229 {
00230 typedef typename MeshType::CellType CellType;
00231
00232 std::string filename = __filename;
00233 filename += ".vtu";
00234
00235 const MeshType& mesh
00236 = static_cast<const MeshType&>(*__mesh);
00237
00238
00239
00240
00241
00242
00243 std::ofstream file(filename.c_str());
00244 file.precision(15);
00245
00246 XMLWriter xmlWriter(file);
00247
00248 xmlWriter.writeHeader();
00249 {
00250 XMLTag vtkFile("VTKFile");
00251 ReferenceCounting<XMLAttribute> attribute
00252 = new XMLAttribute("type","UnstructuredGrid");
00253 vtkFile.add(attribute);
00254
00255 if (this->__binary) {
00256 ReferenceCounting<XMLAttribute> endiannes
00257 = new XMLAttribute("byte_order","LittleEndian");
00258 vtkFile.add(endiannes);
00259 }
00260
00261 xmlWriter.add(vtkFile);
00262 }
00263
00264 {
00265 XMLTag unstructuredGrid("UnstructuredGrid");
00266 xmlWriter.add(unstructuredGrid);
00267 }
00268
00269 {
00270 XMLTag piece("Piece");
00271 ReferenceCounting<XMLAttribute>
00272 nbPoints = new XMLAttribute("NumberOfPoints",
00273 stringify(mesh.numberOfVertices()));
00274 piece.add(nbPoints);
00275 ReferenceCounting<XMLAttribute>
00276 nbCells = new XMLAttribute("NumberOfCells",
00277 stringify(mesh.numberOfCells()));
00278 piece.add(nbCells);
00279 xmlWriter.add(piece);
00280
00281 {
00282 XMLTag points("Points");
00283 xmlWriter.add(points);
00284
00285 {
00286 XMLTag dataarray("DataArray");
00287 ReferenceCounting<XMLAttribute>
00288 type = new XMLAttribute("type","Float64");
00289 dataarray.add(type);
00290 ReferenceCounting<XMLAttribute>
00291 name = new XMLAttribute("Name","Position");
00292 dataarray.add(name);
00293 ReferenceCounting<XMLAttribute>
00294 nbComponent = new XMLAttribute("NumberOfComponents","3");
00295 dataarray.add(nbComponent);
00296
00297 if (not this->__binary) {
00298 ReferenceCounting<XMLAttribute>
00299 format = new XMLAttribute("format","ascii");
00300 dataarray.add(format);
00301
00302 xmlWriter.add(dataarray);
00303
00304 for (size_t i=0; i<mesh.numberOfVertices(); ++i) {
00305 const Vertex& x = mesh.vertex(i);
00306 xmlWriter.insert(x[0]);
00307 xmlWriter.insert(x[1]);
00308 xmlWriter.insert(x[2]);
00309 }
00310 xmlWriter.insertNewLine();
00311 xmlWriter.closeTag();
00312 } else {
00313 ReferenceCounting<XMLAttribute>
00314 format = new XMLAttribute("format","appended");
00315 dataarray.add(format);
00316
00317 ReferenceCounting<XMLAttribute>
00318 offset = new XMLAttribute("offset",stringify(serializer.offset()));
00319 dataarray.add(offset);
00320
00321 xmlWriter.add(dataarray);
00322
00323 Vector<real_t> coords(3*mesh.numberOfVertices());
00324 for (size_t i=0; i<mesh.numberOfVertices(); ++i) {
00325 const Vertex& x = mesh.vertex(i);
00326 coords[3*i+0] = x[0];
00327 coords[3*i+1] = x[1];
00328 coords[3*i+2] = x[2];
00329 }
00330
00331 serializer.add(coords);
00332 xmlWriter.closeTag();
00333 }
00334 }
00335 xmlWriter.closeTag();
00336 }
00337
00338 {
00339 XMLTag cells("Cells");
00340 xmlWriter.add(cells);
00341
00342 {
00343 XMLTag dataarray("DataArray");
00344 ReferenceCounting<XMLAttribute>
00345 type = new XMLAttribute("type","Int32");
00346 dataarray.add(type);
00347 ReferenceCounting<XMLAttribute>
00348 name = new XMLAttribute("Name","connectivity");
00349 dataarray.add(name);
00350 ReferenceCounting<XMLAttribute>
00351 nbComponent = new XMLAttribute("NumberOfComponents","1");
00352 dataarray.add(nbComponent);
00353
00354 if (not this->__binary) {
00355 ReferenceCounting<XMLAttribute>
00356 format = new XMLAttribute("format","ascii");
00357 dataarray.add(format);
00358 xmlWriter.add(dataarray);
00359
00360 for (size_t i=0;i<mesh.numberOfCells(); ++i) {
00361 const CellType& cell = mesh.cell(i);
00362 for (size_t j=0; j<CellType::NumberOfVertices; ++j) {
00363 xmlWriter.insert(mesh.vertexNumber(cell(j)));
00364 }
00365 }
00366 xmlWriter.insertNewLine();
00367 xmlWriter.closeTag();
00368 } else {
00369 ReferenceCounting<XMLAttribute>
00370 format = new XMLAttribute("format","appended");
00371 dataarray.add(format);
00372
00373 ReferenceCounting<XMLAttribute>
00374 offset = new XMLAttribute("offset",stringify(serializer.offset()));
00375 dataarray.add(offset);
00376
00377 Vector<int> cellDescription(CellType::NumberOfVertices*mesh.numberOfCells());
00378
00379 for (size_t i=0;i<mesh.numberOfCells(); ++i) {
00380 const CellType& cell = mesh.cell(i);
00381 for (size_t j=0; j<CellType::NumberOfVertices; ++j) {
00382 cellDescription[i*CellType::NumberOfVertices+j]
00383 = mesh.vertexNumber(cell(j));
00384 }
00385 }
00386
00387 serializer.add(cellDescription);
00388
00389 xmlWriter.add(dataarray);
00390 xmlWriter.closeTag();
00391 }
00392 }
00393
00394 {
00395 XMLTag dataarray("DataArray");
00396 ReferenceCounting<XMLAttribute>
00397 type = new XMLAttribute("type","Int32");
00398 dataarray.add(type);
00399 ReferenceCounting<XMLAttribute>
00400 name = new XMLAttribute("Name","offsets");
00401 dataarray.add(name);
00402 ReferenceCounting<XMLAttribute>
00403 nbComponent = new XMLAttribute("NumberOfComponents","1");
00404 dataarray.add(nbComponent);
00405 if (not this->__binary) {
00406 ReferenceCounting<XMLAttribute>
00407 format = new XMLAttribute("format","ascii");
00408 dataarray.add(format);
00409 xmlWriter.add(dataarray);
00410
00411 for (size_t i=1; i<=mesh.numberOfCells(); ++i) {
00412 xmlWriter.insert(i*CellType::NumberOfVertices);
00413 }
00414
00415 xmlWriter.insertNewLine();
00416 xmlWriter.closeTag();
00417 } else {
00418 ReferenceCounting<XMLAttribute>
00419 format = new XMLAttribute("format","appended");
00420 dataarray.add(format);
00421
00422 ReferenceCounting<XMLAttribute>
00423 offset = new XMLAttribute("offset",stringify(serializer.offset()));
00424 dataarray.add(offset);
00425
00426 Vector<int> offsets(mesh.numberOfCells());
00427 for (size_t i=0; i<mesh.numberOfCells(); ++i) {
00428 offsets[i] = ((i+1)*CellType::NumberOfVertices);
00429 }
00430
00431 serializer.add(offsets);
00432
00433 xmlWriter.add(dataarray);
00434 xmlWriter.closeTag();
00435 }
00436 }
00437
00438 {
00439 XMLTag dataarray("DataArray");
00440 ReferenceCounting<XMLAttribute>
00441 type = new XMLAttribute("type","UInt8");
00442 dataarray.add(type);
00443 ReferenceCounting<XMLAttribute>
00444 name = new XMLAttribute("Name","types");
00445 dataarray.add(name);
00446 ReferenceCounting<XMLAttribute>
00447 nbComponent = new XMLAttribute("NumberOfComponents","1");
00448 dataarray.add(nbComponent);
00449
00450 if (not this->__binary) {
00451 ReferenceCounting<XMLAttribute>
00452 format = new XMLAttribute("format","ascii");
00453 dataarray.add(format);
00454 xmlWriter.add(dataarray);
00455
00456 for (size_t i=0; i<mesh.numberOfCells(); ++i) {
00457 xmlWriter.insert(Traits<CellType>::VTKType);
00458 }
00459 xmlWriter.insertNewLine();
00460 xmlWriter.closeTag();
00461 } else {
00462 ReferenceCounting<XMLAttribute>
00463 format = new XMLAttribute("format","appended");
00464 dataarray.add(format);
00465
00466 ReferenceCounting<XMLAttribute>
00467 offset = new XMLAttribute("offset",stringify(serializer.offset()));
00468 dataarray.add(offset);
00469
00470 Vector<unsigned char> types(mesh.numberOfCells());
00471 for (size_t i=0; i<mesh.numberOfCells(); ++i) {
00472 types[i] = Traits<CellType>::VTKType;
00473 }
00474
00475 serializer.add(types);
00476
00477 xmlWriter.add(dataarray);
00478 xmlWriter.closeTag();
00479 }
00480 }
00481 }
00482 xmlWriter.closeTag();
00483 }
00484 {
00485 XMLTag pointdata("PointData");
00486 xmlWriter.add(pointdata);
00487
00488 for (size_t i=0; i<__scalarFunctionList.size(); ++i) {
00489
00490 const ScalarFunctionBase& function = *__scalarFunctionList[i];
00491
00492 if (not this->__binary) {
00493 XMLTag dataarray("DataArray");
00494 ReferenceCounting<XMLAttribute>
00495 type = new XMLAttribute("type","Float64");
00496 dataarray.add(type);
00497 ReferenceCounting<XMLAttribute>
00498 name = new XMLAttribute("Name",stringify(function));
00499 dataarray.add(name);
00500 ReferenceCounting<XMLAttribute>
00501 nbComponent = new XMLAttribute("NumberOfComponents","1");
00502 dataarray.add(nbComponent);
00503 ReferenceCounting<XMLAttribute>
00504 format = new XMLAttribute("format","ascii");
00505 dataarray.add(format);
00506
00507 xmlWriter.add(dataarray);
00508
00509 switch (function.type()) {
00510 case ScalarFunctionBase::femfunction: {
00511 const FEMFunctionBase& fem
00512 = static_cast<const FEMFunctionBase&>(function);
00513
00514 if ((fem.discretizationType() == ScalarDiscretizationTypeBase::lagrangianFEM1)
00515 and (fem.baseMesh() == __mesh)) {
00516 for (size_t i=0; i<mesh.numberOfVertices(); ++i) {
00517 xmlWriter.insert(fem[i]);
00518 }
00519 break;
00520 }
00521 }
00522 default: {
00523 for (size_t i=0; i<mesh.numberOfVertices(); ++i) {
00524 const Vertex& x = mesh.vertex(i);
00525 xmlWriter.insert(function(x));
00526 }
00527 }
00528 }
00529
00530 xmlWriter.insertNewLine();
00531 xmlWriter.closeTag();
00532 } else {
00533 XMLTag dataArray("DataArray");
00534 ReferenceCounting<XMLAttribute> type
00535 = new XMLAttribute("type","Float64");
00536 dataArray.add(type);
00537 ReferenceCounting<XMLAttribute> name
00538 = new XMLAttribute("Name",stringify(function));
00539 dataArray.add(name);
00540 ReferenceCounting<XMLAttribute>
00541 nbComponent = new XMLAttribute("NumberOfComponents","1");
00542 dataArray.add(nbComponent);
00543
00544 ReferenceCounting<XMLAttribute>
00545 format = new XMLAttribute("format","appended");
00546 dataArray.add(format);
00547
00548 ReferenceCounting<XMLAttribute>
00549 offset = new XMLAttribute("offset",stringify(serializer.offset()));
00550 dataArray.add(offset);
00551
00552 xmlWriter.add(dataArray);
00553 xmlWriter.closeTag();
00554
00555 Vector<real_t> values(mesh.numberOfVertices());
00556
00557 switch (function.type()) {
00558 case ScalarFunctionBase::femfunction: {
00559 const FEMFunctionBase& fem
00560 = static_cast<const FEMFunctionBase&>(function);
00561
00562 if ((fem.discretizationType() == ScalarDiscretizationTypeBase::lagrangianFEM1)
00563 and (fem.baseMesh() == __mesh)) {
00564 for (size_t i=0; i<mesh.numberOfVertices(); ++i) {
00565 values[i] = fem[i];
00566 }
00567 break;
00568 }
00569 }
00570 default: {
00571 for (size_t i=0; i<mesh.numberOfVertices(); ++i) {
00572 const Vertex& x = mesh.vertex(i);
00573 values[i] = function(x);
00574 }
00575 }
00576 }
00577 serializer.add(values);
00578 }
00579 }
00580
00581 for (size_t i=0; i<__fieldList.size(); ++i) {
00582
00583 const FieldOfScalarFunction& field = *__fieldList[i];
00584
00585 XMLTag dataArray("DataArray");
00586 ReferenceCounting<XMLAttribute> type
00587 = new XMLAttribute("type","Float64");
00588 dataArray.add(type);
00589 ReferenceCounting<XMLAttribute> name
00590 = new XMLAttribute("Name",stringify(field));
00591 dataArray.add(name);
00592 ReferenceCounting<XMLAttribute>
00593 nbComponent = new XMLAttribute("NumberOfComponents",
00594 stringify(field.numberOfComponents()));
00595 dataArray.add(nbComponent);
00596
00597 Vector<real_t> values(field.numberOfComponents()*__mesh->numberOfVertices());
00598
00599 this->__fillCrossedComponent(field,values);
00600 if (not this->__binary) {
00601 ReferenceCounting<XMLAttribute> format
00602 = new XMLAttribute("format","ascii");
00603 dataArray.add(format);
00604 xmlWriter.add(dataArray);
00605
00606
00607 for (size_t i=0; i<values.size(); ++i) {
00608 xmlWriter.insert(values[i]);
00609 }
00610
00611 xmlWriter.insertNewLine();
00612 xmlWriter.closeTag();
00613 } else {
00614 ReferenceCounting<XMLAttribute>
00615 format = new XMLAttribute("format","appended");
00616 dataArray.add(format);
00617
00618 ReferenceCounting<XMLAttribute>
00619 offset = new XMLAttribute("offset",stringify(serializer.offset()));
00620 dataArray.add(offset);
00621
00622 xmlWriter.add(dataArray);
00623 xmlWriter.closeTag();
00624
00625 serializer.add(values);
00626 }
00627 }
00628
00629 xmlWriter.closeTag();
00630 }
00631
00632 if (this->__binary) {
00633 xmlWriter.closeTag();
00634 xmlWriter.closeTag();
00635 {
00636 XMLTag appended("AppendedData");
00637
00638 ReferenceCounting<XMLAttribute>
00639 encoding = new XMLAttribute("encoding","raw");
00640
00641 appended.add(encoding);
00642 xmlWriter.add(appended);
00643
00644 xmlWriter.insertUnderscore();
00645
00646 file << serializer;
00647
00648 xmlWriter.insertNewLine();
00649 }
00650 }
00651 }
00652
00653 template <>
00654 void WriterVTK::
00655 __proceed<Structured3DMesh>() const
00656 {
00657 std::string filename = __filename;
00658 filename += ".vti";
00659
00660 const Structured3DMesh& mesh
00661 = static_cast<const Structured3DMesh&>(*__mesh);
00662
00663 std::ofstream file(filename.c_str());
00664 file.precision(15);
00665
00666 XMLWriter xmlWriter(file);
00667
00668 xmlWriter.writeHeader();
00669 {
00670 XMLTag vtkFile("VTKFile");
00671 ReferenceCounting<XMLAttribute> attribute
00672 = new XMLAttribute("type","ImageData");
00673 vtkFile.add(attribute);
00674
00675 if (this->__binary) {
00676 ReferenceCounting<XMLAttribute> endiannes
00677 = new XMLAttribute("byte_order","LittleEndian");
00678 vtkFile.add(endiannes);
00679 }
00680
00681 xmlWriter.add(vtkFile);
00682 }
00683
00684 {
00685 XMLTag rectilinearGrid("ImageData");
00686 ReferenceCounting<XMLAttribute> wholeExtent
00687 = new XMLAttribute("WholeExtent",
00688 "0 "+stringify(mesh.shape().nx()-1)+
00689 " 0 "+stringify(mesh.shape().ny()-1)+
00690 " 0 "+stringify(mesh.shape().nz()-1));
00691 rectilinearGrid.add(wholeExtent);
00692 ReferenceCounting<XMLAttribute> origin
00693 = new XMLAttribute("Origin",
00694 stringify(mesh.shape().a(0))+" "+
00695 stringify(mesh.shape().a(1))+" "+
00696 stringify(mesh.shape().a(2)));
00697 rectilinearGrid.add(origin);
00698 ReferenceCounting<XMLAttribute> spacing
00699 = new XMLAttribute("Spacing",
00700 stringify(mesh.shape().hx())+" "+
00701 stringify(mesh.shape().hy())+" "+
00702 stringify(mesh.shape().hz()));
00703 rectilinearGrid.add(spacing);
00704 xmlWriter.add(rectilinearGrid);
00705 }
00706
00707 {
00708 XMLTag piece("Piece");
00709 ReferenceCounting<XMLAttribute> extent
00710 = new XMLAttribute("Extent",
00711 "0 "+stringify(mesh.shape().nx()-1)
00712 +" 0 "+stringify(mesh.shape().ny()-1)
00713 +" 0 "+stringify(mesh.shape().nz()-1));
00714 piece.add(extent);
00715 xmlWriter.add(piece);
00716 }
00717
00718 {
00719 XMLTag pointData("PointData");
00720 XMLAttribute scalars("Scalars",__filename);
00721 xmlWriter.add(pointData);
00722
00723 for (size_t i=0; i<__scalarFunctionList.size(); ++i) {
00724
00725 const ScalarFunctionBase& function = *__scalarFunctionList[i];
00726
00727 if (not this->__binary) {
00728 XMLTag dataArray("DataArray");
00729 ReferenceCounting<XMLAttribute> type
00730 = new XMLAttribute("type","Float64");
00731 dataArray.add(type);
00732 ReferenceCounting<XMLAttribute> name
00733 = new XMLAttribute("Name",stringify(function));
00734 dataArray.add(name);
00735 ReferenceCounting<XMLAttribute> format
00736 = new XMLAttribute("format","ascii");
00737 dataArray.add(format);
00738 xmlWriter.add(dataArray);
00739
00740 switch (function.type()) {
00741 case ScalarFunctionBase::femfunction: {
00742 const FEMFunctionBase& fem
00743 = static_cast<const FEMFunctionBase&>(function);
00744
00745 if ((fem.discretizationType() == ScalarDiscretizationTypeBase::lagrangianFEM1)
00746 and (fem.baseMesh() == __mesh)) {
00747 for (size_t k=0; k<mesh.shape().nz(); ++k)
00748 for (size_t j=0; j<mesh.shape().ny(); ++j)
00749 for (size_t i=0; i<mesh.shape().nx(); ++i) {
00750 const size_t pointNumber = mesh.shape()(i,j,k);
00751 xmlWriter.insert(fem[pointNumber]);
00752 }
00753 break;
00754 }
00755 }
00756 default: {
00757 for (size_t k=0; k<mesh.shape().nz(); ++k)
00758 for (size_t j=0; j<mesh.shape().ny(); ++j)
00759 for (size_t i=0; i<mesh.shape().nx(); ++i) {
00760 const Vertex& x = mesh.vertex(i,j,k);
00761 xmlWriter.insert(function(x));
00762 }
00763 }
00764 }
00765 xmlWriter.insertNewLine();
00766 xmlWriter.closeTag();
00767 } else {
00768 XMLTag dataArray("DataArray");
00769 ReferenceCounting<XMLAttribute> type
00770 = new XMLAttribute("type","Float64");
00771 dataArray.add(type);
00772 ReferenceCounting<XMLAttribute> name
00773 = new XMLAttribute("Name",stringify(function));
00774 dataArray.add(name);
00775 ReferenceCounting<XMLAttribute>
00776 nbComponent = new XMLAttribute("NumberOfComponents","1");
00777 dataArray.add(nbComponent);
00778
00779 ReferenceCounting<XMLAttribute>
00780 format = new XMLAttribute("format","appended");
00781 dataArray.add(format);
00782
00783 ReferenceCounting<XMLAttribute>
00784 offset = new XMLAttribute("offset",stringify(serializer.offset()));
00785 dataArray.add(offset);
00786
00787 xmlWriter.add(dataArray);
00788 xmlWriter.closeTag();
00789
00790 Vector<real_t> values(mesh.numberOfVertices());
00791
00792 switch (function.type()) {
00793 case ScalarFunctionBase::femfunction: {
00794 const FEMFunctionBase& fem
00795 = static_cast<const FEMFunctionBase&>(function);
00796
00797 if ((fem.discretizationType() == ScalarDiscretizationTypeBase::lagrangianFEM1)
00798 and (fem.baseMesh() == __mesh)) {
00799 size_t l=0;
00800 for (size_t k=0; k<mesh.shape().nz(); ++k)
00801 for (size_t j=0; j<mesh.shape().ny(); ++j)
00802 for (size_t i=0; i<mesh.shape().nx(); ++i) {
00803 const size_t pointNumber = mesh.shape()(i,j,k);
00804 values[l] = fem[pointNumber];
00805 l++;
00806 }
00807 break;
00808 }
00809 }
00810 default: {
00811 size_t l=0;
00812 for (size_t k=0; k<mesh.shape().nz(); ++k)
00813 for (size_t j=0; j<mesh.shape().ny(); ++j)
00814 for (size_t i=0; i<mesh.shape().nx(); ++i) {
00815 const Vertex& x = mesh.vertex(i,j,k);
00816 values[l] = function(x);
00817 l++;
00818 }
00819 }
00820 }
00821
00822 serializer.add(values);
00823 }
00824 }
00825
00826 for (size_t i=0; i<__fieldList.size(); ++i) {
00827
00828 const FieldOfScalarFunction& field = *__fieldList[i];
00829
00830 XMLTag dataArray("DataArray");
00831 ReferenceCounting<XMLAttribute> type
00832 = new XMLAttribute("type","Float64");
00833 dataArray.add(type);
00834 ReferenceCounting<XMLAttribute> name
00835 = new XMLAttribute("Name",stringify(field));
00836 dataArray.add(name);
00837 ReferenceCounting<XMLAttribute>
00838 nbComponent = new XMLAttribute("NumberOfComponents",
00839 stringify(field.numberOfComponents()));
00840 dataArray.add(nbComponent);
00841
00842 Vector<real_t> values(field.numberOfComponents()*__mesh->numberOfVertices());
00843 this->__fillCrossedComponent(field,values);
00844
00845 if (not this->__binary) {
00846 ReferenceCounting<XMLAttribute> format
00847 = new XMLAttribute("format","ascii");
00848 dataArray.add(format);
00849 xmlWriter.add(dataArray);
00850
00851
00852 for (size_t i=0; i<values.size(); ++i) {
00853 xmlWriter.insert(values[i]);
00854 }
00855
00856 xmlWriter.insertNewLine();
00857 xmlWriter.closeTag();
00858 } else {
00859 ReferenceCounting<XMLAttribute>
00860 format = new XMLAttribute("format","appended");
00861 dataArray.add(format);
00862
00863 ReferenceCounting<XMLAttribute>
00864 offset = new XMLAttribute("offset",stringify(serializer.offset()));
00865 dataArray.add(offset);
00866
00867 xmlWriter.add(dataArray);
00868 xmlWriter.closeTag();
00869
00870 serializer.add(values);
00871 }
00872 }
00873
00874 xmlWriter.closeTag();
00875 }
00876
00877 xmlWriter.closeTag();
00878 xmlWriter.closeTag();
00879
00880 if (this->__binary) {
00881 XMLTag appended("AppendedData");
00882
00883 ReferenceCounting<XMLAttribute>
00884 encoding = new XMLAttribute("encoding","raw");
00885
00886 appended.add(encoding);
00887 xmlWriter.add(appended);
00888
00889 xmlWriter.insertUnderscore();
00890 file << serializer;
00891 xmlWriter.insertNewLine();
00892 }
00893 }
00894
00895 void WriterVTK::
00896 proceed() const
00897 {
00898 switch (__mesh->type()) {
00899 case Mesh::cartesianHexahedraMesh: {
00900 this->__proceed<Structured3DMesh>();
00901 break;
00902 }
00903 case Mesh::hexahedraMesh: {
00904 this->__proceed<MeshOfHexahedra>();
00905 break;
00906 }
00907 case Mesh::octreeMesh: {
00908 this->__proceed<OctreeMesh>();
00909 break;
00910 }
00911 case Mesh::tetrahedraMesh: {
00912 this->__proceed<MeshOfTetrahedra>();
00913 break;
00914 }
00915 case Mesh::spectralMesh: {
00916 this->__proceed<SpectralMesh>();
00917 break;
00918 }
00919 case Mesh::surfaceMeshTriangles: {
00920 this->__proceed<SurfaceMeshOfTriangles>();
00921 break;
00922 }
00923 case Mesh::surfaceMeshQuadrangles: {
00924 this->__proceed<SurfaceMeshOfQuadrangles>();
00925 break;
00926 }
00927 default: {
00928 throw ErrorHandler(__FILE__,__LINE__,
00929 "cannot save this mesh type to VTK format",
00930 ErrorHandler::normal);
00931 }
00932 }
00933 }
00934
00935 WriterVTK::
00936 WriterVTK(ConstReferenceCounting<Mesh> mesh,
00937 const std::string& filename,
00938 const FileDescriptor& fileDescriptor)
00939 : WriterBase(mesh,
00940 filename,
00941 fileDescriptor),
00942 __binary((fileDescriptor.type() == FileDescriptor::binary) or
00943 (fileDescriptor.type() == FileDescriptor::formatDefault))
00944 {
00945 ;
00946 }
00947
00948 WriterVTK::
00949 ~WriterVTK()
00950 {
00951 ;
00952 }