47 for (
unsigned f = 0; f<
face_.size(); f++)
49 for (
unsigned i = 0; i<3; i++)
51 if (other.
face_[f].neighbor[i]) {
57 logger(
DEBUG,
"TriangulatedWall(TriangulatedWall&) constructed.");
72 file.open(filename.c_str(), std::ios::in);
73 logger.assert_always(file.is_open(),
"File opening failed: %",filename);
82 file >> dummy >> num >> dummy;
85 for (
unsigned i = 0; i < num; i++)
87 file >> v.
X >> v.
Y >> v.
Z;
91 file >> dummy >> num >> dummy;
94 unsigned id0, id1, id2;
95 for (
unsigned i = 0; i < num; i++)
97 file >> dummy >> id0 >> id1 >> id2;
105 for (
auto& face:
face_)
110 for (
auto face0=face_.begin(); face0+1!=face_.end(); face0++)
112 for (
auto face1=face0+1; face1!=face_.end(); face1++)
114 if (face0->vertex[0]==face1->vertex[0]) {
115 if (face0->vertex[1]==face1->vertex[2]) {
116 face0->neighbor[0]=&*face1;
117 face1->neighbor[2]=&*face0;
118 }
else if (face0->vertex[2]==face1->vertex[1]) {
119 face0->neighbor[2]=&*face1;
120 face1->neighbor[0]=&*face0;
122 }
else if (face0->vertex[0]==face1->vertex[1]) {
123 if (face0->vertex[1]==face1->vertex[0]) {
124 face0->neighbor[0]=&*face1;
125 face1->neighbor[0]=&*face0;
126 }
else if (face0->vertex[2]==face1->vertex[2]) {
127 face0->neighbor[2]=&*face1;
128 face1->neighbor[1]=&*face0;
130 }
else if (face0->vertex[0]==face1->vertex[2]) {
131 if (face0->vertex[1]==face1->vertex[1]) {
132 face0->neighbor[0]=&*face1;
133 face1->neighbor[1]=&*face0;
134 }
else if (face0->vertex[2]==face1->vertex[0]) {
135 face0->neighbor[2]=&*face1;
136 face1->neighbor[2]=&*face0;
138 }
else if (face0->vertex[1]==face1->vertex[0]) {
139 if (face0->vertex[2]==face1->vertex[2]) {
140 face0->neighbor[1]=&*face1;
141 face1->neighbor[2]=&*face0;
143 }
else if (face0->vertex[1]==face1->vertex[1]) {
144 if (face0->vertex[2]==face1->vertex[0]) {
145 face0->neighbor[1]=&*face1;
146 face1->neighbor[0]=&*face0;
148 }
else if (face0->vertex[1]==face1->vertex[2]) {
149 if (face0->vertex[2]==face1->vertex[1]) {
150 face0->neighbor[1]=&*face1;
151 face1->neighbor[1]=&*face0;
158 for (
auto& face: face_)
169 logger(
DEBUG,
"~TriangulatedWall() has been called.");
177 logger(
DEBUG,
"TriangulatedWall::operator= called.");
182 return *(other.
copy());
212 for (
const auto& face :
face_)
214 if (face.getDistanceAndNormal(p, distance, normal_return))
254 os <<
"Vertices " <<
vertex_.size();
255 for (
const auto& vertex:
vertex_)
259 unsigned counter = 0;
260 for (
const auto& face:
face_)
262 os <<
"Face " << counter++
263 <<
" vertex " << face.vertex[0] - &vertex_[0]
264 <<
" " << face.vertex[1] - &vertex_[0]
265 <<
" " << face.vertex[2] - &vertex_[0]
266 <<
" neighbor " << (face.neighbor[0]?(face.neighbor[0] - &face_[0]):-1)
267 <<
" " << (face.neighbor[1]?(face.neighbor[1] - &face_[0]):-1)
268 <<
" " << (face.neighbor[2]?(face.neighbor[2] - &face_[0]):-1)
269 <<
" normal " << face.normal
270 <<
" edgeNormal " << face.edgeNormal[0]
271 <<
" " << face.edgeNormal[1]
272 <<
" " << face.edgeNormal[2]
282 return "TriangulatedWall";
299 std::vector<BaseInteraction*> interactions;
300 for (
const auto& face :
face_)
302 if (face.getDistanceAndNormal(*p, distance, normal))
312 interactions.push_back(c);
333 if (fabs(distance) >= interactionRadius)
337 Mdouble allowedDistanceSquared = interactionRadius*interactionRadius-distance*distance;
338 int touchingEdge = -1;
339 Vec3D* touchingVertex =
nullptr;
341 for (
unsigned i=0; i<3; i++)
347 if (edgeDistance * edgeDistance >= allowedDistanceSquared)
351 bool convex = (neighbor[i] && ((neighbor[i]->getDistance(p.
getPosition())<0)?(
Vec3D::dot(neighbor[i]->normal,edgeNormal[i])>1e-12):(
Vec3D::dot(neighbor[i]->normal,edgeNormal[i])<-1e-12)));
352 if (touchingEdge==-1) {
357 touchingVertex = vertex[(i==2 && touchingEdge==0)?0:i];
361 if (neighbor[i] >
this){
362 if (neighbor[i]->neighbor[0]==
this) {
364 }
else if (neighbor[i]->neighbor[1]==
this) {
369 if (edgeDistance<=0 && !convex)
371 }
else if (neighbor[i] && !convex) {
378 if (touchingVertex) {
381 normal_return /= distance;
384 }
else if (touchingEdge==-1) {
386 normal_return = normal;
388 normal_return = -normal;
389 distance = -distance;
395 Vec3D VW = *vertex[touchingEdge] - *vertex[(touchingEdge==2)?0:(touchingEdge+1)];
398 normal_return /= distance;
407 const int s = vtk.
points.size();
412 for (
auto f :
face_) {
413 std::vector<double> cell;
415 cell.push_back(s+f.vertex[0]- &vertex_[0]);
416 cell.push_back(s+f.vertex[1]- &vertex_[0]);
417 cell.push_back(s+f.vertex[2]- &vertex_[0]);
void setNormal(Vec3D normal)
Sets the normal vector between the two interacting objects.
Mdouble X
the vector components
TriangulatedWall()
Default constructor.
static Vec3D getUnitVector(const Vec3D &a)
Returns a unit Vec3D based on a.
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
void setOverlap(Mdouble overlap)
Set the overlap between the two interacting object.
bool getDistanceAndNormal(const BaseParticle &p, Mdouble &distance, Vec3D &normal_return) const
Returns true if contact with the face exists, false if not. If contact exists, then the distance and ...
A TriangulatedWall is a triangulation created from a set of vertices and a n-by-3 connectivity matrix...
BaseInteraction * getInteraction(BaseInteractable *P, BaseInteractable *I, Mdouble timeStamp)
Returns the Interaction between the BaseInteractable's P and I.
bool getDistanceAndNormal(const BaseParticle &p, Mdouble &distance, Vec3D &normal_return) const override
Compute the distance from the wall for a given BaseParticle and return if there is a collision...
void setContactPoint(Vec3D contactPoint)
Set the location of the contact point between the two interacting objects.
void write(std::ostream &os) const override
Writes an TriangulatedWall to an output stream, for example a restart file.
static Mdouble dot(const Vec3D &a, const Vec3D &b)
Calculates the dot product of two Vec3D: .
void setDistance(Mdouble distance)
Sets the interaction distance between the two interacting objects.
Mdouble getLengthSquared() const
Calculates the squared length of this Vec3D: .
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
Stores information about interactions between two interactable objects; often particles but could be ...
std::vector< Vec3D > vertex_
Mdouble getWallInteractionRadius() const
Returns the interaction radius for interaction with walls. See also BaseParticle::getInteractionRadiu...
Struct used to store the properties of a face needed for contact detection.
void read(std::istream &is) override
Reads an TriangulatedWall from an input stream, for example a restart file.
TriangulatedWall & operator=(const TriangulatedWall &other)
void readVTK(std::string filename)
std::vector< BaseInteraction * > getInteractionWith(BaseParticle *p, Mdouble timeStamp, InteractionHandler *interactionHandler) override
Get the interaction between this TriangulatedWall and given BaseParticle at a given time...
std::array< Vec3D *, 3 > vertex
defines the three vertices (anticlockwise direction around the normal)
std::vector< std::vector< double > > triangleStrips
Container to store Interaction objects.
std::string getName() const override
Returns the name of the object, here the string "TriangulatedWall".
Vec3D normal
face normal (vertices are ordered anticlockwise direction around the normal)
static Vec3D cross(const Vec3D &a, const Vec3D &b)
Calculates the cross product of two Vec3D: .
Mdouble getRadius() const
Returns the particle's radius_.
void writeVTK(VTKContainer &vtk) const override
void move(const Vec3D &move) override
Move the TriangulatedWall to a new position, which is a Vec3D from the old position.
std::vector< Vec3D > points
Mdouble getLength() const
Calculates the length of this Vec3D: .
std::vector< Face > face_
virtual ~TriangulatedWall()
Destructor.
TriangulatedWall * copy() const override
Wall copy method. It calls the copy constructor of this Wall, useful for polymorphism.
Mdouble getDistance(const Vec3D &otherPosition) const
computes the signed distance to the face in normal direction
Implementation of a 3D vector (by Vitaliy).
virtual void move(const Vec3D &move)
Moves this BaseInteractable by adding an amount to the position.
void setSpecies(const ParticleSpecies *species)
Define the species of this wall.