Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #include "ComputePolycrystalElasticityTensor.h" 11 : #include "RotationTensor.h" 12 : 13 : registerMooseObject("PhaseFieldApp", ComputePolycrystalElasticityTensor); 14 : 15 : InputParameters 16 0 : ComputePolycrystalElasticityTensor::validParams() 17 : { 18 0 : InputParameters params = ComputeElasticityTensorBase::validParams(); 19 0 : params.addClassDescription( 20 : "Compute an evolving elasticity tensor coupled to a grain growth phase field model."); 21 0 : params.addRequiredParam<UserObjectName>( 22 : "grain_tracker", "Name of GrainTracker user object that provides RankFourTensors"); 23 0 : params.addParam<Real>("length_scale", 1.0e-9, "Length scale of the problem, in meters"); 24 0 : params.addParam<Real>("pressure_scale", 1.0e6, "Pressure scale of the problem, in pa"); 25 0 : params.addRequiredCoupledVarWithAutoBuild( 26 : "v", "var_name_base", "op_num", "Array of coupled variables"); 27 0 : return params; 28 0 : } 29 : 30 0 : ComputePolycrystalElasticityTensor::ComputePolycrystalElasticityTensor( 31 0 : const InputParameters & parameters) 32 : : ComputeElasticityTensorBase(parameters), 33 0 : _length_scale(getParam<Real>("length_scale")), 34 0 : _pressure_scale(getParam<Real>("pressure_scale")), 35 0 : _grain_tracker(getUserObject<GrainDataTracker<RankFourTensor>>("grain_tracker")), 36 0 : _op_num(coupledComponents("v")), 37 0 : _vals(coupledValues("v")), 38 0 : _D_elastic_tensor(_op_num), 39 0 : _JtoeV(6.24150974e18) 40 : { 41 : // Loop over variables (ops) 42 0 : for (MooseIndex(_op_num) op_index = 0; op_index < _op_num; ++op_index) 43 : { 44 : // declare elasticity tensor derivative properties 45 0 : _D_elastic_tensor[op_index] = &declarePropertyDerivative<RankFourTensor>( 46 0 : _elasticity_tensor_name, coupledName("v", op_index)); 47 : } 48 0 : } 49 : 50 : void 51 0 : ComputePolycrystalElasticityTensor::computeQpElasticityTensor() 52 : { 53 : // Get list of active order parameters from grain tracker 54 0 : const auto & op_to_grains = _grain_tracker.getVarToFeatureVector(_current_elem->id()); 55 : 56 : // Calculate elasticity tensor 57 0 : _elasticity_tensor[_qp].zero(); 58 0 : Real sum_h = 0.0; 59 0 : for (MooseIndex(op_to_grains) op_index = 0; op_index < op_to_grains.size(); ++op_index) 60 : { 61 0 : auto grain_id = op_to_grains[op_index]; 62 0 : if (grain_id == FeatureFloodCount::invalid_id) 63 : continue; 64 : 65 : // Interpolation factor for elasticity tensors 66 0 : Real h = (1.0 + std::sin(libMesh::pi * ((*_vals[op_index])[_qp] - 0.5))) / 2.0; 67 : 68 : // Sum all rotated elasticity tensors 69 0 : _elasticity_tensor[_qp] += _grain_tracker.getData(grain_id) * h; 70 0 : sum_h += h; 71 : } 72 : 73 0 : const Real tol = 1.0e-10; 74 0 : sum_h = std::max(sum_h, tol); 75 0 : _elasticity_tensor[_qp] /= sum_h; 76 : 77 : // Calculate elasticity tensor derivative: Cderiv = dhdopi/sum_h * (Cop - _Cijkl) 78 0 : for (MooseIndex(_op_num) op_index = 0; op_index < _op_num; ++op_index) 79 0 : (*_D_elastic_tensor[op_index])[_qp].zero(); 80 : 81 0 : for (MooseIndex(op_to_grains) op_index = 0; op_index < op_to_grains.size(); ++op_index) 82 : { 83 0 : auto grain_id = op_to_grains[op_index]; 84 0 : if (grain_id == FeatureFloodCount::invalid_id) 85 : continue; 86 : 87 0 : Real dhdopi = libMesh::pi * std::cos(libMesh::pi * ((*_vals[op_index])[_qp] - 0.5)) / 2.0; 88 0 : RankFourTensor & C_deriv = (*_D_elastic_tensor[op_index])[_qp]; 89 : 90 0 : C_deriv = (_grain_tracker.getData(grain_id) - _elasticity_tensor[_qp]) * dhdopi / sum_h; 91 : 92 : // Convert from XPa to eV/(xm)^3, where X is pressure scale and x is length scale; 93 0 : C_deriv *= _JtoeV * (_length_scale * _length_scale * _length_scale) * _pressure_scale; 94 : } 95 0 : }