00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <WriterMedit.hpp>
00021 #include <Mesh.hpp>
00022
00023 #include <Structured3DMesh.hpp>
00024 #include <SpectralMesh.hpp>
00025 #include <MeshOfHexahedra.hpp>
00026 #include <MeshOfTetrahedra.hpp>
00027
00028 #include <OctreeMesh.hpp>
00029
00030 #include <SurfaceMeshOfTriangles.hpp>
00031 #include <SurfaceMeshOfQuadrangles.hpp>
00032 #include <MeshOfTriangles.hpp>
00033
00034 #include <fstream>
00035
00036 #include <ScalarFunctionBase.hpp>
00037 #include <FieldOfScalarFunction.hpp>
00038
00039 #include <FEMFunction.hpp>
00040
00041 void WriterMedit::
00042 __fillCrossedComponent(const FieldOfScalarFunction& field,
00043 Vector<real_t>& values) const
00044 {
00045 const size_t numberOfComponents = field.numberOfComponents();
00046 ASSERT(values.size() == __mesh->numberOfVertices()*numberOfComponents);
00047
00048 for (size_t i = 0; i<numberOfComponents; ++i) {
00049 const ScalarFunctionBase& function = *field.function(i);
00050
00051 switch (function.type()) {
00052 case ScalarFunctionBase::femfunction: {
00053 const FEMFunctionBase& fem
00054 = static_cast<const FEMFunctionBase&>(function);
00055 if ((fem.baseMesh() == __mesh) and
00056 ((fem.discretizationType() == ScalarDiscretizationTypeBase::lagrangianFEM1))) {
00057 for (size_t j=0; j<fem.values().size(); ++j) {
00058 values[numberOfComponents*j+i] = fem[j];
00059 }
00060 break;
00061 }
00062 }
00063 default: {
00064 for (size_t j=0; j<__mesh->numberOfVertices(); ++j) {
00065 const TinyVector<3,real_t>& X = __mesh->vertex(j);
00066 values[numberOfComponents*j+i] = function(X);
00067 }
00068 }
00069 }
00070 }
00071 }
00072
00073
00074 void WriterMedit::
00075 __proceedData() const
00076 {
00077 std::string filename = __filename;
00078 filename += ".bb";
00079 std::ofstream file(filename.c_str());
00080 if (not(file)) {
00081 throw ErrorHandler(__FILE__,__LINE__,
00082 "cannot open file '"+stringify(filename)+"'",
00083 ErrorHandler::normal);
00084 }
00085
00086 if (__fieldList.size() + __scalarFunctionList.size() > 1) {
00087 throw ErrorHandler(__FILE__,__LINE__,
00088 "writing file '"+stringify(__filename.c_str())+
00089 "': cannot save more than one field or function in Medit format!",
00090 ErrorHandler::normal);
00091 }
00092
00093 if (__scalarFunctionList.size()>0) {
00094 file << "3 1 " << __mesh->numberOfVertices() << " 2" << __CR;
00095
00096 const ScalarFunctionBase& f = *__scalarFunctionList[0];
00097
00098 switch (f.type()) {
00099 case ScalarFunctionBase::femfunction: {
00100 const FEMFunctionBase& fem = static_cast<const FEMFunctionBase&>(f);
00101 if ((fem.baseMesh() == __mesh) and
00102 (fem.discretizationType() == ScalarDiscretizationTypeBase::lagrangianFEM1)) {
00103 for (size_t i=0; i<fem.values().size(); ++i) {
00104 file << fem[i] << __CR;
00105 }
00106 break;
00107 }
00108 }
00109 default: {
00110 for (size_t i=0; i<__mesh->numberOfVertices(); ++i) {
00111 const TinyVector<3,real_t>& X = __mesh->vertex(i);
00112 file << f(X) << __CR;
00113 }
00114 }
00115 }
00116 }
00117
00118 if (__fieldList.size() > 0) {
00119 const FieldOfScalarFunction& field = *__fieldList[0];
00120 file << "3 " << field.numberOfComponents() << " " << __mesh->numberOfVertices() << " 2" << __CR;
00121
00122 Vector<real_t> values(3*__mesh->numberOfVertices());
00123
00124 this->__fillCrossedComponent(field, values);
00125
00126 for (size_t i=0; i<values.size(); ++i) {
00127 file << values[i] << __CR;
00128 }
00129 }
00130 }
00131
00132 template <typename MeshType>
00133 void WriterMedit::
00134 __saveElements(std::ostream& os,
00135 const MeshType& mesh) const
00136 {
00137 typedef typename MeshType::CellType CellType;
00138
00139 os << mesh.numberOfCells() << __CR;
00140
00141 for (size_t i = 0; i<mesh.numberOfCells(); ++i) {
00142 const CellType& c = mesh.cell(i);
00143
00144 for (size_t j=0; j<CellType::NumberOfVertices; ++j) {
00145 os << mesh.vertexNumber(c(j))+1 << ' ';
00146 }
00147
00148 os << c.reference() << __CR;
00149 }
00150 }
00151
00152 void WriterMedit::
00153 __proceedMesh() const
00154 {
00155 std::string filename = __filename;
00156 filename += ".mesh";
00157 std::ofstream file(filename.c_str());
00158 if (not(file)) {
00159 throw ErrorHandler(__FILE__,__LINE__,
00160 "cannot open file '"+stringify(filename)+"'",
00161 ErrorHandler::normal);
00162 }
00163
00164 file << "MeshVersionFormatted 1" << __CR;
00165 file << "Dimension" << __CR;
00166 file << 3 << __CR;
00167
00168 file << "Vertices " << __mesh->numberOfVertices() << __CR;
00169
00170 for (size_t i=0; i<__mesh->numberOfVertices(); ++i) {
00171 const TinyVector<3>& X = __mesh->vertex(i);
00172 file << X[0] << ' ' << X[1] << ' ' << X[2]
00173 << ' ' << __mesh->vertex(i).reference() << __CR;
00174 }
00175
00176 switch (__mesh->type()) {
00177 case Mesh::cartesianHexahedraMesh: {
00178 const Structured3DMesh& mesh = dynamic_cast<const Structured3DMesh&>(*__mesh);
00179 file << "Hexahedra ";
00180 this->__saveElements(file, mesh);
00181 if (mesh.hasBorderMesh()) {
00182 file << "Quadrilaterals ";
00183 this->__saveElements(file, *mesh.borderMesh());
00184 }
00185 break;
00186 }
00187 case Mesh::octreeMesh: {
00188 const OctreeMesh& mesh = dynamic_cast<const OctreeMesh&>(*__mesh);
00189 file << "Hexahedra ";
00190 this->__saveElements(file, mesh);
00191 if (mesh.hasBorderMesh()) {
00192 file << "Quadrilaterals ";
00193 this->__saveElements(file, *mesh.borderMesh());
00194 }
00195 break;
00196 }
00197 case Mesh::spectralMesh: {
00198 const SpectralMesh& mesh = dynamic_cast<const SpectralMesh&>(*__mesh);
00199 file << "Hexahedra ";
00200 this->__saveElements(file, mesh);
00201 if (mesh.hasBorderMesh()) {
00202 file << "Quadrilaterals ";
00203 this->__saveElements(file, *mesh.borderMesh());
00204 }
00205 break;
00206 }
00207 case Mesh::hexahedraMesh: {
00208 const MeshOfHexahedra& mesh = dynamic_cast<const MeshOfHexahedra&>(*__mesh);
00209 file << "Hexahedra ";
00210 this->__saveElements(file, mesh);
00211 if (mesh.hasBorderMesh()) {
00212 file << "Quadrilaterals ";
00213 this->__saveElements(file, *mesh.borderMesh());
00214 }
00215 break;
00216 }
00217 case Mesh::tetrahedraMesh: {
00218 const MeshOfTetrahedra& mesh = dynamic_cast<const MeshOfTetrahedra&>(*__mesh);
00219 file << "Tetrahedra ";
00220 this->__saveElements(file, mesh);
00221 if (mesh.hasBorderMesh()) {
00222 file << "Triangles ";
00223 this->__saveElements<SurfaceMeshOfTriangles>(file, *mesh.borderMesh());
00224 }
00225 break;
00226 }
00227 case Mesh::trianglesMesh: {
00228 const MeshOfTriangles& mesh = dynamic_cast<const MeshOfTriangles&>(*__mesh);
00229 file << "Triangles ";
00230 this->__saveElements(file, mesh);
00231 break;
00232 }
00233 case Mesh::surfaceMeshTriangles: {
00234 const SurfaceMeshOfTriangles& mesh = dynamic_cast<const SurfaceMeshOfTriangles&>(*__mesh);
00235 file << "Triangles ";
00236 this->__saveElements(file, mesh);
00237 break;
00238 }
00239 case Mesh::surfaceMeshQuadrangles: {
00240 const SurfaceMeshOfQuadrangles& mesh = dynamic_cast<const SurfaceMeshOfQuadrangles&>(*__mesh);
00241 file << "Quadrilaterals ";
00242 this->__saveElements(file, mesh);
00243 break;
00244 }
00245 default: {
00246 throw ErrorHandler(__FILE__,__LINE__,
00247 "unexpected mesh type",
00248 ErrorHandler::unexpected);
00249 }
00250 }
00251
00252 file << "End" << __CR;
00253 }
00254
00255 void WriterMedit::
00256 proceed() const
00257 {
00258 if (__fieldList.size() + __scalarFunctionList.size() == 0) {
00259 this->__proceedMesh();
00260 } else {
00261 this->__proceedData();
00262 }
00263 }
00264
00265
00266 WriterMedit::
00267 WriterMedit(ConstReferenceCounting<Mesh> mesh,
00268 const std::string& filename,
00269 const FileDescriptor& fileDescriptor)
00270 : WriterBase(mesh,
00271 filename,
00272 fileDescriptor)
00273 {
00274 ;
00275 }
00276
00277 WriterMedit::
00278 ~WriterMedit()
00279 {
00280 ;
00281 }