Real JIntegral::computeQpIntegral() { ColumnMajorMatrix grad_of_vector_q; const RealVectorValue& crack_direction = _crack_front_definition->getCrackDirection(_crack_front_node_index); grad_of_vector_q(0,0) = crack_direction(0)*_grad_of_scalar_q[_qp](0); grad_of_vector_q(0,1) = crack_direction(0)*_grad_of_scalar_q[_qp](1); grad_of_vector_q(0,2) = crack_direction(0)*_grad_of_scalar_q[_qp](2); grad_of_vector_q(1,0) = crack_direction(1)*_grad_of_scalar_q[_qp](0); grad_of_vector_q(1,1) = crack_direction(1)*_grad_of_scalar_q[_qp](1); grad_of_vector_q(1,2) = crack_direction(1)*_grad_of_scalar_q[_qp](2); grad_of_vector_q(2,0) = crack_direction(2)*_grad_of_scalar_q[_qp](0); grad_of_vector_q(2,1) = crack_direction(2)*_grad_of_scalar_q[_qp](1); grad_of_vector_q(2,2) = crack_direction(2)*_grad_of_scalar_q[_qp](2); Real eq = _Eshelby_tensor[_qp].doubleContraction(grad_of_vector_q); //Thermal component Real eq_thermal = 0.0; if (_J_thermal_term_vec) { for (unsigned int i = 0; i < 3; i++) eq_thermal += crack_direction(i)*_scalar_q[_qp]*(*_J_thermal_term_vec)[_qp](i); } Real q_avg_seg = 1.0; if (!_crack_front_definition->treatAs2D()) { q_avg_seg = (_crack_front_definition->getCrackFrontForwardSegmentLength(_crack_front_node_index) + _crack_front_definition->getCrackFrontBackwardSegmentLength(_crack_front_node_index)) / 2.0; } Real etot = -eq + eq_thermal; return etot/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; }
void CrackFrontDefinition::updateCrackFrontGeometry() { updateDataForCrackDirection(); _segment_lengths.clear(); _tangent_directions.clear(); _crack_directions.clear(); _rot_matrix.clear(); if (_treat_as_2d) { RealVectorValue tangent_direction; RealVectorValue crack_direction; tangent_direction(_axis_2d) = 1.0; _tangent_directions.push_back(tangent_direction); const Node* crack_front_node = _mesh.nodePtr(_ordered_crack_front_nodes[0]); crack_direction = calculateCrackFrontDirection(crack_front_node,tangent_direction,MIDDLE_NODE); _crack_directions.push_back(crack_direction); _crack_plane_normal = crack_direction.cross(tangent_direction); ColumnMajorMatrix rot_mat; rot_mat(0,0) = crack_direction(0); rot_mat(0,1) = crack_direction(1); rot_mat(0,2) = crack_direction(2); rot_mat(1,0) = _crack_plane_normal(0); rot_mat(1,1) = _crack_plane_normal(1); rot_mat(1,2) = _crack_plane_normal(2); rot_mat(2,0) = 0.0; rot_mat(2,1) = 0.0; rot_mat(2,2) = 0.0; rot_mat(2,_axis_2d) = 1.0; _rot_matrix.push_back(rot_mat); _segment_lengths.push_back(std::make_pair(0.0,0.0)); _overall_length = 0.0; } else { unsigned int num_crack_front_nodes = _ordered_crack_front_nodes.size(); std::vector<Node*> crack_front_nodes; crack_front_nodes.reserve(num_crack_front_nodes); _segment_lengths.reserve(num_crack_front_nodes); _tangent_directions.reserve(num_crack_front_nodes); _crack_directions.reserve(num_crack_front_nodes); for (unsigned int i=0; i<num_crack_front_nodes; ++i) { crack_front_nodes.push_back(_mesh.nodePtr(_ordered_crack_front_nodes[i])); } _overall_length = 0.0; RealVectorValue back_segment; Real back_segment_len = 0.0; for (unsigned int i=0; i<num_crack_front_nodes; ++i) { CRACK_NODE_TYPE ntype = MIDDLE_NODE; if (i==0) { ntype = END_1_NODE; } else if (i==num_crack_front_nodes-1) { ntype = END_2_NODE; } RealVectorValue forward_segment; Real forward_segment_len = 0.0; if (ntype != END_2_NODE) { forward_segment = *crack_front_nodes[i+1] - *crack_front_nodes[i]; forward_segment_len = forward_segment.size(); } _segment_lengths.push_back(std::make_pair(back_segment_len,forward_segment_len)); //Moose::out<<"seg len: "<<back_segment_len<<" "<<forward_segment_len<<std::endl; RealVectorValue tangent_direction = back_segment + forward_segment; tangent_direction = tangent_direction / tangent_direction.size(); _tangent_directions.push_back(tangent_direction); //Moose::out<<"tan dir: "<<tangent_direction(0)<<" "<<tangent_direction(1)<<" "<<tangent_direction(2)<<std::endl; _crack_directions.push_back(calculateCrackFrontDirection(crack_front_nodes[i],tangent_direction,ntype)); _overall_length += forward_segment_len; back_segment = forward_segment; back_segment_len = forward_segment_len; } //For CURVED_CRACK_FRONT, _crack_plane_normal gets computed in updateDataForCrackDirection if (_direction_method != CURVED_CRACK_FRONT) { unsigned int mid_id = (num_crack_front_nodes-1)/2; _crack_plane_normal = _tangent_directions[mid_id].cross(_crack_directions[mid_id]); //Make sure the normal vector is non-zero RealVectorValue zero_vec(0.0); if (_crack_plane_normal.absolute_fuzzy_equals(zero_vec,1.e-15)) mooseError("Crack plane normal vector evaluates to zero"); } // Create rotation matrix for (unsigned int i=0; i<num_crack_front_nodes; ++i) { ColumnMajorMatrix rot_mat; rot_mat(0,0) = _crack_directions[i](0); rot_mat(0,1) = _crack_directions[i](1); rot_mat(0,2) = _crack_directions[i](2); rot_mat(1,0) = _crack_plane_normal(0); rot_mat(1,1) = _crack_plane_normal(1); rot_mat(1,2) = _crack_plane_normal(2); rot_mat(2,0) = _tangent_directions[i](0); rot_mat(2,1) = _tangent_directions[i](1); rot_mat(2,2) = _tangent_directions[i](2); _rot_matrix.push_back(rot_mat); } Moose::out<<"Summary of J-Integral crack front geometry:"<<std::endl; Moose::out<<"index node id x coord y coord z coord x dir y dir z dir seg length"<<std::endl; for (unsigned int i=0; i<crack_front_nodes.size(); ++i) { Moose::out<<std::left <<std::setw(8) <<i+1 <<std::setw(10)<<crack_front_nodes[i]->id() <<std::setw(14)<<(*crack_front_nodes[i])(0) <<std::setw(14)<<(*crack_front_nodes[i])(1) <<std::setw(14)<<(*crack_front_nodes[i])(2) <<std::setw(14)<<_crack_directions[i](0) <<std::setw(14)<<_crack_directions[i](1) <<std::setw(14)<<_crack_directions[i](2) <<std::setw(14)<<(_segment_lengths[i].first+_segment_lengths[i].second)/2.0 <<std::endl; } Moose::out<<"overall length: "<<_overall_length<<std::endl; } }
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 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; }