Skip to content

Commit

Permalink
Merge branch 'develop' into feature/multiphase_material
Browse files Browse the repository at this point in the history
  • Loading branch information
kks32 authored Jul 24, 2020
2 parents e2e18ad + 72bbd93 commit 1e1b8f7
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 28 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ The CB-Geo MPM code uses a `JSON` file for input configuration. To run the mpm c
For example:

```
export OMP_SCHEDULE="static, 4"
./mpm -f /path/to/input-dir/ -i mpm-usf-3d.json -p 8
```

Expand Down
26 changes: 13 additions & 13 deletions include/mesh.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,15 @@ bool mpm::Mesh<Tdim>::remove_node(
template <unsigned Tdim>
template <typename Toper>
void mpm::Mesh<Tdim>::iterate_over_nodes(Toper oper) {
#pragma omp parallel for
#pragma omp parallel for schedule(runtime)
for (auto nitr = nodes_.cbegin(); nitr != nodes_.cend(); ++nitr) oper(*nitr);
}

//! Iterate over nodes
template <unsigned Tdim>
template <typename Toper, typename Tpred>
void mpm::Mesh<Tdim>::iterate_over_nodes_predicate(Toper oper, Tpred pred) {
#pragma omp parallel for
#pragma omp parallel for schedule(runtime)
for (auto nitr = nodes_.cbegin(); nitr != nodes_.cend(); ++nitr) {
if (pred(*nitr)) oper(*nitr);
}
Expand All @@ -97,7 +97,7 @@ void mpm::Mesh<Tdim>::find_active_nodes() {
template <unsigned Tdim>
template <typename Toper>
void mpm::Mesh<Tdim>::iterate_over_active_nodes(Toper oper) {
#pragma omp parallel for
#pragma omp parallel for schedule(runtime)
for (auto nitr = active_nodes_.cbegin(); nitr != active_nodes_.cend(); ++nitr)
oper(*nitr);
}
Expand Down Expand Up @@ -172,15 +172,15 @@ void mpm::Mesh<Tdim>::nodal_halo_exchange(Tgetfunctor getter,
std::vector<Ttype> prop_get(nhalo_nodes_, mpm::zero<Ttype>());
std::vector<Ttype> prop_set(nhalo_nodes_, mpm::zero<Ttype>());

#pragma omp parallel for shared(prop_get)
#pragma omp parallel for schedule(runtime) shared(prop_get)
for (auto nitr = domain_shared_nodes_.cbegin();
nitr != domain_shared_nodes_.cend(); ++nitr)
prop_get.at((*nitr)->ghost_id()) = getter((*nitr));

MPI_Allreduce(prop_get.data(), prop_set.data(), nhalo_nodes_ * Tnparam,
MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);

#pragma omp parallel for
#pragma omp parallel for schedule(runtime)
for (auto nitr = domain_shared_nodes_.cbegin();
nitr != domain_shared_nodes_.cend(); ++nitr)
setter((*nitr), prop_set.at((*nitr)->ghost_id()));
Expand Down Expand Up @@ -260,7 +260,7 @@ bool mpm::Mesh<Tdim>::remove_cell(
template <unsigned Tdim>
template <typename Toper>
void mpm::Mesh<Tdim>::iterate_over_cells(Toper oper) {
#pragma omp parallel for
#pragma omp parallel for schedule(runtime)
for (auto citr = cells_.cbegin(); citr != cells_.cend(); ++citr) oper(*citr);
}

Expand All @@ -275,7 +275,7 @@ void mpm::Mesh<Tdim>::find_cell_neighbours() {
for (auto id : (*citr)->nodes_id()) node_cell_map[id].insert(cell_id);
}

#pragma omp parallel for
#pragma omp parallel for schedule(runtime)
for (auto citr = cells_.cbegin(); citr != cells_.cend(); ++citr) {
// Iterate over each node in current cell
for (auto id : (*citr)->nodes_id()) {
Expand Down Expand Up @@ -907,7 +907,7 @@ void mpm::Mesh<Tdim>::transfer_nonrank_particles(
template <unsigned Tdim>
void mpm::Mesh<Tdim>::find_domain_shared_nodes() {
// Clear MPI rank at the nodes
#pragma omp parallel for
#pragma omp parallel for schedule(runtime)
for (auto nitr = nodes_.cbegin(); nitr != nodes_.cend(); ++nitr)
(*nitr)->clear_mpi_ranks();

Expand All @@ -917,7 +917,7 @@ void mpm::Mesh<Tdim>::find_domain_shared_nodes() {
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
#endif

#pragma omp parallel for
#pragma omp parallel for schedule(runtime)
// Assign MPI rank to nodes of cell
for (auto citr = cells_.cbegin(); citr != cells_.cend(); ++citr)
(*citr)->assign_mpi_rank_to_nodes();
Expand Down Expand Up @@ -998,7 +998,7 @@ bool mpm::Mesh<Tdim>::locate_particle_cells(
}

bool status = false;
#pragma omp parallel for
#pragma omp parallel for schedule(runtime)
for (auto citr = cells_.cbegin(); citr != cells_.cend(); ++citr) {
// Check if particle is already found, if so don't run for other cells
// Check if co-ordinates is within the cell, if true
Expand All @@ -1017,7 +1017,7 @@ bool mpm::Mesh<Tdim>::locate_particle_cells(
template <unsigned Tdim>
template <typename Toper>
void mpm::Mesh<Tdim>::iterate_over_particles(Toper oper) {
#pragma omp parallel for
#pragma omp parallel for schedule(runtime)
for (auto pitr = particles_.cbegin(); pitr != particles_.cend(); ++pitr)
oper(*pitr);
}
Expand All @@ -1032,7 +1032,7 @@ void mpm::Mesh<Tdim>::iterate_over_particle_set(int set_id, Toper oper) {
} else {
// Iterate over the particle set
auto set = particle_sets_.at(set_id);
#pragma omp parallel for
#pragma omp parallel for schedule(runtime)
for (auto sitr = set.begin(); sitr != set.cend(); ++sitr) {
unsigned pid = (*sitr);
if (map_particles_.find(pid) != map_particles_.end())
Expand Down Expand Up @@ -1270,7 +1270,7 @@ bool mpm::Mesh<Tdim>::assign_nodal_concentrated_forces(
Vector<NodeBase<Tdim>> nodes =
(set_id == -1) ? this->nodes_ : node_sets_.at(set_id);

#pragma omp parallel for
#pragma omp parallel for schedule(runtime)
for (auto nitr = nodes.cbegin(); nitr != nodes.cend(); ++nitr) {
if (!(*nitr)->assign_concentrated_force(phase, dir, concentrated_force,
mfunction))
Expand Down
39 changes: 39 additions & 0 deletions include/mutex.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#ifndef MPM_MUTEX_H_
#define MPM_MUTEX_H_

#include <atomic>

namespace mpm {
//! Hybrid SpinMutex class
//! \brief SpinMutex class that offers a fast locking and unlocking mechanism
class SpinMutex {

public:
//! Attempt locking
bool try_lock() { return !lock_.test_and_set(std::memory_order_acquire); }

//! Call lock
void lock() {
std::size_t spin_count{0};
while (!try_lock()) {
++spin_count;

if (spin_count < spin_pred_ * 2) continue;

std::this_thread::sleep_for(std::chrono::nanoseconds(1));
}

spin_pred_ += (spin_count - spin_pred_) / 8;
}

//! Call unlock
void unlock() { lock_.clear(std::memory_order_release); }

private:
//! Lock variable
std::atomic_flag lock_ = ATOMIC_FLAG_INIT;
//! Spin prediction
std::atomic<std::size_t> spin_pred_{0};
};
} // namespace mpm
#endif // MPM_MUTEX_H_
3 changes: 2 additions & 1 deletion include/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define MPM_NODE_H_

#include "logger.h"
#include "mutex.h"
#include "nodal_properties.h"
#include "node_base.h"

Expand Down Expand Up @@ -265,7 +266,7 @@ class Node : public NodeBase<Tdim> {

private:
//! Mutex
std::mutex node_mutex_;
SpinMutex node_mutex_;
//! nodebase id
Index id_{std::numeric_limits<Index>::max()};
//! nodal property id
Expand Down
42 changes: 28 additions & 14 deletions include/node.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ void mpm::Node<Tdim, Tdof, Tnphases>::update_mass(bool update, unsigned phase,
const double factor = (update == true) ? 1. : 0.;

// Update/assign mass
std::lock_guard<std::mutex> guard(node_mutex_);
node_mutex_.lock();
mass_(phase) = (mass_(phase) * factor) + mass;
node_mutex_.unlock();
}

//! Update volume at the nodes from particle
Expand All @@ -66,8 +67,9 @@ void mpm::Node<Tdim, Tdof, Tnphases>::update_volume(bool update, unsigned phase,
const double factor = (update == true) ? 1. : 0.;

// Update/assign volume
std::lock_guard<std::mutex> guard(node_mutex_);
node_mutex_.lock();
volume_(phase) = volume_(phase) * factor + volume;
node_mutex_.unlock();
}

// Assign concentrated force to the node
Expand Down Expand Up @@ -115,8 +117,9 @@ void mpm::Node<Tdim, Tdof, Tnphases>::update_external_force(
const double factor = (update == true) ? 1. : 0.;

// Update/assign external force
std::lock_guard<std::mutex> guard(node_mutex_);
node_mutex_.lock();
external_force_.col(phase) = external_force_.col(phase) * factor + force;
node_mutex_.unlock();
}

//! Update internal force (body force / traction force)
Expand All @@ -131,8 +134,9 @@ void mpm::Node<Tdim, Tdof, Tnphases>::update_internal_force(
const double factor = (update == true) ? 1. : 0.;

// Update/assign internal force
std::lock_guard<std::mutex> guard(node_mutex_);
node_mutex_.lock();
internal_force_.col(phase) = internal_force_.col(phase) * factor + force;
node_mutex_.unlock();
}

//! Assign nodal momentum
Expand All @@ -147,8 +151,9 @@ void mpm::Node<Tdim, Tdof, Tnphases>::update_momentum(
const double factor = (update == true) ? 1. : 0.;

// Update/assign momentum
std::lock_guard<std::mutex> guard(node_mutex_);
node_mutex_.lock();
momentum_.col(phase) = momentum_.col(phase) * factor + momentum;
node_mutex_.unlock();
}

//! Update pressure at the nodes from particle
Expand All @@ -161,8 +166,9 @@ void mpm::Node<Tdim, Tdof, Tnphases>::update_mass_pressure(
const double tolerance = 1.E-16;
// Compute pressure from mass*pressure
if (mass_(phase) > tolerance) {
std::lock_guard<std::mutex> guard(node_mutex_);
node_mutex_.lock();
pressure_(phase) += mass_pressure / mass_(phase);
node_mutex_.unlock();
}
}

Expand All @@ -171,8 +177,9 @@ template <unsigned Tdim, unsigned Tdof, unsigned Tnphases>
void mpm::Node<Tdim, Tdof, Tnphases>::assign_pressure(unsigned phase,
double pressure) {
// Compute pressure from mass*pressure
std::lock_guard<std::mutex> guard(node_mutex_);
node_mutex_.lock();
pressure_(phase) = pressure;
node_mutex_.unlock();
}

//! Compute velocity from momentum
Expand Down Expand Up @@ -207,8 +214,9 @@ void mpm::Node<Tdim, Tdof, Tnphases>::update_acceleration(
const double factor = (update == true) ? 1. : 0.;

//! Update/assign acceleration
std::lock_guard<std::mutex> guard(node_mutex_);
node_mutex_.lock();
acceleration_.col(phase) = acceleration_.col(phase) * factor + acceleration;
node_mutex_.unlock();
}

//! Compute acceleration and velocity
Expand Down Expand Up @@ -515,15 +523,17 @@ void mpm::Node<Tdim, Tdof, Tnphases>::apply_friction_constraints(double dt) {
//! Add material id from material points to material_ids_
template <unsigned Tdim, unsigned Tdof, unsigned Tnphases>
void mpm::Node<Tdim, Tdof, Tnphases>::append_material_id(unsigned id) {
std::lock_guard<std::mutex> guard(node_mutex_);
node_mutex_.lock();
material_ids_.emplace(id);
node_mutex_.unlock();
}

// Assign MPI rank to node
template <unsigned Tdim, unsigned Tdof, unsigned Tnphases>
bool mpm::Node<Tdim, Tdof, Tnphases>::mpi_rank(unsigned rank) {
std::lock_guard<std::mutex> guard(node_mutex_);
node_mutex_.lock();
auto status = this->mpi_ranks_.insert(rank);
node_mutex_.unlock();
return status.second;
}

Expand All @@ -534,9 +544,10 @@ void mpm::Node<Tdim, Tdof, Tnphases>::update_property(
const Eigen::MatrixXd& property_value, unsigned mat_id,
unsigned nprops) noexcept {
// Update/assign property
std::lock_guard<std::mutex> guard(node_mutex_);
node_mutex_.lock();
property_handle_->update_property(property, prop_id_, mat_id, property_value,
nprops);
node_mutex_.unlock();
}

//! Compute multimaterial change in momentum
Expand All @@ -545,7 +556,7 @@ void mpm::Node<Tdim, Tdof,
Tnphases>::compute_multimaterial_change_in_momentum() {
// iterate over all materials in the material_ids set and update the change in
// momentum
std::lock_guard<std::mutex> guard(node_mutex_);
node_mutex_.lock();
for (auto mitr = material_ids_.begin(); mitr != material_ids_.end(); ++mitr) {
const Eigen::Matrix<double, 1, 1> mass =
property_handle_->property("masses", prop_id_, *mitr);
Expand All @@ -556,6 +567,7 @@ void mpm::Node<Tdim, Tdof,
property_handle_->update_property("change_in_momenta", prop_id_, *mitr,
change_in_momenta, Tdim);
}
node_mutex_.unlock();
}

//! Compute multimaterial separation vector
Expand All @@ -565,7 +577,7 @@ void mpm::Node<Tdim, Tdof,
// iterate over all materials in the material_ids set, update the
// displacements and calculate the displacement of the center of mass for this
// node
std::lock_guard<std::mutex> guard(node_mutex_);
node_mutex_.lock();
for (auto mitr = material_ids_.begin(); mitr != material_ids_.end(); ++mitr) {
const auto& material_displacement =
property_handle_->property("displacements", prop_id_, *mitr, Tdim);
Expand Down Expand Up @@ -596,14 +608,15 @@ void mpm::Node<Tdim, Tdof,
property_handle_->update_property("separation_vectors", prop_id_, *mitr,
separation_vector, Tdim);
}
node_mutex_.unlock();
}

//! Compute multimaterial normal unit vector
template <unsigned Tdim, unsigned Tdof, unsigned Tnphases>
void mpm::Node<Tdim, Tdof,
Tnphases>::compute_multimaterial_normal_unit_vector() {
// Iterate over all materials in the material_ids set
std::lock_guard<std::mutex> guard(node_mutex_);
node_mutex_.lock();
for (auto mitr = material_ids_.begin(); mitr != material_ids_.end(); ++mitr) {
// calculte the normal unit vector
VectorDim domain_gradient =
Expand All @@ -616,4 +629,5 @@ void mpm::Node<Tdim, Tdof,
property_handle_->assign_property("normal_unit_vectors", prop_id_, *mitr,
normal_unit_vector, Tdim);
}
node_mutex_.unlock();
}

0 comments on commit 1e1b8f7

Please sign in to comment.