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

Apply ground motion input as nodal acceleration constraint #715

Open
wants to merge 25 commits into
base: develop
Choose a base branch
from

Conversation

thiagordonho
Copy link
Contributor

@thiagordonho thiagordonho commented Jun 22, 2021

Describe the PR
This implementation is based on the issue presented in the RFC #692 . It adds a feature to read and apply input ground motion in terms of acceleration-time history.

Related Issues/PRs
Continuation of PR #701.

Additional context
This design involves creating a class for acceleration constraints (AccelerationConstraint) based on the already existing class for velocity constraints (VelocityConstraint). However, a math function can be associated with the acceleration constraint defined from an acceleration-time history input. The acceleration constraints are applied at the nodes with the implemented Node::apply_acceleration_constraint function within the Node::compute_acceleration_velocity function as follows:

//! Compute acceleration and velocity
template <unsigned Tdim, unsigned Tdof, unsigned Tnphases>
bool mpm::Node<Tdim, Tdof, Tnphases>::compute_acceleration_velocity(
    unsigned phase, double dt) noexcept {
  bool status = false;
  const double tolerance = 1.0E-15;
  if (mass_(phase) > tolerance) {
    // acceleration = (unbalaced force / mass)
    this->acceleration_.col(phase) =
        (this->external_force_.col(phase) + this->internal_force_.col(phase)) /
        this->mass_(phase);

    // Apply friction constraints
    this->apply_friction_constraints(dt);

    // Apply acceleration constraints
    this->apply_acceleration_constraints();

    // Velocity += acceleration * dt
    this->velocity_.col(phase) += this->acceleration_.col(phase) * dt;
    // Apply velocity constraints, which also sets acceleration to 0,
    // when velocity is set.
    this->apply_velocity_constraints();

    // Set a threshold
    for (unsigned i = 0; i < Tdim; ++i)
      if (std::abs(velocity_.col(phase)(i)) < tolerance)
        velocity_.col(phase)(i) = 0.;
    for (unsigned i = 0; i < Tdim; ++i)
      if (std::abs(acceleration_.col(phase)(i)) < tolerance)
        acceleration_.col(phase)(i) = 0.;
    status = true;
  }
  return status;
}

The acceleration-time input, as mentioned, is done with math functions. An additional way to initialize a ”Linear” math function is to read a .csv file with the time and respective acceleration entries. This procedure is herein extended from the one presented in PR #701, where the CSVReader header file is used for reading the .csv file. In this implementation, reading the math function .csv file was moved to the io/io_mesh_ascii.tcc within the newly created function called IOMeshAscii::read_math_functions:

// Return array with math function entries
template <unsigned Tdim>
std::array<std::vector<double>, 2> mpm::IOMeshAscii<Tdim>::read_math_functions(
    const std::string& math_file) {
  // Initialise vector with 2 empty vectors
  std::array<std::vector<double>, 2> xfx_values;

  // Read from csv file
  try {
    io::CSVReader<2> in(math_file);
    double x_value, fx_value;
    while (in.read_row(x_value, fx_value)) {
      xfx_values[0].push_back(x_value);
      xfx_values[1].push_back(fx_value);
    }
  } catch (std::exception& exception) {
    console_->error("Read math functions: {}", exception.what());
  }

  return xfx_values;
}

Benchmark tests

To test the implemented feature, a time-dependent acceleration was imposed to a Linear elastic, 2D block. The acceleration was imposed on the nodes at the bottom boundary of a 3 x 2 (width x height) mesh. The mesh has a spacing of 0.25 m. The block is 1 meter high and 1 meter wide. A detail of the model is shown in Figure 1. No gravity was considered in this model. Four particles per cell and direction were considered in this model. The following are the elastic characteristics of the block:

  • density: 3000 kg/m3
  • Young's modulus; 7 MPa
  • Poisson's ratio: 0.38

image
Figure 1; Schematic of the model in its starting position.

