Real InteractionIntegral::computeQpIntegral() { Real scalar_q = 0.0; RealVectorValue grad_q(0.0, 0.0, 0.0); const std::vector<std::vector<Real>> & phi_curr_elem = *_phi_curr_elem; const std::vector<std::vector<RealGradient>> & dphi_curr_elem = *_dphi_curr_elem; for (unsigned int i = 0; i < _current_elem->n_nodes(); ++i) { scalar_q += phi_curr_elem[i][_qp] * _q_curr_elem[i]; for (unsigned int j = 0; j < _current_elem->dim(); ++j) grad_q(j) += dphi_curr_elem[i][_qp](j) * _q_curr_elem[i]; } // In the crack front coordinate system, the crack direction is (1,0,0) RealVectorValue crack_direction(0.0); crack_direction(0) = 1.0; // Calculate (r,theta) position of qp relative to crack front Point p(_q_point[_qp]); _crack_front_definition->calculateRThetaToCrackFront(p, _crack_front_point_index, _r, _theta); RankTwoTensor aux_stress; RankTwoTensor aux_du; if (_sif_mode == SifMethod::KI || _sif_mode == SifMethod::KII || _sif_mode == SifMethod::KIII) computeAuxFields(aux_stress, aux_du); else if (_sif_mode == SifMethod::T) computeTFields(aux_stress, aux_du); RankTwoTensor grad_disp((*_grad_disp[0])[_qp], (*_grad_disp[1])[_qp], (*_grad_disp[2])[_qp]); // Rotate stress, strain, displacement and temperature to crack front coordinate system RealVectorValue grad_q_cf = _crack_front_definition->rotateToCrackFrontCoords(grad_q, _crack_front_point_index); RankTwoTensor grad_disp_cf = _crack_front_definition->rotateToCrackFrontCoords(grad_disp, _crack_front_point_index); RankTwoTensor stress_cf = _crack_front_definition->rotateToCrackFrontCoords((*_stress)[_qp], _crack_front_point_index); RankTwoTensor strain_cf = _crack_front_definition->rotateToCrackFrontCoords((*_strain)[_qp], _crack_front_point_index); RealVectorValue grad_temp_cf = _crack_front_definition->rotateToCrackFrontCoords(_grad_temp[_qp], _crack_front_point_index); RankTwoTensor dq; dq(0, 0) = crack_direction(0) * grad_q_cf(0); dq(0, 1) = crack_direction(0) * grad_q_cf(1); dq(0, 2) = crack_direction(0) * grad_q_cf(2); // Calculate interaction integral terms // Term1 = stress * x1-derivative of aux disp * dq RankTwoTensor tmp1 = dq * stress_cf; Real term1 = aux_du.doubleContraction(tmp1); // Term2 = aux stress * x1-derivative of disp * dq RankTwoTensor tmp2 = dq * aux_stress; Real term2 = grad_disp_cf(0, 0) * tmp2(0, 0) + grad_disp_cf(1, 0) * tmp2(0, 1) + grad_disp_cf(2, 0) * tmp2(0, 2); // Term3 = aux stress * strain * dq_x (= stress * aux strain * dq_x) Real term3 = dq(0, 0) * aux_stress.doubleContraction(strain_cf); // Term4 (thermal strain term) = q * aux_stress * alpha * dtheta_x // - the term including the derivative of alpha is not implemented Real term4 = 0.0; if (_has_temp) { Real sigma_alpha = aux_stress.doubleContraction((*_total_deigenstrain_dT)[_qp]); term4 = scalar_q * sigma_alpha * grad_temp_cf(0); } Real q_avg_seg = 1.0; if (!_crack_front_definition->treatAs2D()) { q_avg_seg = (_crack_front_definition->getCrackFrontForwardSegmentLength(_crack_front_point_index) + _crack_front_definition->getCrackFrontBackwardSegmentLength(_crack_front_point_index)) / 2.0; } Real eq = term1 + term2 - term3 + term4; if (_has_symmetry_plane) eq *= 2.0; return eq / q_avg_seg; }
Real InteractionIntegralSM::computeQpIntegral() { Real scalar_q = 0.0; RealVectorValue grad_q(0.0, 0.0, 0.0); const std::vector<std::vector<Real>> & phi_curr_elem = *_phi_curr_elem; const std::vector<std::vector<RealGradient>> & dphi_curr_elem = *_dphi_curr_elem; for (unsigned int i = 0; i < _current_elem->n_nodes(); ++i) { scalar_q += phi_curr_elem[i][_qp] * _q_curr_elem[i]; for (unsigned int j = 0; j < _current_elem->dim(); ++j) grad_q(j) += dphi_curr_elem[i][_qp](j) * _q_curr_elem[i]; } // In the crack front coordinate system, the crack direction is (1,0,0) RealVectorValue crack_direction(0.0); crack_direction(0) = 1.0; RankTwoTensor stress; stress(0, 0) = _stress[_qp].xx(); stress(0, 1) = _stress[_qp].xy(); stress(0, 2) = _stress[_qp].xz(); stress(1, 0) = _stress[_qp].xy(); stress(1, 1) = _stress[_qp].yy(); stress(1, 2) = _stress[_qp].yz(); stress(2, 0) = _stress[_qp].xz(); stress(2, 1) = _stress[_qp].yz(); stress(2, 2) = _stress[_qp].zz(); RankTwoTensor strain; strain(0, 0) = _strain[_qp].xx(); strain(0, 1) = _strain[_qp].xy(); strain(0, 2) = _strain[_qp].xz(); strain(1, 0) = _strain[_qp].xy(); strain(1, 1) = _strain[_qp].yy(); strain(1, 2) = _strain[_qp].yz(); strain(2, 0) = _strain[_qp].xz(); strain(2, 1) = _strain[_qp].yz(); strain(2, 2) = _strain[_qp].zz(); RankTwoTensor grad_disp; grad_disp(0, 0) = _grad_disp_x[_qp](0); grad_disp(0, 1) = _grad_disp_x[_qp](1); grad_disp(0, 2) = _grad_disp_x[_qp](2); grad_disp(1, 0) = _grad_disp_y[_qp](0); grad_disp(1, 1) = _grad_disp_y[_qp](1); grad_disp(1, 2) = _grad_disp_y[_qp](2); grad_disp(2, 0) = _grad_disp_z[_qp](0); grad_disp(2, 1) = _grad_disp_z[_qp](1); grad_disp(2, 2) = _grad_disp_z[_qp](2); // Rotate stress, strain, displacement and temperature to crack front coordinate system RealVectorValue grad_q_cf = _crack_front_definition->rotateToCrackFrontCoords(grad_q, _crack_front_point_index); RankTwoTensor grad_disp_cf = _crack_front_definition->rotateToCrackFrontCoords(grad_disp, _crack_front_point_index); RankTwoTensor stress_cf = _crack_front_definition->rotateToCrackFrontCoords(stress, _crack_front_point_index); RankTwoTensor strain_cf = _crack_front_definition->rotateToCrackFrontCoords(strain, _crack_front_point_index); RealVectorValue grad_temp_cf = _crack_front_definition->rotateToCrackFrontCoords(_grad_temp[_qp], _crack_front_point_index); RankTwoTensor dq; dq(0, 0) = crack_direction(0) * grad_q_cf(0); dq(0, 1) = crack_direction(0) * grad_q_cf(1); dq(0, 2) = crack_direction(0) * grad_q_cf(2); // Calculate interaction integral terms // Term1 = stress * x1-derivative of aux disp * dq RankTwoTensor tmp1 = dq * stress_cf; Real term1 = _aux_grad_disp[_qp].doubleContraction(tmp1); // Term2 = aux stress * x1-derivative of disp * dq RankTwoTensor tmp2 = dq * _aux_stress[_qp]; Real term2 = grad_disp_cf(0, 0) * tmp2(0, 0) + grad_disp_cf(1, 0) * tmp2(0, 1) + grad_disp_cf(2, 0) * tmp2(0, 2); // Term3 = aux stress * strain * dq_x (= stress * aux strain * dq_x) Real term3 = dq(0, 0) * _aux_stress[_qp].doubleContraction(strain_cf); // Term4 (thermal strain term) = q * aux_stress * alpha * dtheta_x // - the term including the derivative of alpha is not implemented Real term4 = 0.0; if (_has_temp) { Real aux_stress_trace = _aux_stress[_qp](0, 0) + _aux_stress[_qp](1, 1) + _aux_stress[_qp](2, 2); term4 = scalar_q * aux_stress_trace * (*_current_instantaneous_thermal_expansion_coef)[_qp] * grad_temp_cf(0); } Real q_avg_seg = 1.0; if (!_crack_front_definition->treatAs2D()) { q_avg_seg = (_crack_front_definition->getCrackFrontForwardSegmentLength(_crack_front_point_index) + _crack_front_definition->getCrackFrontBackwardSegmentLength(_crack_front_point_index)) / 2.0; } Real eq = term1 + term2 - term3 + term4; if (_has_symmetry_plane) eq *= 2.0; return eq / q_avg_seg; }
Real InteractionIntegral::computeQpIntegral() { RealVectorValue grad_q = _grad_of_scalar_q[_qp]; //In the crack front coordinate system, the crack direction is (1,0,0) RealVectorValue crack_direction(0.0); crack_direction(0) = 1.0; ColumnMajorMatrix aux_du; aux_du(0,0) = _aux_grad_disp[_qp](0,0); aux_du(0,1) = _aux_grad_disp[_qp](0,1); aux_du(0,2) = _aux_grad_disp[_qp](0,2); ColumnMajorMatrix stress; stress(0,0) = _stress[_qp].xx(); stress(0,1) = _stress[_qp].xy(); stress(0,2) = _stress[_qp].xz(); stress(1,0) = _stress[_qp].xy(); stress(1,1) = _stress[_qp].yy(); stress(1,2) = _stress[_qp].yz(); stress(2,0) = _stress[_qp].xz(); stress(2,1) = _stress[_qp].yz(); stress(2,2) = _stress[_qp].zz(); ColumnMajorMatrix strain; strain(0,0) = _strain[_qp].xx(); strain(0,1) = _strain[_qp].xy(); strain(0,2) = _strain[_qp].xz(); strain(1,0) = _strain[_qp].xy(); strain(1,1) = _strain[_qp].yy(); strain(1,2) = _strain[_qp].yz(); strain(2,0) = _strain[_qp].xz(); strain(2,1) = _strain[_qp].yz(); strain(2,2) = _strain[_qp].zz(); ColumnMajorMatrix grad_disp; grad_disp(0,0) = _grad_disp_x[_qp](0); grad_disp(0,1) = _grad_disp_x[_qp](1); grad_disp(0,2) = _grad_disp_x[_qp](2); grad_disp(1,0) = _grad_disp_y[_qp](0); grad_disp(1,1) = _grad_disp_y[_qp](1); grad_disp(1,2) = _grad_disp_y[_qp](2); grad_disp(2,0) = _grad_disp_z[_qp](0); grad_disp(2,1) = _grad_disp_z[_qp](1); grad_disp(2,2) = _grad_disp_z[_qp](2); //Rotate stress, strain, and displacement to crack front coordinate system RealVectorValue grad_q_cf = _crack_front_definition->rotateToCrackFrontCoords(grad_q,_crack_front_point_index); ColumnMajorMatrix grad_disp_cf = _crack_front_definition->rotateToCrackFrontCoords(grad_disp,_crack_front_point_index); ColumnMajorMatrix stress_cf = _crack_front_definition->rotateToCrackFrontCoords(stress,_crack_front_point_index); ColumnMajorMatrix strain_cf = _crack_front_definition->rotateToCrackFrontCoords(strain,_crack_front_point_index); ColumnMajorMatrix dq; dq(0,0) = crack_direction(0)*grad_q_cf(0); dq(0,1) = crack_direction(0)*grad_q_cf(1); dq(0,2) = crack_direction(0)*grad_q_cf(2); //Calculate interaction integral terms // Term1 = stress * x1-derivative of aux disp * dq ColumnMajorMatrix tmp1 = dq * stress_cf; Real term1 = aux_du.doubleContraction(tmp1); // Term2 = aux stress * x1-derivative of disp * dq ColumnMajorMatrix tmp2 = dq * _aux_stress[_qp]; Real term2 = grad_disp_cf(0,0)*tmp2(0,0)+grad_disp_cf(1,0)*tmp2(0,1)+grad_disp_cf(2,0)*tmp2(0,2); // Term3 = aux stress * strain * dq_x (= stress * aux strain * dq_x) Real term3 = dq(0,0) * _aux_stress[_qp].doubleContraction(strain_cf); Real q_avg_seg = 1.0; if (!_crack_front_definition->treatAs2D()) { q_avg_seg = (_crack_front_definition->getCrackFrontForwardSegmentLength(_crack_front_point_index) + _crack_front_definition->getCrackFrontBackwardSegmentLength(_crack_front_point_index)) / 2.0; } Real eq = term1 + term2 - term3; if (_has_symmetry_plane) eq *= 2.0; return eq/q_avg_seg; }