1 #include <fstream>
2 
3 namespace Dune {
4 namespace GridGlue {
5 
6 namespace ProjectionWriterImplementation {
7 
8 template<unsigned side, typename Coordinate, typename Corners>
write_points(const Projection<Coordinate> & projection,const Corners & corners,std::ostream & out)9 void write_points(const Projection<Coordinate>& projection, const Corners& corners, std::ostream& out)
10 {
11   using namespace ProjectionImplementation;
12   using std::get;
13   const unsigned other_side = 1 - side;
14 
15   for (const auto& c : get<side>(corners))
16     out << c << "\n";
17 
18   for (const auto& i : get<side>(projection.images())) {
19     const auto global = interpolate(i, get<other_side>(corners));
20     out << global << "\n";
21   }
22 }
23 
24 template<unsigned side, typename Coordinate, typename Normals>
write_normals(const Projection<Coordinate> & projection,const Normals & normals,std::ostream & out)25 void write_normals(const Projection<Coordinate>& projection, const Normals& normals, std::ostream& out)
26 {
27   using namespace ProjectionImplementation;
28   using std::get;
29   const unsigned other_side = 1 - side;
30 
31   for (const auto& n : get<side>(normals))
32     out << n << "\n";
33 
34   for (const auto& x : get<side>(projection.images())) {
35     const auto n = interpolate_unit_normals(x, get<other_side>(normals));
36     out << n << "\n";
37   }
38 }
39 
40 template<typename Coordinate, typename Corners>
write_edge_intersection_points(const Projection<Coordinate> & projection,const Corners & corners,std::ostream & out)41 void write_edge_intersection_points(const Projection<Coordinate>& projection, const Corners& corners, std::ostream& out)
42 {
43   using namespace ProjectionImplementation;
44   using std::get;
45 
46   for (std::size_t i = 0; i < projection.numberOfEdgeIntersections(); ++i) {
47     const auto& local = projection.edgeIntersections()[i].local;
48     out << interpolate(local[0], get<0>(corners)) << "\n"
49         << interpolate(local[1], get<1>(corners)) << "\n";
50   }
51 }
52 
53 template<typename Coordinate, typename Normals>
write_edge_intersection_normals(const Projection<Coordinate> & projection,const Normals & normals,std::ostream & out)54 void write_edge_intersection_normals(const Projection<Coordinate>& projection, const Normals& normals, std::ostream& out)
55 {
56   using namespace ProjectionImplementation;
57   using std::get;
58 
59   for (std::size_t i = 0; i < projection.numberOfEdgeIntersections(); ++i) {
60     const auto& local = projection.edgeIntersections()[i].local;
61     const auto n0 = interpolate_unit_normals(local[0], get<0>(normals));
62     const auto n1 = interpolate_unit_normals(local[1], get<1>(normals));
63 
64     out << n0 << "\n"
65         << n1 << "\n";
66   }
67 }
68 
69 template<unsigned side, typename Coordinate>
write_success(const Projection<Coordinate> & projection,std::ostream & out)70 void write_success(const Projection<Coordinate>& projection, std::ostream& out)
71 {
72   using std::get;
73 
74   out << side << "\n";
75 
76   const auto& success = get<side>(projection.success());
77   for (std::size_t i = 0; i < success.size(); ++i)
78     out << (success[i] ? "1\n" : "0\n");
79 }
80 
81 } /* namespace ProjectionWriterImplementation */
82 
83 template<typename Coordinate, typename Corners, typename Normals>
write(const Projection<Coordinate> & projection,const Corners & corners,const Normals & normals,std::ostream & out)84 void write(const Projection<Coordinate>& projection,
85            const Corners& corners,
86            const Normals& normals,
87            std::ostream& out)
88 {
89   using namespace ProjectionWriterImplementation;
90 
91   const auto numberOfEdgeIntersections = projection.numberOfEdgeIntersections();
92   const auto nPoints = 12 + 2 * numberOfEdgeIntersections;
93 
94   out << "# vtk DataFile Version2.0\n"
95       << "Filename: projection\n"
96       << "ASCII\n"
97       << "DATASET UNSTRUCTURED_GRID\n"
98       << "POINTS " << nPoints << " double\n";
99   write_points<0>(projection, corners, out);
100   write_points<1>(projection, corners, out);
101   write_edge_intersection_points(projection, corners, out);
102   out << "CELLS " << (8 + numberOfEdgeIntersections) << " " << (26 + 3 * numberOfEdgeIntersections) << "\n";
103   out << "3 0 1 2\n" "2 0 3\n" "2 1 4\n" "2 2 5\n"
104       << "3 6 7 8\n" "2 6 9\n" "2 7 10\n" "2 8 11\n";
105   for (std::size_t i = 0; i < numberOfEdgeIntersections; ++i)
106     out << "2 " << (12 + 2*i) << " " << (12 + 2*i + 1) << "\n";
107   out << "CELL_TYPES " << (8 + numberOfEdgeIntersections) << "\n" "5\n3\n3\n3\n" "5\n3\n3\n3\n";
108   for (std::size_t i = 0; i < numberOfEdgeIntersections; ++i)
109     out << "3\n";
110   out << "CELL_DATA " << (8 + numberOfEdgeIntersections) << "\n";
111   out << "SCALARS success int 1\n"
112       << "LOOKUP_TABLE success\n";
113   write_success<0>(projection, out);
114   write_success<1>(projection, out);
115   for (std::size_t i = 0; i < numberOfEdgeIntersections; ++i)
116     out << "2\n";
117   out << "LOOKUP_TABLE success 2\n"
118       << "1.0 0.0 0.0 1.0\n"
119       << "0.0 1.0 0.0 1.0\n";
120   out << "POINT_DATA " << nPoints << "\n"
121       << "NORMALS normals double\n";
122   write_normals<0>(projection, normals, out);
123   write_normals<1>(projection, normals, out);
124   write_edge_intersection_normals(projection, normals, out);
125 }
126 
127 template<typename Coordinate, typename Corners, typename Normals>
write(const Projection<Coordinate> & projection,const Corners & corners,const Normals & normals,const std::string & filename)128 void write(const Projection<Coordinate>& projection,
129            const Corners& corners,
130            const Normals& normals,
131            const std::string& filename)
132 {
133   std::ofstream out(filename.c_str());
134   write(projection, corners, normals, out);
135 }
136 
137 template<typename Coordinate, typename Corners, typename Normals>
print(const Projection<Coordinate> & projection,const Corners & corners,const Normals & normals)138 void print(const Projection<Coordinate>& projection,
139            const Corners& corners,
140            const Normals& normals)
141 {
142   using namespace ProjectionWriterImplementation;
143 
144   std::cout << "Side 0 corners and images:\n";
145   write_points<0>(projection, corners, std::cout);
146   std::cout << "Side 0 success:\n";
147   write_success<0>(projection, std::cout);
148   std::cout << "Side 1 corners and images:\n";
149   write_points<1>(projection, corners, std::cout);
150   std::cout << "Side 1 success:\n";
151   write_success<1>(projection, std::cout);
152   std::cout << "Side 0 normals and projected normals:\n";
153   write_normals<0>(projection, normals, std::cout);
154   std::cout << "Side 1 normals and projected normals:\n";
155   write_normals<1>(projection, normals, std::cout);
156   std::cout << projection.numberOfEdgeIntersections() << " edge intersections:\n";
157   write_edge_intersection_points(projection, corners, std::cout);
158 }
159 
160 } /* namespace GridGlue */
161 } /* namespace Dune */
162