Membrane::Edge Struct Reference

#include <Membrane.h>

Public Member Functions

void applyForce (Mdouble Kn, Mdouble critDampCoeff, Mdouble Ke, Mdouble Kd, bool bendingAreaConstant)
 Calculates and applies all neccesary forces. More...
 
void applyStretchForce (Mdouble Kn, Mdouble critDampCoeff)
 Apply the force due to stretching only. More...
 
void applyBendForce (Mdouble Kn, Mdouble Kd, bool bendingAreaConstant)
 Apply a force due to bending. More...
 
void calculateUPre (Vec3D &state, Mdouble &length, std::array< Mdouble, 2 > &faceArea)
 Calculate some prefactors for the bending penalty. More...
 
Mdouble getSineHalfTheta ()
 Calculate the sine of half the bending angle. More...
 
void handleParticleRemoval (unsigned int id)
 handle the partical removal More...
 
void handleParticleAddition (unsigned int id, BaseParticle *p)
 Handle the particle addition. More...
 
void checkActive ()
 check if the edge should calculate bending or stretch forces More...
 

Public Attributes

std::array< unsigned int, 2 > vertexId
 
std::array< BaseParticle *, 2 > vertex = {{nullptr}}
 
std::array< unsigned int, 2 > faceVertexId
 
std::array< BaseParticle *, 2 > faceVertex = {{nullptr}}
 
std::array< MeshTriangle *, 2 > face = {{nullptr}}
 
std::array< Mdouble, 2 > faceInitialArea
 
std::array< Mdouble, 8 > uPre
 
Vec3D initialState
 
Mdouble initialLength
 
Mdouble initialSineHalfTheta
 
Mdouble effectiveMass
 
bool isStretchActive
 
bool isBendActive
 

Detailed Description

A struct containing the information needed for calculations along one edge

Member Function Documentation

◆ applyBendForce()

void Membrane::Edge::applyBendForce ( Mdouble  Ke,
Mdouble  Kd,
bool  bendingAreaConstant 
)

Apply a force due to bending.

Parameters
[in]KeThe spring constant used for bending.
[in]KnThe dissipation constant used for bending.

This function applies the forces due to bending of the triangles connected by the edge. The calculation is based on the model described in doi:10.1109/SIBGRAPI.2014.20.

