Membrane Class Reference

A Membrane consists of masses connected by springs. More...

#include <Membrane.h>

+ Inheritance diagram for Membrane:

Classes

struct  Edge
 

Public Member Functions

 Membrane ()
 Default constructor. More...
 
 Membrane (ParticleSpecies *membraneSpecies, ParticleSpecies *membraneParticleSpecies)
 
 ~Membrane () override
 Copy constructor. More...
 
Membranecopy () const
 Copy method. It calls the copy constructor of this Object. More...
 
void read (std::istream &is) override
 Reads a Membrane from an input stream, for example a restart file. More...
 
void write (std::ostream &os) const override
 Writes a Membrane to an output stream, for example a restart file. More...
 
std::string getName () const override
 Returns the name of the object, here the string "Membrane". More...
 
void setKnAndCrittDampCoeff (Mdouble Kn, Mdouble critDampCoeff)
 Set the parameters needed for the stretching forces. More...
 
void setElasticModulusAndThickness (Mdouble E, Mdouble thickness)
 Set the elastic modulus and thickness of the membrane. More...
 
void setSpringConstant (Mdouble k)
 Set the spring constant of the membrane. More...
 
void setCriticalDampingCoefficient (Mdouble coeff)
 Set damping coefficient for the distance springs. More...
 
void setKeAndKd (Mdouble Ke, Mdouble Kd)
 Set the parameters needed for the bending forces. More...
 
void setBendingAreaConstant (bool areaConstant)
 
void setThickness (Mdouble thickness)
 Set the thickness of the membrane. More...
 
Mdouble getKn ()
 
Mdouble getCriticalDampingCoefficient ()
 
Mdouble getKe ()
 
Mdouble getKd ()
 
Mdouble getThickness ()
 
Mdouble getBendingAreaConstant ()
 
void setParticleRadius (Mdouble radius)
 Set the radius of the vertex particles. More...
 
Mdouble getParticleRadius ()
 Returns the radius of the vertex particles. More...
 
void setDPMBase (DPMBase *dpm)
 Set a pointer to DPMBase. More...
 
DPMBasegetDPMBase ()
 Get the stored pointer to DPMBase. More...
 
std::vector< BaseParticle * > getVertexParticles ()
 Returns a vector with pointers to the vertex particles. More...
 
std::vector< MeshTriangle * > getFaces ()
 Returns a vecter with pointers to the mesh triangles. More...
 
void saveVertexPositions (std::ostream &os)
 save the current positions of the vertex particles to a stream More...
 
void loadVertexPositions (std::istream &is)
 Load the positions of the vertex particles from a stream and apply them to existing particles. More...
 
void saveAsOFF (unsigned int d)
 Save the Membrane as a .off file. More...
 
void saveAsSTL (std::string fileName)
 Save the Membrane as a .stl file. More...
 
void loadFromSTL (BaseParticle &p0, std::string fileName)
 Load the Membrane geometry from a .stl file. More...
 
void loadFromSTL (BaseParticle &p0, std::string fileName, Mdouble eps)
 Load the Membrane geometry from a .stl file. More...
 
void buildMesh (BaseParticle &p0, std::vector< Vec3D > vertexPositions, std::vector< unsigned int > edgeVertices, std::vector< unsigned int > faceVertices)
 Build the geometry from specified positions and their connectivity. More...
 
void adjustVertexParticleSize ()
 Calculates an updated radius for every vertex particle in order to account for the correct mass. More...
 
void updateEdgeMass ()
 Set the correct edge mass by taking the mass from the conencted vertices. More...
 
void computeAdditionalForces ()
 Compute the forces due to the mass spring system. More...
 
void applyPressure (Mdouble pressure)
 Apply a surface pressure to the membrane. More...
 
void handleParticleRemoval (unsigned int id)
 Handles the removal of vertex particles from the particle handler. More...
 
void handleParticleAddition (unsigned int id, BaseParticle *p)
 Handles the addition of vertex particles to the particle handler. More...
 
Mdouble getVolume ()
 Calculate the volume of the membrane. More...
 
- Public Member Functions inherited from BaseObject
 BaseObject ()=default
 Default constructor. More...
 
 BaseObject (const BaseObject &p)=default
 Copy constructor, copies all the objects BaseObject contains. More...
 
virtual ~BaseObject ()=default
 virtual destructor More...
 
virtual void moveInHandler (unsigned int index)
 Except that it is virtual, it does the same thing as setIndex() does. More...
 
void setIndex (unsigned int index)
 Allows one to assign an index to an object in the handler/container. More...
 
void setId (unsigned long id)
 Assigns a unique identifier to each object in the handler (container) which remains constant even after the object is deleted from the container/handler. More...
 
unsigned int getIndex () const
 Returns the index of the object in the handler. More...
 
unsigned int getId () const
 Returns the unique identifier of any particular object. More...
 
void setGroupId (unsigned groupId)
 
unsigned getGroupId () const
 

Private Member Functions

void createVertexParticles (BaseParticle &p0, std::vector< Vec3D > vertexPositions)
 Handles the actual creation of vertex particles. More...
 
void initializeEdgeBendingQuantities ()
 Compute the forces due to the mass spring system. More...
 
void updateFaceNeighbors ()
 Update the faces to have the correct neighbors. More...
 
unsigned int addVertex (std::vector< Vec3D > &vertices, Vec3D pos, Mdouble eps)
 Helper function to check if a given vertex already exists. More...
 
bool addEdge (std::vector< unsigned int > &edges, std::map< std::pair< unsigned int, unsigned int >, int > &map, unsigned int v0, unsigned int v1)
 Helper function to check if a given edge already exists. More...
 

Private Attributes

std::vector< BaseParticle * > vertexParticle_
 
std::vector< unsigned intvertexParticleId_
 
unsigned int vertexInitId_
 
std::vector< MeshTriangle * > face_
 
std::vector< unsigned intfaceVertices_
 
std::vector< Edgeedge_
 
Mdouble particleRadius_
 
Mdouble Kn_
 
Mdouble critDampCoeff_
 
Mdouble Ke_
 
Mdouble Kd_
 
Mdouble thickness_
 
bool bendingAreaConstant_
 
ParticleSpeciesmembraneSpecies_ = nullptr
 
ParticleSpeciesmembraneParticleSpecies_ = nullptr
 
DPMBaseDPMBase_ = nullptr
 

Detailed Description

A Membrane consists of masses connected by springs.

This class assumes, that the masses are connected in a triangular mesh. Additionally, for correct calculation of the spring constant for the distance spring, a hexagonal unit cell is assumed.

This class creates the particles required for the mass spring system. For contact detections, further triangular wall elements are created

Please make sure to provide appropriate a species for the particles as well as the wall elements (e.g giving the particles a species so that they do not interact with other particles in the simulation).

An instance of the membrane may be initialized with the following lines, e.g. by using a STL file:

