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.

1137 {
1138  // Calculation according to doi:10.1109/SIBGRAPI.2014.20
1139  // Now bending
1140  // normal / face area
1141  if ( !isBendActive )
1142  {
1143  return;
1144  }
1145 
1146  unsigned int i;
1147 
1148  std::array<Vec3D, 4> u;
1149  std::array<Vec3D, 4> force;
1150 
1151  Vec3D initialState1 = vertex[1]->getPosition()-vertex[0]->getPosition();
1152  Mdouble initialLength1 = initialState1.getLength();
1153 
1154  // Do adapt when triangle changes
1155  std::array<Mdouble, 2> faceArea;
1156  if (!bendingAreaConstant)
1157  {
1158  faceArea[0] = face[0]->getArea();
1159  faceArea[1] = face[1]->getArea();
1160  }
1161  else
1162  {
1163  faceArea[0] = faceInitialArea[0];
1164  faceArea[1] = faceInitialArea[1];
1165  }
1166  calculateUPre(initialState1, initialLength1, faceArea);
1167 
1168 
1169  for (i=0; i<4; i++)
1170  {
1171  u[i] = face[0]->getFaceNormal() * uPre[i] + face[1]->getFaceNormal() * uPre[4+i];
1172  }
1173  Mdouble sineHalfTheta = getSineHalfTheta();
1174  Mdouble prefactor = Ke*initialLength1*initialLength1 / (faceArea[0]+faceArea[1]) * ( sineHalfTheta - initialSineHalfTheta );
1175 
1176  for (i=0; i<4; i++)
1177  {
1178  force[i] = prefactor*u[i];
1179  }
1180 
1181  Mdouble dThetadT = Vec3D::dot(u[0], faceVertex[0]->getVelocity())
1182  + Vec3D::dot(u[1], faceVertex[1]->getVelocity())
1183  + Vec3D::dot(u[2], vertex[0]->getVelocity())
1184  + Vec3D::dot(u[3], vertex[1]->getVelocity());
1185 
1186  prefactor = -Kd*initialLength1*dThetadT;
1187  for (i=0; i<4; i++)
1188  {
1189  force[i] += prefactor*u[i];
1190  }
1191 
1192  faceVertex[0]->addForce(force[0]);
1193  faceVertex[1]->addForce(force[1]);
1194  vertex[0]->addForce(force[2]);
1195  vertex[1]->addForce(force[3]);
1196 
1197 }
double Mdouble
Definition: GeneralDefine.h:34
Definition: Vector.h:51
static Mdouble getLength(const Vec3D &a)
Calculates the length of a Vec3D: .
Definition: Vector.cc:331
static Mdouble dot(const Vec3D &a, const Vec3D &b)
Calculates the dot product of two Vec3D: .
Definition: Vector.cc:76
const std::complex< Mdouble > i
Definition: ExtendedMath.h:51
void calculateUPre(Vec3D &state, Mdouble &length, std::array< Mdouble, 2 > &faceArea)
Calculate some prefactors for the bending penalty.
Definition: Membrane.cc:1200
std::array< Mdouble, 8 > uPre
Definition: Membrane.h:123
bool isBendActive
Definition: Membrane.h:153
std::array< BaseParticle *, 2 > vertex
Definition: Membrane.h:97
Mdouble initialSineHalfTheta
Definition: Membrane.h:138
std::array< BaseParticle *, 2 > faceVertex
Definition: Membrane.h:108
std::array< Mdouble, 2 > faceInitialArea
Definition: Membrane.h:118
Mdouble getSineHalfTheta()
Calculate the sine of half the bending angle.
Definition: Membrane.cc:1227
std::array< MeshTriangle *, 2 > face
Definition: Membrane.h:113

References Vec3D::dot(), Vec3D::getLength(), and constants::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.

1089 {
1090  applyStretchForce(Kn, critDampCoeff);
1091  applyBendForce(Ke, Kd, bendingAreaConstant);
1092 }
void applyBendForce(Mdouble Kn, Mdouble Kd, bool bendingAreaConstant)
Apply a force due to bending.
Definition: Membrane.cc:1136
void applyStretchForce(Mdouble Kn, Mdouble critDampCoeff)
Apply the force due to stretching only.
Definition: Membrane.cc:1099

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

1100 {
1101  if ( !isStretchActive ) return;
1102  // First stretching
1103  Vec3D distanceVec = vertex[1]->getPosition() - vertex[0]->getPosition();
1104  Mdouble distance = distanceVec.getLength();
1105  Vec3D normal = distanceVec/distance;
1106 
1107  if (distance<0.1*initialLength)
1108  {
1109  logger(WARN, "Edge length critical: % of original length", distance/initialLength);
1110  }
1111 
1112  Vec3D normalDisplacement = normal*(initialLength-distance);
1113 
1114  Vec3D force = Vec3D(0,0,0);
1115 
1116  // Normal force
1117  force += normalDisplacement * Kn;
1118 
1119  // Damping
1120  Vec3D normalRelativeVelocity = normal* Vec3D::dot(normal, vertex[1]->getVelocity() - vertex[0]->getVelocity());
1121  Mdouble dissipationCoefficientN = 2*critDampCoeff * sqrt(effectiveMass * Kn);
1122  force += -dissipationCoefficientN*normalRelativeVelocity;
1123 
1124  // Normal force and Tangential Force
1125  vertex[0]->addForce(-force);
1126  vertex[1]->addForce(force);
1127 }
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
@ WARN
Mdouble effectiveMass
Definition: Membrane.h:143
Mdouble initialLength
Definition: Membrane.h:133
bool isStretchActive
Definition: Membrane.h:148