1116 {
1117  // Calculation according to doi:10.1109/SIBGRAPI.2014.20
1118  // Now bending
1119  // normal / face area
1120  if ( !isBendActive )
1121  {
1122  return;
1123  }
1124 
1125  unsigned int i;
1126 
1127  std::array<Vec3D, 4> u;
1128  std::array<Vec3D, 4> force;
1129 
1130  Vec3D initialState1 = vertex[1]->getPosition()-vertex[0]->getPosition();
1131  Mdouble initialLength1 = initialState1.getLength();
1132 
1133  // Do adapt when triangle changes
1134  std::array<Mdouble, 2> faceArea;
1135  if (!bendingAreaConstant)
1136  {
1137  faceArea[0] = face[0]->getArea();
1138  faceArea[1] = face[1]->getArea();
1139  }
1140  else
1141  {
1142  faceArea[0] = faceInitialArea[0];
1143  faceArea[1] = faceInitialArea[1];
1144  }
1145  calculateUPre(initialState1, initialLength1, faceArea);
1146 
1147 
1148  for (i=0; i<4; i++)
1149  {
1150  u[i] = face[0]->getFaceNormal() * uPre[i] + face[1]->getFaceNormal() * uPre[4+i];
1151  }
1152  Mdouble sineHalfTheta = getSineHalfTheta();
1153  Mdouble prefactor = Ke*initialLength1*initialLength1 / (faceArea[0]+faceArea[1]) * ( sineHalfTheta - initialSineHalfTheta );
1154 
1155  for (i=0; i<4; i++)
1156  {
1157  force[i] = prefactor*u[i];
1158  }
1159 
1160  Mdouble dThetadT = Vec3D::dot(u[0], faceVertex[0]->getVelocity())
1161  + Vec3D::dot(u[1], faceVertex[1]->getVelocity())
1162  + Vec3D::dot(u[2], vertex[0]->getVelocity())
1163  + Vec3D::dot(u[3], vertex[1]->getVelocity());
1164 
1165  prefactor = -Kd*initialLength1*dThetadT;
1166  for (i=0; i<4; i++)
1167  {
1168  force[i] += prefactor*u[i];
1169  }
1170 
1171  faceVertex[0]->addForce(force[0]);
1172  faceVertex[1]->addForce(force[1]);
1173  vertex[0]->addForce(force[2]);
1174  vertex[1]->addForce(force[3]);
1175 
1176 }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Definition: Kernel/Math/Vector.h:30
static Mdouble getLength(const Vec3D &a)
Calculates the length of a Vec3D: .
Definition: Vector.cc:350
static Mdouble dot(const Vec3D &a, const Vec3D &b)
Calculates the dot product of two Vec3D: .
Definition: Vector.cc:56
void calculateUPre(Vec3D &state, Mdouble &length, std::array< Mdouble, 2 > &faceArea)
Calculate some prefactors for the bending penalty.
Definition: Membrane.cc:1179
std::array< Mdouble, 8 > uPre
Definition: Membrane.h:102
bool isBendActive
Definition: Membrane.h:132
std::array< BaseParticle *, 2 > vertex
Definition: Membrane.h:76
Mdouble initialSineHalfTheta
Definition: Membrane.h:117
std::array< BaseParticle *, 2 > faceVertex
Definition: Membrane.h:87
std::array< Mdouble, 2 > faceInitialArea
Definition: Membrane.h:97
Mdouble getSineHalfTheta()
Calculate the sine of half the bending angle.
Definition: Membrane.cc:1206
std::array< MeshTriangle *, 2 > face
Definition: Membrane.h:92

References Vec3D::dot(), Vec3D::getLength(), and i.

Referenced by applyForce().

◆ applyForce()

void Membrane::Edge::applyForce ( Mdouble  Kn,
Mdouble  critDampCoeff,
Mdouble  Ke,
Mdouble  Kd,
bool  bendingAreaConstant 
)

Calculates and applies all neccesary forces.

Parameters
[in]KnThe spring constant used for stretching.
[in]critDampCoeffThe critical damping coefficient used for stretching.
[in]KeThe spring constant used for bending.
[in]KnThe dissipation constant used for bending.

This function applies the forces due to the mass spring system.

1068 {
1069  applyStretchForce(Kn, critDampCoeff);
1070  applyBendForce(Ke, Kd, bendingAreaConstant);
1071 }
void applyBendForce(Mdouble Kn, Mdouble Kd, bool bendingAreaConstant)
Apply a force due to bending.
Definition: Membrane.cc:1115
void applyStretchForce(Mdouble Kn, Mdouble critDampCoeff)
Apply the force due to stretching only.
Definition: Membrane.cc:1078

References applyBendForce(), and applyStretchForce().

◆ applyStretchForce()

void Membrane::Edge::applyStretchForce ( Mdouble  Kn,
Mdouble  critDampCoeff 
)

Apply the force due to stretching only.

Parameters
[in]KnThe spring constant used for stretching.
[in]critDampCoeffThe critical damping coefficient used for stretching.

This function applies the forces due to stretching of the edge