// Initialize the membrane and set neccesary quantities
membrane.setDPMBase(this);
membrane.setKeAndKd(Ke_, Kd_);
// Set the (approximate) radius of the vertex particles
membrane.setParticleRadius(membraneParticleRadius_);
// Create an initial particle for the vertex particles
p0.setRadius(membrane.getParticleRadius());
p0.setVelocity(Vec3D(0.0, 0.0, 0.0));
// Create the system using the specified particle and stl file
membrane_.readFromSTL(p0, "geometry.stl");
Vector3f p0
Definition: MatrixBase_all.cpp:2
A Membrane consists of masses connected by springs.
Definition: Membrane.h:59
void setKnAndCrittDampCoeff(Mdouble Kn, Mdouble critDampCoeff)
Set the parameters needed for the stretching forces.
Definition: Membrane.cc:265
Mdouble critDampCoeff_
Definition: Membrane.h:441
ParticleSpecies * membraneSpecies_
Definition: Membrane.h:466
Mdouble Ke_
Definition: Membrane.h:446
ParticleSpecies * membraneParticleSpecies_
Definition: Membrane.h:471
void setParticleRadius(Mdouble radius)
Set the radius of the vertex particles.
Definition: Membrane.cc:307
Mdouble Kn_
Definition: Membrane.h:436
Mdouble Kd_
Definition: Membrane.h:451
Membrane()
Default constructor.
Definition: Membrane.cc:18
Mdouble getParticleRadius()
Returns the radius of the vertex particles.
Definition: Membrane.h:275
void setDPMBase(DPMBase *dpm)
Set a pointer to DPMBase.
Definition: Membrane.h:280
void setKeAndKd(Mdouble Ke, Mdouble Kd)
Set the parameters needed for the bending forces.
Definition: Membrane.cc:290
A spherical particle is the most simple particle used in MercuryDPM.
Definition: SphericalParticle.h:16
Definition: Kernel/Math/Vector.h:30

Note that the method computeAdditionalForces needs to be called from the overridden DPMBase::computeAdditionalForces every timestep for the Membrane to work.

As an example please also have a look at the Driver code MembraneDemo

Constructor & Destructor Documentation

◆ Membrane() [1/2]

Membrane::Membrane ( )

Default constructor.

19 {
20  logger(DEBUG, "Membrane() constructed.");
21  vertexInitId_ = 0;
22  particleRadius_ = 0;
23  Kn_ = 0;
24  critDampCoeff_ = 0;
25  Ke_ = 0;
26  Kd_ = 0;
27  thickness_ = 0;
29 }
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
@ DEBUG
Mdouble thickness_
Definition: Membrane.h:456
unsigned int vertexInitId_
Definition: Membrane.h:410
bool bendingAreaConstant_
Definition: Membrane.h:461
Mdouble particleRadius_
Definition: Membrane.h:431

References bendingAreaConstant_, critDampCoeff_, DEBUG, Kd_, Ke_, Kn_, logger, particleRadius_, thickness_, and vertexInitId_.

Referenced by copy().

◆ Membrane() [2/2]

Membrane::Membrane ( ParticleSpecies membraneSpecies,
ParticleSpecies membraneParticleSpecies 
)
31  : Membrane()
32 {
33  membraneSpecies_ = membraneSpecies;
34  membraneParticleSpecies_ = membraneParticleSpecies;
35 }

References membraneParticleSpecies_, and membraneSpecies_.

◆ ~Membrane()

Membrane::~Membrane ( )
override

Copy constructor.

Destructor.

Member Function Documentation

◆ addEdge()

bool Membrane::addEdge ( std::vector< unsigned int > &  edges,
std::map< std::pair< unsigned int, unsigned int >, int > &  map,
unsigned int  v0,
unsigned int  v1 
)
private

Helper function to check if a given edge already exists.

Parameters
[in]edgesThe vector, where the new edge should be added
[in]mapA map used to dtermin, if the edge already exists
[in]v0The index of the first point of the edge
[in]v0The index of the second point of the edge
Returns
True if a new edge was added, false if not.

This function adds a given edge to the vector edges, if it is not already contained.

568 {
569  if ( map.find(std::make_pair(v0, v1)) == map.end() ){
570  map[std::make_pair(v0,v1)] = 1;
571  map[std::make_pair(v1,v0)] = 1;
572 
573  edges.push_back(v0);
574  edges.push_back(v1);
575  return true;
576  }
577  return false;
578 }
M1<< 1, 2, 3, 4, 5, 6, 7, 8, 9;Map< RowVectorXf > v1(M1.data(), M1.size())

References v1().

Referenced by loadFromSTL().

◆ addVertex()

unsigned int Membrane::addVertex ( std::vector< Vec3D > &  vertices,
Vec3D  pos,
Mdouble  eps 
)
private

Helper function to check if a given vertex already exists.

Parameters
[in]verticesThe vector, where the new position should be added
[in]posThe new position to add to the vector
[in]epsThe distance between two points below which they are assumed to be the same.
Returns
the index of the position in the vector vertices.

This function adds a given position pos to the vector vertices, if it is not already contained.

543 {
544  unsigned int i;
545  for (i=0; i<vertices.size(); i++)
546  {
547  if ((vertices[i]-pos).getLength() < eps)
548  {
549  return i;
550  }
551  }
552 
553  vertices.push_back(pos);
554 
555  return vertices.size() - 1;
556 }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
double eps
Definition: crbond_bessel.cc:24

References CRBond_Bessel::eps, and i.

Referenced by loadFromSTL().

◆ adjustVertexParticleSize()

void Membrane::adjustVertexParticleSize ( )

Calculates an updated radius for every vertex particle in order to account for the correct mass.

Calculates an updated radius for every vertex particle in order to account for the correct mass.

886 {
887  std::vector<unsigned int> numberTriangles(vertexParticle_.size(), 0);
888  std::vector<Mdouble> massParticle(vertexParticle_.size(), 0.0);
889 
890  Mdouble mass;
891  for (auto f: face_)
892  {
893  // 3 Nodes per triangle
894  mass = 1/f->getInvMass()/3;
895  for (auto id: f->getVertexIds())
896  {
897  numberTriangles[id-vertexInitId_] += 1;
898  massParticle[id-vertexInitId_] += mass;
899  }
900  }
901 
902  unsigned int i;
903  Mdouble volume;
904  Mdouble radius;
906  for (i=0; i<vertexParticle_.size(); i++)
907  {
908  mass = massParticle[i]/numberTriangles[i];
909  volume = mass / density;
910  radius = std::cbrt(3.0/4.0 * volume/constants::pi);
911 
912  vertexParticle_[i]->setRadius(radius);
913  }
914 }
std::vector< BaseParticle * > vertexParticle_
Definition: Membrane.h:399
std::vector< MeshTriangle * > face_
Definition: Membrane.h:415
Mdouble getDensity() const
Allows density_ to be accessed.
Definition: ParticleSpecies.cc:98
static int f(const TensorMap< Tensor< int, 3 > > &tensor)
Definition: cxx11_tensor_map.cpp:237
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE T cbrt(const T &x)
Definition: MathFunctions.h:1320
density
Definition: UniformPSDSelfTest.py:19
radius
Definition: UniformPSDSelfTest.py:15
const Mdouble pi
Definition: ExtendedMath.h:23

References Eigen::numext::cbrt(), UniformPSDSelfTest::density, f(), face_, ParticleSpecies::getDensity(), i, membraneParticleSpecies_, constants::pi, UniformPSDSelfTest::radius, vertexInitId_, and vertexParticle_.

◆ applyPressure()

void Membrane::applyPressure ( Mdouble  pressure)

Apply a surface pressure to the membrane.

Parameters
[in]pressureValue of the surface pressure acing on the membrane [Pa]

This function applies a given pressure to the surface by calling the function applyPressure of a MeshTriangle.

957  {
958  // Set the pressureforce to 0
959  logger(DEBUG,"Calculating pressure force.");
960 
961  // #pragma omp parallel num_threads(getNumberOfOMPThreads())
962  {
963  // This should also be OMP parralelizable, because addForce pays attention
964  // to OMP
965  // #pragma omp for
966  for (unsigned int i=0; i < face_.size(); i++ ){
967  face_[i]->applyPressure(pressure);
968  }
969  }
970 }

