49 template <
int dim,
int order>
void bindSimplex(py::module_ &module)
52 const auto name =
"Simplex" + std::to_string(dim) + std::to_string(
order);
53 auto b = py::class_<S, std::shared_ptr<S>>(module, name.c_str(), py::dynamic_attr())
54 .def_property_readonly_static(
"dim",
59 .def_property_readonly_static(
"order",
64 .def_property_readonly(
"xID",
69 .def_property_readonly(
"sID",
77 return s.center().eval();
79 .
def(
"isBoundarySimplex", &S::isBoundarySimplex)
80 .def(
"isRegionBoundarySimplex", &S::isRegionBoundarySimplex)
81 .def(
"regionIDs", &S::regionIDs)
86 for (
const auto *
v : self.cast<
const S &>().vertices())
92 if constexpr (
order > 0)
94 b.def_property_readonly(
"vol0",
99 .
def(
"vertexPositionMatrix", &S::vertexPositionMatrix)
100 .def(
"bary2pos", &S::bary2pos)
105 for (
const auto &child : self.cast<
const S &>().children())
114 b.def_readonly(
"P0", &S::P0);
116 if constexpr (
order < dim)
121 return retainedMap(self.cast<
const S &>().parents(), self);
126 return s.outNormal();
129 [](
const S &s,
size_t id)
131 return s.outNormal(
id);
136 b.def_property_readonly(
"region",
139 return retained(self.cast<
const S &>().region, self);
141 .
def(
"pos2bary", &S::pos2bary);
147 const auto name =
"Polyhedron" + std::to_string(dim) + std::to_string(
order);
148 auto b = py::class_<C, std::shared_ptr<C>>(module, name.c_str(), py::dynamic_attr())
149 .def_property_readonly_static(
"dim",
154 .def_property_readonly_static(
"order",
159 .def_property_readonly(
"key",
168 for (
const auto *s :
c.simplices())
178 for (
const auto *s : self.cast<
const C &>().simplices())
184 if constexpr (
order > 0)
186 b.def_property_readonly(
"children",
189 return retainedMap(self.cast<
const C &>().children, self);
192 if constexpr (
order < dim)
194 b.def_property_readonly(
"parents",
198 for (
const auto &entry : self.cast<
const C &>().parents)
200 if (
const auto p = entry.second.lock())
208 if constexpr (
order == dim)
210 b.def_readonly(
"regionID", &C::regionID)
214 return retainedMap(self.cast<
const C &>().faces(), self);
217 if constexpr (
order == dim - 1)
219 b.def_readonly(
"sID", &C::sID)
220 .def_readonly(
"regionIDs", &C::regionIDs)
221 .def(
"isExternal", &C::isExternal)
222 .def(
"center", &C::center)
226 return c.outNormal();
229 [](
const C &
c,
int id)
231 return c.outNormal(
id);
233 .def_property_readonly(
"periodicShift",
236 return c.periodicFacePair.first;
238 .def_property_readonly(
"periodicPartner",
241 return retained(self.cast<
const C &>().periodicFacePair.second, self);
244 if constexpr (
order == 0)
246 b.def_readonly(
"position", &C::position);
284 template <
int dim>
void bindMesh(py::module_ &module)
289 using V = Eigen::Matrix<double, dim, 1>;
290 using A = Eigen::Matrix<double, dim, dim>;
292 const auto suffix = std::to_string(dim);
293 py::class_<R>(module, (
"SimplexReader" + suffix).c_str())
297 [](R &reader,
const std::string &file,
const A &transform,
const V &origin)
299 reader.read(file, transform, origin);
301 py::arg(
"filename"), py::arg(
"A") = A::Identity().eval(), py::arg(
"x0") = V::Zero().eval())
305 return reader.nodes();
311 for (
const auto &entry : reader.elements())
313 result[py::int_(entry.first)] =
314 py::make_tuple(
keyObject(entry.second.first), entry.second.second);
319 py::class_<Boundary>(module, (
"MeshRegionBoundary" + suffix).c_str(), py::dynamic_attr())
320 .def_readonly(
"regionBndID", &Boundary::regionBndID)
324 return retainedMap(self.cast<
const Boundary &>().faces(), self);
330 for (
const auto *simplex : self.cast<
const Boundary &>().simplices())
336 py::class_<P, std::shared_ptr<P>>(module, (
"PolyhedralMesh" + suffix).c_str(), py::dynamic_attr())
339 [](py::object self,
int order)
343 py::arg(
"order") = dim)
345 [](py::object self,
size_t id)
347 return retained(&self.cast<
const P &>().region(
id), self);
350 [](py::object self,
size_t id)
352 return retained(&self.cast<
const P &>().face(
id), self);
354 .
def(
"validate", &P::validate);
355 py::class_<M, std::shared_ptr<M>>(module, (
"SimplicialMesh" + suffix).c_str(), py::dynamic_attr())
357 .def(py::init<
const std::string &,
const A &,
const V &,
const std::set<int> &>(), py::arg(
"filename"),
358 py::arg(
"A") = A::Identity().
eval(), py::arg(
"x0") = V::Zero().
eval(),
359 py::arg(
"periodicFaceIDs") = std::set<int>{})
360 .def_property_readonly_static(
"dim",
368 return mesh.xMin().eval();
373 return mesh.xMax().eval();
375 .
def(
"xCenter", &M::xCenter)
376 .def(
"volume", &M::volume)
377 .def(
"periodicBasis",
380 return Eigen::MatrixXd(
mesh.periodicBasis());
382 .
def(
"identifyParallelFaces", &M::identifyParallelFaces, py::arg(
"periodicFaceIDs"))
384 [](py::object self,
size_t id)
386 return retained(self.cast<
const M &>().regions().at(
id), self);
391 return retainedMap(self.cast<
const M &>().regions(), self);
395 [](py::object self,
int order)
399 py::arg(
"order") = dim)
400 .
def(
"regionBoundaries",
404 for (
const auto &entry : self.cast<
const M &>().regionBoundaries())
406 result[py::make_tuple(entry.first.first, entry.first.second)] =
retained(&entry.second, self);
410 .
def(
"polyhedralMesh",
413 return retained(&self.cast<
const M &>().polyhedralMesh(), self);
416 [](py::object self,
const V &point)
418 if (self.cast<
const M &>().simplices().empty())
420 return py::object(py::none());
422 const auto found = self.cast<
const M &>().search(point);
423 return found.first ?
retained(found.second, self) : py::none();
425 .
def(
"periodicSimplexPairs",
429 for (
const auto &entry : self.cast<
const M &>().periodicSimplexPairs())
432 retained(entry.second.partner, self), entry.second.shift, entry.second.vertexPermutation);