Bembel
GeometryIO.hpp
1 // This file is part of Bembel, the higher order C++ boundary element library.
2 //
3 // Copyright (C) 2024 see <http://www.bembel.eu>
4 //
5 // It was written as part of a cooperation of J. Doelz, H. Harbrecht, S. Kurz,
6 // M. Multerer, S. Schoeps, and F. Wolf at Technische Universitaet Darmstadt,
7 // Universitaet Basel, and Universita della Svizzera italiana, Lugano. This
8 // source code is subject to the GNU General Public License version 3 and
9 // provided WITHOUT ANY WARRANTY, see <http://www.bembel.eu> for further
10 // information.
11 
12 #ifndef BEMBEL_SRC_GEOMETRY_GEOMETRYIO_HPP_
13 #define BEMBEL_SRC_GEOMETRY_GEOMETRYIO_HPP_
14 
15 namespace Bembel {
16 
25 inline std::vector<Patch> LoadGeometryFileDAT(
26  const std::string &file_name) noexcept {
27  std::vector<Bembel::Patch> out;
28  std::stringstream iss;
29  std::string word;
30  std::string row;
31  int infoInt[5];
32  std::ifstream file;
33  file.open(file_name);
34  if (!file) {
35  std::cerr << "File " << file_name << " doesn't exist!";
36  exit(1);
37  }
38  // first 4 rows are irrelevant
39  for (int i = 0; i < 5; i++) {
40  getline(file, row);
41  }
42  // main information
43  iss.str(row);
44  for (int i = 0; i < 5; i++) {
45  iss >> word;
46 
47  infoInt[i] = stoi(word);
48  }
49  // main loop - patches
50  for (int patchNr = 1; patchNr <= infoInt[2]; patchNr++) {
51  Bembel::Patch tempPatch;
52  std::vector<double> tempknt1;
53  std::vector<double> tempknt2;
54  std::vector<int> info; // p and ncp / 0,1-p 2,3-ncp
55  std::vector<Eigen::MatrixXd> tmp;
56 
57  getline(file, row); // file_name
58 
59  getline(file, row);
60  iss.str(row);
61  while (iss >> word) {
62  info.push_back(stoi(word));
63  }
64  getline(file, row);
65 
66  word = "";
67  iss.clear();
68  iss.str(row);
69  while (iss >> word) {
70  info.push_back(stoi(word));
71  }
72 
73  word = "";
74  iss.clear();
75 
76  // In textfiles are only 2 knotVectors and 4 Matrices
77 
78  getline(file, row);
79  iss.str(row);
80 
81  // first knotVector
82 
83  for (int k = 0; k < info[0] + info[2] + 1; k++) {
84  iss >> word;
85  tempknt1.push_back(atof(word.c_str()));
86  }
87  iss.clear();
88  getline(file, row);
89  iss.str(row);
90  word = "";
91  // second knotVector
92  for (int k = 0; k < info[1] + info[3] + 1; k++) {
93  iss >> word;
94  tempknt2.push_back(atof(word.c_str()));
95  }
96  iss.clear();
97  // 4 Matrices
98  int N = info[2];
99  int M = info[3];
100  for (int k = 0; k < 4; k++) {
101  Eigen::Matrix<double, -1, -1> tempMatrix(
102  M, N); // == Eigen::MatrixXd tempMatrix(M,N);
103  getline(file, row);
104  iss.str(row);
105  for (int i = 0; i < M; i++)
106  for (int j = 0; j < N; j++) {
107  iss >> word;
108 
109  tempMatrix(i, j) = atof(word.c_str());
110  }
111 
112  tmp.push_back(tempMatrix);
113  iss.clear();
114  }
115  // Important
116  tempPatch.init_Patch(tmp, tempknt1, tempknt2);
117  out.push_back(tempPatch);
118  }
119 
120  file.close();
121  return out;
122 }
123 
130 inline void MakeFile(const std::string &file_name,
131  int number_of_patches) noexcept {
132  std::ofstream file;
133  file.open(file_name);
134  file << "# nurbs mesh v.2.1"
135  << "\r\n";
136  file << "# " << file_name << "\r\n";
137  file << "# Generated by BEMBEL, see www.bembel.eu"
138  << "\r\n";
139  file << "#"
140  << "\r\n";
141  file << "2 3 " << number_of_patches << " 0 0 "
142  << "\r\n";
143  file.close();
144 }
154 void WritePatch(const std::string &file_name, int current_patch_number,
155  const std::vector<Eigen::MatrixXd> &xyzw,
156  const std::vector<double> &knt1,
157  const std::vector<double> &knt2) noexcept {
158  std::ofstream file(file_name, std::ios::app);
159  int N = xyzw[0].cols(); // ncp
160  int M = xyzw[0].rows(); // ncp
161  int p1 = knt1.size() - N - 1;
162  int p2 = knt2.size() - M - 1;
163  file << "PATCH " << current_patch_number << " \r\n";
164  file << p1 << " " << p2 << " \r\n";
165  file << N << " " << M << " \r\n";
166  // knotVectors
167  for (unsigned int i = 0; i < knt1.size() - 1; i++) {
168  file << std::fixed << std::setprecision(15) << knt1[i] << " ";
169  }
170  file << std::fixed << std::setprecision(15) << knt1[knt1.size() - 1]
171  << " \r\n";
172  for (unsigned int i = 0; i < knt2.size() - 1; i++) {
173  file << std::fixed << std::setprecision(15) << knt2[i] << " ";
174  }
175  file << std::fixed << std::setprecision(15) << knt2[knt2.size() - 1]
176  << " \r\n";
177 
178  // Matrices
179  for (unsigned int n = 0; n < xyzw.size(); n++) {
180  for (int i = 0; i < M; i++)
181  for (int j = 0; j < N; j++) {
182  file << std::fixed << std::setprecision(15) << xyzw[n](i, j);
183  if (N * i + j == M * N - 1) {
184  file << " \r\n";
185  continue;
186  }
187  file << " ";
188  }
189  }
190 
191  file.close();
192 }
193 
204 void WriteDATFile(const std::vector<Patch> &Geometry,
205  const std::string &file_name) {
206  const int number_of_patches = Geometry.size();
207  MakeFile(file_name, number_of_patches);
208 
209  int patch_count = 0;
210  for (auto &patch : Geometry) {
211  assert(patch.unique_knots_x_.size() == 2 &&
212  "I assume 0 and 1 as unique knots!");
213  assert(patch.unique_knots_y_.size() == 2 &&
214  "I assume 0 and 1 as unique knots!");
215 
216  const int polynomial_degree_x = patch.polynomial_degree_x_;
217  const int polynomial_degree_y = patch.polynomial_degree_y_;
218 
219  std::vector<double> knt_x(2 * polynomial_degree_x, 1.0);
220  std::vector<double> knt_y(2 * polynomial_degree_y, 1.0);
221  for (auto i = 0; i < polynomial_degree_x; ++i) knt_x[i] = 0.0;
222  for (auto i = 0; i < polynomial_degree_y; ++i) knt_y[i] = 0.0;
223 
224  const int number_of_points_x = knt_x.size() - polynomial_degree_x;
225  const int number_of_points_y = knt_y.size() - polynomial_degree_y;
226 
227  std::vector<Eigen::MatrixXd> data(
228  4, Eigen::MatrixXd::Zero(number_of_points_y, number_of_points_x));
229 
230  const int matrix_size = number_of_points_x * number_of_points_y;
231  for (auto i = 0; i < matrix_size; ++i) {
232  const int rowIndex = i % number_of_points_y;
233  const int colIndex = i / number_of_points_y;
234  data[0](rowIndex, colIndex) = patch.data_[4 * i];
235  data[1](rowIndex, colIndex) = patch.data_[4 * i + 1];
236  data[2](rowIndex, colIndex) = patch.data_[4 * i + 2];
237  data[3](rowIndex, colIndex) = patch.data_[4 * i + 3];
238  }
239 
240  WritePatch(file_name, patch_count, data, knt_x, knt_y);
241  ++patch_count;
242  }
243 
244  return;
245 }
246 
247 } // namespace Bembel
248 #endif // BEMBEL_SRC_GEOMETRY_GEOMETRYIO_HPP_
this class wraps a GeometryVector and provides some basic functionality, like reading Geometry files
Definition: Geometry.hpp:20
handles a single patch
Definition: Patch.hpp:20
void init_Patch(const std::vector< Eigen::Matrix< double, -1, -1 >> &xyzw, const std::vector< double > &x_knots, const std::vector< double > &y_knots)
init
Definition: Patch.hpp:63
void WriteDATFile(const std::vector< Patch > &Geometry, const std::string &file_name)
exports a geometry from Bembel to a .dat file.
Definition: GeometryIO.hpp:204
std::vector< Patch > LoadGeometryFileDAT(const std::string &file_name) noexcept
loads geometry from file with GEOPDE-format. Note that the direction of the normals must be consisten...
Definition: GeometryIO.hpp:25
Routines for the evalutation of pointwise errors.
Definition: AnsatzSpace.hpp:14
void WritePatch(const std::string &file_name, int current_patch_number, const std::vector< Eigen::MatrixXd > &xyzw, const std::vector< double > &knt1, const std::vector< double > &knt2) noexcept
method to write Patch information into textfile
Definition: GeometryIO.hpp:154
void MakeFile(const std::string &file_name, int number_of_patches) noexcept
method to generate textfile for the geometry
Definition: GeometryIO.hpp:130