RandomNumberGeneration::RandomNumberGeneration(const std::string & name, InputParameters parameters) :
  Function(name, parameters),
    _min(getParam<Real>("min")),
    _max(getParam<Real>("max")),
    _range(_max - _min)
{
  mooseAssert(_range > 0.0, "Min > Max for RandomIC!");
  MooseRandom::seed(getParam<unsigned int>("seed"));
}
VectorPostprocessorData::VectorPostprocessorState &
VectorPostprocessorData::getVectorPostprocessorHelper(const VectorPostprocessorName & vpp_name,
                                                      const std::string & vector_name,
                                                      bool get_current,
                                                      bool contains_complete_history,
                                                      bool is_broadcast,
                                                      bool needs_broadcast,
                                                      bool needs_scatter)
{
  // Retrieve or create the data structure for this VPP
  auto vec_it_pair = _vpp_data.emplace(
      std::piecewise_construct, std::forward_as_tuple(vpp_name), std::forward_as_tuple());
  auto & vec_storage = vec_it_pair.first->second;

  // If the VPP is declaring a vector, see if complete history is needed. Note: This parameter
  // is constant and applies to _all_ declared vectors.
  vec_storage._contains_complete_history |= contains_complete_history;

  // If the VPP is declaring a vector, see if it will already be replicated in parallel.
  // Note: This parameter is constant and applies to _all_ declared vectors.
  vec_storage._is_broadcast |= is_broadcast;

  // Keep track of whether an old vector is needed for copying back later.
  if (!get_current)
    vec_storage._needs_old = true;

  // lambda for doing comparison on name (i.e., first item in pair)
  auto comp = [&vector_name](std::pair<std::string, VectorPostprocessorState> & pair) {
    return pair.first == vector_name;
  };
  // Search for the vector, if it is not located create the entry in the storage
  auto iter = std::find_if(vec_storage._values.rbegin(), vec_storage._values.rend(), comp);
  if (iter == vec_storage._values.rend())
  {
    vec_storage._values.emplace_back(
        std::piecewise_construct, std::forward_as_tuple(vector_name), std::forward_as_tuple());
    iter = vec_storage._values.rbegin();
  }

  auto & vec_struct = iter->second;
  if (!vec_struct.current)
  {
    mooseAssert(!vec_struct.old, "Uninitialized pointers in VectorPostprocessor Data");
    vec_struct.current = &declareRestartableDataWithObjectName<VectorPostprocessorValue>(
        vpp_name + "_" + vector_name, "values");
    vec_struct.old = &declareRestartableDataWithObjectName<VectorPostprocessorValue>(
        vpp_name + "_" + vector_name, "values_old");
  }

  // Does the VPP need to be broadcast after computing
  vec_struct.needs_broadcast |= needs_broadcast;

  // Does the VPP need to be scattered after computing
  vec_struct.needs_scatter |= needs_scatter;

  return vec_struct;
}
Exemple #3
0
Point
FauxGrainTracker::getGrainCentroid(unsigned int grain_index) const
{
  const auto grain_center = _centroid.find(grain_index);
  mooseAssert(grain_center != _centroid.end(),
              "Grain " << grain_index << " does not exist in data structure");

  return grain_center->second;
}
Exemple #4
0
Number
MooseVariable::getNodalValue(const Node & node)
{
  mooseAssert(_subproblem.mesh().isSemiLocal(const_cast<Node *>(&node)), "Node is not Semilocal");

  // Make sure that the node has DOFs
  /* Note, this is a reproduction of an assert within libMesh::Node::dof_number, this is done to
   * produce a
   * better error (see misc/check_error.node_value_off_block) */
  mooseAssert(node.n_dofs(_sys.number(), _var_num) > 0,
              "Node " << node.id() << " does not contain any dofs for the "
                      << _sys.system().variable_name(_var_num)
                      << " variable");

  dof_id_type dof = node.dof_number(_sys.number(), _var_num, 0);

  return (*_sys.currentSolution())(dof);
}
Exemple #5
0
void
VolumeHistogram::threadJoin(const UserObject & y)
{
  const VolumeHistogram & uo = static_cast<const VolumeHistogram &>(y);
  mooseAssert(uo._volume_tmp.size() == _volume_tmp.size(), "Inconsistent volume vector lengths across threads.");

  for (auto i = beginIndex(_volume_tmp); i < _volume_tmp.size(); ++i)
    _volume_tmp[i] += uo._volume_tmp[i];
}
Exemple #6
0
void
VolumeHistogram::threadJoin(const UserObject & y)
{
  const VolumeHistogram & uo = static_cast<const VolumeHistogram &>(y);
  mooseAssert(uo._volume.size() == _volume.size(), "Inconsistent volume vector lengths across threads.");

  for (unsigned int i = 0; i < _volume.size(); ++i)
    _volume[i] += uo._volume[i];
}
void
StiffenedGasFluidProperties::e_dprho(
    Real pressure, Real rho, Real & e, Real & de_dp, Real & de_drho) const
{
  mooseAssert((_gamma - 1) * rho != 0., "Invalid gamma or density detected!");
  e = this->e(pressure, rho);
  de_dp = 1. / ((_gamma - 1) * rho);
  de_drho = -(pressure + _gamma * _p_inf) / ((_gamma - 1) * rho * rho);
}
void
AEFVFreeOutflowBoundaryFlux::calcJacobian(unsigned int /*iside*/,
                                          dof_id_type /*ielem*/,
                                          const std::vector<Real> & libmesh_dbg_var(uvec1),
                                          const RealVectorValue & /*dwave*/,
                                          DenseMatrix<Real> & /*jac1*/) const
{
  mooseAssert(uvec1.size() == 1, "Invalid size for uvec1. Must be single variable coupling.");
}
Exemple #9
0
const std::set<SubdomainID> *
SystemBase::getVariableBlocks(unsigned int var_number)
{
  mooseAssert(_var_map.find(var_number) != _var_map.end(), "Variable does not exist.");
  if (_var_map[var_number].empty())
    return NULL;
  else
    return & _var_map[var_number];
}
Exemple #10
0
void
PerfGraph::recursivelyPrintHeaviestGraph(PerfNode * current_node,
                                         FullTable & vtable,
                                         unsigned int current_depth)
{
  mooseAssert(!_section_time_ptrs.empty(),
              "updateTiming() must be run before recursivelyPrintGraph!");

  auto & name = _id_to_section_name[current_node->id()];

  auto section = std::string(current_depth * 2, ' ') + name;

  // The total time of the root node
  auto total_root_time = _section_time_ptrs[0]->_total;

  auto num_calls = current_node->numCalls();
  auto self = std::chrono::duration<double>(current_node->selfTime()).count();
  auto self_avg = self / static_cast<Real>(num_calls);
  auto self_percent = 100. * self / total_root_time;

  auto children = std::chrono::duration<double>(current_node->childrenTime()).count();
  auto children_avg = children / static_cast<Real>(num_calls);
  auto children_percent = 100. * children / total_root_time;

  auto total = std::chrono::duration<double>(current_node->totalTime()).count();
  auto total_avg = total / static_cast<Real>(num_calls);
  auto total_percent = 100. * total / total_root_time;

  vtable.addRow(section,
                num_calls,
                self,
                self_avg,
                self_percent,
                children,
                children_avg,
                children_percent,
                total,
                total_avg,
                total_percent);

  current_depth++;

  if (!current_node->children().empty())
  {
    PerfNode * heaviest_child = nullptr;

    for (auto & child_it : current_node->children())
    {
      auto current_child = child_it.second.get();

      if (!heaviest_child || (current_child->totalTime() > heaviest_child->totalTime()))
        heaviest_child = current_child;
    }

    recursivelyPrintHeaviestGraph(heaviest_child, vtable, current_depth);
  }
}
void
MultiPlasticityLinearSystem::calculateConstraints(const RankTwoTensor & stress, const std::vector<Real> & intnl_old, const std::vector<Real> & intnl, const std::vector<Real> & pm, const RankTwoTensor & delta_dp, std::vector<Real> & f, std::vector<RankTwoTensor> & r, RankTwoTensor & epp, std::vector<Real> & ic, const std::vector<bool> & active)
{
  // see comments at the start of .h file

  mooseAssert(intnl_old.size() == _num_models, "Size of intnl_old is " << intnl_old.size() << " which is incorrect in calculateConstraints");
  mooseAssert(intnl.size() == _num_models, "Size of intnl is " << intnl.size() << " which is incorrect in calculateConstraints");
  mooseAssert(pm.size() == _num_surfaces, "Size of pm is " << pm.size() << " which is incorrect in calculateConstraints");
  mooseAssert(active.size() == _num_surfaces, "Size of active is " << active.size() << " which is incorrect in calculateConstraints");


  // yield functions
  yieldFunction(stress, intnl, active, f);


  // flow directions and "epp"
  flowPotential(stress, intnl, active, r);
  epp = RankTwoTensor();
  unsigned ind = 0;
  for (unsigned surface = 0 ; surface < _num_surfaces ; ++surface)
    if (active[surface])
      epp += pm[surface]*r[ind++]; // note, even the deactivated_due_to_ld must get added in
  epp -= delta_dp;


  // internal constraints
  std::vector<Real> h;
  hardPotential(stress, intnl, active, h);
  ic.resize(0);
  ind = 0;
  std::vector<unsigned int> active_surfaces;
  std::vector<unsigned int>::iterator active_surface;
  for (unsigned model = 0 ; model < _num_models ; ++model)
  {
    activeSurfaces(model, active, active_surfaces);
    if (active_surfaces.size() > 0)
    {
      // some surfaces are active in this model, so must form an internal constraint
      ic.push_back(intnl[model] - intnl_old[model]);
      for (active_surface = active_surfaces.begin() ; active_surface != active_surfaces.end() ; ++active_surface)
        ic[ic.size()-1] += pm[*active_surface]*h[ind++]; // we know the correct one is h[ind] since it was constructed in the same manner
    }
  }
}
Exemple #12
0
void
PerfGraph::printHeaviestSections(const ConsoleStream & console, const unsigned int num_sections)
{
  updateTiming();

  console << "\nHeaviest Sections:\n";

  // Indirect Sort The Self Time
  std::vector<size_t> sorted;
  Moose::indirectSort(_section_time_ptrs.begin(),
                      _section_time_ptrs.end(),
                      sorted,
                      [](SectionTime * lhs, SectionTime * rhs) {

                        if (lhs && rhs)
                          return lhs->_self > rhs->_self;

                        // If the LHS exists - it's definitely bigger than a non-existant RHS
                        if (lhs)
                          return true;

                        // Both don't exist - so it doesn't matter how we sort them
                        return false;
                      });

  HeaviestTable vtable({"Section", "Calls", "Self(s)", "Avg.", "%"}, 10);

  vtable.setColumnFormat({VariadicTableColumnFormat::AUTO, // Doesn't matter
                          VariadicTableColumnFormat::AUTO,
                          VariadicTableColumnFormat::FIXED,
                          VariadicTableColumnFormat::FIXED,
                          VariadicTableColumnFormat::PERCENT});

  vtable.setColumnPrecision({1, 1, 3, 3, 2});

  mooseAssert(!_section_time_ptrs.empty(),
              "updateTiming() must be run before printHeaviestSections()!");

  // The total time of the root node
  auto total_root_time = _section_time_ptrs[0]->_total;

  // Now print out the largest ones
  for (unsigned int i = 0; i < num_sections; i++)
  {
    auto id = sorted[i];

    vtable.addRow(_id_to_section_name[id],
                  _section_time_ptrs[id]->_num_calls,
                  _section_time_ptrs[id]->_self,
                  _section_time_ptrs[id]->_self /
                      static_cast<Real>(_section_time_ptrs[id]->_num_calls),
                  100 * _section_time_ptrs[id]->_self / total_root_time);
  }

  vtable.print(console);
}
Exemple #13
0
void
RestartableDataIO::readRestartableDataHeader(std::string base_file_name)
{
  unsigned int n_threads = libMesh::n_threads();
  processor_id_type n_procs = _fe_problem.n_processors();
  processor_id_type proc_id = _fe_problem.processor_id();

  for (unsigned int tid=0; tid<n_threads; tid++)
  {
    std::ostringstream file_name_stream;
    file_name_stream << base_file_name;
    file_name_stream << "-" << proc_id;

    if (n_threads > 1)
      file_name_stream << "-" << tid;

    std::string file_name = file_name_stream.str();

    MooseUtils::checkFileReadable(file_name);

    const unsigned int file_version = 2;

    mooseAssert(_in_file_handles[tid] == NULL, "Looks like you might be leaking in RestartableDataIO.C");
    _in_file_handles[tid] = new std::ifstream(file_name.c_str(), std::ios::in | std::ios::binary);

    // header
    char id[2];
    _in_file_handles[tid]->read(id, 2);

    unsigned int this_file_version;
    _in_file_handles[tid]->read((char *)&this_file_version, sizeof(this_file_version));

    processor_id_type this_n_procs = 0;
    unsigned int this_n_threads = 0;

    _in_file_handles[tid]->read((char *)&this_n_procs, sizeof(this_n_procs));
    _in_file_handles[tid]->read((char *)&this_n_threads, sizeof(this_n_threads));

    // check the header
    if (id[0] != 'R' || id[1] != 'D')
      mooseError("Corrupted restartable data file!");

    // check the file version
    if (this_file_version > file_version)
      mooseError("Trying to restart from a newer file version - you need to update MOOSE");

    if (this_file_version < file_version)
      mooseError("Trying to restart from an older file version - you need to checkout an older version of MOOSE.");

    if (this_n_procs != n_procs)
      mooseError("Cannot restart using a different number of processors!");

    if (this_n_threads != n_threads)
      mooseError("Cannot restart using a different number of threads!");
  }
}
Exemple #14
0
RankFourTensor::RankFourTensor()
{
  mooseAssert(N == 3, "RankFourTensor is currently only tested for 3 dimensions.");

  for (unsigned int i = 0; i < N; ++i)
    for (unsigned int j = 0; j < N; ++j)
      for (unsigned int k = 0; k < N; ++k)
        for (unsigned int l = 0; l < N; ++l)
          _vals[i][j][k][l] = 0.0;
}
Exemple #15
0
template<> void dataStore(std::ostream & stream, GrainTracker::UniqueGrain * & unique_grain, void * context)
{
  mooseAssert(unique_grain, "Unique Grain Pointer is NULL");

  storeHelper(stream, unique_grain->variable_idx, context);
  storeHelper(stream, unique_grain->status, context);
  storeHelper(stream, unique_grain->sphere_ptrs, context);

  // We do not need to store the entities_ptrs structure. This information is not necessary for restart.
}
void
StiffenedGasFluidProperties::rho_dpT(
    Real pressure, Real temperature, Real & rho, Real & drho_dp, Real & drho_dT) const
{
  mooseAssert(((_gamma - 1) * _cv * temperature) != 0.0,
              "Invalid gamma or cv or temperature detected!");
  rho = (pressure + _p_inf) / ((_gamma - 1) * _cv * temperature);
  drho_dp = 1. / ((_gamma - 1) * _cv * temperature);
  drho_dT = -(pressure + _p_inf) / ((_gamma - 1) * _cv * temperature * temperature);
}
Exemple #17
0
void
Sampler::setSampleNames(const std::vector<std::string> & names)
{
  _sample_names = names;

  // Use assert because to check the size a getSamples call is required, which you don't
  // want to do if you don't need it.
  mooseAssert(getSamples().size() == _sample_names.size(),
              "The number of sample names must match the number of samples returned.");
}
Exemple #18
0
Real
ElementUOIC::value(const Point & /*p*/)
{
  mooseAssert(_current_elem, "Current Elem is nullptr");

  if (_field_type == "long")
    return _elem_uo.getElementalValueLong(_current_elem->id(), _field_name);
  else
    return _elem_uo.getElementalValueReal(_current_elem->id(), _field_name);
}
Exemple #19
0
void
Adaptivity::uniformRefine(MooseMesh *mesh)
{
  mooseAssert(mesh, "Mesh pointer must not be NULL");

  // NOTE: we are using a separate object here, since adaptivity may not be on, but we need to be able to do refinements
  MeshRefinement mesh_refinement(*mesh);
  unsigned int level = mesh->uniformRefineLevel();
  mesh_refinement.uniformly_refine(level);
}
Exemple #20
0
void
FeatureFloodCount::buildFeatureIdToLocalIndices(unsigned int max_id)
{
  _feature_id_to_local_index.assign(max_id + 1, invalid_size_t);
  for (auto feature_index = beginIndex(_feature_sets); feature_index < _feature_sets.size(); ++feature_index)
  {
    mooseAssert(_feature_sets[feature_index]._id <= max_id, "Feature ID out of range");
    _feature_id_to_local_index[_feature_sets[feature_index]._id] = feature_index;
  }
}
PolycrystalUserObjectBase::PolycrystalUserObjectBase(const InputParameters & parameters)
  : FeatureFloodCount(parameters),
    _dim(_mesh.dimension()),
    _op_num(_vars.size()),
    _coloring_algorithm(getParam<MooseEnum>("coloring_algorithm")),
    _colors_assigned(false),
    _output_adjacency_matrix(getParam<bool>("output_adjacency_matrix"))
{
  mooseAssert(_single_map_mode, "Do not turn off single_map_mode with this class");
}
void
TensorMechanicsPlasticModel::activeConstraints(const std::vector<Real> & f, const RankTwoTensor & /*stress*/, Real /*intnl*/,
                                               const RankFourTensor & /*Eijkl*/, std::vector<bool> & act,
                                               RankTwoTensor & /*returned_stress*/) const
{
  mooseAssert(f.size() == numberSurfaces(), "f incorrectly sized at " << f.size() << " in activeConstraints");
  act.resize(numberSurfaces());
  for (unsigned surface = 0; surface < numberSurfaces(); ++surface)
    act[surface] = (f[surface] > _f_tol);
}
Exemple #23
0
void
FeatureFloodCount::visitNodalNeighbors(const Node * node, unsigned long current_idx, FeatureData * feature, bool expand_halos_only)
{
  mooseAssert(node, "Node is NULL");

  std::vector<const Node *> all_active_neighbors;
  MeshTools::find_nodal_neighbors(_mesh.getMesh(), *node, _nodes_to_elem_map, all_active_neighbors);

  visitNeighborsHelper(node, all_active_neighbors, current_idx, feature, expand_halos_only);
}
Exemple #24
0
bool
BlockRestrictable::hasBlocks(std::set<SubdomainID> ids) const
{
  mooseAssert(_initialized, "BlockRestrictable not initialized");

  if (_blk_ids.empty() || _blk_ids.find(Moose::ANY_BLOCK_ID) != _blk_ids.end())
    return true;
  else
    return std::includes(_blk_ids.begin(), _blk_ids.end(), ids.begin(), ids.end());
}
Real
NearestNodeValueAux::computeValue()
{
  // Assumes the variable you are coupling to is from the nonlinear system for now.
  const Node * nearest = _nearest_node.nearestNode(_current_node->id());
  mooseAssert(nearest != NULL, "I do not have the nearest node for you");
  dof_id_type dof_number = nearest->dof_number(_nl_sys.number(), _paired_variable, 0);

  return (*_serialized_solution)(dof_number);
}
Exemple #26
0
bool
BlockRestrictable::hasBlocks(SubdomainID id) const
{
  mooseAssert(_initialized, "BlockRestrictable not initialized");

  if (_blk_ids.empty() || _blk_ids.find(Moose::ANY_BLOCK_ID) != _blk_ids.end())
    return true;
  else
    return _blk_ids.find(id) != _blk_ids.end();
}
Exemple #27
0
RndSmoothCircleIC::RndSmoothCircleIC(const std::string & name,
                               InputParameters parameters)
  :InitialCondition(name, parameters),
   _x1(parameters.get<Real>("x1")),
   _y1(parameters.get<Real>("y1")),
   _z1(parameters.get<Real>("z1")),
   _mx_invalue(parameters.get<Real>("mx_invalue")),
   _mn_invalue(parameters.get<Real>("mn_invalue")),
   _mx_outvalue(parameters.get<Real>("mx_outvalue")),
   _mn_outvalue(parameters.get<Real>("mn_outvalue")),
   _range_invalue(_mx_invalue - _mn_invalue),
   _range_outvalue(_mx_outvalue - _mn_outvalue),
   _radius(parameters.get<Real>("radius")),
   _center(_x1,_y1,_z1)
{
  mooseAssert(_range_invalue >= 0.0, "Inside Min > Max for RndSmoothCircleIC!");
  mooseAssert(_range_outvalue >= 0.0, "Outside Min > Max for RndSmoothCircleIC!");
  MooseRandom::seed(getParam<unsigned int>("seed"));
}
Exemple #28
0
void
GrainTracker::calculateBubbleVolumes()
{
  Moose::perf_log.push("calculateBubbleVolumes()", "GrainTracker");

  // The size of the bubble array will be sized to the max index of the unique grains map
  unsigned int max_id = _unique_grains.size() ? _unique_grains.rbegin()->first + 1: 0;
  _all_feature_volumes.resize(max_id, 0);

  const MeshBase::const_element_iterator el_end = _mesh.getMesh().active_local_elements_end();
  for (MeshBase::const_element_iterator el = _mesh.getMesh().active_local_elements_begin(); el != el_end; ++el)
  {
    Elem * elem = *el;
    unsigned int elem_n_nodes = elem->n_nodes();
    Real curr_volume = elem->volume();

    for (std::map<unsigned int, MooseSharedPointer<FeatureData> >::iterator it = _unique_grains.begin(); it != _unique_grains.end(); ++it)
    {
      if (it->second->_status == INACTIVE)
        continue;

      if (_is_elemental)
      {
        dof_id_type elem_id = elem->id();
        if (it->second->_local_ids.find(elem_id) != it->second->_local_ids.end())
        {
          mooseAssert(it->first < _all_feature_volumes.size(), "_all_feature_volumes access out of bounds");
          _all_feature_volumes[it->first] += curr_volume;
          break;
        }
      }
      else
      {
        // Count the number of nodes on this element which are flooded.
        unsigned int flooded_nodes = 0;
        for (unsigned int node = 0; node < elem_n_nodes; ++node)
        {
          dof_id_type node_id = elem->node(node);
          if (it->second->_local_ids.find(node_id) != it->second->_local_ids.end())
            ++flooded_nodes;
        }

        // If a majority of the nodes for this element are flooded,
        // assign its volume to the current bubble_counter entry.
        if (flooded_nodes >= elem_n_nodes / 2)
          _all_feature_volumes[it->first] += curr_volume;
      }
    }
  }

  // do all the sums!
  _communicator.sum(_all_feature_volumes);

  Moose::perf_log.pop("calculateBubbleVolumes()", "GrainTracker");
}
Exemple #29
0
double
SheepReadBC::sampleTime(double t, double xcoord, double ycoord)
{

    mooseAssert(_x.size() > 0, "Sampling an empty SheepReadBC.");
    int posi;
    int posj;
    bool found = false;
    if(t <= _x[0])
    {
        posi = 0;
        for(unsigned int i(0); i < _nx * _ny; ++i)
            if( (std::fabs(_px(posi, i) - xcoord) < 0.1) && (std::fabs(_py(posi, i)- ycoord) < 0.1) )
                return _pv(posi, i);
        mooseError("Unreachable? Dirichlet: x="<<xcoord<<" , y="<<ycoord<<" , file="<<_y[posi]<<" !!" );
    }
    else if(t >= _x.back())
    {
        posi = _x.size()-1;
        for(unsigned int i(0); i < _nx * _ny; ++i)
            if( (std::fabs(_px(posi, i) - xcoord) < 0.1) && (std::fabs(_py(posi, i)- ycoord) < 0.1) )
                return _pv(posi, i);
        mooseError("Unreachable? Dirichlet: x="<<xcoord<<" , y="<<ycoord<<" , file="<<_y[posi]<<" !!" );
    }
    else
    {
        found = false;
        for(unsigned int i(0); i+1 < _x.size(); ++i)
        {
            if( t >= _x[i] && t < _x[i+1])
            {
                posi = i;
                found = true;
                break;
            }
        }
        if( !found )
            mooseError("Unreachable? sampleTime: x="<<xcoord<<" , y="<<ycoord<<" , posi="<<posi<<" !!" );

        found = false;
        for(unsigned int j(0); j < _nx* _ny; ++j)
        {
            if(std::fabs(_px(posi, j) - xcoord) < 0.1 && std::fabs(_py(posi, j) - ycoord) < 0.1)
            {
                posj = j;
                found = true;
                break;
            }
        }
        if( !found )
            mooseError("Unreachable? sampleTime: x="<<xcoord<<" , y="<<ycoord<<" , posj="<<posj<<" !!" );
        return _pv(posi,posj) + (_pv(posi+1,posj) - _pv(posi,posj)) * (t - _x[posi])/(_x[posi+1] - _x[posi]);
    }
    return 0;
}
Exemple #30
0
void
InertialForceBeam::computeJacobian()
{
  DenseMatrix<Number> & ke = _assembly.jacobianBlock(_var.number(), _var.number());
  _local_ke.resize(ke.m(), ke.n());
  _local_ke.zero();

  mooseAssert(_beta > 0.0, "InertialForceBeam: Beta parameter should be positive.");

  Real factor = 0.0;
  if (isParamValid("beta"))
    factor = 1.0 / (_beta * _dt * _dt) + _eta[0] * (1.0 + _alpha) * _gamma / _beta / _dt;
  else
    factor = (*_du_dotdot_du)[0] + _eta[0] * (1.0 + _alpha) * (*_du_dot_du)[0];

  for (unsigned int i = 0; i < _test.size(); ++i)
  {
    for (unsigned int j = 0; j < _phi.size(); ++j)
    {
      if (_component < 3)
        _local_ke(i, j) = (i == j ? 1.0 / 3.0 : 1.0 / 6.0) * _density[0] * _area[0] *
                          _original_length[0] * factor;
      else if (_component > 2)
      {
        RankTwoTensor I;
        if (isParamValid("Ix"))
          I(0, 0) = _Ix[0];
        else
          I(0, 0) = _Iy[0] + _Iz[0];
        I(1, 1) = _Iz[0];
        I(2, 2) = _Iy[0];

        // conversion from local config to global coordinate system
        RankTwoTensor Ig = _original_local_config[0].transpose() * I * _original_local_config[0];

        _local_ke(i, j) = (i == j ? 1.0 / 3.0 : 1.0 / 6.0) * _density[0] *
                          Ig(_component - 3, _component - 3) * _original_length[0] * factor;
      }
    }
  }

  ke += _local_ke;

  if (_has_diag_save_in)
  {
    unsigned int rows = ke.m();
    DenseVector<Number> diag(rows);
    for (unsigned int i = 0; i < rows; ++i)
      diag(i) = _local_ke(i, i);

    Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
    for (unsigned int i = 0; i < _diag_save_in.size(); ++i)
      _diag_save_in[i]->sys().solution().add_vector(diag, _diag_save_in[i]->dofIndices());
  }
}