#ifndef _SURFACE_HPP_ #define _SURFACE_HPP_ #include namespace biest { enum class SurfType { AxisymCircleWide, // 125 x 50 AxisymCircleNarrow, // 250 x 50 AxisymWide, // 125 x 50 AxisymNarrow, // 250 x 50 RotatingEllipseWide, // 125 x 50 RotatingEllipseNarrow, // 250 x 50 Quas3, // 250 x 50 LHD, // 250 x 50 W7X, // 250 x 45 Stell, // 250 x 50 W7X_ // 250 x 50 }; template class Surface { static constexpr sctl::Integer COORD_DIM = 3; public: Surface() : Nt0(0), Np0(0) {} Surface(sctl::Long Nt, sctl::Long Np, SurfType type = SurfType::AxisymCircleWide); sctl::Long NTor() const {return Nt0;} sctl::Long NPol() const {return Np0;} sctl::Vector& Coord() {return X0_;} const sctl::Vector& Coord() const {return X0_;} Real& Coord(sctl::Long i, sctl::Long j, sctl::Long k) {return X0_[(k*Nt0+i)*Np0+j];} const Real& Coord(sctl::Long i, sctl::Long j, sctl::Long k) const {return X0_[(k*Nt0+i)*Np0+j];} private: sctl::Long Nt0, Np0; sctl::Vector X0_; }; struct VTKData { typedef double VTKReal; static constexpr sctl::Integer COORD_DIM = 3; std::vector point_coord; std::vector point_value; std::vector line_connect; std::vector line_offset; std::vector poly_connect; std::vector poly_offset; void WriteVTK(const char* fname, const sctl::Comm& comm = sctl::Comm::Self()) { sctl::Integer np = comm.Size(); sctl::Integer myrank = comm.Rank(); std::vector& coord=this->point_coord; std::vector& value=this->point_value; std::vector& line_connect=this->line_connect; std::vector& line_offset=this->line_offset; std::vector& poly_connect=this->poly_connect; std::vector& poly_offset=this->poly_offset; sctl::Long pt_cnt=coord.size()/COORD_DIM; sctl::Long line_cnt=line_offset.size(); sctl::Long poly_cnt=poly_offset.size(); // Open file for writing. std::stringstream vtufname; vtufname<\n"; if(isLittleEndian) vtufile<<"\n"; else vtufile<<"\n"; //=========================================================================== vtufile<<" \n"; vtufile<<" \n"; //--------------------------------------------------------------------------- vtufile<<" \n"; vtufile<<" \n"; data_size+=sizeof(uint32_t)+coord.size()*sizeof(VTKReal); vtufile<<" \n"; //--------------------------------------------------------------------------- if(value.size()){ // value vtufile<<" \n"; vtufile<<" \n"; data_size+=sizeof(uint32_t)+value.size()*sizeof(VTKReal); vtufile<<" \n"; } //--------------------------------------------------------------------------- vtufile<<" \n"; vtufile<<" \n"; data_size+=sizeof(uint32_t)+line_connect.size()*sizeof(int32_t); vtufile<<" \n"; data_size+=sizeof(uint32_t)+line_offset.size() *sizeof(int32_t); vtufile<<" \n"; //--------------------------------------------------------------------------- vtufile<<" \n"; vtufile<<" \n"; data_size+=sizeof(uint32_t)+poly_connect.size()*sizeof(int32_t); vtufile<<" \n"; data_size+=sizeof(uint32_t)+poly_offset.size() *sizeof(int32_t); vtufile<<" \n"; //--------------------------------------------------------------------------- vtufile<<" \n"; vtufile<<" \n"; //=========================================================================== vtufile<<" \n"; vtufile<<" _"; int32_t block_size; block_size=coord.size()*sizeof(VTKReal); vtufile.write((char*)&block_size, sizeof(int32_t)); vtufile.write((char*)&coord [0], coord.size()*sizeof(VTKReal)); if(value.size()){ // value block_size=value.size()*sizeof(VTKReal); vtufile.write((char*)&block_size, sizeof(int32_t)); vtufile.write((char*)&value [0], value.size()*sizeof(VTKReal)); } block_size=line_connect.size()*sizeof(int32_t); vtufile.write((char*)&block_size, sizeof(int32_t)); vtufile.write((char*)&line_connect[0], line_connect.size()*sizeof(int32_t)); block_size=line_offset .size()*sizeof(int32_t); vtufile.write((char*)&block_size, sizeof(int32_t)); vtufile.write((char*)&line_offset [0], line_offset .size()*sizeof(int32_t)); block_size=poly_connect.size()*sizeof(int32_t); vtufile.write((char*)&block_size, sizeof(int32_t)); vtufile.write((char*)&poly_connect[0], poly_connect.size()*sizeof(int32_t)); block_size=poly_offset .size()*sizeof(int32_t); vtufile.write((char*)&block_size, sizeof(int32_t)); vtufile.write((char*)&poly_offset [0], poly_offset .size()*sizeof(int32_t)); vtufile<<"\n"; vtufile<<" \n"; //=========================================================================== vtufile<<"\n"; vtufile.close(); if(myrank) return; std::stringstream pvtufname; pvtufname<\n"; pvtufile<<"\n"; pvtufile<<" \n"; pvtufile<<" \n"; pvtufile<<" \n"; pvtufile<<" \n"; if(value.size()){ // value pvtufile<<" \n"; pvtufile<<" \n"; pvtufile<<" \n"; } { // Extract filename from path. std::stringstream vtupath; vtupath<<'/'<\n"; } pvtufile<<" \n"; pvtufile<<"\n"; pvtufile.close(); } }; struct VTUData { typedef float VTKReal; // Point data sctl::Vector coord; // always 3D sctl::Vector value; // Cell data sctl::Vector connect; sctl::Vector offset; sctl::Vector types; void WriteVTK(const std::string& fname, const sctl::Comm& comm = sctl::Comm::Self()) const { typedef typename VTUData::VTKReal VTKReal; sctl::Long value_dof = 0; { // Write vtu file. std::ofstream vtufile; { // Open file for writing. std::stringstream vtufname; vtufname << fname << std::setfill('0') << std::setw(6) << comm.Rank() << ".vtu"; vtufile.open(vtufname.str().c_str()); if (vtufile.fail()) return; } { // Write to file. sctl::Long pt_cnt = coord.Dim() / 3; sctl::Long cell_cnt = types.Dim(); value_dof = (pt_cnt ? value.Dim() / pt_cnt : 0); sctl::Vector mpi_rank; { // Set mpi_rank sctl::Integer new_myrank = comm.Rank(); mpi_rank.ReInit(pt_cnt); for (sctl::Long i = 0; i < mpi_rank.Dim(); i++) mpi_rank[i] = new_myrank; } bool isLittleEndian; { // Set isLittleEndian uint16_t number = 0x1; uint8_t *numPtr = (uint8_t *)&number; isLittleEndian = (numPtr[0] == 1); } sctl::Long data_size = 0; vtufile << "\n"; vtufile << "\n"; // =========================================================================== vtufile << " \n"; vtufile << " \n"; //--------------------------------------------------------------------------- vtufile << " \n"; vtufile << " \n"; data_size += sizeof(uint32_t) + coord.Dim() * sizeof(VTKReal); vtufile << " \n"; //--------------------------------------------------------------------------- vtufile << " \n"; if (value_dof) { // value vtufile << " \n"; data_size += sizeof(uint32_t) + value.Dim() * sizeof(VTKReal); } { // mpi_rank vtufile << " \n"; data_size += sizeof(uint32_t) + pt_cnt * sizeof(int32_t); } vtufile << " \n"; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- vtufile << " \n"; vtufile << " \n"; data_size += sizeof(uint32_t) + connect.Dim() * sizeof(int32_t); vtufile << " \n"; data_size += sizeof(uint32_t) + offset.Dim() * sizeof(int32_t); vtufile << " \n"; data_size += sizeof(uint32_t) + types.Dim() * sizeof(uint8_t); vtufile << " \n"; //--------------------------------------------------------------------------- vtufile << " \n"; vtufile << " \n"; // =========================================================================== vtufile << " \n"; vtufile << " _"; int32_t block_size; { // coord block_size = coord.Dim() * sizeof(VTKReal); vtufile.write((char *)&block_size, sizeof(int32_t)); if (coord.Dim()) vtufile.write((char *)&coord[0], coord.Dim() * sizeof(VTKReal)); } if (value_dof) { // value block_size = value.Dim() * sizeof(VTKReal); vtufile.write((char *)&block_size, sizeof(int32_t)); if (value.Dim()) vtufile.write((char *)&value[0], value.Dim() * sizeof(VTKReal)); } { // mpi_rank block_size = mpi_rank.Dim() * sizeof(int32_t); vtufile.write((char *)&block_size, sizeof(int32_t)); if (mpi_rank.Dim()) vtufile.write((char *)&mpi_rank[0], mpi_rank.Dim() * sizeof(int32_t)); } { // block_size block_size = connect.Dim() * sizeof(int32_t); vtufile.write((char *)&block_size, sizeof(int32_t)); if (connect.Dim()) vtufile.write((char *)&connect[0], connect.Dim() * sizeof(int32_t)); } { // offset block_size = offset.Dim() * sizeof(int32_t); vtufile.write((char *)&block_size, sizeof(int32_t)); if (offset.Dim()) vtufile.write((char *)&offset[0], offset.Dim() * sizeof(int32_t)); } { // types block_size = types.Dim() * sizeof(uint8_t); vtufile.write((char *)&block_size, sizeof(int32_t)); if (types.Dim()) vtufile.write((char *)&types[0], types.Dim() * sizeof(uint8_t)); } vtufile << "\n"; vtufile << " \n"; // =========================================================================== vtufile << "\n"; } vtufile.close(); // close file } if (!comm.Rank()) { // Write pvtu file std::ofstream pvtufile; { // Open file for writing std::stringstream pvtufname; pvtufname << fname << ".pvtu"; pvtufile.open(pvtufname.str().c_str()); if (pvtufile.fail()) return; } { // Write to file. pvtufile << "\n"; pvtufile << "\n"; pvtufile << " \n"; pvtufile << " \n"; pvtufile << " \n"; pvtufile << " \n"; pvtufile << " \n"; if (value_dof) { // value pvtufile << " \n"; } { // mpi_rank pvtufile << " \n"; } pvtufile << " \n"; { // Extract filename from path. std::stringstream vtupath; vtupath << '/' << fname; std::string pathname = vtupath.str(); std::string fname_ = pathname.substr(pathname.find_last_of("/\\") + 1); // char *fname_ = (char*)strrchr(vtupath.str().c_str(), '/') + 1; // std::string fname_ = // boost::filesystem::path(fname).filename().string(). for (sctl::Integer i = 0; i < comm.Size(); i++) pvtufile << " \n"; } pvtufile << " \n"; pvtufile << "\n"; } pvtufile.close(); // close file } }; }; template void WriteVTK(const char* fname, const sctl::Vector>& Svec, const sctl::Vector F = sctl::Vector(), const sctl::Comm& comm = sctl::Comm::Self()) { VTKData data; typedef VTKData::VTKReal VTKReal; auto& point_coord =data.point_coord ; auto& point_value =data.point_value ; auto& poly_connect=data.poly_connect; auto& poly_offset =data.poly_offset ; constexpr sctl::Integer COORD_DIM = VTKData::COORD_DIM; sctl::Long dof, offset = 0; { // Set dof sctl::Long Npt = 0; for (const auto& S : Svec) Npt += S.NTor() * S.NPol(); dof = F.Dim() / Npt; SCTL_ASSERT(F.Dim() == dof * Npt); } for (auto& S: Svec) { // Set point_coord, point_value, poly_connect sctl::Long Nt = S.NTor(); sctl::Long Np = S.NPol(); sctl::Long N = Nt * Np; for (sctl::Long i = 0; i < Nt; i++) { for (sctl::Long j = 0; j < Np; j++) { sctl::Long i0 = (i + 0) % Nt; sctl::Long i1 = (i + 1) % Nt; sctl::Long j0 = (j + 0) % Np; sctl::Long j1 = (j + 1) % Np; poly_connect.push_back(point_coord.size() / COORD_DIM + Np*i0+j0); poly_connect.push_back(point_coord.size() / COORD_DIM + Np*i1+j0); poly_connect.push_back(point_coord.size() / COORD_DIM + Np*i1+j1); poly_connect.push_back(point_coord.size() / COORD_DIM + Np*i0+j1); poly_offset.push_back(poly_connect.size()); } } const auto X = S.Coord(); SCTL_ASSERT(X.Dim() == COORD_DIM * N); for (sctl::Long i = 0; i < N; i++){ // Set point_coord for (sctl::Integer k = 0; k < COORD_DIM; k++) point_coord.push_back((VTKReal)X[k * N + i]); } for (sctl::Long i = 0; i < N; i++){ // Set point_value for (sctl::Long k = 0; k < dof; k++) point_value.push_back((VTKReal)F[dof * offset + k * N + i]); } offset += N; } data.WriteVTK(fname, comm); } template void WriteVTK(const char* fname, const Surface& S, const sctl::Vector F = sctl::Vector(), const sctl::Comm& comm = sctl::Comm::Self()) { WriteVTK(fname, sctl::Vector>(1,sctl::Ptr2Itr>((Surface*)&S,1),false), F, comm); } } #include #endif //_SURFACE_HPP_