Two acceleration-time series were considered for two separate simulations. The charts below show the imposed nodal acceleration at the boundary (Figure 2) and the results of the center of mass of the block (Figure 3 and 4).

image
Figure 2: Imposed acceleration-time history at the nodes of the bottom boundary.

image
Figure 3: Horizontal velocity of the center of mass of the block.

image
Figure 4: Horizontal position of the center of mass of the block.

The velocity of the center of mass shows a slight deviation of the expected results, but the horizontal position of the center of mass is very close to the expected values.

Ezra Tjung and others added 24 commits November 26, 2020 23:12
@@ -358,9 +358,9 @@ std::vector<std::array<mpm::Index, 2>>
// ignore comment lines (# or !) or blank lines
if ((line.find('#') == std::string::npos) &&
(line.find('!') == std::string::npos) && (line != "")) {
// ID
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// ID
// Particle and cell ids

unsigned dir() const { return dir_; }

// Return acceleration
double acceleration(double current_time) const {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inline this function

//! AccelerationConstraint class to store acceleration constraint on a set
//! \brief AccelerationConstraint class to store a constraint on a set
//! \details AccelerationConstraint stores the constraint as a static value
class AccelerationConstraint {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a general constraint class from which this could be derived?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, no. But I do agree that we should implement a general constraint from which this one and others (VelocityConstraint, FrictionConstraint, Traction) should be derived. They all have a setid_, dir_ and their main value (acceleration_, velocity_, traction_, or friction_). They only differ on the way these main values are named and if they can or cannot be time-dependent -- i.e. if they can have a pointer to a math function. Currently, only traction and acceleration constraints can be time-dependent.

@kks32
Copy link
Contributor

kks32 commented Jun 23, 2021

@thiagordonho is there an elastic wave propagation benchmark that demonstrates this implementation?

@thiagordonho
Copy link
Contributor Author

@thiagordonho is there an elastic wave propagation benchmark that demonstrates this implementation?

@kks32 I ran two simple simulations of a linear elastic block, no gravity, positioned on top of the bottom boundary. I applied the acceleration-time constraint to the nodes at the bottom boundary. The first simulation considers a sinusoidal math function an the second considers a piecewise linear math function. I will attach the obtained results to the body of the PR description.

Copy link
Contributor

@kks32 kks32 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you interpolate between timesteps? Is that linear?

void mpm::Mesh<Tdim>::update_nodal_acceleration_constraints(
double current_time) {
// Iterate over all nodal acceleration constraints
for (const auto& nacceleration : nodal_acceleration_constraints_) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

n is usually reserved for number not nodal, use nodal_acceleration

@codecov
Copy link

codecov bot commented Jul 12, 2021

Codecov Report

Merging #715 (34c848d) into develop (86ba10e) will decrease coverage by 0.05%.
The diff coverage is 95.02%.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop     #715      +/-   ##
===========================================
- Coverage    96.78%   96.73%   -0.05%     
===========================================
  Files          130      132       +2     
  Lines        25899    26456     +557     
===========================================
+ Hits         25065    25591     +526     
- Misses         834      865      +31     
Impacted Files Coverage Δ
include/io/io_mesh.h 100.00% <ø> (ø)
include/io/io_mesh_ascii.h 100.00% <ø> (ø)
include/loads_bcs/constraints.h 100.00% <ø> (ø)
include/mesh.h 100.00% <ø> (ø)
include/node.h 100.00% <ø> (ø)
include/node_base.h 100.00% <ø> (ø)
include/solvers/mpm_base.h 50.00% <ø> (ø)
include/solvers/mpm_base.tcc 74.39% <37.21%> (-2.65%) ⬇️
include/io/io_mesh_ascii.tcc 76.33% <90.00%> (+1.52%) ⬆️
include/loads_bcs/constraints.tcc 96.39% <96.30%> (-0.04%) ⬇️
... and 13 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 86ba10e...34c848d. Read the comment docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants