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()); }
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(); }
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); } }