00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "SundanceVTKWriter.hpp"
00043 #include "PlayaExceptions.hpp"
00044 #include "SundanceOut.hpp"
00045 #include "PlayaTabs.hpp"
00046 #include "Teuchos_XMLObject.hpp"
00047
00048
00049
00050 using namespace Sundance;
00051 using namespace Sundance;
00052 using namespace Sundance;
00053 using namespace Teuchos;
00054
00055
00056
00057
00058 void VTKWriter::write() const
00059 {
00060 lowLevelWrite(filename(), false);
00061 if (nProc() > 1 && myRank()==0) lowLevelWrite(filename(), true);
00062 }
00063
00064 void VTKWriter::lowLevelWrite(const std::string& filename, bool isPHeader) const
00065 {
00066 std::string PHeader = "";
00067 if (isPHeader) PHeader="P";
00068
00069 std::string f = filename;
00070
00071 if (isPHeader) f = f + ".pvtu";
00072 else if (nProc() > 1)
00073 {
00074 f = f + Teuchos::toString(myRank()) + ".vtu";
00075 }
00076 else
00077 {
00078 f = f + ".vtu";
00079 }
00080
00081 SUNDANCE_VERB_MEDIUM("writing VTK file " << f);
00082
00083 std::ofstream os(f.c_str());
00084
00085 XMLObject head("VTKFile");
00086 head.addAttribute("type", PHeader + "UnstructuredGrid");
00087 head.addAttribute("version", "0.1");
00088
00089 os << head.header() << std::endl;
00090
00091 for (int i=0; i<comments().length(); i++)
00092 {
00093 os << "<!-- " << comments()[i] << " -->" << std::endl;
00094 }
00095
00096 XMLObject ug(PHeader + "UnstructuredGrid");
00097 os << ug.header() << std::endl;
00098
00099 if (isPHeader)
00100 {
00101 writePoints(os, isPHeader);
00102 writePointData(os, isPHeader);
00103 writeCellData(os, isPHeader);
00104 for (int p=0; p<nProc(); p++)
00105 {
00106 XMLObject pc("Piece");
00107 std::string pfile = filename + Teuchos::toString(p) + ".vtu";
00108 size_t pos = pfile.find_last_of("/");
00109 if (pos != std::string::npos)
00110 {
00111 pfile = pfile.substr(pos+1);
00112 }
00113 pc.addAttribute("Source", pfile);
00114 os << pc << std::endl;
00115 }
00116 }
00117 else
00118 {
00119 XMLObject pc("Piece");
00120 pc.addAttribute("NumberOfPoints", Teuchos::toString(mesh().numCells(0)));
00121 pc.addAttribute("NumberOfCells", Teuchos::toString(mesh().numCells(mesh().spatialDim())));
00122
00123 os << pc.header() << std::endl;
00124
00125 writePoints(os, false);
00126 writeCells(os);
00127 writePointData(os, false);
00128 writeCellData(os, false);
00129
00130 os << pc.footer() << std::endl;
00131 }
00132
00133 os << ug.footer() << std::endl;
00134 os << head.footer() << std::endl;
00135 }
00136
00137 void VTKWriter::writePoints(std::ostream& os, bool isPHeader) const
00138 {
00139 std::string PHeader = "";
00140 if (isPHeader) PHeader="P";
00141 XMLObject pts(PHeader + "Points");
00142
00143 os << pts.header() << std::endl;
00144
00145 XMLObject xml(PHeader + "DataArray");
00146 xml.addAttribute("NumberOfComponents", "3");
00147 xml.addAttribute("type", "Float32");
00148 xml.addAttribute("format", "ascii");
00149
00150 os << xml.header() << std::endl;
00151
00152
00153 if (!isPHeader)
00154 {
00155 int np = mesh().numCells(0);
00156 int dim = mesh().spatialDim();
00157
00158 for (int i=0; i<np; i++)
00159 {
00160 const Point& x = mesh().nodePosition(i);
00161
00162 for (int d=0; d<dim; d++)
00163 {
00164 os << x[d] << " ";
00165 }
00166 for (int d=dim; d<3; d++)
00167 {
00168 os << "0.0 ";
00169 }
00170 os << std::endl;
00171 }
00172 }
00173
00174 os << xml.footer() << std::endl;
00175
00176 os << pts.footer() << std::endl;
00177 }
00178
00179
00180 void VTKWriter::writeCells(std::ostream& os) const
00181 {
00182 XMLObject cells("Cells");
00183 os << cells.header() << std::endl;
00184
00185 XMLObject conn("DataArray");
00186 conn.addAttribute("type", "Int32");
00187 conn.addAttribute("Name", "connectivity");
00188 conn.addAttribute("format", "ascii");
00189
00190 int dim = mesh().spatialDim();
00191 int nc = mesh().numCells(dim);
00192 int dummySign;
00193
00194 os << conn.header() << std::endl;
00195 CellType cellType = mesh().cellType(dim);
00196
00197 for (int c=0; c<nc; c++)
00198 {
00199 int nNodes = mesh().numFacets( dim , c , 0 );
00200
00201 switch(cellType)
00202 {
00203 case TriangleCell: case LineCell: case TetCell:
00204 for (int i=0; i<nNodes; i++)
00205 {
00206 os << " " << mesh().facetLID(dim,c,0,i,dummySign);
00207 }
00208 os << std::endl;
00209 break;
00210 case QuadCell:
00211 os << " " << mesh().facetLID(dim,c,0,0,dummySign);
00212 os << " " << mesh().facetLID(dim,c,0,1,dummySign);
00213 os << " " << mesh().facetLID(dim,c,0,3,dummySign);
00214 os << " " << mesh().facetLID(dim,c,0,2,dummySign);
00215 os << std::endl;
00216 break;
00217 case BrickCell:
00218 os << " " << mesh().facetLID(dim,c,0,0,dummySign);
00219 os << " " << mesh().facetLID(dim,c,0,1,dummySign);
00220 os << " " << mesh().facetLID(dim,c,0,2,dummySign);
00221 os << " " << mesh().facetLID(dim,c,0,3,dummySign);
00222 os << " " << mesh().facetLID(dim,c,0,4,dummySign);
00223 os << " " << mesh().facetLID(dim,c,0,5,dummySign);
00224 os << " " << mesh().facetLID(dim,c,0,6,dummySign);
00225 os << " " << mesh().facetLID(dim,c,0,7,dummySign);
00226 os << std::endl;
00227 break;
00228 default:
00229 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "call type " << cellType <<
00230 " not handled in VTKWriter::writeCells()");
00231 }
00232 }
00233
00234 os << conn.footer() << std::endl;
00235
00236
00237 XMLObject offsets("DataArray");
00238 offsets.addAttribute("type", "Int32");
00239 offsets.addAttribute("Name", "offsets");
00240 offsets.addAttribute("format", "ascii");
00241
00242 os << offsets.header() << std::endl;
00243
00244 int count = 0;
00245 for (int c=0; c<nc; c++)
00246 {
00247 count += mesh().numFacets(dim, c, 0);
00248 os << count << std::endl;
00249 }
00250
00251 os << offsets.footer() << std::endl;
00252
00253 XMLObject types("DataArray");
00254 types.addAttribute("type", "UInt8");
00255 types.addAttribute("Name", "types");
00256 types.addAttribute("format", "ascii");
00257
00258 os << types.header() << std::endl;
00259
00260 for (int c=0; c<nc; c++)
00261 {
00262
00263 int vtkCode = 0;
00264 switch(cellType)
00265 {
00266 case TriangleCell:
00267 vtkCode = 5;
00268 break;
00269 case QuadCell:
00270 vtkCode = 9;
00271 break;
00272 case TetCell:
00273 vtkCode = 10;
00274 break;
00275 case BrickCell:
00276 vtkCode = 11;
00277 break;
00278 default:
00279 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00280 "call type " << cellType << " not handled "
00281 "in VTKWriter::writeCells()");
00282 }
00283 os << vtkCode << std::endl;
00284 }
00285
00286 os << types.footer() << std::endl;
00287
00288 os << cells.footer() << std::endl;
00289 }
00290
00291 void VTKWriter::writePointData(std::ostream& os, bool isPHeader) const
00292 {
00293 std::string PHeader = "";
00294 if (isPHeader) PHeader="P";
00295
00296 XMLObject xml(PHeader + "PointData");
00297
00298 if (pointVectorNames().length() > 0) xml.addAttribute("Vectors", pointVectorNames()[0]);
00299 if (pointScalarNames().length() > 0) xml.addAttribute("Scalars", pointScalarNames()[0]);
00300
00301 os << xml.header() << std::endl;
00302
00303 for (int i=0; i<pointScalarNames().length(); i++)
00304 {
00305 writeDataArray(os, pointScalarNames()[i], pointScalarFields()[i], isPHeader, true);
00306 }
00307
00308 for (int i=0; i<pointVectorNames().length(); i++)
00309 {
00310 writeDataArray(os, pointVectorNames()[i], pointVectorFields()[i], isPHeader, true);
00311 }
00312
00313 os << xml.footer() << std::endl;
00314 }
00315
00316 void VTKWriter::writeCellData(std::ostream& os, bool isPHeader) const
00317 {
00318 std::string PHeader = "";
00319 if (isPHeader) PHeader="P";
00320
00321 XMLObject xml(PHeader + "CellData");
00322
00323 if (cellVectorNames().length() > 0) xml.addAttribute("Vectors", cellVectorNames()[0]);
00324 if (cellScalarNames().length() > 0) xml.addAttribute("Scalars", cellScalarNames()[0]);
00325
00326 os << xml.header() << std::endl;
00327
00328 for (int i=0; i<cellScalarNames().length(); i++)
00329 {
00330 writeDataArray(os, cellScalarNames()[i], cellScalarFields()[i], isPHeader, false);
00331 }
00332
00333
00334 for (int i=0; i<cellVectorNames().length(); i++)
00335 {
00336 writeDataArray(os, cellVectorNames()[i], cellVectorFields()[i], isPHeader, false);
00337 }
00338
00339 os << xml.footer() << std::endl;
00340 }
00341
00342
00343 void VTKWriter::writeDataArray(std::ostream& os, const std::string& name,
00344 const RCP<FieldBase>& expr, bool isPHeader, bool isPointData) const
00345 {
00346 std::string PHeader = "";
00347 if (isPHeader) PHeader="P";
00348
00349 XMLObject xml(PHeader + "DataArray");
00350 xml.addAttribute("type", "Float32");
00351 xml.addAttribute("Name", name);
00352 xml.addAttribute("format", "ascii");
00353
00354 if (expr->numElems() > 1)
00355 {
00356
00357 xml.addAttribute("NumberOfComponents", "3" );
00358 }
00359
00360 os << xml.header() << std::endl;
00361
00362
00363 if (!isPHeader)
00364 {
00365
00366 if (isPointData)
00367 {
00368 int numNodes = mesh().numCells(0);
00369
00370 for (int i=0; i<numNodes; i++)
00371 {
00372 for (int j=0; j < expr->numElems(); j++)
00373 {
00374 if (expr->isDefined(0,i,j)){
00375 double val = expr->getData(0, i, j);
00376 val = (fabs(val) > 1e-16) ? val : 0.0;
00377 os << (float) val << std::endl;
00378 }else
00379 os << undefinedValue() << std::endl;
00380 }
00381
00382 if (expr->numElems() > 1)
00383 for (int j= expr->numElems(); j < 3 ; j++)
00384 os << "0.0 " << std::endl;
00385 }
00386 }
00387 else
00388 {
00389 int dim = mesh().spatialDim();
00390 int nc = mesh().numCells(dim);
00391
00392 for (int c=0; c<nc; c++)
00393 {
00394 for (int j=0; j < expr->numElems(); j++)
00395 {
00396 if (expr->isDefined(dim,c,j)){
00397 double val = expr->getData(dim, c, j);
00398 val = (fabs(val) > 1e-16) ? val : 0.0;
00399 os << (float) val << std::endl;
00400 }else
00401 os << undefinedValue() << std::endl;
00402 }
00403
00404 if (expr->numElems() > 1)
00405 for (int j= expr->numElems(); j < 3 ; j++)
00406 os << "0.0 " << std::endl;
00407 }
00408 }
00409 }
00410
00411 os << xml.footer() << std::endl;
00412 }
00413