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 MechanicalContactConstraint::computeOffDiagJacobian(unsigned int jvar) { getConnectedDofIndices(jvar); _Kee.resize(_test_slave.size(), _connected_dof_indices.size()); DenseMatrix<Number> & Knn = _assembly.jacobianBlockNeighbor(Moose::NeighborNeighbor, _master_var.number(), jvar); for (_i=0; _i<_test_slave.size(); _i++) // Loop over the connected dof indices so we can get all the jacobian contributions for (_j=0; _j<_connected_dof_indices.size(); _j++) _Kee(_i,_j) += computeQpOffDiagJacobian(Moose::SlaveSlave, jvar); if (_master_slave_jacobian) { DenseMatrix<Number> & Ken = _assembly.jacobianBlockNeighbor(Moose::ElementNeighbor, _var.number(), jvar); for (_i=0; _i<_test_slave.size(); _i++) for (_j=0; _j<_phi_master.size(); _j++) Ken(_i,_j) += computeQpOffDiagJacobian(Moose::SlaveMaster, jvar); _Kne.resize(_test_master.size(), _connected_dof_indices.size()); if (_Kne.m() && _Kne.n()) for (_i=0; _i<_test_master.size(); _i++) // Loop over the connected dof indices so we can get all the jacobian contributions for (_j=0; _j<_connected_dof_indices.size(); _j++) _Kne(_i,_j) += computeQpOffDiagJacobian(Moose::MasterSlave, jvar); } for (_i=0; _i<_test_master.size(); _i++) for (_j=0; _j<_phi_master.size(); _j++) Knn(_i,_j) += computeQpOffDiagJacobian(Moose::MasterMaster, jvar); }
void NodeFaceConstraint::computeJacobian() { getConnectedDofIndices(_var.number()); // DenseMatrix<Number> & Kee = _assembly.jacobianBlock(_var.number(), _var.number()); DenseMatrix<Number> & Ken = _assembly.jacobianBlockNeighbor(Moose::ElementNeighbor, _var.number(), _var.number()); // DenseMatrix<Number> & Kne = _assembly.jacobianBlockNeighbor(Moose::NeighborElement, _var.number(), _var.number()); DenseMatrix<Number> & Knn = _assembly.jacobianBlockNeighbor(Moose::NeighborNeighbor, _master_var.number(), _var.number()); _Kee.resize(_test_slave.size(), _connected_dof_indices.size()); _Kne.resize(_test_master.size(), _connected_dof_indices.size()); _phi_slave.resize(_connected_dof_indices.size()); _qp = 0; // Fill up _phi_slave so that it is 1 when j corresponds to this dof and 0 for every other dof // This corresponds to evaluating all of the connected shape functions at _this_ node for (unsigned int j=0; j<_connected_dof_indices.size(); j++) { _phi_slave[j].resize(1); if (_connected_dof_indices[j] == _var.nodalDofIndex()) _phi_slave[j][_qp] = 1.0; else _phi_slave[j][_qp] = 0.0; } for (_i = 0; _i < _test_slave.size(); _i++) // Loop over the connected dof indices so we can get all the jacobian contributions for (_j=0; _j<_connected_dof_indices.size(); _j++) _Kee(_i,_j) += computeQpJacobian(Moose::SlaveSlave); if (Ken.m() && Ken.n()) for (_i=0; _i<_test_slave.size(); _i++) for (_j=0; _j<_phi_master.size(); _j++) Ken(_i,_j) += computeQpJacobian(Moose::SlaveMaster); for (_i=0; _i<_test_master.size(); _i++) // Loop over the connected dof indices so we can get all the jacobian contributions for (_j=0; _j<_connected_dof_indices.size(); _j++) _Kne(_i,_j) += computeQpJacobian(Moose::MasterSlave); if (Knn.m() && Knn.n()) for (_i=0; _i<_test_master.size(); _i++) for (_j=0; _j<_phi_master.size(); _j++) Knn(_i,_j) += computeQpJacobian(Moose::MasterMaster); }