Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Levelset #88

Draft
wants to merge 21 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
93d82dc
start project :tada:
LDTalbot Jul 31, 2023
746fa63
levelset first draft :tada: :construction:
LDTalbot Jan 13, 2024
d84dd21
Merge branch 'master' into levelset
LDTalbot Jan 13, 2024
baafa05
working on constructors :construction:
LDTalbot Jan 18, 2024
4fca077
debugging :bug: and input flow :refactor:
LDTalbot Jan 19, 2024
bc3c8cb
debug virtual classes and is_levelset warnings :bug:
LDTalbot Jan 23, 2024
0ddf0e6
levelset first draft working with debug flags :bug: :construction:
LDTalbot Feb 1, 2024
8f3904c
levelset_mp_radius now directly input and const within contact :recyc…
LDTalbot Feb 1, 2024
9a759a4
tidy for draft PR :bookmark: :construction:
LDTalbot Feb 1, 2024
c905255
bug fixes :bug: and autocalc mp_radius :sparkles:
LDTalbot Feb 10, 2024
c31aa74
remove levelset_mp_radius as input :recycle: :fire:
LDTalbot Feb 10, 2024
fcdc443
small edits :adhesive_bandage:
LDTalbot Mar 12, 2024
1a55ec1
fix 3D tangent special case :bug:
LDTalbot Mar 12, 2024
ff75cee
contact criteria improved (must be accelerating towards levelset) and…
LDTalbot Mar 18, 2024
53f03c1
update contact condition w.r.t velocity :rocket: :bug:
LDTalbot Mar 19, 2024
3397e43
minor changes :adhesive_bandage: :goal_net:
LDTalbot Apr 17, 2024
3f20199
add adhesion and uphill force prevention :sparkles: :rocket: :bug:
LDTalbot Apr 24, 2024
f36c0cb
merge master changes :twisted_rightwards_arrows:
LDTalbot Apr 24, 2024
f89edfa
area and couple updates, contact rule :rocket: :bug:
LDTalbot May 2, 2024
be94707
contact conditions improved :rocket: :bug:
LDTalbot May 13, 2024
d2c7d5e
optional friction smoothing :adhesive_bandage:
LDTalbot May 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions include/contacts/contact.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ class Contact {
//! Compute contact forces
virtual inline void compute_contact_forces(){};

//! Compute contact forces
//! \param[in] dt Analysis time step
virtual inline void compute_contact_forces(double dt){};

protected:
//! Mesh object
std::shared_ptr<mpm::Mesh<Tdim>> mesh_;
Expand Down
8 changes: 6 additions & 2 deletions include/contacts/contact_friction.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@ class ContactFriction : public Contact<Tdim> {
ContactFriction(const std::shared_ptr<mpm::Mesh<Tdim>>& mesh);

//! Intialize
virtual inline void initialise() override;
void initialise() override;

//! Compute contact forces
virtual inline void compute_contact_forces() override;
void compute_contact_forces() override;

//! Compute contact forces
//! \param[in] dt Analysis time step
void compute_contact_forces(double dt) override;

protected:
//! Mesh object
Expand Down
39 changes: 37 additions & 2 deletions include/contacts/contact_friction.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ mpm::ContactFriction<Tdim>::ContactFriction(

//! Initialize nodal properties
template <unsigned Tdim>
inline void mpm::ContactFriction<Tdim>::initialise() {
void mpm::ContactFriction<Tdim>::initialise() {
// Initialise nodal properties
mesh_->initialise_nodal_properties();

Expand All @@ -18,7 +18,42 @@ inline void mpm::ContactFriction<Tdim>::initialise() {

//! Compute contact forces
template <unsigned Tdim>
inline void mpm::ContactFriction<Tdim>::compute_contact_forces() {
void mpm::ContactFriction<Tdim>::compute_contact_forces() {

// Map multimaterial properties from particles to nodes
mesh_->iterate_over_particles(std::bind(
&mpm::ParticleBase<Tdim>::map_multimaterial_mass_momentum_to_nodes,
std::placeholders::_1));

// Map multimaterial displacements from particles to nodes
mesh_->iterate_over_particles(std::bind(
&mpm::ParticleBase<Tdim>::map_multimaterial_displacements_to_nodes,
std::placeholders::_1));

// Map multimaterial domain gradients from particles to nodes
mesh_->iterate_over_particles(std::bind(
&mpm::ParticleBase<Tdim>::map_multimaterial_domain_gradients_to_nodes,
std::placeholders::_1));

// Compute multimaterial change in momentum
mesh_->iterate_over_nodes(
std::bind(&mpm::NodeBase<Tdim>::compute_multimaterial_change_in_momentum,
std::placeholders::_1));

// Compute multimaterial separation vector
mesh_->iterate_over_nodes(
std::bind(&mpm::NodeBase<Tdim>::compute_multimaterial_separation_vector,
std::placeholders::_1));

// Compute multimaterial normal unit vector
mesh_->iterate_over_nodes(
std::bind(&mpm::NodeBase<Tdim>::compute_multimaterial_normal_unit_vector,
std::placeholders::_1));
}

//! Compute contact forces
template <unsigned Tdim>
void mpm::ContactFriction<Tdim>::compute_contact_forces(double dt) {

// Map multimaterial properties from particles to nodes
mesh_->iterate_over_particles(std::bind(
Expand Down
38 changes: 38 additions & 0 deletions include/contacts/contact_levelset.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#ifndef MPM_CONTACT_LEVELSET_H_
#define MPM_CONTACT_LEVELSET_H_

#include "contact.h"
#include "mesh_levelset.h"
#include "particle_levelset.h"

namespace mpm {

//! ContactLevelset class
//! \brief ContactLevelset base class
//! \tparam Tdim Dimension
template <unsigned Tdim>
class ContactLevelset : public Contact<Tdim> {
public:
//! Default constructor with mesh class
ContactLevelset(const std::shared_ptr<mpm::Mesh<Tdim>>& mesh);

//! Intialize
void initialise() override;

//! Compute contact forces
//! \param[in] dt Analysis time step
void compute_contact_forces(double dt) override;

//! Mesh levelset object
std::shared_ptr<mpm::MeshLevelset<Tdim>> mesh_levelset_;

protected:
//! Mesh object
using mpm::Contact<Tdim>::mesh_;

}; // ContactLevelset class
} // namespace mpm

#include "contact_levelset.tcc"

#endif // MPM_CONTACT_LEVELSET_H_
25 changes: 25 additions & 0 deletions include/contacts/contact_levelset.tcc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//! Constructor of contact with mesh
template <unsigned Tdim>
mpm::ContactLevelset<Tdim>::ContactLevelset(
const std::shared_ptr<mpm::Mesh<Tdim>>& mesh)
: mpm::Contact<Tdim>(mesh) {
// Assign mesh
mesh_ = mesh;
}

//! Initialize nodal properties
template <unsigned Tdim>
void mpm::ContactLevelset<Tdim>::initialise() {
// Initialise nodal properties
mesh_->initialise_nodal_properties();
}

//! Compute contact forces
template <unsigned Tdim>
void mpm::ContactLevelset<Tdim>::compute_contact_forces(double dt) {

// Compute and map contact forces to nodes
mesh_->iterate_over_particles(
std::bind(&mpm::ParticleBase<Tdim>::map_particle_contact_force_to_nodes,
std::placeholders::_1, dt));
}
14 changes: 10 additions & 4 deletions include/io/io_mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ class IOMesh {
virtual std::vector<Eigen::Matrix<double, 6, 1>> read_particles_stresses(
const std::string& particles_stresses) = 0;

//! Read particle scalar properties
//! Read scalar properties for particles or nodes
//! \param[in] scalar_file file name with particle scalar properties
//! \retval Vector of particles scalar properties
virtual std::vector<std::tuple<mpm::Index, double>>
read_particles_scalar_properties(const std::string& scalar_file) = 0;
//! \retval Vector of scalar properties for particles or nodes
virtual std::vector<std::tuple<mpm::Index, double>> read_scalar_properties(
const std::string& scalar_file) = 0;

//! Read pressure constraints file
//! \param[in] pressure_constraints_files file name with pressure constraints
Expand Down Expand Up @@ -123,6 +123,12 @@ class IOMesh {
read_adhesion_constraints(
const std::string& adhesion_constraints_file) = 0;

//! Read levelset file
//! \param[in] levelset_input_file file name with levelset values
virtual std::vector<
std::tuple<mpm::Index, double, double, double, double, double>>
read_levelset_input(const std::string& levelset_input_file) = 0;

//! Read forces file
//! \param[in] forces_file file name with nodal concentrated force
virtual std::vector<std::tuple<mpm::Index, unsigned, double>> read_forces(
Expand Down
13 changes: 9 additions & 4 deletions include/io/io_mesh_ascii.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ class IOMeshAscii : public IOMesh<Tdim> {
std::vector<Eigen::Matrix<double, 6, 1>> read_particles_stresses(
const std::string& particles_stresses) override;

//! Read particle scalar properties
//! \param[in] scalar_file file name with particle scalar properties
//! \retval Vector of particles scalar properties
std::vector<std::tuple<mpm::Index, double>> read_particles_scalar_properties(
//! Read scalar properties for particles or nodes
//! \param[in] scalar_file file name with particle or node scalar properties
//! \retval Vector of scalar properties for particles or nodes
std::vector<std::tuple<mpm::Index, double>> read_scalar_properties(
const std::string& scalar_file) override;

//! Read pressure constraints file
Expand Down Expand Up @@ -110,6 +110,11 @@ class IOMeshAscii : public IOMesh<Tdim> {
read_adhesion_constraints(
const std::string& adhesion_constraints_file) override;

//! Read levelset file
//! \param[in] levelset_input_file file name with levelset values
std::vector<std::tuple<mpm::Index, double, double, double, double, double>>
read_levelset_input(const std::string& levelset_input_file) override;

//! Read traction file
//! \param[in] forces_file file name with nodal concentrated force
std::vector<std::tuple<mpm::Index, unsigned, double>> read_forces(
Expand Down
68 changes: 63 additions & 5 deletions include/io/io_mesh_ascii.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -254,13 +254,13 @@ std::vector<Eigen::Matrix<double, 6, 1>>
return stresses;
}

//! Return particles scalar properties
//! Return scalar properties for particles or nodes
template <unsigned Tdim>
std::vector<std::tuple<mpm::Index, double>>
mpm::IOMeshAscii<Tdim>::read_particles_scalar_properties(
mpm::IOMeshAscii<Tdim>::read_scalar_properties(
const std::string& scalar_file) {

// Particles scalar properties
// Scalar properties for particles or nodes
std::vector<std::tuple<mpm::Index, double>> scalar_properties;

// input file stream
Expand Down Expand Up @@ -293,7 +293,7 @@ std::vector<std::tuple<mpm::Index, double>>
}
file.close();
} catch (std::exception& exception) {
console_->error("Read particle {} #{}: {}\n", __FILE__, __LINE__,
console_->error("Read particle/node {} #{}: {}\n", __FILE__, __LINE__,
exception.what());
file.close();
}
Expand Down Expand Up @@ -641,7 +641,7 @@ std::vector<std::tuple<mpm::Index, unsigned, double>>
return constraints;
}

//! Return friction constraints of particles
//! Return friction constraints
template <unsigned Tdim>
std::vector<std::tuple<mpm::Index, unsigned, int, double>>
mpm::IOMeshAscii<Tdim>::read_friction_constraints(
Expand Down Expand Up @@ -748,6 +748,64 @@ std::vector<std::tuple<mpm::Index, unsigned, int, double, double, int>>
return constraints;
}

//! Return nodal levelset information
template <unsigned Tdim>
std::vector<std::tuple<mpm::Index, double, double, double, double, double>>
mpm::IOMeshAscii<Tdim>::read_levelset_input(
const std::string& levelset_input_file) {

// Nodal levelset information
std::vector<std::tuple<mpm::Index, double, double, double, double, double>>
levelset_inputs;
levelset_inputs.clear();

// input file stream
std::fstream file;
file.open(levelset_input_file.c_str(), std::ios::in);

try {
if (file.is_open() && file.good()) {
// Line
std::string line;
while (std::getline(file, line)) {
boost::algorithm::trim(line);
std::istringstream istream(line);
// ignore comment lines (# or !) or blank lines
if ((line.find('#') == std::string::npos) &&
(line.find('!') == std::string::npos) && (line != "")) {
// ID
mpm::Index id;
// Levelset value
double levelset;
// Friction
double levelset_mu;
// Adhesion coefficient
double levelset_alpha;
// Barrier stiffness
double barrier_stiffness;
// Slip threshold
double slip_threshold;
while (istream.good()) {
// Read stream
istream >> id >> levelset >> levelset_mu >> levelset_alpha >>
barrier_stiffness >> slip_threshold;
levelset_inputs.emplace_back(
std::make_tuple(id, levelset, levelset_mu, levelset_alpha,
barrier_stiffness, slip_threshold));
}
}
}
} else {
throw std::runtime_error("File not open or not good!");
}
file.close();
} catch (std::exception& exception) {
console_->error("Read levelset inputs: {}", exception.what());
file.close();
}
return levelset_inputs;
}

//! Return particles force
template <unsigned Tdim>
std::vector<std::tuple<mpm::Index, unsigned, double>>
Expand Down
34 changes: 29 additions & 5 deletions include/mesh/mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ class Mesh {
//! \param[in] cells Node ids of cells
//! \param[in] check_duplicates Parameter to check duplicates
//! \retval status Create cells status
bool create_cells(mpm::Index gnid,
bool create_cells(mpm::Index gcid,
const std::shared_ptr<mpm::Element<Tdim>>& element,
const std::vector<std::vector<mpm::Index>>& cells,
bool check_duplicates = true);
Expand Down Expand Up @@ -263,7 +263,7 @@ class Mesh {
//! Locate particles in a cell
//! Iterate over all cells in a mesh to find the cell in which particles
//! are located.
//! \retval particles Particles which cannot be located in the mesh
//! \retval particles which cannot be located in the mesh
std::vector<std::shared_ptr<mpm::ParticleBase<Tdim>>> locate_particles_mesh();

//! Iterate over particles
Expand Down Expand Up @@ -475,7 +475,7 @@ class Mesh {
//! Create map of vector of particles in sets
//! \param[in] map of particles ids in sets
//! \param[in] check_duplicates Parameter to check duplicates
//! \retval status Status of create particle sets
//! \retval status Status of create particle sets
bool create_particle_sets(
const tsl::robin_map<mpm::Index, std::vector<mpm::Index>>& particle_sets,
bool check_duplicates);
Expand Down Expand Up @@ -518,11 +518,34 @@ class Mesh {
void inject_particles(double current_time);

// Create the nodal properties' map
void create_nodal_properties();
virtual void create_nodal_properties();

// Initialise the nodal properties' map
void initialise_nodal_properties();

/**
* \defgroup Levelset Functions
*/
/**@{*/

//! Assign nodal levelset values
//! \ingroup Levelset
//! \param[in] levelset Levelset value at the particle
//! \param[in] levelset_mu Levelset friction
//! \param[in] levelset_alpha Levelset adhesion coefficient
//! \param[in] barrier_stiffness Barrier stiffness
//! \param[in] slip_threshold Slip threshold
virtual bool assign_nodal_levelset_values(
const std::vector<std::tuple<mpm::Index, double, double, double, double,
double>>& levelset_input_file) {
throw std::runtime_error(
"Calling the base class function (assign_nodal_levelset_values) in "
"Mesh:: illegal operation!");
return false;
};

/**@}*/

/**
* \defgroup MultiPhase Functions dealing with multi-phase MPM
*/
Expand Down Expand Up @@ -673,10 +696,11 @@ class Mesh {
const Json& generator, unsigned pset_id);

// Locate a particle in mesh cells
//! \param[in] particle of interest
bool locate_particle_cells(
const std::shared_ptr<mpm::ParticleBase<Tdim>>& particle);

private:
protected:
//! mesh id
unsigned id_{std::numeric_limits<unsigned>::max()};
//! Isoparametric mesh
Expand Down
Loading