Real ExceptionKernel::computeQpResidual() { // We need a thread lock here so that we don't introduce a race condition when inspecting or // changing the static variable Threads::spin_mutex::scoped_lock lock(Threads::spin_mutex); if (_when == WhenType::INITIAL_CONDITION) throw MooseException("MooseException thrown during initial condition computation"); // Make sure we have called computeQpResidual enough times to // guarantee that we are in the middle of a linear solve, to verify // that we can throw an exception at that point. // Also, only throw on one rank if the user requests it else if (_when == WhenType::RESIDUAL && !_res_has_thrown && time_to_throw() && (_rank == DofObject::invalid_processor_id || _rank == processor_id())) { // The residual has now thrown _res_has_thrown = true; if (_should_throw) throw MooseException("MooseException thrown during residual calculation"); else mooseError("Intentional error triggered during residual calculation"); } else return 0.; }
void inverse(const std::vector<std::vector<Real>> & m, std::vector<std::vector<Real>> & m_inv) { unsigned int n = m.size(); // check the matrix m exists and is square if (n == 0) throw MooseException("Input matrix empty during matrix inversion."); if (n != m_inv.size() || n != m[0].size() || n != m_inv[0].size()) throw MooseException("Input and output matrix are not same size square matrices."); // build the vectorial representation std::vector<PetscScalar> A; for (const auto & rowvec : m) for (const auto & matrix_entry : rowvec) A.push_back(matrix_entry); inverse(A, n); // build the inverse unsigned int i = 0; for (auto & rowvec : m_inv) for (auto & inv_entry : rowvec) inv_entry = A[i++]; }
void inverse(std::vector<PetscScalar> & A, unsigned int n) { mooseAssert(n >= 1, "MatrixTools::inverse - n (leading dimension) needs to be positive"); mooseAssert(n <= std::numeric_limits<int>::max(), "MatrixTools::inverse - n (leading dimension) too large"); std::vector<PetscBLASInt> ipiv(n); std::vector<PetscScalar> buffer(n * 64); // Following does a LU decomposition of "square matrix A" // upon return "A = P*L*U" if return_value == 0 // Here I use quotes because A is actually an array of length n^2, not a matrix of size n-by-n int return_value; LAPACKgetrf_(reinterpret_cast<int *>(&n), reinterpret_cast<int *>(&n), &A[0], reinterpret_cast<int *>(&n), &ipiv[0], &return_value); if (return_value != 0) throw MooseException( return_value < 0 ? "Argument " + Moose::stringify(-return_value) + " was invalid during LU factorization in MatrixTools::inverse." : "Matrix on-diagonal entry " + Moose::stringify(return_value) + " was exactly zero during LU factorization in MatrixTools::inverse."); // get the inverse of A int buffer_size = buffer.size(); #if PETSC_VERSION_LESS_THAN(3, 5, 0) FORTRAN_CALL(dgetri) (reinterpret_cast<int *>(&n), &A[0], reinterpret_cast<int *>(&n), &ipiv[0], &buffer[0], &buffer_size, &return_value); #else LAPACKgetri_(reinterpret_cast<int *>(&n), &A[0], reinterpret_cast<int *>(&n), &ipiv[0], &buffer[0], &buffer_size, &return_value); #endif if (return_value != 0) throw MooseException(return_value < 0 ? "Argument " + Moose::stringify(-return_value) + " was invalid during invert in MatrixTools::inverse." : "Matrix on-diagonal entry " + Moose::stringify(return_value) + " was exactly zero during invert in MatrixTools::inverse."); }
Real StiffenedGasFluidProperties::s_from_h_p(Real h, Real p) const { const Real aux = (p + _p_inf) * std::pow((h - _q) / (_gamma * _cv), -_gamma / (_gamma - 1)); if (aux <= 0.0) throw MooseException(name() + ": Non-positive argument in the ln() function."); return _q_prime - (_gamma - 1) * _cv * std::log(aux); }
Real StiffenedGasFluidProperties::s_from_p_T(Real p, Real T) const { Real n = std::pow(T, _gamma) / std::pow(p + _p_inf, _gamma - 1.0); if (n <= 0.0) throw MooseException(name() + ": Negative argument in the ln() function."); return _cv * std::log(n) + _q_prime; }
Real StiffenedGasFluidProperties::s(Real v, Real u) const { Real T = this->temperature(v, u); Real p = this->pressure(v, u); Real n = std::pow(T, _gamma) / std::pow(p + _p_inf, _gamma - 1.0); if (n <= 0.0) throw MooseException(name() + ": Negative argument in the ln() function."); return _cv * std::log(n) + _q_prime; }
Real ExceptionKernel::computeQpResidual() { if (_when == INITIAL_CONDITION) throw MooseException("MooseException thrown during initial condition computation"); // Make sure we have called computeQpResidual enough times to // guarantee that we are in the middle of a linear solve, to verify // that we can throw an exception at that point. else if (_when == RESIDUAL && !_res_has_thrown && time_to_throw()) { // The residual has now thrown _res_has_thrown = true; throw MooseException("MooseException thrown during residual calculation"); } else return 0; }
Real ExceptionKernel::computeQpResidual() { // We need a thread lock here so that we don't introduce a race condition when inspecting or changing the static variable Threads::spin_mutex::scoped_lock lock(Threads::spin_mutex); if (_when == INITIAL_CONDITION) throw MooseException("MooseException thrown during initial condition computation"); // Make sure we have called computeQpResidual enough times to // guarantee that we are in the middle of a linear solve, to verify // that we can throw an exception at that point. else if (_when == RESIDUAL && !_res_has_thrown && time_to_throw()) { // The residual has now thrown _res_has_thrown = true; throw MooseException("MooseException thrown during residual calculation"); } else return 0; }
Real MethaneFluidProperties::saturatedLiquidDensity(Real temperature) const { if (temperature < _T_triple || temperature > _T_critical) throw MooseException("Temperature is out of range in " + name() + ": saturatedLiquidDensity()"); const Real Tr = temperature / _T_critical; const Real theta = 1.0 - Tr; const Real logdensity = 1.9906389 * std::pow(theta, 0.354) - 0.78756197 * std::sqrt(theta) + 0.036976723 * std::pow(theta, 2.5); return _rho_critical * std::exp(logdensity); }
Real MethaneFluidProperties::mu_from_p_T(Real /*pressure*/, Real temperature) const { // Check the temperature is in the range of validity (200 K <= T <= 1000 K) if (temperature <= 200.0 || temperature >= 1000.0) throw MooseException("Temperature " + Moose::stringify(temperature) + "K out of range (200K, 1000K) in " + name() + ": mu_from_p_T()"); Real viscosity = 0.0; for (std::size_t i = 0; i < _a.size(); ++i) viscosity += _a[i] * MathUtils::pow(temperature, i); return viscosity * 1.e-6; }
Real MethaneFluidProperties::vaporPressure(Real temperature) const { if (temperature < _T_triple || temperature > _T_critical) throw MooseException("Temperature is out of range in " + name() + ": vaporPressure()"); const Real Tr = temperature / _T_critical; const Real theta = 1.0 - Tr; const Real logpressure = (-6.036219 * theta + 1.409353 * std::pow(theta, 1.5) - 0.4945199 * Utility::pow<2>(theta) - 1.443048 * std::pow(theta, 4.5)) / Tr; return _p_critical * std::exp(logpressure); }
void StiffenedGasFluidProperties::s_from_p_T(Real p, Real T, Real & s, Real & ds_dp, Real & ds_dT) const { const Real n = std::pow(T, _gamma) / std::pow(p + _p_inf, _gamma - 1.0); if (n <= 0.0) throw MooseException(name() + ": Negative argument in the ln() function."); s = _cv * std::log(n) + _q_prime; const Real dn_dT = _gamma * std::pow(T, _gamma - 1.0) / std::pow(p + _p_inf, _gamma - 1.0); const Real dn_dp = std::pow(T, _gamma) * (1.0 - _gamma) * std::pow(p + _p_inf, -_gamma); ds_dp = _cv / n * dn_dp; ds_dT = _cv / n * dn_dT; }
Real ExceptionKernel::computeQpJacobian() { // Throw on the first nonlinear step of the first timestep -- should // hopefully be the same in both serial and parallel. if (_when == JACOBIAN && !_jac_has_thrown && time_to_throw()) { // The Jacobian has now thrown _jac_has_thrown = true; throw MooseException("MooseException thrown during Jacobian calculation"); } return 0.; }
Real MethaneFluidProperties::saturatedVaporDensity(Real temperature) const { if (temperature < _T_triple || temperature > _T_critical) throw MooseException("Temperature is out of range in " + name() + ": saturatedVaporDensity()"); const Real Tr = temperature / _T_critical; const Real theta = 1.0 - Tr; const Real logdensity = -1.880284 * std::pow(theta, 0.354) - 2.8526531 * std::pow(theta, 5.0 / 6.0) - 3.000648 * std::pow(theta, 1.5) - 5.251169 * std::pow(theta, 2.5) - 13.191859 * std::pow(theta, 25.0 / 6.0) - 37.553961 * std::pow(theta, 47.0 / 6.0); return _rho_critical * std::exp(logdensity); }
void StiffenedGasFluidProperties::s_from_h_p(Real h, Real p, Real & s, Real & ds_dh, Real & ds_dp) const { const Real aux = (p + _p_inf) * std::pow((h - _q) / (_gamma * _cv), -_gamma / (_gamma - 1)); if (aux <= 0.0) throw MooseException(name() + ": Non-positive argument in the ln() function."); const Real daux_dh = (p + _p_inf) * std::pow((h - _q) / (_gamma * _cv), -_gamma / (_gamma - 1) - 1) * (-_gamma / (_gamma - 1)) / (_gamma * _cv); const Real daux_dp = std::pow((h - _q) / (_gamma * _cv), -_gamma / (_gamma - 1)); s = _q_prime - (_gamma - 1) * _cv * std::log(aux); ds_dh = -(_gamma - 1) * _cv / aux * daux_dh; ds_dp = -(_gamma - 1) * _cv / aux * daux_dp; }
Real ExceptionKernel::computeQpJacobian() { // We need a thread lock here so that we don't introduce a race condition when inspecting or changing the static variable Threads::spin_mutex::scoped_lock lock(Threads::spin_mutex); // Throw on the first nonlinear step of the first timestep -- should // hopefully be the same in both serial and parallel. if (_when == JACOBIAN && !_jac_has_thrown && time_to_throw()) { // The Jacobian has now thrown _jac_has_thrown = true; throw MooseException("MooseException thrown during Jacobian calculation"); } return 0.; }
void MethaneFluidProperties::k_from_p_T( Real /*pressure*/, Real temperature, Real & k, Real & dk_dp, Real & dk_dT) const { // Check the temperature is in the range of validity (200 K <= T <= 1000 K) if (temperature <= 200.0 || temperature >= 1000.0) throw MooseException("Temperature " + Moose::stringify(temperature) + "K out of range (200K, 1000K) in " + name() + ": k()"); Real kt = 0.0, dkt_dT = 0.0; for (std::size_t i = 0; i < _b.size(); ++i) kt += _b[i] * MathUtils::pow(temperature, i); for (std::size_t i = 1; i < _b.size(); ++i) dkt_dT += i * _b[i] * MathUtils::pow(temperature, i) / temperature; k = kt; dk_dp = 0.0; dk_dT = dkt_dT; }
Real ExceptionKernel::computeQpJacobian() { // We need a thread lock here so that we don't introduce a race condition when inspecting or // changing the static variable Threads::spin_mutex::scoped_lock lock(Threads::spin_mutex); // Throw on the first nonlinear step of the first timestep -- should // hopefully be the same in both serial and parallel. if (_when == WhenType::JACOBIAN && !_jac_has_thrown && time_to_throw() && (_rank == DofObject::invalid_processor_id || _rank == processor_id())) { // The Jacobian has now thrown _jac_has_thrown = true; if (_should_throw) throw MooseException("MooseException thrown during Jacobian calculation"); else mooseError("Intentional error triggered during Jacobian calculation"); } return 0.; }
void StiffenedGasFluidProperties::s_from_v_e(Real v, Real e, Real & s, Real & ds_dv, Real & ds_de) const { Real T, dT_dv, dT_de; T_from_v_e(v, e, T, dT_dv, dT_de); Real p, dp_dv, dp_de; p_from_v_e(v, e, p, dp_dv, dp_de); const Real n = std::pow(T, _gamma) / std::pow(p + _p_inf, _gamma - 1.0); if (n <= 0.0) throw MooseException(name() + ": Negative argument in the ln() function."); s = _cv * std::log(n) + _q_prime; const Real dn_dT = _gamma * std::pow(T, _gamma - 1.0) / std::pow(p + _p_inf, _gamma - 1.0); const Real dn_dp = std::pow(T, _gamma) * (1.0 - _gamma) * std::pow(p + _p_inf, -_gamma); const Real dn_dv = dn_dT * dT_dv + dn_dp * dp_dv; const Real dn_de = dn_dT * dT_de + dn_dp * dp_de; ds_dv = _cv / n * dn_dv; ds_de = _cv / n * dn_de; }
void ComputeMultipleInelasticStress::updateQpState(RankTwoTensor & elastic_strain_increment, RankTwoTensor & combined_inelastic_strain_increment) { if (_output_iteration_info == true) { _console << std::endl << "iteration output for ComputeMultipleInelasticStress solve:" << " time=" << _t << " int_pt=" << _qp << std::endl; } Real l2norm_delta_stress; Real first_l2norm_delta_stress = 1.0; unsigned int counter = 0; std::vector<RankTwoTensor> inelastic_strain_increment; inelastic_strain_increment.resize(_num_models); for (unsigned i_rmm = 0; i_rmm < _models.size(); ++i_rmm) inelastic_strain_increment[i_rmm].zero(); RankTwoTensor stress_max, stress_min; do { for (unsigned i_rmm = 0; i_rmm < _num_models; ++i_rmm) { _models[i_rmm]->setQp(_qp); // initially assume the strain is completely elastic elastic_strain_increment = _strain_increment[_qp]; // and subtract off all inelastic strain increments calculated so far // except the one that we're about to calculate for (unsigned j_rmm = 0; j_rmm < _num_models; ++j_rmm) if (i_rmm != j_rmm) elastic_strain_increment -= inelastic_strain_increment[j_rmm]; // form the trial stress, with the check for changed elasticity constants if (_is_elasticity_tensor_guaranteed_isotropic || !_perform_finite_strain_rotations) { _stress[_qp] = _elasticity_tensor[_qp] * (_elastic_strain_old[_qp] + elastic_strain_increment); // InitialStress Deprecation: remove these lines if (_perform_finite_strain_rotations) rotateQpInitialStress(); addQpInitialStress(); } else _stress[_qp] = _stress_old[_qp] + _elasticity_tensor[_qp] * elastic_strain_increment; // given a trial stress (_stress[_qp]) and a strain increment (elastic_strain_increment) // let the i^th model produce an admissible stress (as _stress[_qp]), and decompose // the strain increment into an elastic part (elastic_strain_increment) and an // inelastic part (inelastic_strain_increment[i_rmm]) computeAdmissibleState(i_rmm, elastic_strain_increment, inelastic_strain_increment[i_rmm], _consistent_tangent_operator[i_rmm]); if (i_rmm == 0) { stress_max = _stress[_qp]; stress_min = _stress[_qp]; } else { for (unsigned int i = 0; i < LIBMESH_DIM; ++i) { for (unsigned int j = 0; j < LIBMESH_DIM; ++j) { if (_stress[_qp](i, j) > stress_max(i, j)) stress_max(i, j) = _stress[_qp](i, j); else if (stress_min(i, j) > _stress[_qp](i, j)) stress_min(i, j) = _stress[_qp](i, j); } } } } // now check convergence in the stress: // once the change in stress is within tolerance after each recompute material // consider the stress to be converged l2norm_delta_stress = (stress_max - stress_min).L2norm(); if (counter == 0 && l2norm_delta_stress > 0.0) first_l2norm_delta_stress = l2norm_delta_stress; if (_output_iteration_info == true) { _console << "stress iteration number = " << counter << "\n" << " relative l2 norm delta stress = " << (0 == first_l2norm_delta_stress ? 0 : l2norm_delta_stress / first_l2norm_delta_stress) << "\n" << " stress convergence relative tolerance = " << _relative_tolerance << "\n" << " absolute l2 norm delta stress = " << l2norm_delta_stress << "\n" << " stress convergence absolute tolerance = " << _absolute_tolerance << std::endl; } ++counter; } while (counter < _max_iterations && l2norm_delta_stress > _absolute_tolerance && (l2norm_delta_stress / first_l2norm_delta_stress) > _relative_tolerance && _num_models != 1); if (counter == _max_iterations && l2norm_delta_stress > _absolute_tolerance && (l2norm_delta_stress / first_l2norm_delta_stress) > _relative_tolerance) throw MooseException("Max stress iteration hit during ComputeMultipleInelasticStress solve!"); combined_inelastic_strain_increment.zero(); for (unsigned i_rmm = 0; i_rmm < _num_models; ++i_rmm) combined_inelastic_strain_increment += _inelastic_weights[i_rmm] * inelastic_strain_increment[i_rmm]; if (_fe_problem.currentlyComputingJacobian()) computeQpJacobianMult(); _matl_timestep_limit[_qp] = 0.0; for (unsigned i_rmm = 0; i_rmm < _num_models; ++i_rmm) _matl_timestep_limit[_qp] += 1.0 / _models[i_rmm]->computeTimeStepLimit(); if (MooseUtils::absoluteFuzzyEqual(_matl_timestep_limit[_qp], 0.0)) { _matl_timestep_limit[_qp] = std::numeric_limits<Real>::max(); } else { _matl_timestep_limit[_qp] = 1.0 / _matl_timestep_limit[_qp]; } }