void GolemMaterialTH::computeQpProperties() { if (_has_lumped_mass_matrix) { (*_node_number)[_qp] = nearest(); (*_nodal_temp)[_qp] = (*_nodal_temp_var)[(*_node_number)[_qp]]; (*_nodal_temp_old)[_qp] = (*_nodal_temp_var_old)[(*_node_number)[_qp]]; (*_nodal_pf)[_qp] = (*_nodal_pf_var)[(*_node_number)[_qp]]; if (_has_boussinesq) (*_nodal_pf_old)[_qp] = (*_nodal_pf_var_old)[(*_node_number)[_qp]]; } _scaling_factor[_qp] = computeQpScaling(); computeDensity(); computeViscosity(); _porosity[_qp] = _porosity_uo->computePorosity(_phi0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); _permeability[_qp] = _permeability_uo->computePermeability(_k0, _phi0, _porosity[_qp], _scaling_factor[_qp]); // GolemKernelT related properties _T_kernel_diff[_qp] = _porosity[_qp] * _lambda_f + (1.0 - _porosity[_qp]) * _lambda_s; if (_has_T_source_sink) (*_T_kernel_source)[_qp] = -1.0 * _T_source_sink; // GolemKernelH related properties GolemPropertiesH(); // GolemkernelTH related poperties _TH_kernel[_qp] = -_H_kernel[_qp] * _fluid_density[_qp] * _c_f; if (_fe_problem.isTransient()) { // Correct H_kernel_time if (_drho_dpf[_qp] != 0.0) (*_H_kernel_time)[_qp] = (_porosity[_qp] * _drho_dpf[_qp]) / _fluid_density[_qp]; (*_T_kernel_time)[_qp] = _porosity[_qp] * _fluid_density[_qp] * _c_f + (1.0 - _porosity[_qp]) * _rho0_s * _c_s; } // Properties derivatives // H_kernel derivatives (*_dH_kernel_dpf)[_qp] = -_H_kernel[_qp] * _dmu_dpf[_qp] / _fluid_viscosity[_qp]; _dH_kernel_dT[_qp] = -_H_kernel[_qp] * _dmu_dT[_qp] / _fluid_viscosity[_qp]; // H_kernel_grav derivatives _dH_kernel_grav_dpf[_qp] = -_drho_dpf[_qp] * _gravity; _dH_kernel_grav_dT[_qp] = -_drho_dT[_qp] * _gravity; if (_fe_problem.isTransient()) { // T_kernel_time (*_dT_kernel_time_dpf)[_qp] = _drho_dpf[_qp] * _porosity[_qp] * _c_f; (*_dT_kernel_time_dT)[_qp] = _drho_dT[_qp] * _porosity[_qp] * _c_f; } // TH_kernel derivatives _dTH_kernel_dpf[_qp] = -(_fluid_density[_qp] * _c_f * (*_dH_kernel_dpf)[_qp] + _H_kernel[_qp] * _c_f * _drho_dpf[_qp]); _dTH_kernel_dT[_qp] = -(_fluid_density[_qp] * _c_f * _dH_kernel_dT[_qp] + _H_kernel[_qp] * _c_f * _drho_dT[_qp]); if (_has_SUPG_upwind) computeQpSUPG(); if (_has_disp) { // Declare some property when this material is used for fractures or faults in a THM simulation (*_dH_kernel_dev)[_qp] = RankTwoTensor(); (*_dT_kernel_diff_dev)[_qp] = 0.0; (*_dT_kernel_diff_dpf)[_qp] = 0.0; (*_dT_kernel_diff_dT)[_qp] = 0.0; if (_fe_problem.isTransient()) { (*_dT_kernel_time_dev)[_qp] = 0.0; (*_dH_kernel_time_dev)[_qp] = 0.0; (*_dH_kernel_time_dpf)[_qp] = 0.0; (*_dH_kernel_time_dT)[_qp] = 0.0; } } }
/******************************************************************************* Routine: computeQpProperties -- self-explanatory Authors: Yidong Xia *******************************************************************************/ void PTGeothermal::computeQpProperties() { // assign user-input values or keep default // scalar arrays _stat[_qp] = _istat; _stab[_qp] = _istab; _perm[_qp] = _iperm; _poro[_qp] = _iporo; _rrho[_qp] = _irrho; _rsph[_qp] = _irsph; _comp[_qp] = _icomp; _wrho[_qp] = _iwrho; _wvis[_qp] = _iwvis; _wsph[_qp] = _iwsph; _thco[_qp] = _ithco; _gfor[_qp] = _igfor; _epor[_qp] = 0.0; _drop[_qp] = 0.0; _drot[_qp] = 0.0; _tau1[_qp] = 0.0; _tau2[_qp] = 0.0; // vector arrays _guvec[_qp] = _igvec; gradp = _igrdp; // use the nonlinear variables when available rpres = _ipres; if (_has_pres) rpres = _pres[_qp]; rtemp = _itemp; if (_has_temp) rtemp = _temp[_qp]; rpres_old = _ipres; if (_has_pres) rpres_old = _pres_old[_qp]; rtemp_old = _itemp; if (_has_temp) rtemp_old = _temp_old[_qp]; if (_has_pres) { gradp = _grad_pres[_qp]; // permeability function if (_pres_dep_perm) mooseError("Pressure-dependent permeability function to be implemented"); } // options for calculating variable water properties if (_stat[_qp] == 1) // solely T-dependent fluid properties and use compressibility { _wrho[_qp] = computeTempBasedWaterDens(rtemp); _wvis[_qp] = computeTempBasedWaterVisc(rtemp); _drot[_qp] = computeTempBasedWaterPartialDensOverPartialTemp(rtemp); _drop[_qp] = _wrho[_qp]*_comp[_qp]; } else if (_stat[_qp] == 2) // P-T dependent fluid properties { Real inp[2] = {rpres, rtemp}; Real out[2] = {0.0, 0.0}; Real inpd[2][2] = { {1.0, 0.0}, {0.0, 1.0} }; Real outd[2][2] = { {0.0, 0.0}, {0.0, 0.0} }; computeWaterEquationOfStatePT_dv(inp, inpd, out, outd, 2); _wrho[_qp] = out[0]; _drop[_qp] = outd[0][0]; _drot[_qp] = outd[0][1]; computeViscosity(_wrho[_qp], rtemp, _wvis[_qp]); } // water mobility _wtau[_qp] = _perm[_qp]/_wvis[_qp]; // compute the following vectors and use them in kernels and aux kernels _wdflx[_qp] = -_wtau[_qp]*(gradp-_wrho[_qp]*_gfor[_qp]*_guvec[_qp]); _wdmfx[_qp] = _wrho[_qp]*_wdflx[_qp]; _evelo[_qp] = _wsph[_qp]*_wdmfx[_qp]; if (_has_temp) { // to be used in both energy time derivative and residual kernels if (_is_transient) _epor[_qp] = (1.0-_poro[_qp])*_rrho[_qp]*_rsph[_qp] + _poro[_qp]*_wrho[_qp]*_wsph[_qp]; // pre-compute a few varialbes upon stabilization options if (_stab[_qp] == 1) { _evelo[_qp] = 0.0; } else if (_stab[_qp] == 2) { // Streamline Upwind Petrov Galerkin // compute the SUPG h size const double hsupg = _current_elem->hmin(); // compute the energy convective velocity magnitude Real amag = _wsph[_qp]*sqrt(_wdmfx[_qp](0)*_wdmfx[_qp](0)+ _wdmfx[_qp](1)*_wdmfx[_qp](1)+ _wdmfx[_qp](2)*_wdmfx[_qp](2)); // compute the SUPG stabilization parameter: tau1 _tau1[_qp] = hsupg / (2.0*(amag+1.0e-7)); } else if (_stab[_qp] == 3) { // Streamline Upwind Petrov Galerkin with Discontinuity Capturing // (Note: this method may only slightly improve stability // or make it worse depending on specific situations) // Specifically speaking, the nonlinear convergence becomes worse // So always use with caution and only when you understand the mechanism // compute the SUPG h size const double hsupg = _current_elem->hmin(); // compute the energy convective velocity magnitude Real amag = _wsph[_qp]*sqrt(_wdmfx[_qp](0)*_wdmfx[_qp](0)+ _wdmfx[_qp](1)*_wdmfx[_qp](1)+ _wdmfx[_qp](2)*_wdmfx[_qp](2)); // compute the SUPG stabilization parameter: tau1 _tau1[_qp] = hsupg / (2.0*(amag+1.0e-7)); // compute the magnitude of temperature gradient Real grad_temp_mod = sqrt( _grad_temp[_qp](0)+_grad_temp[_qp](0) +_grad_temp[_qp](1)+_grad_temp[_qp](1) +_grad_temp[_qp](2)+_grad_temp[_qp](2)); // compute the discontinuity capturing parameter: tau2 if (grad_temp_mod > _ipgdc) _tau2[_qp] = hsupg / (2.0*grad_temp_mod); } } }