References DEBUG, face_, i, and logger.

◆ buildMesh()

void Membrane::buildMesh ( BaseParticle p0,
std::vector< Vec3D vertexPositions,
std::vector< unsigned int edgeVertices,
std::vector< unsigned int faceVertices 
)

Build the geometry from specified positions and their connectivity.

Parameters
[in]p0BaseParticle that will be used for the vertex particles
[in]vertexPositionsThe position of the vertices
[in]edgeVerticesA vector of indices, where two consecutive values define the vertex particles connected by the edge
[in]faceVerticesA vector of indices, where three consecutive values define the vertex particles making up the triangle face

This function creates the actual mesh including the vertex particles and wall elements. The mass of the triangles is set to match the actual weight of the cooresponding triangle. The density of the particle species is set, so that the mass of a vertex particle is equal to 5/3 times the mass of a triangle.

593 {
594  unsigned int triangleCount = faceVertices.size() / 3;
595  unsigned int edgeCount = edgeVertices.size() / 2;
596  // #ifdef MERCURYDPM_USE_MPI
597  // if (PROCESSOR_ID==0)
598  // #endif
599  // logger(INFO, "Creating membrane with % vertices and % faces.", vertexPositions.size(), triangleCount);
600 
601  // Some helper variables
602  unsigned int i;
603  Vec3D v;
604 
605  // Calculate the density of the Membrane particles to approximately get the membrane weight
606  // Note this should be changed. But for the beginning it is a way of setting an approx. okej density for the particles.
607  i = 0;
608  Mdouble membraneDensity = membraneSpecies_->getDensity();
609 
610 
611  // Create particles corresponding to the Vertex Positions
612  createVertexParticles(p0, vertexPositions);
613 
614  Mdouble averageTriangleMass = 0;
615  Mdouble triangleMass = 0;
616  // Create all faces with their initial positions
617  face_.reserve(triangleCount);
618  for (i = 0; i < triangleCount; i++)
619  {
620  // It seems copyAndAddObject does not actually copy in MPI mode
621  MeshTriangle f;
622  f.setVertices(vertexPositions[faceVertices[3*i]],
623  vertexPositions[faceVertices[3*i+1]],
624  vertexPositions[faceVertices[3*i+2]]);
625  f.setVertexIds(vertexParticleId_[faceVertices[3*i]],
626  vertexParticleId_[faceVertices[3*i+1]],
627  vertexParticleId_[faceVertices[3*i+2]]);
628  f.setSpecies(membraneSpecies_);
629 
630  triangleMass = f.getArea()*thickness_*membraneDensity;
631  averageTriangleMass += triangleMass;
632  f.setMass(triangleMass);
633 
634  f.actionsAfterParticleGhostUpdate();
635 
636  face_.push_back(getDPMBase()->wallHandler.copyAndAddObject(f));
637 
638  }
639 
640  averageTriangleMass /= triangleCount;
641  Mdouble particleDensity = 5.0/3.0 * averageTriangleMass/(particleRadius_*particleRadius_*particleRadius_*4/3.0*constants::pi);
642  membraneParticleSpecies_->setDensity(particleDensity);
643 
644  // Create the edges
645  Mdouble invMass1, invMass2;
646 
648  for (i=0; i<edgeCount; i++){
649  Edge e;
650  e.vertexId[0] = vertexParticleId_[edgeVertices[2*i+0]];
651  e.vertexId[1] = vertexParticleId_[edgeVertices[2*i+1]];
652 
653  invMass1 = vertexInvMass;
654  invMass2 = vertexInvMass;
655 
656  e.vertex[0] = getDPMBase()->particleHandler.getObjectById(e.vertexId[0]);
657  e.vertex[1] = getDPMBase()->particleHandler.getObjectById(e.vertexId[1]);
658 
659  // e.vertex[1] = vertexParticle_[edgeVertices[2*i+1]];
660  e.initialState = vertexPositions[edgeVertices[2*i+1]]-vertexPositions[edgeVertices[2*i+0]];
661  e.initialLength = e.initialState.getLength();
662  e.effectiveMass = 1/(invMass1 + invMass2);
663 
664  // e.checkActive();
665  edge_.push_back(e);
666  }
667 
669 
670  for (i=0; i<edge_.size(); i++){
671  edge_[i].checkActive();
672  }
674  for (i=0; i<edge_.size(); i++)
675  {
676  edge_[i].calculateUPre(edge_[i].initialState, edge_[i].initialLength, edge_[i].faceInitialArea);
677  }
678 }
Array< int, Dynamic, 1 > v
Definition: Array_initializer_list_vector_cxx11.cpp:1
Array< double, 1, 3 > e(1./3., 0.5, 2.)
T * getObjectById(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
Definition: BaseHandler.h:573
ParticleHandler particleHandler
An object of the class ParticleHandler, contains the pointers to all the particles created.
Definition: DPMBase.h:1443
std::vector< unsigned int > vertexParticleId_
Definition: Membrane.h:404
void updateFaceNeighbors()
Update the faces to have the correct neighbors.
Definition: Membrane.cc:768
void createVertexParticles(BaseParticle &p0, std::vector< Vec3D > vertexPositions)
Handles the actual creation of vertex particles.
Definition: Membrane.cc:684
std::vector< Edge > edge_
Definition: Membrane.h:426
void initializeEdgeBendingQuantities()
Compute the forces due to the mass spring system.
Definition: Membrane.cc:706
DPMBase * getDPMBase()
Get the stored pointer to DPMBase.
Definition: Membrane.h:285
MeshTriangle implements a triangle whose vertex positions are defined by three particles.
Definition: MeshTriangle.h:54
void setDensity(Mdouble density)
Definition: ParticleSpecies.cc:88

References createVertexParticles(), e(), edge_, f(), face_, ParticleSpecies::getDensity(), getDPMBase(), BaseHandler< T >::getObjectById(), i, initializeEdgeBendingQuantities(), membraneParticleSpecies_, membraneSpecies_, p0, DPMBase::particleHandler, particleRadius_, constants::pi, ParticleSpecies::setDensity(), thickness_, updateFaceNeighbors(), v, and vertexParticleId_.

Referenced by loadFromSTL().

◆ computeAdditionalForces()

void Membrane::computeAdditionalForces ( )

Compute the forces due to the mass spring system.

This function iterates through all edges to calculate the forces due to the mass spring system. Ideally this function is called from the computeAllForces function of DPMBase.

945  {
946  #pragma omp parallel for schedule(static) num_threads(getDPMBase()->getNumberOfOMPThreads())
947  for (int i=0; i < edge_.size(); i++){
949  }
950 }

References bendingAreaConstant_, critDampCoeff_, edge_, i, Kd_, Ke_, and Kn_.

Referenced by MembraneDemo::computeAdditionalForces(), and MembraneSelfTest::computeAdditionalForces().

◆ copy()

Membrane * Membrane::copy ( ) const

Copy method. It calls the copy constructor of this Object.

Copy assignment operator.

  \param[in] other The Membrane that must be copied.
 &zwj;/

Membrane::Membrane(const Membrane& other) : BaseObject(other) { face_ = other.face_; membraneSpecies_ = other.membraneSpecies_; DPMBase_ = other.DPMBase_;

logger(DEBUG, "Membrane(Membrane&) constructed."); }

Membrane::~Membrane() { logger(DEBUG, "~Membrane() has been called."); }

/*!

Returns
pointer to a Membrane object allocated using new.
60 {
61  return new Membrane(*this);
62 }

References Membrane().

◆ createVertexParticles()

void Membrane::createVertexParticles ( BaseParticle p0,
std::vector< Vec3D vertexPositions 
)
private

Handles the actual creation of vertex particles.

Parameters
[in]p0The template particle used to create the vertex particles

This function creates a particle for every position in the vector vertexPositions

685 {
686 
688 
689  Vec3D pos;
690  for (unsigned int i = 0; i < vertexPositions.size(); i++){
691  pos = vertexPositions[i];
692  // Set the position
693  p0.setPosition(pos);
694 
695  // Add the particle and save a reference
697  vertexParticleId_.push_back(vertexInitId_+i);
698  vertexParticle_.push_back(getDPMBase()->particleHandler.getObjectById(vertexInitId_+i));
699  }
700 
701 }
std::enable_if<!std::is_pointer< U >::value, U * >::type copyAndAddObject(const U &object)
Creates a copy of a Object and adds it to the BaseHandler.
Definition: BaseHandler.h:360
unsigned int getNumberOfRealObjects() const
Returns the number of real objects (on all processors)
Definition: ParticleHandler.cc:1302

References BaseHandler< T >::copyAndAddObject(), getDPMBase(), ParticleHandler::getNumberOfRealObjects(), i, p0, DPMBase::particleHandler, vertexInitId_, vertexParticle_, and vertexParticleId_.

Referenced by buildMesh().

◆ getBendingAreaConstant()

Mdouble Membrane::getBendingAreaConstant ( )
inline
265 { return bendingAreaConstant_; }

References bendingAreaConstant_.

◆ getCriticalDampingCoefficient()

Mdouble Membrane::getCriticalDampingCoefficient ( )
inline

◆ getDPMBase()

DPMBase* Membrane::getDPMBase ( )
inline

Get the stored pointer to DPMBase.

285 { return DPMBase_; }
DPMBase * DPMBase_
Definition: Membrane.h:476

References DPMBase_.

Referenced by buildMesh(), createVertexParticles(), initializeEdgeBendingQuantities(), read(), and saveVertexPositions().

◆ getFaces()

std::vector<MeshTriangle*> Membrane::getFaces ( )
inline

Returns a vecter with pointers to the mesh triangles.

295 { return face_; };

References face_.

◆ getKd()

Mdouble Membrane::getKd ( )
inline
263 { return Kd_; }

References Kd_.

Referenced by MembraneDemo::setUpMembrane(), and MembraneSelfTest::setUpMembrane().

◆ getKe()

Mdouble Membrane::getKe ( )
inline
262 { return Ke_; }

References Ke_.

Referenced by MembraneDemo::setUpMembrane(), and MembraneSelfTest::setUpMembrane().

◆ getKn()

Mdouble Membrane::getKn ( )
inline
260 { return Kn_; }

References Kn_.

Referenced by MembraneDemo::setUpMembrane(), and MembraneSelfTest::setUpMembrane().

◆ getName()

std::string Membrane::getName ( ) const
overridevirtual

Returns the name of the object, here the string "Membrane".

Returns
The string "Membrane".

Implements BaseObject.

261 {
262  return "Membrane";
263 }

◆ getParticleRadius()

Mdouble Membrane::getParticleRadius ( )
inline

Returns the radius of the vertex particles.

275 { return particleRadius_; }

References particleRadius_.

Referenced by MembraneDemo::setUpMembrane(), and MembraneSelfTest::setUpMembrane().

◆ getThickness()

Mdouble Membrane::getThickness ( )
inline
264 { return thickness_; }

References thickness_.

◆ getVertexParticles()

std::vector<BaseParticle*> Membrane::getVertexParticles ( )
inline

Returns a vector with pointers to the vertex particles.

290 { return vertexParticle_; };

References vertexParticle_.

Referenced by MembraneDemo::fixMembraneEdges(), and MembraneSelfTest::fixMembraneEdges().

◆ getVolume()

Mdouble Membrane::getVolume ( )

Calculate the volume of the membrane.

Returns
volume The enclosed volume of the membrane

This function computes the current volume enclosed by the membrane. Note: This function uses the Divergence theorem to integrate along the surface. The volume is therefore only accurate, if the surface is closed.

1046 {
1047  Mdouble volume = 0;
1048 
1049  for (auto f: face_)
1050  {
1051  volume += Vec3D::dot(f->getPosition(), f->getFaceNormal()) * f->getArea();
1052  }
1053 
1054  return volume/3;
1055 }
static Mdouble dot(const Vec3D &a, const Vec3D &b)
Calculates the dot product of two Vec3D: .
Definition: Vector.cc:56

References Vec3D::dot(), f(), and face_.

◆ handleParticleAddition()

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

Handles the addition of vertex particles to the particle handler.

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 an edge, the edge is potentially. reactivated. This function is potentially usable for MPI parallelization

1013 {
1014  for (auto& e: edge_)
1015  {
1016  e.handleParticleAddition(id, p);
1017  }
1018 
1019  // Now find the corresponding vertexParticle_
1020  unsigned i = id - vertexInitId_;
1021  if (vertexParticleId_.size() > i && vertexParticleId_[i] == id)
1022  {
1023  vertexParticle_[i] = p;
1024  } else
1025  {
1026  // Need to search for it
1027  for (i = 0; i < vertexParticleId_.size(); i++)
1028  {
1029  if (vertexParticleId_[i]==id)
1030  {
1031  // now i is the correct index
1032  vertexParticle_[i] = p;
1033  break;
1034  }
1035  }
1036  }
1037 }
float * p
Definition: Tutorial_Map_using.cpp:9

References e(), edge_, i, p, vertexInitId_, vertexParticle_, and vertexParticleId_.

◆ handleParticleRemoval()

void Membrane::handleParticleRemoval ( unsigned int  id)

Handles the removal of vertex particles from the particle handler.

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 an edge, the edge is disabled. This function is potentially usable for MPI parallelization

979 {
980  for (auto& e: edge_)
981  {
982  e.handleParticleRemoval(id);
983  }
984 
985  // Now find the corresponding vertexParticle_
986  unsigned i = id - vertexInitId_;
987  if (vertexParticleId_[i] == id)
988  {
989  vertexParticle_[i] = nullptr;
990  } else
991  {
992  // Need to search for it
993  for (i = 0; i < vertexParticleId_.size(); i++)
994  {
995  if (vertexParticleId_[i]==id)
996  {
997  // now i is the coorect index
998  vertexParticle_[i] = nullptr;
999  break;
1000  }
1001  }
1002  }
1003 }

References e(), edge_, i, vertexInitId_, vertexParticle_, and vertexParticleId_.

◆ initializeEdgeBendingQuantities()

void Membrane::initializeEdgeBendingQuantities ( )
private

Compute the forces due to the mass spring system.

This function initializes the quantities and pointer needed on the edges for calculating the forces due to the mass spring system.

707 {
708  //set neighbours
709  unsigned int i, j;
710 
711  for (auto& e: edge_)
712  {
713  e.face[0] = nullptr;
714  e.face[1] = nullptr;
715  e.faceVertexId[0] = UINT_MAX;
716  e.faceVertexId[1] = UINT_MAX;
717  e.faceVertex[0] = nullptr;
718  e.faceVertex[1] = nullptr;
719  e.faceInitialArea[0] = 0;
720  e.faceInitialArea[1] = 0;
721  e.initialSineHalfTheta = 0;
722  i = 0;
723 
724  unsigned int edgeId0 = e.vertexId[0];
725  unsigned int edgeId1 = e.vertexId[1];
726 
727  for (unsigned int f=0; f<face_.size(); f++)
728  {
730  std::array<unsigned int, 3> particleIds = face0->getVertexIds();
731  j = UINT_MAX;
732 
733  if ( particleIds[0] == edgeId0)
734  {
735  if (particleIds[1] == edgeId1) j = particleIds[2];
736  if (particleIds[2] == edgeId1) j = particleIds[1];
737  }
738  else if ( particleIds[0] == edgeId1)
739  {
740  if (particleIds[1] == edgeId0) j = particleIds[2];
741  if (particleIds[2] == edgeId0) j = particleIds[1];
742  }
743  else if ( (particleIds[1] == edgeId1 && particleIds[2] == edgeId0)
744  ||(particleIds[1] == edgeId0 && particleIds[2] == edgeId1))
745  {
746  j = particleIds[0];
747  }
748 
749  if (j!=UINT_MAX)
750  {
751  e.faceVertexId[i] = j;
752  e.faceVertex[i] = getDPMBase()->particleHandler.getObjectById(j);
753  e.face[i] = face0;
754  e.faceInitialArea[i] = face0->getArea();
755  if (i==1)
756  {
757  e.initialSineHalfTheta = e.getSineHalfTheta();
758  }
759  i += 1;
760  }
761  }
762  }
763 }
void face0(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the face s0 = -1.0.
Definition: Qelement_face_coordinate_translation_schemes.cc:38
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References e(), edge_, f(), oomph::QElement1FaceToBulkCoordinates::face0(), face_, getDPMBase(), BaseHandler< T >::getObjectById(), i, j, and DPMBase::particleHandler.

Referenced by buildMesh().

◆ loadFromSTL() [1/2]

void Membrane::loadFromSTL ( BaseParticle p0,
std::string  fileName 
)

Load the Membrane geometry from a .stl file.

Parameters
[in]p0BaseParticle that will be used for the vertex particles
[in]fileNameThe name of the file to load.

This function loads the geometry from the STL file and calls the function buildMesh.

466 {
467  loadFromSTL(p0, fileName, 1e-8);
468 }
void loadFromSTL(BaseParticle &p0, std::string fileName)
Load the Membrane geometry from a .stl file.
Definition: Membrane.cc:465
string fileName
Definition: UniformPSDSelfTest.py:10

References e(), UniformPSDSelfTest::fileName, and p0.

Referenced by MembraneDemo::setUpMembrane(), and MembraneSelfTest::setUpMembrane().

◆ loadFromSTL() [2/2]

void Membrane::loadFromSTL ( BaseParticle p0,
std::string  fileName,
Mdouble  eps 
)

Load the Membrane geometry from a .stl file.

Parameters
[in]p0BaseParticle that will be used for the vertex particles
[in]fileNameThe name of the file to load.
[in]epsThe distance between two points below which they are assumed to be the same.

This function loads the geometry from the STL file and calls the function buildMesh.

479 {
480  std::vector<Vec3D> vertexPositions;
481  std::vector<unsigned int> edgeVertices;
482  std::vector<unsigned int> faceVertices;
483 
484 
485  std::ifstream is;
486  is.open(fileName, std::ios_base::in);
487 
488  if (!is.is_open())
489  logger(ERROR, "Membrane::loadFromSTL Cannot open file %.", fileName);
490 
491  std::string dummy;
492  unsigned int i;
493  Vec3D pos;
494 
495  // solid name
496  is >> dummy >> dummy;
497  // endsolid or facet
498  is >> dummy;
499  while ( dummy.compare("endsolid") )
500  {
501  // normal Vec3D
502  is >> dummy >> pos;
503  // outer loop
504  is >> dummy >> dummy;
505  for (i=0; i<3; i++)
506  {
507  // vertex pos
508  is >> dummy >> pos;
509  faceVertices.push_back(addVertex(vertexPositions, pos, eps));
510  }
511  // endloop
512  is >> dummy;
513  // endfacet
514  is >> dummy;
515  // endsolid or facet
516  is >> dummy;
517  }
518  is.close();
519 
520  // Create the neccesary edges;
521  std::map<std::pair<unsigned int, unsigned int>, int> existingEdges;
522  for (i=0; i<faceVertices.size()/3; i++)
523  {
524  addEdge(edgeVertices, existingEdges, faceVertices[3*i+0], faceVertices[3*i+1]);
525  addEdge(edgeVertices, existingEdges, faceVertices[3*i+1], faceVertices[3*i+2]);
526  addEdge(edgeVertices, existingEdges, faceVertices[3*i+2], faceVertices[3*i+0]);
527  }
528 
529  // logger(INFO, "Got % vertices, % edges % faces", vertexPositions.size(), edgeVertices.size()/2, faceVertices.size()/3);
530  buildMesh(p0, vertexPositions, edgeVertices, faceVertices);
531 }
@ ERROR
unsigned int addVertex(std::vector< Vec3D > &vertices, Vec3D pos, Mdouble eps)
Helper function to check if a given vertex already exists.
Definition: Membrane.cc:542
void buildMesh(BaseParticle &p0, std::vector< Vec3D > vertexPositions, std::vector< unsigned int > edgeVertices, std::vector< unsigned int > faceVertices)
Build the geometry from specified positions and their connectivity.
Definition: Membrane.cc:592
bool addEdge(std::vector< unsigned int > &edges, std::map< std::pair< unsigned int, unsigned int >, int > &map, unsigned int v0, unsigned int v1)
Helper function to check if a given edge already exists.
Definition: Membrane.cc:567
std::string string(const unsigned &i)
Definition: oomph_definitions.cc:286

References addEdge(), addVertex(), buildMesh(), CRBond_Bessel::eps, ERROR, UniformPSDSelfTest::fileName, i, logger, p0, and oomph::Global_string_for_annotation::string().

◆ loadVertexPositions()

void Membrane::loadVertexPositions ( std::istream &  is)

Load the positions of the vertex particles from a stream and apply them to existing particles.

363 {
364  unsigned int nVertices, i;
365  std::string dummy;
366  Vec3D pos;
367  is >> dummy >> nVertices;
368  is >> dummy;
369 
370  #ifdef MERCURYDPM_USE_MPI
371  if (PROCESSOR_ID==0)
372  #endif
373  logger.assert_always(nVertices==vertexParticleId_.size(),
374  "Error in Membrane::loadVertexPositions: The number of saved Particles differs from the number of actual particles");
375  for (i=0; i<nVertices; i++)
376  {
377  is >> pos;
378  if (vertexParticle_[i])
379  {
380  vertexParticle_[i]->setPosition(pos);
381  }
382  }
383 
384  // #ifdef MERCURYDPM_USE_MPI
385  // if (PROCESSOR_ID==0)
386  // #endif
387  // logger(INFO, "Loaded % membrane particles", nVertices);
388 }
#define PROCESSOR_ID
Definition: GeneralDefine.h:42

References i, logger, PROCESSOR_ID, oomph::Global_string_for_annotation::string(), vertexParticle_, and vertexParticleId_.

◆ read()

void Membrane::read ( std::istream &  is)
overridevirtual

Reads a Membrane from an input stream, for example a restart file.

Parameters
[in]isThe input stream from which the Membrane is read, usually a restart file.

Implements BaseObject.

69 {
70 
71  logger.assert_debug(DPMBase_, "Error in Membrane::read: DPMBase is not knwon.");
72 
73  std::string dummy;
74  unsigned int i, n, Id;
75 
76  // Reading in the Ids of all the vertex particles
77  is >> dummy >> n;
78  vertexParticle_.reserve(n);
79  for (i=0; i<n; i++)
80  {
81  is >> Id;
82  vertexParticleId_.push_back(Id);
83  // this might retrieve a nullptr
84  vertexParticle_.push_back(getDPMBase()->particleHandler.getObjectById(Id));
85  }
86  is >> dummy >> vertexInitId_;
87 
88  // Reading in the Ids of the faces
89  is >> dummy >> n;
90  face_.reserve(n);
91  MeshTriangle* f;
92  for (i=0; i<n; i++)
93  {
94  is >> Id;
95  f = dynamic_cast<MeshTriangle*>(getDPMBase()->wallHandler.getObjectById(Id));
96  face_.push_back(f);
97  }
98 
99  // Reading in the edge information
100  is >> dummy >> n;
101  edge_.reserve(n);
102  for (i=0; i<n; i++)
103  {
104  Edge e;
105  // the vertex ids
106  is >> dummy >> e.vertexId[0];
107  e.vertex[0] = getDPMBase()->particleHandler.getObjectById(e.vertexId[0]);
108  is >> dummy >> e.vertexId[1];
109  e.vertex[1] = getDPMBase()->particleHandler.getObjectById(e.vertexId[1]);
110 
111  is >> dummy >> e.faceVertexId[0];
112  if (e.faceVertexId[0] != UINT_MAX) {
113  e.faceVertex[0] = getDPMBase()->particleHandler.getObjectById(e.faceVertexId[0]);
114  } else {
115  e.faceVertex[0] = nullptr;
116  }
117  is >> dummy >> e.faceVertexId[1];
118  if (e.faceVertexId[1] != UINT_MAX) {
119 
120  e.faceVertex[1] = getDPMBase()->particleHandler.getObjectById(e.faceVertexId[1]);
121  } else {
122  e.faceVertex[1] = nullptr;
123  }
124  is >> dummy >> Id;
125  if (Id != UINT_MAX) {
126  e.face[0] = dynamic_cast<MeshTriangle*>(getDPMBase()->wallHandler.getObjectById(Id));
127  } else {
128  e.face[0] = nullptr;
129  }
130  is >> dummy >> Id;
131  if (Id != UINT_MAX) {
132  e.face[1] = dynamic_cast<MeshTriangle*>(getDPMBase()->wallHandler.getObjectById(Id));
133  } else {
134  e.face[1] = nullptr;
135  }
136 
137  is >> dummy >> e.faceInitialArea[0];
138  is >> dummy >> e.faceInitialArea[1];
139  for (unsigned int i=0; i<8; i++){
140  is >> dummy >> e.uPre[i];
141  }
142 
143  // initial state
144  is >> dummy >> e.initialState;
145  is >> dummy >> e.initialLength;
146 
147  is >> dummy >> e.initialSineHalfTheta;
148 
149  is >> dummy >> e.effectiveMass;
150 
151  e.checkActive();
152  edge_.push_back(e);
153  }
154 
155  // Reading in some general attributes
156  is >> dummy >> particleRadius_; // Mdouble
157 
158  is >> dummy >> Kn_; // Mdouble
159  is >> dummy >> critDampCoeff_; //Mdouble
160 
161  is >> dummy >> Ke_; // Mdouble
162  is >> dummy >> Kd_; // Mdouble
163 
164  is >> dummy >> thickness_;
165 
166  is >> dummy >> bendingAreaConstant_;
167 
168  is >> dummy >> Id;
170  is >> dummy >> Id;
172 
173  for (auto& e: edge_)
174  {
175  e.checkActive();
176  }
177 }
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
SpeciesHandler speciesHandler
A handler to that stores the species type i.e. LinearViscoelasticSpecies, etc.
Definition: DPMBase.h:1433
WallHandler wallHandler
An object of the class WallHandler. Contains pointers to all the walls created.
Definition: DPMBase.h:1453

References bendingAreaConstant_, critDampCoeff_, DPMBase_, e(), edge_, f(), face_, getDPMBase(), BaseHandler< T >::getObjectById(), i, Kd_, Ke_, Kn_, logger, membraneParticleSpecies_, membraneSpecies_, n, DPMBase::particleHandler, particleRadius_, DPMBase::speciesHandler, oomph::Global_string_for_annotation::string(), thickness_, vertexInitId_, vertexParticle_, vertexParticleId_, and DPMBase::wallHandler.

◆ saveAsOFF()

void Membrane::saveAsOFF ( unsigned int  d)

Save the Membrane as a .off file.

Parameters
[in]unsignedint d

This function saves the current geometry of the membrane to a file named membrane.$d.off.

396 {
397  std::stringstream lastName("");
398  lastName << "membrane." << d << ".off";
399 
400  std::ofstream membraneOFF;
401  membraneOFF.open(lastName.str(), std::ios_base::out);
402 
403  membraneOFF << "OFF\n";
404  membraneOFF << "# membrane.off\n";
405 
406  // Number of Vertices Faces and Edges (edges are optional)
407  membraneOFF << vertexParticle_.size() << " " << face_.size() << " 0" << std::endl;
408 
409  // Print the coordinates of all vertices
410  for (auto p: vertexParticle_)
411  {
412  membraneOFF << p->getPosition() << std::endl;
413  }
414 
415  // Print all faces
416  for (auto f: face_)
417  {
418  membraneOFF << "3 ";
419  for (auto id: f->getVertexIds())
420  {
421  membraneOFF << id - vertexInitId_ << " ";
422  }
423  membraneOFF << std::endl;
424  }
425 }
std::ofstream out("Result.txt")

References f(), face_, out(), p, vertexInitId_, and vertexParticle_.

◆ saveAsSTL()

void Membrane::saveAsSTL ( std::string  fileName)

Save the Membrane as a .stl file.

Parameters
[in]fileNameThe name of the file where the data is written to.

This function writes the current geometry of the Membrane to a STL file.

433 {
434  std::ofstream os;
435  os.open(fileName, std::ios_base::out);
436 
437  if (!os.is_open())
438  logger(ERROR, "Membrane::saveAsSTL Cannot open file %.", fileName);
439 
440  os << "solid Membrane" << std::endl;
441 
442  std::array<Vec3D,3> vertexPositions;
443  for (auto face: face_)
444  {
445  os << " facet normal " << face->getFaceNormal() << std::endl;
446  os << " outer loop" << std::endl;
447  vertexPositions = face->getVertices();
448  for (auto pos: vertexPositions)
449  {
450  os << " vertex " << pos << std::endl;
451  }
452  os << " endloop" << std::endl;
453  os << " endfacet" << std::endl;
454  }
455 
456  os << "endsolid Membrane" << std::endl;
457 }

References ERROR, face_, UniformPSDSelfTest::fileName, logger, and out().

◆ saveVertexPositions()

void Membrane::saveVertexPositions ( std::ostream &  os)

save the current positions of the vertex particles to a stream

314 {
315  #ifdef MERCURYDPM_USE_MPI
316  if (PROCESSOR_ID==0)
317  {
318  os << " nMembraneParticles " << vertexParticleId_.size();
319  os << " membraneParticlePositions ";
320  }
321 
322  Vec3D pos, pos1;
323  Mdouble active;
324  BaseParticle* p0;
325  for (unsigned int i=0; i < vertexParticleId_.size(); i++)
326  {
327  pos = Vec3D(0,0,0);
329  if (p0 && !p0->isMPIParticle())
330  {
331  pos = p0->getPosition();
332  active = getMPISum(1.0);
333  }
334  else
335  {
336  active = getMPISum(0.0);
337  }
338 
339  pos1 = getMPISum(pos);
340  if (PROCESSOR_ID==0 && active > 0.1)
341  {
342  os << pos1 << " ";
343  }
344  }
345  if (PROCESSOR_ID==0)
346  {
347  os << "\n";
348  }
349  #else
350  os << " nMembraneParticles " << vertexParticleId_.size();
351  os << " membraneParticlePositions ";
352  BaseParticle* p0;
353  for (unsigned int i=0; i < vertexParticleId_.size(); i++)
354  {
356  os << p0->getPosition() << " ";
357  }
358  #endif
359 }
Vec3D getMPISum(Vec3D &val)
Definition: MpiDataClass.cc:178
Definition: BaseParticle.h:33

References getDPMBase(), getMPISum(), BaseHandler< T >::getObjectById(), i, p0, DPMBase::particleHandler, PROCESSOR_ID, and vertexParticleId_.

◆ setBendingAreaConstant()

void Membrane::setBendingAreaConstant ( bool  areaConstant)

If set to true, the bending penalty is calulated using the initial triangle area instead of the current one.

303 {
304  bendingAreaConstant_ = areaConstant;
305 }

References bendingAreaConstant_.

◆ setCriticalDampingCoefficient()

void Membrane::setCriticalDampingCoefficient ( Mdouble  coeff)

Set damping coefficient for the distance springs.

283 {
284  critDampCoeff_ = coeff;
285 }

References critDampCoeff_.

Referenced by MembraneDemo::setUpMembrane(), and MembraneSelfTest::setUpMembrane().

◆ setDPMBase()

void Membrane::setDPMBase ( DPMBase dpm)
inline

Set a pointer to DPMBase.

280 { DPMBase_ = dpm; }

References DPMBase_.

Referenced by MembraneDemo::read(), MembraneSelfTest::read(), MembraneDemo::setUpMembrane(), and MembraneSelfTest::setUpMembrane().

◆ setElasticModulusAndThickness()

void Membrane::setElasticModulusAndThickness ( Mdouble  E,
Mdouble  thickness 
)

Set the elastic modulus and thickness of the membrane.

The supplied values are used to calculate the spring constant of the membrane.

271 {
272  setThickness(thickness);
273  Kn_ = E * thickness_/(sqrt(3)*(1-1/3.0));
274 }
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
void setThickness(Mdouble thickness)
Set the thickness of the membrane.
Definition: Membrane.cc:296
double E
Elastic modulus.
Definition: TwenteMeshGluing.cpp:68

References Global_Physical_Variables::E, Kn_, setThickness(), sqrt(), and thickness_.

Referenced by MembraneDemo::setUpMembrane(), and MembraneSelfTest::setUpMembrane().

◆ setKeAndKd()

void Membrane::setKeAndKd ( Mdouble  Ke,
Mdouble  Kd 
)

Set the parameters needed for the bending forces.

291 {
292  Ke_ = Ke;
293  Kd_ = Kd;
294 }

References Kd_, and Ke_.

Referenced by MembraneDemo::setUpMembrane(), and MembraneSelfTest::setUpMembrane().

◆ setKnAndCrittDampCoeff()

void Membrane::setKnAndCrittDampCoeff ( Mdouble  Kn,
Mdouble  critDampCoeff 
)

Set the parameters needed for the stretching forces.

265  {
266  Kn_ = Kn;
267  critDampCoeff_ = critDampCoeff;
268 }

References critDampCoeff_, and Kn_.

◆ setParticleRadius()

void Membrane::setParticleRadius ( Mdouble  radius)

Set the radius of the vertex particles.

308 {
309  logger.assert_debug(radius > 0, "Error in Membrane::setParticleRadius: Radius has to be greater than 0.");
311 }

References logger, particleRadius_, and UniformPSDSelfTest::radius.

Referenced by MembraneDemo::setUpMembrane(), and MembraneSelfTest::setUpMembrane().

◆ setSpringConstant()

void Membrane::setSpringConstant ( Mdouble  k)

Set the spring constant of the membrane.

277 {
278  logger.assert_debug(k >= 0, "Error in Membrane::setSpringConstant: The constant has to be greater than or equal to 0.");
279  Kn_ = k;
280 }
char char char int int * k
Definition: level2_impl.h:374

References k, Kn_, and logger.

◆ setThickness()

void Membrane::setThickness ( Mdouble  thickness)

Set the thickness of the membrane.

297 {
298  logger.assert_debug(thickness > 0, "Error in Membrane::setThickness: The thickness has to be greater than 0.");
299  thickness_ = thickness;
300 }

References logger, and thickness_.

Referenced by setElasticModulusAndThickness().

◆ updateEdgeMass()

void Membrane::updateEdgeMass ( )

Set the correct edge mass by taking the mass from the conencted vertices.

Set the correct edge mass by taking the mass from the conencted vertices.

920 {
921  Mdouble invMass;
922  for (auto e: edge_)
923  {
924  invMass = vertexParticle_[e.vertexId[0]-vertexInitId_]->getInvMass()
925  + vertexParticle_[e.vertexId[1]-vertexInitId_]->getInvMass();
926 
927  if (invMass > 0)
928  {
929  e.effectiveMass = 1/invMass;
930  }
931  else
932  {
933  e.effectiveMass = 0;
934  }
935 
936  e.checkActive();
937  }
938 }

References e(), edge_, vertexInitId_, and vertexParticle_.

Referenced by MembraneDemo::fixMembraneEdges().

◆ updateFaceNeighbors()

void Membrane::updateFaceNeighbors ( )
private

Update the faces to have the correct neighbors.

This function assigns the coorect neighbors to the wall elements.

769 {
770  //set neighbours
771  unsigned int i, j, k, l;
772 
773  for (i =0 ; i<face_.size(); i++)
774  {
775  face_[i]->vertexNeighbors = std::vector<std::vector<unsigned int>>();
776  for (j=0; j<3; j++)
777  {
778  face_[i]->neighbor[j] = nullptr;
779  std::vector<unsigned int> a;
780  face_[i]->vertexNeighbors.push_back(a);
781  }
782  }
783  for (i =0 ; i<face_.size(); i++)
784  {
786  std::array<unsigned int, 3> particleIds0 = face0->getVertexIds();
787  for (j=i+1 ; j<face_.size(); j++)
788  {
790  std::array<unsigned int, 3> particleIds1 = face1->getVertexIds();
791  if (particleIds0[0] == particleIds1[0])
792  {
793  if (particleIds0[1] == particleIds1[2])
794  { //edge 0=2
795  face0->neighbor[0] = &*face1;
796  face1->neighbor[2] = &*face0;
797  }
798  else if (particleIds0[2] == particleIds1[1])
799  { //edge 2=0
800  face0->neighbor[2] = &*face1;
801  face1->neighbor[0] = &*face0;
802  }
803  }
804  else if (particleIds0[0] == particleIds1[1])
805  {
806  if (particleIds0[1] == particleIds1[0])
807  { //edge 0=0
808  face0->neighbor[0] = &*face1;
809  face1->neighbor[0] = &*face0;
810  }
811  else if (particleIds0[2] == particleIds1[2])
812  { //edge 2=1
813  face0->neighbor[2] = &*face1;
814  face1->neighbor[1] = &*face0;
815  }
816  }
817  else if (particleIds0[0] == particleIds1[2])
818  {
819  if (particleIds0[1] == particleIds1[1])
820  { //edge 0=1
821  face0->neighbor[0] = &*face1;
822  face1->neighbor[1] = &*face0;
823  }
824  else if (particleIds0[2] == particleIds1[0])
825  { //edge 2=2
826  face0->neighbor[2] = &*face1;
827  face1->neighbor[2] = &*face0;
828  }
829  }
830  else if (particleIds0[1] == particleIds1[0])
831  {
832  if (particleIds0[2] == particleIds1[2])
833  { //edge 1=2
834  face0->neighbor[1] = &*face1;
835  face1->neighbor[2] = &*face0;
836  }
837  }
838  else if (particleIds0[1] == particleIds1[1])
839  {
840  if (particleIds0[2] == particleIds1[0])
841  { //edge 1=0
842  face0->neighbor[1] = &*face1;
843  face1->neighbor[0] = &*face0;
844  }
845  }
846  else if (particleIds0[1] == particleIds1[2])
847  {
848  if (particleIds0[2] == particleIds1[1])
849  { //edge 1=1
850  face0->neighbor[1] = &*face1;
851  face1->neighbor[1] = &*face0;
852  }
853  }
854 
855  }
856  }
857 
858  for (i =0 ; i<face_.size(); i++)
859  {
861  std::array<unsigned int, 3> particleIds0 = face0->getVertexIds();
862  for (j=i+1 ; j<face_.size(); j++)
863  {
865  std::array<unsigned int, 3> particleIds1 = face1->getVertexIds();
866  for (k=0; k<3; k++)
867  {
868  for (l=0; l<3; l++)
869  {
870  if( particleIds0[k] == particleIds1[l])
871  {
872  face0->vertexNeighbors[k].push_back(face1->getId());
873  face1->vertexNeighbors[l].push_back(face0->getId());
874  }
875  }
876  }
877  }
878  }
879 }
const Scalar * a
Definition: level2_cplx_impl.h:32
void face1(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the face s0 = 1.0.
Definition: Qelement_face_coordinate_translation_schemes.cc:44

References a, oomph::QElement1FaceToBulkCoordinates::face0(), oomph::QElement1FaceToBulkCoordinates::face1(), face_, i, j, and k.

Referenced by buildMesh().

◆ write()

void Membrane::write ( std::ostream &  os) const
overridevirtual

Writes a Membrane to an output stream, for example a restart file.

Parameters
[in]osThe output stream where the Membrane must be written to, usually a restart file.

Implements BaseObject.

184 {
185 
186  // Write out the vertex-Particle Ids
187  os << " vertexParticle " << vertexParticleId_.size();
188  for (unsigned int i: vertexParticleId_)
189  {
190  os << " " << i;
191  }
192 
193  os << " vertexInitId_ " << vertexInitId_;
194  os << "\n";
195 
196  // Write out the face-wall Ids
197  os << " face " << face_.size();
198  for (auto f: face_)
199  {
200  os << " " << f->getId();
201  }
202  os << "\n";
203 
204  // Write out edge information
205  os << " edge " << edge_.size();
206  for (auto e: edge_)
207  {
208  // the vertex ids
209  os << " v3 " << e.vertexId[0];
210  os << " v4 " << e.vertexId[1];
211 
212 
213  os << " v1 " << e.faceVertexId[0];
214  os << " v2 " << e.faceVertexId[1];
215 
216  if (e.face[1] != nullptr){
217  os << " f1 " << e.face[0]->getId();
218  } else {
219  os << " f1 " << UINT_MAX;
220  }
221  if (e.face[1] != nullptr){
222  os << " f2 " << e.face[1]->getId();
223  } else {
224  os << " f2 " << UINT_MAX;
225  }
226 
227  os << " area1 " << e.faceInitialArea[0];
228  os << " area2 " << e.faceInitialArea[1];
229  for (unsigned int i=0; i<8; i++){
230  os << " uPre " << e.uPre[i];
231  }
232  // initial state
233  os << " initState " << e.initialState;
234  os << " initDist " << e.initialLength;
235  os << " initialSineHalfTheta " << e.initialSineHalfTheta;
236  os << " effectiveMass " << e.effectiveMass;
237  os << "\n";
238  }
239 
240  // Write out general properties
241  os << " particleRadius " << particleRadius_; // Mdouble
242 
243  os << " Kn " << Kn_; // Mdouble
244  os << " critDampCoeff " << critDampCoeff_; //Mdouble
245 
246  os << " Ke " << Ke_; // Mdouble
247  os << " Kd " << Kd_; // Mdouble
248 
249  os << " thickness " << thickness_;
250 
251  os << " bendingAreaConstant " << bendingAreaConstant_;
252 
253  os << " membraneSpecies " << membraneSpecies_->getId();
254  os << " membraneParticleSpecies " << membraneParticleSpecies_->getId();
255 }
unsigned int getId() const
Returns the unique identifier of any particular object.
Definition: BaseObject.h:104

References bendingAreaConstant_, critDampCoeff_, e(), edge_, f(), face_, BaseObject::getId(), i, Kd_, Ke_, Kn_, membraneParticleSpecies_, membraneSpecies_, particleRadius_, thickness_, vertexInitId_, and vertexParticleId_.

Member Data Documentation

◆ bendingAreaConstant_

bool Membrane::bendingAreaConstant_
private

◆ critDampCoeff_

Mdouble Membrane::critDampCoeff_
private

◆ DPMBase_

DPMBase* Membrane::DPMBase_ = nullptr
private

Stores a pointer to DPMBase

Referenced by getDPMBase(), read(), and setDPMBase().

◆ edge_

◆ face_

std::vector<MeshTriangle*> Membrane::face_
private

◆ faceVertices_

std::vector<unsigned int> Membrane::faceVertices_
private

Stores the 3 indices per face which can be used to get the ids from vertexParticleId_ // Todo: remove this

◆ Kd_

Mdouble Membrane::Kd_
private

Stores dissipation constant for the bending

Referenced by computeAdditionalForces(), getKd(), Membrane(), read(), setKeAndKd(), and write().

◆ Ke_

Mdouble Membrane::Ke_
private

Stores spring constant for the bending

Referenced by computeAdditionalForces(), getKe(), Membrane(), read(), setKeAndKd(), and write().

◆ Kn_

Mdouble Membrane::Kn_
private

◆ membraneParticleSpecies_

ParticleSpecies* Membrane::membraneParticleSpecies_ = nullptr
private

Stores a pointer to the membrane particle species

Referenced by adjustVertexParticleSize(), buildMesh(), Membrane(), read(), and write().

◆ membraneSpecies_

ParticleSpecies* Membrane::membraneSpecies_ = nullptr
private

Stores a pointer to the membrane species

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

◆ particleRadius_

Mdouble Membrane::particleRadius_
private

Stores the radius of membrane particles

Referenced by buildMesh(), getParticleRadius(), Membrane(), read(), setParticleRadius(), and write().

◆ thickness_

Mdouble Membrane::thickness_
private

Stores thickness of the Membrane

Referenced by buildMesh(), getThickness(), Membrane(), read(), setElasticModulusAndThickness(), setThickness(), and write().

◆ vertexInitId_

unsigned int Membrane::vertexInitId_
private

Sores the id of the first particle created for the membrane. This value helps for the eventual MPI parallelization.

Referenced by adjustVertexParticleSize(), createVertexParticles(), handleParticleAddition(), handleParticleRemoval(), Membrane(), read(), saveAsOFF(), updateEdgeMass(), and write().

◆ vertexParticle_

std::vector<BaseParticle*> Membrane::vertexParticle_
private

◆ vertexParticleId_

std::vector<unsigned int> Membrane::vertexParticleId_
private

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