Real INSSplitMomentum::computeQpOffDiagJacobian(unsigned jvar) { if ((jvar == _u_vel_var_number) || (jvar == _v_vel_var_number) || (jvar == _w_vel_var_number)) { // Derivative of viscous stress tensor RealTensorValue dtau; // Initialize to invalid value, then determine correct value. unsigned vel_index = 99; // Set index and build dtau for that index if (jvar == _u_vel_var_number) { vel_index = 0; dtau(0, 0) = 2. * _grad_phi[_j][_qp](0); dtau(0, 1) = _grad_phi[_j][_qp](1); dtau(0, 2) = _grad_phi[_j][_qp](2); dtau(1, 0) = _grad_phi[_j][_qp](1); dtau(2, 0) = _grad_phi[_j][_qp](2); } else if (jvar == _v_vel_var_number) { vel_index = 1; /* */ dtau(0, 1) = _grad_phi[_j][_qp](0); dtau(1, 0) = _grad_phi[_j][_qp](0); dtau(1, 1) = 2. * _grad_phi[_j][_qp](1); dtau(1, 2) = _grad_phi[_j][_qp](2); /* */ dtau(2, 1) = _grad_phi[_j][_qp](2); } else if (jvar == _w_vel_var_number) { vel_index = 2; /* */ dtau(0, 2) = _grad_phi[_j][_qp](0); /* */ dtau(1, 2) = _grad_phi[_j][_qp](1); dtau(2, 0) = _grad_phi[_j][_qp](0); dtau(2, 1) = _grad_phi[_j][_qp](1); dtau(2, 2) = 2. * _grad_phi[_j][_qp](2); } // Vector object for test function RealVectorValue test; test(_component) = _test[_i][_qp]; // Vector object for U RealVectorValue U(_u_vel[_qp], _v_vel[_qp], _w_vel[_qp]); // Tensor object for test function gradient RealTensorValue grad_test; for (unsigned k = 0; k < 3; ++k) grad_test(_component, k) = _grad_test[_i][_qp](k); // Compute the convective part RealVectorValue convective_jac = _phi[_j][_qp] * RealVectorValue(_grad_u_vel[_qp](vel_index), _grad_v_vel[_qp](vel_index), _grad_w_vel[_qp](vel_index)); // Extra contribution in vel_index component convective_jac(vel_index) += U * _grad_phi[_j][_qp]; Real convective_part = convective_jac * test; // Compute the viscous part Real viscous_part = (_mu[_qp] / _rho[_qp]) * dtau.contract(grad_test); // Return the result return convective_part + viscous_part; } else return 0; }
Real INSChorinPredictor::computeQpOffDiagJacobian(unsigned jvar) { switch (_predictor_enum) { case OLD: { return 0.; } case NEW: { if ((jvar == _u_vel_var_number) || (jvar == _v_vel_var_number) || (jvar == _w_vel_var_number)) { // Derivative of grad_U wrt the velocity component RealTensorValue dgrad_U; // Initialize to invalid value, then determine correct value. unsigned vel_index = 99; // Map jvar into the indices (0,1,2) if (jvar == _u_vel_var_number) vel_index = 0; else if (jvar == _v_vel_var_number) vel_index = 1; else if (jvar == _w_vel_var_number) vel_index = 2; // Fill in the vel_index'th row of dgrad_U with _grad_phi[_j][_qp] for (unsigned k=0; k<3; ++k) dgrad_U(vel_index,k) = _grad_phi[_j][_qp](k); // Vector object for test function RealVectorValue test; test(_component) = _test[_i][_qp]; // Vector object for U RealVectorValue U(_u_vel[_qp], _v_vel[_qp], _w_vel[_qp]); // Tensor object for test function gradient RealTensorValue grad_test; for (unsigned k=0; k<3; ++k) grad_test(_component, k) = _grad_test[_i][_qp](k); // Compute the convective part RealVectorValue convective_jac = _phi[_j][_qp] * RealVectorValue(_grad_u_vel[_qp](vel_index), _grad_v_vel[_qp](vel_index), _grad_w_vel[_qp](vel_index)); // Extra contribution in vel_index component convective_jac(vel_index) += U*_grad_phi[_j][_qp]; // Be sure to scale by _dt! Real convective_part = _dt * (convective_jac * test); // Compute the viscous part, be sure to scale by _dt. Note: the contracted // value should be zero unless vel_index and _component match. Real viscous_part = _dt * (_mu/_rho) * dgrad_U.contract(grad_test); // Return the result return convective_part + viscous_part; } else return 0; } case STAR: { if (jvar == _u_vel_star_var_number) { return _dt * _phi[_j][_qp] * _grad_u[_qp](0) * _test[_i][_qp]; } else if (jvar == _v_vel_star_var_number) { return _dt * _phi[_j][_qp] * _grad_u[_qp](1) * _test[_i][_qp]; } else if (jvar == _w_vel_star_var_number) { return _dt * _phi[_j][_qp] * _grad_u[_qp](2) * _test[_i][_qp]; } else return 0; } default: mooseError("Unrecognized Chorin predictor type requested."); } }