Exemple #1
0
void
NodalConstraint::computeJacobian(SparseMatrix<Number> & jacobian)
{
  if ((_weights.size() == 0) && (_master_node_vector.size() == 1))
    _weights.push_back(1.0);

  // Calculate Jacobian enteries and cache those entries along with the row and column indices
  std::vector<dof_id_type> slavedof = _var.dofIndicesNeighbor();
  std::vector<dof_id_type> masterdof = _var.dofIndices();

  DenseMatrix<Number> Kee(masterdof.size(), masterdof.size());
  DenseMatrix<Number> Ken(masterdof.size(), slavedof.size());
  DenseMatrix<Number> Kne(slavedof.size(), masterdof.size());
  DenseMatrix<Number> Knn(slavedof.size(), slavedof.size());

  Kee.zero();
  Ken.zero();
  Kne.zero();
  Knn.zero();

  for (_i = 0; _i < slavedof.size(); ++_i)
  {
    for (_j = 0; _j < masterdof.size(); ++_j)
    {
      switch (_formulation)
      {
        case Moose::Penalty:
          Kee(_j, _j) += computeQpJacobian(Moose::MasterMaster);
          Ken(_j, _i) += computeQpJacobian(Moose::MasterSlave);
          Kne(_i, _j) += computeQpJacobian(Moose::SlaveMaster);
          Knn(_i, _i) += computeQpJacobian(Moose::SlaveSlave);
          break;
        case Moose::Kinematic:
          Kee(_j, _j) = 0.;
          Ken(_j, _i) += jacobian(slavedof[_i], masterdof[_j]) * _weights[_j];
          Kne(_i, _j) += -jacobian(slavedof[_i], masterdof[_j]) / masterdof.size() +
                         computeQpJacobian(Moose::SlaveMaster);
          Knn(_i, _i) += -jacobian(slavedof[_i], slavedof[_i]) / masterdof.size() +
                         computeQpJacobian(Moose::SlaveSlave);
          break;
      }
    }
  }
  _assembly.cacheJacobianBlock(Kee, masterdof, masterdof, _var.scalingFactor());
  _assembly.cacheJacobianBlock(Ken, masterdof, slavedof, _var.scalingFactor());
  _assembly.cacheJacobianBlock(Kne, slavedof, masterdof, _var.scalingFactor());
  _assembly.cacheJacobianBlock(Knn, slavedof, slavedof, _var.scalingFactor());
}
Exemple #2
0
void
FaceFaceConstraint::computeJacobian()
{
  _phi = _assembly.getFE(_var.feType(), _dim-1)->get_phi();                // yes we need to do a copy here
  std::vector<std::vector<Real> > phi_master;
  std::vector<std::vector<Real> > phi_slave;

  DenseMatrix<Number> & Kee = _assembly.jacobianBlock(_var.number(), _var.number());

  for (_qp = 0; _qp < _qrule->n_points(); _qp++)
    for (_i = 0; _i < _test.size(); _i++)
      for (_j = 0; _j < _phi.size(); _j++)
        Kee(_i, _j) += _JxW_lm[_qp] * _coord[_qp] * computeQpJacobian();
}
Exemple #3
0
void
FaceFaceConstraint::computeJacobian(SparseMatrix<Number> & jacobian)
{
  std::vector<std::vector<Real> > phi_master;
  std::vector<std::vector<Real> > phi_slave;

  unsigned int nqp = _qrule->n_points();

  _phys_points_master.resize(nqp);
  _phys_points_slave.resize(nqp);
  _test = _assembly.getFE(_var.feType())->get_phi();               // yes we need to do a copy here
  _phi = _assembly.getFE(_var.feType())->get_phi();                // yes we need to do a copy here
  _JxW_lm = _assembly.getFE(_var.feType())->get_JxW();             // another copy here to preserve the right JxW

  for (_qp = 0; _qp < nqp; _qp++)
  {
    const Node * current_node = _mesh.getQuadratureNode(_current_elem, 0, _qp);

    PenetrationInfo * master_pinfo = _master_penetration_locator._penetration_info[current_node->id()];
    PenetrationInfo * slave_pinfo = _slave_penetration_locator._penetration_info[current_node->id()];

    if (master_pinfo && slave_pinfo)
    {
      _phys_points_master[_qp] = master_pinfo->_closest_point;
      _elem_master = master_pinfo->_elem;

      _phys_points_slave[_qp] = slave_pinfo->_closest_point;
      _elem_slave = slave_pinfo->_elem;
    }
  }

  // fill in the diagonal block
  {
    DenseMatrix<Number> & Kee = _assembly.jacobianBlock(_var.index(), _var.index());

    for (_qp = 0; _qp < _qrule->n_points(); _qp++)
      for (_i = 0; _i < _test.size(); _i++)
        for (_j = 0; _j < _phi.size(); _j++)
          Kee(_i, _j) += _JxW_lm[_qp] * _coord[_qp] * computeQpJacobian();
    _assembly.addJacobian(jacobian);
  }

  // off-diagonal part for master side
  {
    _assembly.reinit(_elem_master);
    _master_var.prepare();
    _assembly.prepare();
    _assembly.reinitAtPhysical(_elem_master, _phys_points_master);

    DenseMatrix<Number> & Ken_master = _assembly.jacobianBlock(_var.index(), _master_var.index());
    DenseMatrix<Number> & Kne_master = _assembly.jacobianBlock(_master_var.index(), _var.index());

    for (_qp = 0; _qp < _qrule->n_points(); _qp++)
      for (_i = 0; _i < _test_master.size(); _i++)
      {
        for (_j = 0; _j < _phi.size(); _j++)
        {
          Ken_master(_j, _i) += _JxW_lm[_qp] * _coord[_qp] * computeQpJacobianSide(Moose::MasterMaster);
          Kne_master(_i, _j) += _JxW_lm[_qp] * _coord[_qp] * computeQpJacobianSide(Moose::SlaveMaster);
        }
      }
    _assembly.addJacobian(jacobian);
  }

  // off-diagonal part for slave side
  {
    _assembly.reinit(_elem_slave);
    _slave_var.prepare();
    _assembly.prepare();
    _assembly.reinitAtPhysical(_elem_slave, _phys_points_slave);

    DenseMatrix<Number> & Ken_slave = _assembly.jacobianBlock(_var.index(), _slave_var.index());
    DenseMatrix<Number> & Kne_slave = _assembly.jacobianBlock(_slave_var.index(), _var.index());
    for (_qp = 0; _qp < _qrule->n_points(); _qp++)
      for (_i = 0; _i < _test_slave.size(); _i++)
      {
        for (_j = 0; _j < _phi.size(); _j++)
        {
          Ken_slave(_j, _i) += _JxW_lm[_qp] * _coord[_qp] * computeQpJacobianSide(Moose::MasterSlave);
          Kne_slave(_i, _j) += _JxW_lm[_qp] * _coord[_qp] * computeQpJacobianSide(Moose::SlaveSlave);
        }
      }
    _assembly.addJacobian(jacobian);
  }
}