1079 {
1080  if ( !isStretchActive ) return;
1081  // First stretching
1082  Vec3D distanceVec = vertex[1]->getPosition() - vertex[0]->getPosition();
1083  Mdouble distance = distanceVec.getLength();
1084  Vec3D normal = distanceVec/distance;
1085 
1086  if (distance<0.1*initialLength)
1087  {
1088  logger(WARN, "Edge length critical: % of original length", distance/initialLength);
1089  }
1090 
1091  Vec3D normalDisplacement = normal*(initialLength-distance);
1092 
1093  Vec3D force = Vec3D(0,0,0);
1094 
1095  // Normal force
1096  force += normalDisplacement * Kn;
1097 
1098  // Damping
1099  Vec3D normalRelativeVelocity = normal* Vec3D::dot(normal, vertex[1]->getVelocity() - vertex[0]->getVelocity());
1100  Mdouble dissipationCoefficientN = 2*critDampCoeff * sqrt(effectiveMass * Kn);
1101  force += -dissipationCoefficientN*normalRelativeVelocity;
1102 
1103  // Normal force and Tangential Force
1104  vertex[0]->addForce(-force);
1105  vertex[1]->addForce(force);
1106 }
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
@ WARN
void normal(const Vector< double > &x, Vector< double > &normal)
Definition: free_surface_rotation.cc:65
Mdouble effectiveMass
Definition: Membrane.h:122
Mdouble initialLength
Definition: Membrane.h:112
bool isStretchActive
Definition: Membrane.h:127

References Vec3D::dot(), Vec3D::getLength(), logger, WallFunction::normal(), sqrt(), and WARN.

Referenced by applyForce().

◆ calculateUPre()

void Membrane::Edge::calculateUPre ( Vec3D state,
Mdouble length,
std::array< Mdouble, 2 > &  faceArea 
)

Calculate some prefactors for the bending penalty.

1180 {
1181  if ( face[0]==nullptr || face[1]==nullptr)
1182  {
1183  for (unsigned int i=0; i<8; i++)
1184  {
1185  uPre[i] = 0;
1186  }
1187  return;
1188  }
1189 
1190  uPre[0] = length/faceArea[0];
1191  uPre[1] = 0;
1192  uPre[2] = Vec3D::dot(state, faceVertex[0]->getPosition()-vertex[1]->getPosition()) / length / faceArea[0];
1193  uPre[3] = - Vec3D::dot(state, faceVertex[0]->getPosition()-vertex[0]->getPosition()) / length / faceArea[0];
1194 
1195  uPre[4] = 0;
1196  uPre[5] = length/faceArea[1];
1197 
1198  uPre[6] = + Vec3D::dot(state, faceVertex[1]->getPosition()-vertex[1]->getPosition()) / length / faceArea[1];
1199  uPre[7] = - Vec3D::dot(state, faceVertex[1]->getPosition()-vertex[0]->getPosition()) / length / faceArea[1];
1200 }

References Vec3D::dot(), and i.

◆ checkActive()

void Membrane::Edge::checkActive ( )

check if the edge should calculate bending or stretch forces

This function checks if the edge knows al required pointers to calculate and apply stretch and/or bending forces.

1282 {
1283  isStretchActive = !(!vertex[0] || !vertex[1]) && effectiveMass > 0;
1284  isBendActive = isStretchActive && !(!faceVertex[0] || !faceVertex[1] || !face[0] || !face[1]);
1285 }

◆ getSineHalfTheta()

Mdouble Membrane::Edge::getSineHalfTheta ( )

Calculate the sine of half the bending angle.

This function calculates the sinus of half the angle between the two connected triangles.

1207 {
1208  Mdouble dotProduct = Vec3D::dot(face[0]->getFaceNormal(), face[1]->getFaceNormal());
1209  Mdouble sineHalfTheta;
1210  if (dotProduct>=1)
1211  {
1212  sineHalfTheta = 0;
1213  }
1214  else
1215  {
1216  sineHalfTheta = sqrt((1-dotProduct)/2);
1217  }
1218 
1219  Vec3D initialState1 = vertex[1]->getPosition()-vertex[0]->getPosition();
1220  if (Vec3D::dot(Vec3D::cross(face[0]->getFaceNormal(), face[1]->getFaceNormal()), initialState1) < 0)
1221  {
1222  return -sineHalfTheta;
1223  }
1224  return sineHalfTheta;
1225 }
static Vec3D cross(const Vec3D &a, const Vec3D &b)
Calculates the cross product of two Vec3D: .
Definition: Vector.cc:143