References Vec3D::dot(), Vec3D::getLength(), logger, 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.

1201 {
1202  if ( face[0]==nullptr || face[1]==nullptr)
1203  {
1204  for (unsigned int i=0; i<8; i++)
1205  {
1206  uPre[i] = 0;
1207  }
1208  return;
1209  }
1210 
1211  uPre[0] = length/faceArea[0];
1212  uPre[1] = 0;
1213  uPre[2] = Vec3D::dot(state, faceVertex[0]->getPosition()-vertex[1]->getPosition()) / length / faceArea[0];
1214  uPre[3] = - Vec3D::dot(state, faceVertex[0]->getPosition()-vertex[0]->getPosition()) / length / faceArea[0];
1215 
1216  uPre[4] = 0;
1217  uPre[5] = length/faceArea[1];
1218 
1219  uPre[6] = + Vec3D::dot(state, faceVertex[1]->getPosition()-vertex[1]->getPosition()) / length / faceArea[1];
1220  uPre[7] = - Vec3D::dot(state, faceVertex[1]->getPosition()-vertex[0]->getPosition()) / length / faceArea[1];
1221 }

References Vec3D::dot(), and constants::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.

1303 {
1304  isStretchActive = !(!vertex[0] || !vertex[1]) && effectiveMass > 0;
1305  isBendActive = isStretchActive && !(!faceVertex[0] || !faceVertex[1] || !face[0] || !face[1]);
1306 }

Referenced by Membrane::read().

◆ 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.

1228 {
1229  Mdouble dotProduct = Vec3D::dot(face[0]->getFaceNormal(), face[1]->getFaceNormal());
1230  Mdouble sineHalfTheta;
1231  if (dotProduct>=1)
1232  {
1233  sineHalfTheta = 0;
1234  }
1235  else
1236  {
1237  sineHalfTheta = sqrt((1-dotProduct)/2);
1238  }
1239 
1240  Vec3D initialState1 = vertex[1]->getPosition()-vertex[0]->getPosition();
1241  if (Vec3D::dot(Vec3D::cross(face[0]->getFaceNormal(), face[1]->getFaceNormal()), initialState1) < 0)
1242  {
1243  return -sineHalfTheta;
1244  }
1245  return sineHalfTheta;
1246 }
static Vec3D cross(const Vec3D &a, const Vec3D &b)
Calculates the cross product of two Vec3D: .
Definition: Vector.cc:163

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

◆ 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

1281 {
1282  unsigned int i;
1283  for (i=0; i<2; i++)
1284  {
1285  if (vertexId[i] == id)
1286  {
1287  vertex[i] = p;
1288  checkActive();
1289  }
1290  if (faceVertexId[i] == id)
1291  {
1292  faceVertex[i] = p;
1293  checkActive();
1294  }
1295  }
1296 }
std::array< unsigned int, 2 > faceVertexId
Definition: Membrane.h:103
void checkActive()
check if the edge should calculate bending or stretch forces
Definition: Membrane.cc:1302
std::array< unsigned int, 2 > vertexId
Definition: Membrane.h:92

References constants::i.

◆ 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

1255 {
1256  unsigned int i;
1257  for (i=0; i<2; i++)
1258  {
1259  if (vertexId[i] == id)
1260  {
1261  vertex[i] = nullptr;
1262  isStretchActive = false;
1263  isBendActive = false;
1264  }
1265  if (faceVertexId[i] == id)
1266  {
1267  faceVertex[i] = nullptr;
1268  isBendActive = false;
1269  }
1270  }
1271 }

References constants::i.

Member Data Documentation

◆ effectiveMass

Mdouble Membrane::Edge::effectiveMass

Stores the effective mass of the edge

Referenced by Membrane::buildMesh(), and Membrane::read().

◆ face

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

Stores a pointer to the faces connected by the edge

Referenced by Membrane::read().

◆ faceInitialArea

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

Stores the initial area of the connected triangles

Referenced by Membrane::read().

◆ faceVertex

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

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

Referenced by Membrane::read().

◆ faceVertexId

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

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

Referenced by Membrane::read().

◆ initialLength

Mdouble Membrane::Edge::initialLength

Stores initial length of the edge

Referenced by Membrane::buildMesh(), and Membrane::read().

◆ initialSineHalfTheta

Mdouble Membrane::Edge::initialSineHalfTheta

Stores the initial sine of half the bending angle

Referenced by Membrane::read().

◆ initialState

Vec3D Membrane::Edge::initialState

Stores the initial difference between the edge particles

Referenced by Membrane::buildMesh(), and Membrane::read().

◆ 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

Referenced by Membrane::read().

◆ vertex

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

Stores a pointer to the particles of the edge

Referenced by Membrane::buildMesh(), and Membrane::read().

◆ vertexId

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

Stores the ids of the particles of the edge

Referenced by Membrane::buildMesh(), and Membrane::read().


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