8#ifndef model_PeriodicGlidePlane_cpp_
9#define model_PeriodicGlidePlane_cpp_
29 const short int& edgeID_in) :
46 patch->patchBoundary->removeUntwinnedEdge(
twin);
50 patch->patchBoundary->addUntwinnedEdge(
this);
60 sink->removeLink(
this);
72 patch->patchBoundary->addUntwinnedEdge(
twin);
76 patch->patchBoundary->removeUntwinnedEdge(
this);
135 return std::to_string(
source->sID) +
" " + std::to_string(
sink->sID)+
" "+std::to_string(
patch->sID)+
" ("+std::to_string(
edgeID)+
")";
151 if(link->
sink->sID==this->sID)
156 assert(patchConnectivity.
inEdge==
nullptr);
157 patchConnectivity.
inEdge=link;
161 assert(link->
next==
nullptr);
168 assert(neighborConnectivity.
inEdge==
nullptr || neighborConnectivity.
inEdge==link);
169 neighborConnectivity.
inEdge=link;
170 if(neighborConnectivity.
outEdge)
173 assert(link->
twin==
nullptr || link->
twin==neighborConnectivity.
outEdge);
179 else if(link->
source->sID==this->sID)
184 assert(patchConnectivity.
outEdge==
nullptr);
185 patchConnectivity.
outEdge=link;
186 if(patchConnectivity.
inEdge)
188 assert(patchConnectivity.
inEdge->
next==
nullptr);
189 assert(link->
prev==
nullptr);
196 assert(neighborConnectivity.
outEdge==
nullptr || neighborConnectivity.
outEdge==link);
197 neighborConnectivity.
outEdge=link;
198 if(neighborConnectivity.
inEdge)
201 assert(link->
twin==
nullptr || link->
twin==neighborConnectivity.
inEdge);
208 assert(
false &&
"CONNECTING LINK TO NON-INCIDENT NODE");
217 if(link->
sink->sID==this->sID)
224 assert(patchConnectivity.
inEdge==link);
225 patchConnectivity.
inEdge=
nullptr;
226 if(patchConnectivity.
inEdge==
nullptr && patchConnectivity.
outEdge==
nullptr)
235 assert(neighborConnectivity.
inEdge==link);
236 neighborConnectivity.
inEdge=
nullptr;
237 if(neighborConnectivity.
inEdge==
nullptr && neighborConnectivity.
outEdge==
nullptr)
243 else if(link->
source->sID==this->sID)
250 assert(patchConnectivity.
outEdge==link);
251 patchConnectivity.
outEdge=
nullptr;
252 if(patchConnectivity.
inEdge==
nullptr && patchConnectivity.
outEdge==
nullptr)
261 assert(neighborConnectivity.
outEdge==link);
262 neighborConnectivity.
outEdge=
nullptr;
263 if(neighborConnectivity.
inEdge==
nullptr && neighborConnectivity.
outEdge==
nullptr)
270 assert(
false &&
"DISCONNECTING LINK FROM NON-INCIDENT NODE");
277 return _patchConnectivities;
283 return _patchConnectivities;
289 return _neighborConnectivities;
295 return _neighborConnectivities;
304 if(connectivity.second.inEdge && !connectivity.second.outEdge)
306 assert(connectivity.second.inEdge->twin==
nullptr);
307 temp.insert(connectivity.second.inEdge);
319 if(connectivity.second.outEdge && !connectivity.second.inEdge)
321 assert(connectivity.second.outEdge->twin==
nullptr);
322 temp.insert(connectivity.second.outEdge);
340 addMeshIntersections(glidePlane->meshIntersections);
344 BoundingMeshSegments<dim> flippedTemp;
345 for (auto it = glidePlane->meshIntersections.rbegin(); it != glidePlane->meshIntersections.rend(); ++it)
347 flippedTemp.emplace_back(new MeshBoundarySegment<dim>((*it)->P1,(*it)->P0,(*it)->faces));
352 patchBoundary->updateBoundaries();
371 for(
const auto& seg : bnd)
373 nA+= 0.5*(seg->P0-P0).cross(seg->P1-seg->P0);
375 return nA.dot(plane.unitNormal)>0.0;
423 for(
size_t k=0;
k<bms.size();++
k)
425 std::shared_ptr<PeriodicPlaneNode<dim>> source(
patchBoundary->getSharedNode(bms[
k]->P0,
shift));
426 std::shared_ptr<PeriodicPlaneNode<dim>> sink(
patchBoundary->getSharedNode(bms[
k]->P1,
shift));
441 for(
const auto& edge :
edges())
443 if(edge->meshIntersection->faces==faces)
448 return std::shared_ptr<PeriodicPlaneEdge<dim>>(
nullptr);
461 if ( ((Pi(1)>
test(1)) != (Pj(1)>
test(1))) &&
462 (
test(0) < (Pj(0)-Pi(0)) * (
test(1)-Pi(1)) / (Pj(1)-Pi(1)) + Pi(0)
531 throw std::runtime_error(
"COULD NOT ERASE LINK FROM BOUNDARYLINKS");
555 for (
i = 0,
j = outerBoundary.size()-1;
i < outerBoundary.size();
j =
i++)
560 if ( ((Pi(1)>
test(1)) != (Pj(1)>
test(1))) &&
561 (
test(0) < (Pj(0)-Pi(0)) * (
test(1)-Pi(1)) / (Pj(1)-Pi(1)) + Pi(0)) )
586 const VectorDim P0(bnd.front()->meshIntersection->P0-(bnd.front())->patch->shift);
587 for(
const auto& seg : bnd)
590 VectorDim P0_temp=seg->meshIntersection->P0-temp_shift;
591 VectorDim P1_temp=seg->meshIntersection->P1-temp_shift;
592 nA+= 0.5*(P0_temp-P0).cross(P1_temp-P0_temp);
598 return VectorDim::Zero();
625 temp.reserve(untwinnedCopy.size());
628 temp.push_back(currentEdge);
629 const size_t erased(untwinnedCopy.erase(currentEdge));
633 std::cout<<
"Trying to erase "<<currentEdge->
tag()<<std::endl;
634 std::cout<<
"untwinnedCopy is"<<std::endl;
635 for(
const auto& edgePtr : untwinnedCopy)
637 std::cout<<
" "<<edgePtr->tag()<<std::endl;
640 std::ofstream pointsFile(
"points.txt");
641 std::cout<<
"points"<<std::endl;
642 for(
const auto& node : this->
nodes())
644 if(!node.second.expired())
646 pointsFile<<
" "<<node.second.lock()->sID<<
" "<<node.first.transpose()<<std::endl;
647 std::cout<<
" "<<node.second.lock()->sID<<
" "<<node.first.transpose()<<std::endl;
661 throw std::runtime_error(
"could not find link in untwinnedEdges 2");
665 if(
temp.back()->sink->sID==
temp.front()->source->sID)
669 currentEdge=currentEdge->
next;
670 while(currentEdge->
twin)
672 currentEdge=currentEdge->
twin->next;
699 while(untwinnedCopy.size())
701 size_t untwinnedSize(untwinnedCopy.size());
702 for(
const auto& edge : untwinnedCopy)
704 if(edge->source->outEdges().size()==1 && edge->source->inEdges().size()==1)
710 if (untwinnedCopy.size() && untwinnedCopy.size()==untwinnedSize)
721 return patches().getFromKey(shift);
765 std::vector<std::shared_ptr<PeriodicPlanePatch<dim>>> currentPatches;
769 std::shared_ptr<PeriodicPlanePatch<dim>> lastPatch(patchBoundary.getPatch(guessShift));
770 currentPatches.push_back(lastPatch);
771 const std::shared_ptr<GlidePlane<dim>>& centralPlane(lastPatch->glidePlane);
772 VectorLowerDim insideReferencePoint(VectorLowerDim::Zero());
773 for(
const auto& seg : centralPlane->meshIntersections)
775 insideReferencePoint+=referencePlane->localPosition(seg->P0-lastPatch->shift);
777 insideReferencePoint/=centralPlane->meshIntersections.size();
778 if(!lastPatch->contains(insideReferencePoint))
780 throw std::runtime_error(
"lastPatch does not cointain insideReferencePoint");
786 while(!lastPatch->contains(P0))
788 std::set<const PeriodicPlaneEdge<dim>*> crossdEdges;
789 for(
const auto& bndEdge : patchBoundary.untwinnedEdges())
792 if(ssd.dMin<FLT_EPSILON)
795 crossdEdges.insert(bndEdge);
799 switch (crossdEdges.size())
803 assert(lastPatch.get()==(*crossdEdges.begin())->patch);
804 if((*crossdEdges.begin())->deltaShift.squaredNorm()<FLT_EPSILON)
806 return std::make_pair(VectorDim::Zero(),
false);
808 const VectorDim newShift((*crossdEdges.begin())->deltaShift+(*crossdEdges.begin())->patch->shift);
809 lastPatch=patchBoundary.getPatch(newShift);
810 currentPatches.push_back(lastPatch);
816 assert(lastPatch.get()==(*crossdEdges.begin())->patch);
817 assert((*crossdEdges.begin())->patch==(*crossdEdges.rbegin())->patch);
818 if(((*crossdEdges.begin())->deltaShift+(*crossdEdges.rbegin())->deltaShift).squaredNorm()<FLT_EPSILON)
820 return std::make_pair(VectorDim::Zero(),
false);
822 const VectorDim newShift((*crossdEdges.begin())->deltaShift+(*crossdEdges.rbegin())->deltaShift+(*crossdEdges.begin())->patch->shift);
823 lastPatch=patchBoundary.getPatch(newShift);
824 currentPatches.push_back(lastPatch);
843 std::cout<<
"untwinnedEdges().size()="<<patchBoundary.untwinnedEdges().size()<<std::endl;
844 std::cout<<
"crossdEdges.size()="<<crossdEdges.size()<<std::endl;
845 assert(
false &&
"1 or 2 edges must be crossed");
850 assert(lastPatch->contains(P0));
851 return std::make_pair(lastPatch->shift,
true);
857 std::cout<<
"PeriodiPlane nodes:"<<std::endl;
858 for(
const auto& node : this->
nodes())
860 if(!node.second.expired())
862 std::cout<<node.second.lock()->sID<<
" "<<node.first.transpose()<<std::endl;
874 std::set<std::shared_ptr<PeriodicPlanePatch<dim>>> tempPatches;
875 for(
const auto& ps : patchShifts)
877 tempPatches.insert(patchBoundary.
getPatch(ps));
887 std::vector<std::shared_ptr<PeriodicPlanePatch<dim>>>
temp;
888 for(
const auto& patch : tempPatches)
921 for(
int d=0;d<dim;++d)
Class template representing a straight line at the intersection of PlanarMeshFaces.
GlidePlaneFactory< dim > & glidePlaneFactory
std::pair< VectorDim, bool > findPatch(const VectorLowerDim &, const VectorDim &)
PeriodicGlidePlaneFactoryType & periodicGlidePlaneFactory
Eigen::Matrix< double, dim-1, 1 > VectorLowerDim
const std::shared_ptr< GlidePlane< dim > > referencePlane
std::vector< std::shared_ptr< PeriodicPlanePatch< dim > > > filledPatches(const std::vector< VectorDim > &patchShifts)
PeriodicGlidePlane(PeriodicGlidePlaneFactoryType *const pgpf, const KeyType &key_in)
GlidePlaneType::KeyType KeyType
PeriodicGlidePlaneFactory< dim > PeriodicGlidePlaneFactoryType
const NodalConnectivityContainerType & neighborConnectivities() const
PeriodicPlaneEdge< dim > PeriodicPlaneEdgeType
const NodalConnectivityContainerType & patchConnectivities() const
Eigen::Matrix< double, dim-1, 1 > VectorLowerDim
void removeLink(PeriodicPlaneEdgeType *const link)
InOutEdgeContainerType outEdges() const
void addLink(PeriodicPlaneEdgeType *const link)
std::map< size_t, NodalConnectivity< dim > > NodalConnectivityContainerType
PeriodicPlaneNode(PeriodicPatchBoundary< dim > *const, const VectorLowerDim &pos)
InOutEdgeContainerType inEdges() const
NodalConnectivity< dim > NodalConnectivityType
std::set< PeriodicPlaneEdgeType * > InOutEdgeContainerType
LatticePlaneKey< dim > GlidePlaneKey
SharedPtrType getFromKey(const KeyType &key)
PeriodicPlaneEdgeType * outEdge
PeriodicPlaneEdgeType * inEdge
static VectorDim rightHandedNormal(const std::vector< const PeriodicPlaneEdge< dim > * > &bnd)
void createNewBoundary(const PeriodicPlaneEdge< dim > *currentEdge, UntwinnedEdgeContainerType &untwinnedCopy)
PeriodicPatchBoundary(GlidePlaneFactory< dim > &, const std::shared_ptr< GlidePlane< dim > > &referencePlane_in)
KeyConstructableWeakPtrFactory< PeriodicPatchBoundary< dim >, PeriodicPlaneNode< dim >, typename PeriodicPlaneNode< dim >::CompareType > NodeCointainerType
std::vector< const PeriodicPlaneEdge< dim > * > BoundaryContainerType
const PatchContainerType & patches() const
BoundariesContainerType & innerBoundaries()
bool isRightHandedBoundary(const std::vector< const PeriodicPlaneEdge< dim > * > &bnd)
BoundariesContainerType _outerBoundaries
std::set< const PeriodicPlaneEdge< dim > * > UntwinnedEdgeContainerType
void addUntwinnedEdge(const PeriodicPlaneEdge< dim > *link)
std::shared_ptr< GlidePlane< dim > > getGlidePlane(const VectorDim &shift)
double rightHandedArea(const std::vector< const PeriodicPlaneEdge< dim > * > &bnd)
const std::shared_ptr< GlidePlane< dim > > referencePlane
int isInsideOuterBoundary(const VectorLowerDim &test)
BoundariesContainerType _innerBoundaries
Eigen::Matrix< double, dim-1, 1 > VectorLowerDim
KeyConstructableWeakPtrFactory< PeriodicPatchBoundary< dim >, PeriodicPlanePatch< dim >, typename PeriodicPlanePatch< dim >::CompareType > PatchContainerType
std::vector< BoundaryContainerType > BoundariesContainerType
Eigen::Matrix< double, dim, 1 > VectorDim
const UntwinnedEdgeContainerType & untwinnedEdges() const
std::shared_ptr< PeriodicPlanePatch< dim > > getPatch(const VectorDim &shift)
NodeCointainerType & nodes()
std::shared_ptr< PeriodicPlaneNode< dim > > getSharedNode(const VectorDim &pointDim, const VectorDim &shift)
BoundariesContainerType & outerBoundaries()
GlidePlaneFactory< dim > & glidePlaneFactory
GlidePlaneKey< dim > getGlidePlaneKey(const VectorDim &shift)
void removeUntwinnedEdge(const PeriodicPlaneEdge< dim > *link)
PeriodicPlaneEdge(const PeriodicPlanePatch< dim > *const patch_in, const std::shared_ptr< PeriodicPlaneNode< dim > > &source_in, const std::shared_ptr< PeriodicPlaneNode< dim > > &sink_in, const std::shared_ptr< const MeshBoundarySegment< dim > > meshIntersection_in, const short int &)
const std::shared_ptr< const MeshBoundarySegment< dim > > meshIntersection
const VectorDim deltaShift
PeriodicPlaneEdge< dim > * next
const std::shared_ptr< PeriodicPlaneNode< dim > > sink
const std::shared_ptr< PeriodicPlaneNode< dim > > source
PeriodicPlaneEdge< dim > * twin
const PeriodicPlanePatch< dim > *const patch
PeriodicPlaneEdge< dim > * prev
std::shared_ptr< PeriodicPlaneEdge< dim > > edgeOnFaces(const std::set< const Polyhedron< dim, dim-1 > * > &faces) const
static bool isRightHandedBoundary(const BoundingMeshSegments< dim > &, const Plane< dim > &)
const PeriodicPlaneEdgeContainerType & edges() const
Eigen::Matrix< double, dim-1, 1 > VectorLowerDim
Eigen::Matrix< double, dim, 1 > VectorDim
const std::shared_ptr< GlidePlane< dim > > glidePlane
PeriodicPatchBoundary< dim > *const patchBoundary
PeriodicPlanePatch(PeriodicPatchBoundary< dim > *const, const VectorDim &)
int contains(const VectorLowerDim &test) const
void addMeshIntersections(const BoundingMeshSegments< dim > &)
std::vector< std::shared_ptr< PeriodicPlaneEdge< dim > > > PeriodicPlaneEdgeContainerType
Eigen::Matrix< double, dim, 1 > VectorDim