References Vec3D::cross(), Vec3D::dot(), and sqrt().

◆ handleParticleAddition()

void Membrane::Edge::handleParticleAddition ( unsigned int  id,
BaseParticle p 
)

Handle the particle addition.

Parameters
[in]idThe id of the added particle
[in]pPointer to the added particle

This function handles the addition of a particle with the given id to the particle handler. If the particle is contained in the edge, the edge is potentially. reactivated. This function is potentially usable for MPI parallelization

1260 {
1261  unsigned int i;
1262  for (i=0; i<2; i++)
1263  {
1264  if (vertexId[i] == id)
1265  {
1266  vertex[i] = p;
1267  checkActive();
1268  }
1269  if (faceVertexId[i] == id)
1270  {
1271  faceVertex[i] = p;
1272  checkActive();
1273  }
1274  }
1275 }
float * p
Definition: Tutorial_Map_using.cpp:9
std::array< unsigned int, 2 > faceVertexId
Definition: Membrane.h:82
void checkActive()
check if the edge should calculate bending or stretch forces
Definition: Membrane.cc:1281
std::array< unsigned int, 2 > vertexId
Definition: Membrane.h:71

References i, and p.

◆ handleParticleRemoval()

void Membrane::Edge::handleParticleRemoval ( unsigned int  id)

handle the partical removal

Parameters
[in]idThe id of the removed particle

This function handles the removal of a particle with the given id from the particle handler. If the particle was contained in the edge, the edge is disabled. This function is potentially usable for MPI parallelization

1234 {
1235  unsigned int i;
1236  for (i=0; i<2; i++)
1237  {
1238  if (vertexId[i] == id)
1239  {
1240  vertex[i] = nullptr;
1241  isStretchActive = false;
1242  isBendActive = false;
1243  }
1244  if (faceVertexId[i] == id)
1245  {
1246  faceVertex[i] = nullptr;
1247  isBendActive = false;
1248  }
1249  }
1250 }

References i.

Member Data Documentation

◆ effectiveMass

Mdouble Membrane::Edge::effectiveMass

Stores the effective mass of the edge

◆ face

std::array<MeshTriangle*, 2> Membrane::Edge::face = {{nullptr}}

Stores a pointer to the faces connected by the edge

◆ faceInitialArea

std::array<Mdouble, 2> Membrane::Edge::faceInitialArea

Stores the initial area of the connected triangles

◆ faceVertex

std::array<BaseParticle*, 2> Membrane::Edge::faceVertex = {{nullptr}}

Stores a pointer to the remaining particles of faces connected by the edge

◆ faceVertexId

std::array<unsigned int, 2> Membrane::Edge::faceVertexId

Stores the ids of the remaining particles of faces connected by the edge

◆ initialLength

Mdouble Membrane::Edge::initialLength

Stores initial length of the edge

◆ initialSineHalfTheta

Mdouble Membrane::Edge::initialSineHalfTheta

Stores the initial sine of half the bending angle

◆ initialState

Vec3D Membrane::Edge::initialState

Stores the initial difference between the edge particles

◆ isBendActive

bool Membrane::Edge::isBendActive

Stores if the edge should calculate the bending penalty forces

◆ isStretchActive

bool Membrane::Edge::isStretchActive

Stores if the edge should calculate the disntance spring forces

◆ uPre

std::array<Mdouble, 8> Membrane::Edge::uPre

Stores values calculated for bending

◆ vertex

std::array<BaseParticle*, 2> Membrane::Edge::vertex = {{nullptr}}

Stores a pointer to the particles of the edge

◆ vertexId

std::array<unsigned int, 2> Membrane::Edge::vertexId

Stores the ids of the particles of the edge


The documentation for this struct was generated from the following files: