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 "ComputeVariableIsotropicElasticityTensor.h" 11 : 12 : registerMooseObject("SolidMechanicsApp", ComputeVariableIsotropicElasticityTensor); 13 : 14 : InputParameters 15 48 : ComputeVariableIsotropicElasticityTensor::validParams() 16 : { 17 48 : InputParameters params = ComputeElasticityTensorBase::validParams(); 18 48 : params.addClassDescription("Compute an isotropic elasticity tensor for elastic constants that " 19 : "change as a function of material properties"); 20 96 : params.addRequiredParam<MaterialPropertyName>( 21 : "youngs_modulus", "Name of material property defining the Young's Modulus"); 22 96 : params.addRequiredParam<MaterialPropertyName>( 23 : "poissons_ratio", "Name of material property defining the Poisson's Ratio"); 24 96 : params.addRequiredCoupledVar( 25 : "args", "Variable dependence for the Young's Modulus and Poisson's Ratio materials"); 26 48 : return params; 27 0 : } 28 : 29 36 : ComputeVariableIsotropicElasticityTensor::ComputeVariableIsotropicElasticityTensor( 30 36 : const InputParameters & parameters) 31 : : ComputeElasticityTensorBase(parameters), 32 36 : _youngs_modulus(getMaterialProperty<Real>("youngs_modulus")), 33 72 : _poissons_ratio(getMaterialProperty<Real>("poissons_ratio")), 34 36 : _num_args(coupledComponents("args")), 35 36 : _dyoungs_modulus(_num_args), 36 36 : _d2youngs_modulus(_num_args), 37 36 : _dpoissons_ratio(_num_args), 38 36 : _d2poissons_ratio(_num_args), 39 36 : _delasticity_tensor(_num_args), 40 36 : _d2elasticity_tensor(_num_args), 41 72 : _isotropic_elastic_constants(2) 42 : { 43 : // all tensors created by this class are always isotropic 44 36 : issueGuarantee(_elasticity_tensor_name, Guarantee::ISOTROPIC); 45 : 46 : // fetch prerequisite derivatives and build elasticity tensor derivatives and cross-derivatives 47 36 : for (unsigned int i = 0; i < _num_args; ++i) 48 : { 49 0 : const VariableName & iname = coupledName("args", i); 50 0 : _dyoungs_modulus[i] = &getMaterialPropertyDerivative<Real>("youngs_modulus", iname); 51 0 : _dpoissons_ratio[i] = &getMaterialPropertyDerivative<Real>("poissons_ratio", iname); 52 : 53 0 : _delasticity_tensor[i] = 54 0 : &declarePropertyDerivative<RankFourTensor>(_elasticity_tensor_name, iname); 55 : 56 0 : _d2youngs_modulus[i].resize(_num_args); 57 0 : _d2poissons_ratio[i].resize(_num_args); 58 0 : _d2elasticity_tensor[i].resize(_num_args); 59 : 60 0 : for (unsigned int j = i; j < _num_args; ++j) 61 : { 62 0 : const VariableName & jname = coupledName("args", j); 63 0 : _d2youngs_modulus[i][j] = 64 0 : &getMaterialPropertyDerivative<Real>("youngs_modulus", iname, jname); 65 0 : _d2poissons_ratio[i][j] = 66 0 : &getMaterialPropertyDerivative<Real>("poissons_ratio", iname, jname); 67 0 : _d2elasticity_tensor[i][j] = 68 0 : &declarePropertyDerivative<RankFourTensor>(_elasticity_tensor_name, iname, jname); 69 : } 70 : } 71 36 : } 72 : 73 : void 74 36 : ComputeVariableIsotropicElasticityTensor::initialSetup() 75 : { 76 108 : validateCoupling<Real>("youngs_modulus"); 77 72 : validateCoupling<Real>("poissons_ratio"); 78 36 : for (unsigned int i = 0; i < _num_args; ++i) 79 : { 80 0 : const VariableName & iname = coupledName("args", i); 81 : 82 0 : if (!_fe_problem.isMatPropRequested( 83 0 : derivativePropertyNameFirst(_elasticity_tensor_name, iname))) 84 0 : _delasticity_tensor[i] = nullptr; 85 : 86 0 : for (unsigned int j = 0; j < _num_args; ++j) 87 : { 88 0 : const VariableName & jname = coupledName("args", j); 89 0 : if (!_fe_problem.isMatPropRequested( 90 0 : derivativePropertyNameSecond(_elasticity_tensor_name, iname, jname))) 91 0 : _d2elasticity_tensor[i][j] = nullptr; 92 : } 93 : } 94 36 : } 95 : 96 : void 97 0 : ComputeVariableIsotropicElasticityTensor::initQpStatefulProperties() 98 : { 99 0 : } 100 : 101 : void 102 254608 : ComputeVariableIsotropicElasticityTensor::computeQpElasticityTensor() 103 : { 104 254608 : const Real E = _youngs_modulus[_qp]; 105 254608 : const Real nu = _poissons_ratio[_qp]; 106 : 107 254608 : _elasticity_tensor[_qp].fillSymmetricIsotropicEandNu(E, nu); 108 : 109 : // Define derivatives of the elasticity tensor 110 254608 : for (unsigned int i = 0; i < _num_args; ++i) 111 : { 112 0 : if (_delasticity_tensor[i]) 113 : { 114 0 : const Real dE = (*_dyoungs_modulus[i])[_qp]; 115 0 : const Real dnu = (*_dpoissons_ratio[i])[_qp]; 116 : 117 0 : const Real dlambda = (E * dnu + dE * nu) / ((1.0 + nu) * (1.0 - 2.0 * nu)) - 118 0 : E * nu * dnu / ((1.0 + nu) * (1.0 + nu) * (1.0 - 2.0 * nu)) + 119 0 : 2.0 * E * nu * dnu / ((1.0 + nu) * (1.0 - 2.0 * nu) * (1.0 - 2.0 * nu)); 120 0 : const Real dG = dE / (2.0 * (1.0 + nu)) - 2.0 * E * dnu / (4.0 * (1.0 + nu) * (1.0 + nu)); 121 : 122 0 : (*_delasticity_tensor[i])[_qp].fillSymmetricIsotropic(dlambda, dG); 123 : } 124 : 125 0 : for (unsigned int j = i; j < _num_args; ++j) 126 0 : if (_d2elasticity_tensor[i][j]) 127 : { 128 0 : const Real dEi = (*_dyoungs_modulus[i])[_qp]; 129 0 : const Real dnui = (*_dpoissons_ratio[i])[_qp]; 130 : 131 0 : const Real dEj = (*_dyoungs_modulus[j])[_qp]; 132 0 : const Real dnuj = (*_dpoissons_ratio[j])[_qp]; 133 : 134 0 : const Real d2E = (*_d2youngs_modulus[i][j])[_qp]; 135 0 : const Real d2nu = (*_d2poissons_ratio[i][j])[_qp]; 136 : 137 0 : const Real d2lambda = 138 0 : 1.0 / ((1.0 + nu) * (2.0 * nu - 1.0)) * 139 0 : (-E * d2nu - nu * d2E - dEi * dnuj - dEj * dnui + 140 0 : (2.0 * E * d2nu * nu + 4.0 * dnui * dnuj * E + 2.0 * dEi * dnuj * nu + 141 0 : 2.0 * dEj * dnui * nu) / 142 0 : (2.0 * nu - 1.0) - 143 0 : 8.0 * dnui * dnuj * E * nu / ((2.0 * nu - 1.0) * (2.0 * nu - 1.0)) + 144 0 : (E * d2nu * nu + 2.0 * E * dnui * dnuj + dEi * dnuj * nu + dEj * dnui * nu) / 145 0 : (nu + 1.0) - 146 0 : 4.0 * E * nu * dnui * dnuj / ((1.0 + nu) * (2.0 * nu - 1.0)) - 147 0 : 2.0 * E * dnui * dnuj * nu / ((nu + 1.0) * (nu + 1.0))); 148 0 : const Real d2G = 1.0 / (nu + 1.0) * 149 0 : (0.5 * d2E - (E * d2nu + dEi * dnuj + dEj * dnui) / (2.0 * nu + 2.0) + 150 0 : dnui * dnuj * E / ((nu + 1.0) * (nu + 1.0))); 151 : 152 0 : (*_d2elasticity_tensor[i][j])[_qp].fillSymmetricIsotropic(d2lambda, d2G); 153 : } 154 : } 155 254608 : }