46 index012_ft* index0_f;
47 index012_ft* index1_f;
48 index012_ft* index2_f;
49 const shared_ptr<MeshAxis>* minor_axis;
50 const shared_ptr<MeshAxis>* medium_axis;
51 const shared_ptr<MeshAxis>* major_axis;
53 void onAxisChanged(
Event&
e);
55 void setChangeSignal(
const shared_ptr<MeshAxis>& axis) {
if (axis) axis->changedConnectMethod(
this, &RectilinearMesh3D::onAxisChanged); }
56 void unsetChangeSignal(
const shared_ptr<MeshAxis>& axis) {
if (axis) axis->changedDisconnectMethod(
this, &RectilinearMesh3D::onAxisChanged); }
65 std::size_t index0, index1, index2;
74 Element(
const RectilinearMesh3D& mesh, std::size_t index0, std::size_t index1, std::size_t index2): mesh(mesh), index0(index0), index1(index1), index2(index2) {}
89 inline std::size_t
getIndex0()
const {
return index0; }
92 inline std::size_t
getIndex1()
const {
return index1; }
95 inline std::size_t
getIndex2()
const {
return index2; }
107 inline double getLower0()
const {
return mesh.axis[0]->at(index0); }
110 inline double getLower1()
const {
return mesh.axis[1]->at(index1); }
113 inline double getLower2()
const {
return mesh.axis[2]->at(index2); }
125 inline double getUpper0()
const {
return mesh.axis[0]->at(getUpperIndex0()); }
128 inline double getUpper1()
const {
return mesh.axis[1]->at(getUpperIndex1()); }
131 inline double getUpper2()
const {
return mesh.axis[2]->at(getUpperIndex2()); }
134 inline double getSize0()
const {
return getUpper0() - getLower0(); }
137 inline double getSize1()
const {
return getUpper1() - getLower1(); }
140 inline double getSize2()
const {
return getUpper2() - getLower2(); }
149 inline std::size_t
getIndex()
const {
return mesh.getElementIndexFromLowIndex(getLoLoLoIndex()); }
152 inline std::size_t
getLoLoLoIndex()
const {
return mesh.index(getLowerIndex0(), getLowerIndex1(), getLowerIndex2()); }
155 inline std::size_t
getUpLoLoIndex()
const {
return mesh.index(getUpperIndex0(), getLowerIndex1(), getLowerIndex2()); }
158 inline std::size_t
getLoUpLoIndex()
const {
return mesh.index(getLowerIndex0(), getUpperIndex1(), getLowerIndex2()); }
161 inline std::size_t
getUpUpLoIndex()
const {
return mesh.index(getUpperIndex0(), getUpperIndex1(), getLowerIndex2()); }
164 inline std::size_t
getLoLoUpIndex()
const {
return mesh.index(getLowerIndex0(), getLowerIndex1(), getUpperIndex2()); }
167 inline std::size_t
getUpLoUpIndex()
const {
return mesh.index(getUpperIndex0(), getLowerIndex1(), getUpperIndex2()); }
170 inline std::size_t
getLoUpUpIndex()
const {
return mesh.index(getLowerIndex0(), getUpperIndex1(), getUpperIndex2()); }
173 inline std::size_t
getUpUpUpIndex()
const {
return mesh.index(getUpperIndex0(), getUpperIndex1(), getUpperIndex2()); }
200 inline Box3D toBox()
const {
return mesh.getElementBox(index0, index1, index2); }
265 template <
typename BaseMeshT>
271 template <
typename... Args>
272 ElementMesh(
const BaseMeshT* originalMesh, Args... args): BaseMeshT(args...), originalMesh(originalMesh) {}
281 template <
typename RandomAccessContainer>
283 ->
typename std::remove_reference<
decltype(data[0])>::type {
284 auto p = flags.wrap(point);
288 size_t i0 = originalMesh->axis[0]->findUpIndex(p.c0),
289 i1 = originalMesh->axis[0]->findUpIndex(p.c1),
290 i2 = originalMesh->axis[2]->findUpIndex(p.c2);
291 if (i0 == originalMesh->axis[0]->size()) --i0;
293 if (i1 == originalMesh->axis[1]->size()) --i1;
295 if (i2 == originalMesh->axis[2]->size()) --i2;
297 return flags.postprocess(point, data[this->index(i0, i1, i2)]);
304 if (this->originalMesh == c->originalMesh)
return true;
305 return BaseMeshT::hasSameNodes(to_compare);
310 const shared_ptr<MeshAxis> axis[3];
339 return Box3D(axis[0]->at(index0), axis[1]->at(index1), axis[2]->at(index2),
340 axis[0]->at(index0+1), axis[1]->at(index1+1), axis[2]->at(index2+1));
349 enum IterationOrder { ORDER_012, ORDER_021, ORDER_102, ORDER_120, ORDER_201, ORDER_210 };
356 void setIterationOrder(IterationOrder order);
363 IterationOrder getIterationOrder()
const;
370 return &
"\0\1\2\0\2\1\1\0\2\1\2\0\2\0\1\2\1\0"[getIterationOrder() * 3];
382 return &
"\0\1\2\0\2\1\1\0\2\2\0\1\1\2\0\2\1\0"[getIterationOrder() * 3];
398 void setOptimalIterationOrder();
423 void reset(shared_ptr<MeshAxis>
mesh0, shared_ptr<MeshAxis> mesh1, shared_ptr<MeshAxis> mesh2, IterationOrder
iterationOrder = ORDER_012);
450 void setAxis(std::size_t
axis_nr, shared_ptr<MeshAxis>
new_val,
bool fireResized =
true);
452 const shared_ptr<MeshAxis>
getAxis0()
const {
return axis[0]; }
456 const shared_ptr<MeshAxis>
getAxis1()
const {
return axis[1]; }
460 const shared_ptr<MeshAxis>
getAxis2()
const {
return axis[2]; }
468 const shared_ptr<MeshAxis>&
getAxis(
size_t n)
const {
469 if (
n >= 3)
throw Exception(
"bad axis number");
480 if (major_axis == &axis[0])
return 0;
481 if (major_axis == &axis[1])
return 1;
492 if (medium_axis == &axis[0])
return 0;
493 if (medium_axis == &axis[1])
return 1;
504 if (minor_axis == &axis[0])
return 0;
505 if (minor_axis == &axis[1])
return 1;
519 return this->getIterationOrder() ==
to_compare.getIterationOrder() ||
531 std::size_t
size()
const override {
return axis[0]->size() * axis[1]->size() * axis[2]->size(); }
534 bool empty()
const override {
return axis[0]->empty() || axis[1]->empty() || axis[2]->empty(); }
543 virtual Vec<3, double> at(std::size_t index0, std::size_t index1, std::size_t index2)
const = 0;
551 return at(index0(index), index1(index), index2(index));
561 return at(index0(index), index1(index), index2(index));
572 return at(index0, index1, index2);
580 double getElementMidpoint0(std::size_t index0)
const {
return 0.5 * (axis[0]->at(index0) + axis[0]->at(index0+1)); }
587 double getElementMidpoint1(std::size_t index1)
const {
return 0.5 * (axis[1]->at(index1) + axis[1]->at(index1+1)); }
594 double getElementMidpoint2(std::size_t index2)
const {
return 0.5 * (axis[2]->at(index2) + axis[2]->at(index2+1)); }
620 return index(indexes[0], indexes[1], indexes[2]);
655 template <std::
size_t axis_nr>
678 return mesh_index / (*minor_axis)->size() / (*medium_axis)->size();
687 return (
mesh_index / (*minor_axis)->size()) % (*medium_axis)->size();
704 const std::size_t s = axis[0]->size();
705 return (s != 0)? s-1 : 0;
713 const std::size_t s = axis[1]->size();
714 return (s != 0)? s-1 : 0;
722 const std::size_t s = axis[2]->size();
723 return (s != 0)? s-1 : 0;
731 return size_t(std::max(
int(axis[0]->size())-1, 0) * std::max(
int(axis[1]->size())-1, 0) * std::max(
int(axis[2]->size())-1, 0));
761 return index0(
meshIndex) + 1 < axis[0]->size() && index1(
meshIndex) + 1 < axis[1]->size() && index2(
meshIndex) + 1 < axis[2]->size();
801 template <
typename RandomAccessContainer>
803 ->
typename std::remove_reference<
decltype(data[0])>::type
805 auto p = flags.wrap(point);
823 typename std::remove_const<
typename std::remove_reference<
decltype(data[0])>::type>::type
840 return flags.postprocess(point,
852 template <
typename RandomAccessContainer>
854 ->
typename std::remove_reference<
decltype(data[0])>::type {
855 auto p = flags.wrap(point);
859 return flags.postprocess(point, data[this->index(axis[0]->findNearestIndex(p.c0), axis[1]->findNearestIndex(p.c1), axis[2]->findNearestIndex(p.c2))]);
878 template <
int CHANGE_DIR_SLOWER,
int CHANGE_DIR_FASTER>
887 const std::size_t indexFasterBegin, indexFasterEnd, indexSlowerEnd;
891 : mesh(mesh), index(index), indexFasterBegin(index[CHANGE_DIR_FASTER]), indexFasterEnd(indexFasterEnd), indexSlowerEnd(indexSlowerEnd)
895 void increment()
override {
896 ++index[CHANGE_DIR_FASTER];
897 if (index[CHANGE_DIR_FASTER] == indexFasterEnd) {
898 index[CHANGE_DIR_FASTER] = indexFasterBegin;
899 ++index[CHANGE_DIR_SLOWER];
904 return index ==
static_cast<const BoundaryIteratorImpl&
>(other).index;
907 std::size_t dereference()
const override {
908 return mesh.index(index);
911 std::unique_ptr<plask::BoundaryNodeSetImpl::IteratorImpl> clone()
const override {
912 return std::unique_ptr<plask::BoundaryNodeSetImpl::IteratorImpl>(
new BoundaryIteratorImpl<CHANGE_DIR_SLOWER, CHANGE_DIR_FASTER>(*
this));
917 template <
int CHANGE_DIR_SLOWER,
int CHANGE_DIR_FASTER>
918 struct BoundaryNodeSetImpl:
public BoundaryNodeSetWithMeshImpl<RectilinearMesh3D> {
920 static constexpr int FIXED_DIR = 3 - CHANGE_DIR_SLOWER - CHANGE_DIR_FASTER;
922 using typename BoundaryNodeSetWithMeshImpl<RectilinearMesh3D>::const_iterator;
928 std::size_t indexFasterEnd, indexSlowerEnd;
930 BoundaryNodeSetImpl(
const RectilinearMesh3D& mesh, std::size_t level)
931 : BoundaryNodeSetWithMeshImpl<RectilinearMesh3D>(mesh),
level(
level) {}
933 bool contains(std::size_t mesh_index)
const override {
934 return mesh_index < this->mesh.size() && this->mesh.template index_axis<FIXED_DIR>(mesh_index) ==
level;
937 const_iterator begin()
const override {
938 Vec<3, std::size_t> index_begin(0, 0, 0);
939 index_begin[FIXED_DIR] =
level;
940 return Iterator(
new BoundaryIteratorImpl<CHANGE_DIR_SLOWER, CHANGE_DIR_FASTER>(this->mesh, index_begin,
941 this->mesh.axis[CHANGE_DIR_SLOWER]->size(),
942 this->mesh.axis[CHANGE_DIR_FASTER]->size()));
945 const_iterator
end()
const override {
946 Vec<3, std::size_t> index_end;
947 index_end[CHANGE_DIR_SLOWER] = this->mesh.axis[CHANGE_DIR_SLOWER]->size();
948 index_end[FIXED_DIR] =
level;
949 index_end[CHANGE_DIR_FASTER] = 0;
950 return Iterator(
new BoundaryIteratorImpl<CHANGE_DIR_SLOWER, CHANGE_DIR_FASTER>(this->mesh, index_end,
951 this->mesh.axis[CHANGE_DIR_SLOWER]->size(),
952 this->mesh.axis[CHANGE_DIR_FASTER]->size()));
955 std::size_t
size()
const override {
956 return this->mesh.axis[CHANGE_DIR_FASTER]->size() * this->mesh.axis[CHANGE_DIR_SLOWER]->size();
959 bool empty()
const override {
960 return this->mesh.axis[CHANGE_DIR_FASTER]->empty() || this->mesh.axis[CHANGE_DIR_SLOWER]->empty();
964 template <
int CHANGE_DIR_SLOWER,
int CHANGE_DIR_FASTER>
965 struct BoundaryNodeSetRangeImpl:
public BoundaryNodeSetWithMeshImpl<RectilinearMesh3D> {
967 static constexpr int FIXED_DIR = 3 - CHANGE_DIR_SLOWER - CHANGE_DIR_FASTER;
969 typedef typename BoundaryNodeSetImpl::Iterator Iterator;
972 Vec<3, std::size_t> index;
975 std::size_t indexFasterEnd, indexSlowerEnd;
977 BoundaryNodeSetRangeImpl(
const RectilinearMesh3D& mesh, Vec<3, std::size_t> index, std::size_t indexSlowerEnd, std::size_t indexFasterEnd)
978 : BoundaryNodeSetWithMeshImpl<RectilinearMesh3D>(mesh), index(index), indexFasterEnd(indexFasterEnd), indexSlowerEnd(indexSlowerEnd) {}
980 BoundaryNodeSetRangeImpl(
const RectilinearMesh3D& mesh, std::size_t index0, std::size_t index1, std::size_t index2, std::size_t indexSlowerEnd, std::size_t indexFasterEnd)
981 : BoundaryNodeSetWithMeshImpl<RectilinearMesh3D>(mesh), index(index0, index1, index2), indexFasterEnd(indexFasterEnd), indexSlowerEnd(indexSlowerEnd) {}
983 bool contains(std::size_t mesh_index)
const override {
984 if (mesh_index >= this->mesh.size())
return false;
985 Vec<3, std::size_t> mesh_indexes = this->mesh.indexes(mesh_index);
986 return mesh_indexes[FIXED_DIR] == index[FIXED_DIR] &&
987 (index[CHANGE_DIR_FASTER] <= mesh_indexes[CHANGE_DIR_FASTER] && mesh_indexes[CHANGE_DIR_FASTER] < indexFasterEnd) &&
988 (index[CHANGE_DIR_SLOWER] <= mesh_indexes[CHANGE_DIR_SLOWER] && mesh_indexes[CHANGE_DIR_SLOWER] < indexSlowerEnd);
991 const_iterator begin()
const override {
992 return Iterator(
new BoundaryIteratorImpl<CHANGE_DIR_SLOWER, CHANGE_DIR_FASTER>(this->mesh, index, indexSlowerEnd, indexFasterEnd));
995 const_iterator
end()
const override {
996 Vec<3, std::size_t> index_end = index;
997 index_end[CHANGE_DIR_SLOWER] = indexSlowerEnd;
998 return Iterator(
new BoundaryIteratorImpl<CHANGE_DIR_SLOWER, CHANGE_DIR_FASTER>(this->mesh, index_end, indexSlowerEnd, indexFasterEnd));
1001 std::size_t
size()
const override {
1002 return (indexFasterEnd - index[CHANGE_DIR_FASTER]) * (indexSlowerEnd - index[CHANGE_DIR_SLOWER]);
1005 bool empty()
const override {
1006 return indexFasterEnd == index[CHANGE_DIR_FASTER] || indexSlowerEnd == index[CHANGE_DIR_SLOWER];
1012 BoundaryNodeSet createIndex0BoundaryAtLine(std::size_t
line_nr_axis0)
const override;
1014 BoundaryNodeSet createBackBoundary()
const override;
1016 BoundaryNodeSet createFrontBoundary()
const override;
1018 BoundaryNodeSet createIndex1BoundaryAtLine(std::size_t
line_nr_axis1)
const override;
1020 BoundaryNodeSet createLeftBoundary()
const override;
1022 BoundaryNodeSet createRightBoundary()
const override;
1024 BoundaryNodeSet createIndex2BoundaryAtLine(std::size_t
line_nr_axis2)
const override;
1026 BoundaryNodeSet createBottomBoundary()
const override;
1028 BoundaryNodeSet createTopBoundary()
const override;
1030 BoundaryNodeSet createIndex0BoundaryAtLine(std::size_t
line_nr_axis0,
1034 BoundaryNodeSet createBackOfBoundary(
const Box3D&
box)
const override;
1036 BoundaryNodeSet createFrontOfBoundary(
const Box3D&
box)
const override;
1038 BoundaryNodeSet createIndex1BoundaryAtLine(std::size_t
line_nr_axis1,
1042 BoundaryNodeSet createLeftOfBoundary(
const Box3D&
box)
const override;
1044 BoundaryNodeSet createRightOfBoundary(
const Box3D&
box)
const override;
1046 BoundaryNodeSet createIndex2BoundaryAtLine(std::size_t
line_nr_axis2,
1050 BoundaryNodeSet createBottomOfBoundary(
const Box3D&
box)
const override;
1052 BoundaryNodeSet createTopOfBoundary(
const Box3D&
box)
const override;