Real StressDivergenceRZ::computeQpOffDiagJacobian(unsigned int jvar) { if ( _rdisp_coupled && jvar == _rdisp_var ) { return calculateJacobian( _component, 0 ); } else if ( _zdisp_coupled && jvar == _zdisp_var ) { return calculateJacobian( _component, 1 ); } else if ( _temp_coupled && jvar == _temp_var ) { SymmTensor test; if (_component == 0) { test.xx() = _grad_test[_i][_qp](0); test.xy() = 0.5*_grad_test[_i][_qp](1); test.zz() = _test[_i][_qp] / _q_point[_qp](0); } else { test.xy() = 0.5*_grad_test[_i][_qp](0); test.yy() = _grad_test[_i][_qp](1); } return _d_stress_dT[_qp].doubleContraction(test) * _phi[_j][_qp]; } return 0; }
Real StressDivergenceRZTensors::computeQpOffDiagJacobian(unsigned int jvar) { for (unsigned int i = 0; i < _ndisp; ++i) { if (jvar == _disp_var[i]) return calculateJacobian(_component, i); } if (_temp_coupled && jvar == _temp_var) { Real jac = 0.0; if (_component == 0) { for (unsigned k = 0; k < LIBMESH_DIM; ++k) for (unsigned l = 0; l < LIBMESH_DIM; ++l) jac -= (_grad_test[_i][_qp](0) * _Jacobian_mult[_qp](0, 0, k, l) + _test[_i][_qp] / _q_point[_qp](0) * _Jacobian_mult[_qp](2, 2, k, l) + _grad_test[_i][_qp](1) * _Jacobian_mult[_qp](0, 1, k, l)) * (*_deigenstrain_dT)[_qp](k, l); return jac * _phi[_j][_qp]; } else if (_component == 1) { for (unsigned k = 0; k < LIBMESH_DIM; ++k) for (unsigned l = 0; l < LIBMESH_DIM; ++l) jac -= (_grad_test[_i][_qp](1) * _Jacobian_mult[_qp](1, 1, k, l) + _grad_test[_i][_qp](0) * _Jacobian_mult[_qp](1, 0, k, l)) * (*_deigenstrain_dT)[_qp](k, l); return jac * _phi[_j][_qp]; } } return 0.0; }
void FiniteStrainPlasticBase::checkJacobian() { _console << "\n ++++++++++++++ \nChecking the Jacobian\n"; outputAndCheckDebugParameters(); RankFourTensor E_inv = _elasticity_tensor[_qp].invSymm(); RankTwoTensor delta_dp = -E_inv*_fspb_debug_stress; std::vector<std::vector<Real> > jac; calculateJacobian(_fspb_debug_stress, _fspb_debug_intnl, _fspb_debug_pm, E_inv, jac); std::vector<std::vector<Real> > fdjac; fdJacobian(_fspb_debug_stress, _intnl_old[_qp], _fspb_debug_intnl, _fspb_debug_pm, delta_dp, E_inv, fdjac); _console << "Hand-coded Jacobian:\n"; for (unsigned row = 0 ; row < jac.size() ; ++row) { for (unsigned col = 0 ; col < jac.size() ; ++col) _console << jac[row][col] << " "; _console << "\n"; } _console << "Finite difference Jacobian:\n"; for (unsigned row = 0 ; row < fdjac.size() ; ++row) { for (unsigned col = 0 ; col < fdjac.size() ; ++col) _console << fdjac[row][col] << " "; _console << "\n"; } }
void MultiPlasticityDebugger::checkJacobian(const RankFourTensor & E_inv, const std::vector<Real> & intnl_old) { Moose::err << "\n\n+++++++++++++++++++++\nChecking the Jacobian\n+++++++++++++++++++++\n"; outputAndCheckDebugParameters(); std::vector<bool> act; act.assign(_num_surfaces, true); std::vector<bool> deactivated_due_to_ld; deactivated_due_to_ld.assign(_num_surfaces, false); RankTwoTensor delta_dp = -E_inv * _fspb_debug_stress; std::vector<std::vector<Real>> jac; calculateJacobian(_fspb_debug_stress, _fspb_debug_intnl, _fspb_debug_pm, E_inv, act, deactivated_due_to_ld, jac); std::vector<std::vector<Real>> fdjac; fdJacobian(_fspb_debug_stress, intnl_old, _fspb_debug_intnl, _fspb_debug_pm, delta_dp, E_inv, false, fdjac); Real L2_numer = 0; Real L2_denom = 0; for (unsigned row = 0; row < jac.size(); ++row) for (unsigned col = 0; col < jac.size(); ++col) { L2_numer += Utility::pow<2>(jac[row][col] - fdjac[row][col]); L2_denom += Utility::pow<2>(jac[row][col] + fdjac[row][col]); } Moose::err << "\nRelative L2norm = " << std::sqrt(L2_numer / L2_denom) / 0.5 << "\n"; Moose::err << "\nHand-coded Jacobian:\n"; for (unsigned row = 0; row < jac.size(); ++row) { for (unsigned col = 0; col < jac.size(); ++col) Moose::err << jac[row][col] << " "; Moose::err << "\n"; } Moose::err << "Finite difference Jacobian:\n"; for (unsigned row = 0; row < fdjac.size(); ++row) { for (unsigned col = 0; col < fdjac.size(); ++col) Moose::err << fdjac[row][col] << " "; Moose::err << "\n"; } }
void CQMathMatrixWidget::updateJacobianIfTabSelected() { if (mpDataModel == NULL) return; CModel* pModel = mpDataModel->getModel(); if (pModel == NULL) return; if (!mpTabWidgetJac->isVisible() && !mpTabWidgetJacRed->isVisible()) return; try { // need to compile at this point otherwise elements might not be valid anymore pModel->compileIfNecessary(NULL); updateJacobianAnnotation(pModel); CMathContainer& container = pModel->getMathContainer(); if (mpTabWidget->currentWidget() == mpTabWidgetJac) { calculateJacobian(mJacobian, &container, tableEigenValues, false, 1e-6); mpJacobianAnnotationWidget->setArrayAnnotation(mpJacobianAnn); } else if (mpTabWidget->currentWidget() == mpTabWidgetJacRed) { calculateJacobian(mJacobianRed, &container, tableEigenValuesRed, true, 1e-6); mpRedJacobianAnnotationWidget->setArrayAnnotation(mpJacobianAnnRed); } } catch (...) { // jacobian couldn't be calculated mpJacobianAnnotationWidget->setArrayAnnotation(NULL); mpRedJacobianAnnotationWidget->setArrayAnnotation(NULL); } }
void MultiPlasticityLinearSystem::nrStep(const RankTwoTensor & stress, const std::vector<Real> & intnl_old, const std::vector<Real> & intnl, const std::vector<Real> & pm, const RankFourTensor & E_inv, const RankTwoTensor & delta_dp, RankTwoTensor & dstress, std::vector<Real> & dpm, std::vector<Real> & dintnl, const std::vector<bool> & active, std::vector<bool> & deactivated_due_to_ld) { // Calculate RHS and Jacobian std::vector<Real> rhs; calculateRHS(stress, intnl_old, intnl, pm, delta_dp, rhs, active, true, deactivated_due_to_ld); std::vector<std::vector<Real> > jac; calculateJacobian(stress, intnl, pm, E_inv, active, deactivated_due_to_ld, jac); // prepare for LAPACKgesv_ routine provided by PETSc int system_size = rhs.size(); std::vector<double> a(system_size*system_size); // Fill in the a "matrix" by going down columns unsigned ind = 0; for (int col = 0 ; col < system_size ; ++col) for (int row = 0 ; row < system_size ; ++row) a[ind++] = jac[row][col]; int nrhs = 1; std::vector<int> ipiv(system_size); int info; LAPACKgesv_(&system_size, &nrhs, &a[0], &system_size, &ipiv[0], &rhs[0], &system_size, &info); if (info != 0) mooseError("In solving the linear system in a Newton-Raphson process, the PETSC LAPACK gsev routine returned with error code " << info); // Extract the results back to dstress, dpm and dintnl std::vector<bool> active_not_deact(_num_surfaces); for (unsigned surface = 0 ; surface < _num_surfaces ; ++surface) active_not_deact[surface] = (active[surface] && !deactivated_due_to_ld[surface]); unsigned int dim = 3; ind = 0; for (unsigned i = 0 ; i < dim ; ++i) for (unsigned j = 0 ; j <= i ; ++j) dstress(i, j) = dstress(j, i) = rhs[ind++]; dpm.assign(_num_surfaces, 0); for (unsigned surface = 0 ; surface < _num_surfaces ; ++surface) if (active_not_deact[surface]) dpm[surface] = rhs[ind++]; dintnl.assign(_num_models, 0); for (unsigned model = 0 ; model < _num_models ; ++model) if (anyActiveSurfaces(model, active_not_deact)) dintnl[model] = rhs[ind++]; mooseAssert(static_cast<int>(ind) == system_size, "Incorrect extracting of changes from NR solution in nrStep"); }
gmtl::Vec3f JacobianMatrix::calculateInverse(const Angle& angle, const gmtl::Vec3f& angular) { gmtl::Matrix33f matrixJ = calculateJacobian(angle); //gmtl::Matrix<float, 3, 1> velocityMatrix; //velocityMatrix[0][0] = velocity[0]; //velocityMatrix[1][0] = velocity[1]; //velocityMatrix[2][0] = velocity[2]; //gmtl::Matrix<float, 3, 1> solution = matrixJ * velocityMatrix; //invert(matrixJ); return invert(matrixJ) * angular;//gmtl::Vec3f(solution[0][0], solution[1][0], solution[2][0]); }
gmtl::Vec3f JacobianMatrix::calculate(const Angle& angle, const gmtl::Vec3f& cartesian) { gmtl::Matrix33f matrixJ = calculateJacobian(angle); //gmtl::Matrix<float, 3, 1> velocityMatrix; //velocityMatrix[0][0] = velocity[0]; //velocityMatrix[1][0] = velocity[1]; //velocityMatrix[2][0] = velocity[2]; //gmtl::Matrix<float, 3, 1> solution = matrixJ * velocityMatrix; return matrixJ * cartesian;//gmtl::Vec3f(solution[0][0], solution[1][0], solution[2][0]); }
Real StressDivergenceRZTensors::computeQpOffDiagJacobian(unsigned int jvar) { for (unsigned int i = 0; i < _ndisp; ++i) { if (jvar == _disp_var[i]) return calculateJacobian( _component, i); } if (_temp_coupled && jvar == _temp_var) return 0.0; return 0; }
void FiniteStrainPlasticBase::nrStep(const RankTwoTensor & stress, const std::vector<Real> & intnl_old, const std::vector<Real> & intnl, const std::vector<Real> & pm, const RankFourTensor & E_inv, const RankTwoTensor & delta_dp, RankTwoTensor & dstress, std::vector<Real> & dpm, std::vector<Real> & dintnl) { // Calculate RHS and Jacobian std::vector<Real> rhs; calculateRHS(stress, intnl_old, intnl, pm, delta_dp, rhs); std::vector<std::vector<Real> > jac; calculateJacobian(stress, intnl, pm, E_inv, jac); // prepare for LAPACKgesv_ routine provided by PETSc (at least since PETSc 3.0.0) int system_size = rhs.size(); std::vector<double> a(system_size*system_size); // Fill in the a "matrix" by going down columns unsigned ind = 0; for (int col = 0 ; col < system_size ; ++col) for (int row = 0 ; row < system_size ; ++row) a[ind++] = jac[row][col]; int nrhs = 1; std::vector<int> ipiv(system_size); int info; LAPACKgesv_(&system_size, &nrhs, &a[0], &system_size, &ipiv[0], &rhs[0], &system_size, &info); if (info != 0) mooseError("In solving the linear system in a Newton-Raphson process, the PETSC LAPACK gsev routine returned with error code " << info); // Extract the results back to dstress, dpm and dintnl unsigned int dim = 3; ind = 0; for (unsigned i = 0 ; i < dim ; ++i) for (unsigned j = 0 ; j <= i ; ++j) dstress(i, j) = dstress(j, i) = rhs[ind++]; dpm.resize(numberOfYieldFunctions()); for (unsigned alpha = 0 ; alpha < numberOfYieldFunctions() ; ++alpha) dpm[alpha] = rhs[ind++]; dintnl.resize(numberOfInternalParameters()); for (unsigned a = 0 ; a < numberOfInternalParameters() ; ++a) dintnl[a] = rhs[ind++]; }
Real StressDivergenceRZ::computeQpJacobian() { return calculateJacobian( _component, _component ); }
void MultiPlasticityDebugger::checkSolution(const RankFourTensor & E_inv) { Moose::err << "\n\n+++++++++++++++++++++\nChecking the Solution\n"; Moose::err << "(Ie, checking Ax = b)\n+++++++++++++++++++++\n"; outputAndCheckDebugParameters(); std::vector<bool> act; act.assign(_num_surfaces, true); std::vector<bool> deactivated_due_to_ld; deactivated_due_to_ld.assign(_num_surfaces, false); RankTwoTensor delta_dp = -E_inv * _fspb_debug_stress; std::vector<Real> orig_rhs; calculateRHS(_fspb_debug_stress, _fspb_debug_intnl, _fspb_debug_intnl, _fspb_debug_pm, delta_dp, orig_rhs, act, true, deactivated_due_to_ld); Moose::err << "\nb = "; for (unsigned i = 0; i < orig_rhs.size(); ++i) Moose::err << orig_rhs[i] << " "; Moose::err << "\n\n"; std::vector<std::vector<Real>> jac_coded; calculateJacobian(_fspb_debug_stress, _fspb_debug_intnl, _fspb_debug_pm, E_inv, act, deactivated_due_to_ld, jac_coded); Moose::err << "Before checking Ax=b is correct, check that the Jacobians given below are equal.\n"; Moose::err << "The hand-coded Jacobian is used in calculating the solution 'x', given 'b' above.\n"; Moose::err << "Note that this only includes degrees of freedom that aren't deactivated due to " "linear dependence.\n"; Moose::err << "Hand-coded Jacobian:\n"; for (unsigned row = 0; row < jac_coded.size(); ++row) { for (unsigned col = 0; col < jac_coded.size(); ++col) Moose::err << jac_coded[row][col] << " "; Moose::err << "\n"; } deactivated_due_to_ld.assign(_num_surfaces, false); // this potentially gets changed by nrStep, below RankTwoTensor dstress; std::vector<Real> dpm; std::vector<Real> dintnl; nrStep(_fspb_debug_stress, _fspb_debug_intnl, _fspb_debug_intnl, _fspb_debug_pm, E_inv, delta_dp, dstress, dpm, dintnl, act, deactivated_due_to_ld); std::vector<bool> active_not_deact(_num_surfaces); for (unsigned surface = 0; surface < _num_surfaces; ++surface) active_not_deact[surface] = !deactivated_due_to_ld[surface]; std::vector<Real> x; x.assign(orig_rhs.size(), 0); unsigned ind = 0; for (unsigned i = 0; i < 3; ++i) for (unsigned j = 0; j <= i; ++j) x[ind++] = dstress(i, j); for (unsigned surface = 0; surface < _num_surfaces; ++surface) if (active_not_deact[surface]) x[ind++] = dpm[surface]; for (unsigned model = 0; model < _num_models; ++model) if (anyActiveSurfaces(model, active_not_deact)) x[ind++] = dintnl[model]; mooseAssert(ind == orig_rhs.size(), "Incorrect extracting of changes from NR solution in the " "finite-difference checking of nrStep"); Moose::err << "\nThis yields x ="; for (unsigned i = 0; i < orig_rhs.size(); ++i) Moose::err << x[i] << " "; Moose::err << "\n"; std::vector<std::vector<Real>> jac_fd; fdJacobian(_fspb_debug_stress, _fspb_debug_intnl, _fspb_debug_intnl, _fspb_debug_pm, delta_dp, E_inv, true, jac_fd); Moose::err << "\nThe finite-difference Jacobian is used to multiply by this 'x',\n"; Moose::err << "in order to check that the solution is correct\n"; Moose::err << "Finite-difference Jacobian:\n"; for (unsigned row = 0; row < jac_fd.size(); ++row) { for (unsigned col = 0; col < jac_fd.size(); ++col) Moose::err << jac_fd[row][col] << " "; Moose::err << "\n"; } Real L2_numer = 0; Real L2_denom = 0; for (unsigned row = 0; row < jac_coded.size(); ++row) for (unsigned col = 0; col < jac_coded.size(); ++col) { L2_numer += Utility::pow<2>(jac_coded[row][col] - jac_fd[row][col]); L2_denom += Utility::pow<2>(jac_coded[row][col] + jac_fd[row][col]); } Moose::err << "Relative L2norm of the hand-coded and finite-difference Jacobian is " << std::sqrt(L2_numer / L2_denom) / 0.5 << "\n"; std::vector<Real> fd_times_x; fd_times_x.assign(orig_rhs.size(), 0); for (unsigned row = 0; row < orig_rhs.size(); ++row) for (unsigned col = 0; col < orig_rhs.size(); ++col) fd_times_x[row] += jac_fd[row][col] * x[col]; Moose::err << "\n(Finite-difference Jacobian)*x =\n"; for (unsigned i = 0; i < orig_rhs.size(); ++i) Moose::err << fd_times_x[i] << " "; Moose::err << "\n"; Moose::err << "Recall that b = \n"; for (unsigned i = 0; i < orig_rhs.size(); ++i) Moose::err << orig_rhs[i] << " "; Moose::err << "\n"; L2_numer = 0; L2_denom = 0; for (unsigned i = 0; i < orig_rhs.size(); ++i) { L2_numer += Utility::pow<2>(orig_rhs[i] - fd_times_x[i]); L2_denom += Utility::pow<2>(orig_rhs[i] + fd_times_x[i]); } Moose::err << "\nRelative L2norm of these is " << std::sqrt(L2_numer / L2_denom) / 0.5 << "\n"; }
int main(int argc, char* argv[]) { //--This first declaration is included for software engineering reasons: allow main method to control flow of data //create function pointer for calculateDependentVariable //We want to do this so that calculateJacobian can call calculateDependentVariables as it needs to, //but we explicitly give it this authority from the main method void (*yourCalculateDependentVariables)(const Teuchos::SerialDenseMatrix<int, std::complex<double> >&, const Teuchos::SerialDenseVector<int, std::complex<double> >&, Teuchos::SerialDenseVector<int, std::complex<double> >&); yourCalculateDependentVariables = &calculateDependentVariables; //Create an object to allow access to LAPACK using a library found in Trilinos // Teuchos::LAPACK<int, std::complex<double> > Teuchos_LAPACK_Object; //The problem being solved is to find the intersection of three infinite paraboloids: //(x-1)^2 + y^2 + z = 0 //x^2 + y^2 -(z+1) = 0 //x^2 + y^2 +(z-1) = 0 // //They should intersect at the point (1, 0, 0) Teuchos::SerialDenseMatrix<int, std::complex<double> > offsets(NUMDIMENSIONS, NUMDIMENSIONS); offsets(0,0) = 1.0; offsets(1,2) = 1.0; offsets(2,2) = 1.0; //We need to initialize the target vectors and provide an initial guess Teuchos::SerialDenseVector<int, std::complex<double> > targetsDesired(NUMDIMENSIONS); Teuchos::SerialDenseVector<int, std::complex<double> > targetsCalculated(NUMDIMENSIONS); Teuchos::SerialDenseVector<int, std::complex<double> > unperturbedTargetsCalculated(NUMDIMENSIONS); Teuchos::SerialDenseVector<int, std::complex<double> > currentGuess(NUMDIMENSIONS); Teuchos::SerialDenseVector<int, std::complex<double> > guessAdjustment(NUMDIMENSIONS); currentGuess[0] = 2.0; currentGuess[1] = 1.0; currentGuess[2] = 1.0; //Place to store our tangent-stiffness matrix or Jacobian //One element for every combination of dependent variable with independent variable Teuchos::SerialDenseMatrix<int, std::complex<double> > jacobian(NUMDIMENSIONS, NUMDIMENSIONS); int count = 0; double error = 1.0E5; std::cout << "Running Forward Difference Example" << std::endl; while(count < MAXITERATIONS and error > ERRORTOLLERANCE) { //Calculate Jacobian tangent to currentGuess point //at the same time, an unperturbed targetsCalculated is, well, calculated calculateJacobian(offsets, jacobian, targetsCalculated, unperturbedTargetsCalculated, currentGuess, yourCalculateDependentVariables); //Compute a guessChange and immediately set the currentGuess equal to the guessChange updateGuess(currentGuess, targetsCalculated, jacobian, Teuchos_LAPACK_Object); //Compute F(x) with the updated, currentGuess calculateDependentVariables(offsets, currentGuess, targetsCalculated); //Calculate the L2 norm of Ftarget - F(xCurrentGuess) calculateResidual(targetsDesired, targetsCalculated, error); count ++; //If we have converged, or if we have exceeded our alloted number of iterations, discontinue the loop std::cout << "Residual Error: " << error << std::endl; } std::cout << "******************************************" << std::endl; std::cout << "Number of iterations: " << count << std::endl; std::cout << "Final guess:\n x, y, z\n " << currentGuess[0] << ", " << currentGuess[1] << ", " << currentGuess[2] << std::endl; std::cout << "Error tollerance: " << ERRORTOLLERANCE << std::endl; std::cout << "Final error: " << error << std::endl; std::cout << "--program complete--" << std::endl; return 0; }
int main(int argc, char* argv[]) { //--This first declaration is included for software engineering reasons: allow main method to control flow of data //create function pointer for calculateDependentVariable //We want to do this so that calculateJacobian can call calculateDependentVariables as it needs to, //but we explicitly give it this authority from the main method void (*yourCalculateDependentVariables)(const arma::Mat<std::complex<double> >&, const arma::Col<std::complex<double> >&, arma::Col<std::complex<double> >&); yourCalculateDependentVariables = &calculateDependentVariables; //The problem being solved is to find the intersection of three infinite paraboloids: //(x-1)^2 + y^2 + z = 0 //x^2 + y^2 -(z+1) = 0 //x^2 + y^2 +(z-1) = 0 // //They should intersect at the point (1, 0, 0) arma::Mat<std::complex<double> > offsets(NUMDIMENSIONS, NUMDIMENSIONS); offsets.fill(0.0); offsets.col(0)[0] = 1.0; offsets.col(2)[1] = 1.0; offsets.col(2)[2] = 1.0; //We need to initialize the target vectors and provide an initial guess arma::Col<std::complex<double> > targetsDesired(NUMDIMENSIONS); targetsDesired.fill(0.0); arma::Col<std::complex<double> > targetsCalculated(NUMDIMENSIONS); targetsCalculated.fill(0.0); arma::Col<double> realTargetsCalculated(NUMDIMENSIONS); realTargetsCalculated.fill(0.0); arma::Col<std::complex<double> > currentGuess(NUMDIMENSIONS); currentGuess.fill(2.0); //Place to store our tangent-stiffness matrix or Jacobian //One element for every combination of dependent variable with independent variable arma::Mat<double> jacobian(NUMDIMENSIONS, NUMDIMENSIONS); jacobian.fill(0.0); int count = 0; double error = 1.0E5; std::cout << "Running complex step example ................" << std::endl; while(count < MAXITERATIONS and error > ERRORTOLLERANCE) { //Calculate Jacobian tangent to currentGuess point //at the same time, an unperturbed targetsCalculated is, well, calculated calculateJacobian(offsets, jacobian, targetsCalculated, currentGuess, yourCalculateDependentVariables); //Compute a new currentGuess updateGuess(currentGuess, realTargetsCalculated, targetsCalculated, jacobian); //Compute F(x) with the updated, currentGuess calculateDependentVariables(offsets, currentGuess, targetsCalculated); //Calculate the L2 norm of Ftarget - F(xCurrentGuess) calculateResidual(targetsDesired, targetsCalculated, error); count ++; //If we have converged, or if we have exceeded our alloted number of iterations, discontinue the loop std::cout << "Residual Error: " << error << std::endl; } std::cout << "******************************************" << std::endl; std::cout << "Number of iterations: " << count << std::endl; std::cout << "Final guess:\n x, y, z\n" << arma::real(currentGuess.t()); std::cout << "Error tollerance: " << ERRORTOLLERANCE << std::endl; std::cout << "Final error: " << error << std::endl; std::cout << "--program complete--" << std::endl; return 0; }
Real StressDivergenceRSphericalTensors::computeQpJacobian() { return calculateJacobian(_component, _component); }