void Nonlinear3D::computeIncrementalDeformationGradient(std::vector<ColumnMajorMatrix> & Fhat) { // A = grad(u(k+1) - u(k)) // Fbar = 1 + grad(u(k)) // Fhat = 1 + A*(Fbar^-1) ColumnMajorMatrix A; ColumnMajorMatrix Fbar; ColumnMajorMatrix Fbar_inverse; ColumnMajorMatrix Fhat_average; Real volume(0); _Fbar.resize(_solid_model.qrule()->n_points()); for (unsigned qp = 0; qp < _solid_model.qrule()->n_points(); ++qp) { fillMatrix(qp, _grad_disp_x, _grad_disp_y, _grad_disp_z, A); fillMatrix(qp, _grad_disp_x_old, _grad_disp_y_old, _grad_disp_z_old, Fbar); A -= Fbar; Fbar.addDiag(1); _Fbar[qp] = Fbar; // Get Fbar^(-1) // Computing the inverse is generally a bad idea. // It's better to compute LU factors. For now at least, we'll take // a direct route. invertMatrix(Fbar, Fbar_inverse); Fhat[qp] = A * Fbar_inverse; Fhat[qp].addDiag(1); if (_volumetric_locking_correction) { // Now include the contribution for the integration of Fhat over the element Fhat_average += Fhat[qp] * _solid_model.JxW(qp); volume += _solid_model.JxW(qp); // Accumulate original configuration volume } } if (_volumetric_locking_correction) { Fhat_average /= volume; const Real det_Fhat_average(detMatrix(Fhat_average)); // Finalize volumetric locking correction for (unsigned qp = 0; qp < _solid_model.qrule()->n_points(); ++qp) { const Real det_Fhat(detMatrix(Fhat[qp])); const Real factor(std::cbrt(det_Fhat_average / det_Fhat)); Fhat[qp] *= factor; } } // Moose::out << "Fhat(0,0)" << Fhat[0](0,0) << std::endl; }
void dataStore(std::ostream & stream, ColumnMajorMatrix & v, void * /*context*/) { for (unsigned int i = 0; i < v.m(); i++) for (unsigned int j = 0; j < v.n(); j++) { Real r = v(i, j); stream.write((char *) &r, sizeof(r)); } }
void dataLoad(std::istream & stream, ColumnMajorMatrix & v, void * /*context*/) { for (unsigned int i = 0; i < v.m(); i++) for (unsigned int j = 0; j < v.n(); j++) { Real r = 0; stream.read((char *) &r, sizeof(r)); v(i, j) = r; } }
void ColumnMajorMatrixTest::zeroMatrix() { ColumnMajorMatrix mat = *two_mat; mat.zero(); CPPUNIT_ASSERT( mat(0,0) == 0 ); CPPUNIT_ASSERT( mat(1,0) == 0 ); CPPUNIT_ASSERT( mat(0,1) == 0 ); CPPUNIT_ASSERT( mat(1,1) == 0 ); }
void ColumnMajorMatrixTest::transposeMatrix() { ColumnMajorMatrix mat = *two_mat; ColumnMajorMatrix test = mat.transpose(); CPPUNIT_ASSERT( test(0,0) == 1 ); CPPUNIT_ASSERT( test(1,0) == 3 ); CPPUNIT_ASSERT( test(0,1) == 2 ); CPPUNIT_ASSERT( test(1,1) == 4 ); }
void ColumnMajorMatrixTest::numEntries() { //numEntries is tested in other functions, like after different //constructors to make sure the number of entries copied over correctly ColumnMajorMatrix mat = *two_mat; ColumnMajorMatrix mat2(3, 4); CPPUNIT_ASSERT( mat.numEntries() == 4 ); CPPUNIT_ASSERT( mat2.numEntries() == 12 ); }
void ColumnMajorMatrixTest::identityMatrix() { ColumnMajorMatrix mat = *two_mat; mat.identity(); CPPUNIT_ASSERT( mat(0,0) == 1 ); CPPUNIT_ASSERT( mat(1,0) == 0 ); CPPUNIT_ASSERT( mat(0,1) == 0 ); CPPUNIT_ASSERT( mat(1,1) == 1 ); }
void ColumnMajorMatrixTest::setDiagMatrix() { ColumnMajorMatrix mat = *two_mat; mat.setDiag( 9 ); CPPUNIT_ASSERT( mat(0,0) == 9 ); CPPUNIT_ASSERT( mat(1,0) == 2 ); CPPUNIT_ASSERT( mat(0,1) == 3 ); CPPUNIT_ASSERT( mat(1,1) == 9 ); }
void ColumnMajorMatrixTest::contractionMatrix() { ColumnMajorMatrix mat = *two_mat; ColumnMajorMatrix sec(2, 2); sec(0, 0) = 4; sec(1, 0) = 3; sec(0, 1) = 2; sec(1, 1) = 1; CPPUNIT_ASSERT( mat.doubleContraction( sec ) == (1*4 + 2*3 + 3*2 + 4*1) ); }
void PlaneStrain::computeDeformationGradient( unsigned int qp, ColumnMajorMatrix & F) { mooseAssert(F.n() == 3 && F.m() == 3, "computeDefGrad requires 3x3 matrix"); F(0,0) = _grad_disp_x[qp](0) + 1.0; F(0,1) = _grad_disp_x[qp](1); F(0,2) = 0.0; F(1,0) = _grad_disp_y[qp](0); F(1,1) = _grad_disp_y[qp](1) + 1.0; F(1,2) = 0.0; F(2,0) = 0.0; F(2,1) = 0.0; F(2,2) = 1.0; }
void Nonlinear3D::computeDeformationGradient( unsigned int qp, ColumnMajorMatrix & F) { mooseAssert(F.n() == 3 && F.m() == 3, "computeDefGrad requires 3x3 matrix"); F(0,0) = _grad_disp_x[qp](0) + 1; F(0,1) = _grad_disp_x[qp](1); F(0,2) = _grad_disp_x[qp](2); F(1,0) = _grad_disp_y[qp](0); F(1,1) = _grad_disp_y[qp](1) + 1; F(1,2) = _grad_disp_y[qp](2); F(2,0) = _grad_disp_z[qp](0); F(2,1) = _grad_disp_z[qp](1); F(2,2) = _grad_disp_z[qp](2) + 1; }
void ColumnMajorMatrixTest::copyConstructor() { ColumnMajorMatrix mat = *two_mat; ColumnMajorMatrix test = mat; test(1, 1) = 9; CPPUNIT_ASSERT( test(0,0) == 1 ); CPPUNIT_ASSERT( test(1,0) == 2 ); CPPUNIT_ASSERT( test(0,1) == 3 ); CPPUNIT_ASSERT( test(1,1) == 9 ); CPPUNIT_ASSERT( mat(1,1) == 4 ); CPPUNIT_ASSERT( test.numEntries() == 4 ); }
void NonlinearRZ::computeDeformationGradient( unsigned int qp, ColumnMajorMatrix & F) { mooseAssert(F.n() == 3 && F.m() == 3, "computeDefGrad requires 3x3 matrix"); F(0,0) = _grad_disp_r[qp](0) + 1; F(0,1) = _grad_disp_r[qp](1); F(0,2) = 0; F(1,0) = _grad_disp_z[qp](0); F(1,1) = _grad_disp_z[qp](1) + 1; F(1,2) = 0; F(2,0) = 0; F(2,1) = 0; F(2,2) = (_solid_model.q_point(qp)(0) != 0.0 ? _disp_r[qp]/_solid_model.q_point(qp)(0) : 0.0) + 1; }
void SymmElasticityTensor::convertFrom6x6(const ColumnMajorMatrix & input) { if (input.numEntries() != 36) { mooseError("Cannot convert from ColumnMajorMatrix (wrong size)"); } _val[0] = input(0, 0); _val[1] = input(0, 1); _val[2] = input(0, 2); _val[3] = input(0, 3); _val[4] = input(0, 4); _val[5] = input(0, 5); _val[6] = input(1, 1); _val[7] = input(1, 2); _val[8] = input(1, 3); _val[9] = input(1, 4); _val[10] = input(1, 5); _val[11] = input(2, 2); _val[12] = input(2, 3); _val[13] = input(2, 4); _val[14] = input(2, 5); _val[15] = input(3, 3); _val[16] = input(3, 4); _val[17] = input(3, 5); _val[18] = input(4, 4); _val[19] = input(4, 5); _val[20] = input(5, 5); }
Real Element::detMatrix( const ColumnMajorMatrix & A ) { mooseAssert(A.n() == 3 && A.m() == 3, "detMatrix requires 3x3 matrix"); Real Axx = A(0,0); Real Axy = A(0,1); Real Axz = A(0,2); Real Ayx = A(1,0); Real Ayy = A(1,1); Real Ayz = A(1,2); Real Azx = A(2,0); Real Azy = A(2,1); Real Azz = A(2,2); return Axx*Ayy*Azz + Axy*Ayz*Azx + Axz*Ayx*Azy - Azx*Ayy*Axz - Azy*Ayz*Axx - Azz*Ayx*Axy; }
void NonlinearPlaneStrain::fillMatrix( unsigned int qp, const VariableGradient & grad_x, const VariableGradient & grad_y, const Real & strain_zz, ColumnMajorMatrix & A) const { mooseAssert(A.n() == 3 && A.m() == 3, "computeDefGrad requires 3x3 matrix"); A(0,0) = grad_x[qp](0); A(0,1) = grad_x[qp](1); A(0,2) = 0; A(1,0) = grad_y[qp](0); A(1,1) = grad_y[qp](1); A(1,2) = 0; A(2,0) = 0; A(2,1) = 0; A(2,2) = strain_zz; }
void NonlinearRZ::fillMatrix( unsigned int qp, const VariableGradient & grad_r, const VariableGradient & grad_z, const VariableValue & u, ColumnMajorMatrix & A) const { mooseAssert(A.n() == 3 && A.m() == 3, "computeDefGrad requires 3x3 matrix"); A(0,0) = grad_r[qp](0); A(0,1) = grad_r[qp](1); A(0,2) = 0; A(1,0) = grad_z[qp](0); A(1,1) = grad_z[qp](1); A(1,2) = 0; A(2,0) = 0; A(2,1) = 0; A(2,2) = (_solid_model.q_point(qp)(0) != 0.0 ? u[qp]/_solid_model.q_point(qp)(0) : 0.0); }
void NonlinearPlaneStrain::computeDeformationGradient( unsigned int qp, ColumnMajorMatrix & F) { mooseAssert(F.n() == 3 && F.m() == 3, "computeDefGrad requires 3x3 matrix"); F(0,0) = _grad_disp_x[qp](0) + 1; F(0,1) = _grad_disp_x[qp](1); F(0,2) = 0; F(1,0) = _grad_disp_y[qp](0); F(1,1) = _grad_disp_y[qp](1) + 1; F(1,2) = 0; F(2,0) = 0; F(2,1) = 0; if (_have_strain_zz) F(2,2) = _strain_zz[qp] + 1; else if (_have_scalar_strain_zz && _scalar_strain_zz.size()>0) F(2,2) = _scalar_strain_zz[qp] + 1; else F(2,2) = 1; }
void Element::polarDecompositionEigen( const ColumnMajorMatrix & Fhat, ColumnMajorMatrix & Rhat, SymmTensor & strain_increment ) { const int ND = 3; ColumnMajorMatrix eigen_value(ND,1), eigen_vector(ND,ND); ColumnMajorMatrix invUhat(ND,ND), logVhat(ND,ND); ColumnMajorMatrix n1(ND,1), n2(ND,1), n3(ND,1), N1(ND,1), N2(ND,1), N3(ND,1); ColumnMajorMatrix Chat = Fhat.transpose() * Fhat; Chat.eigen(eigen_value,eigen_vector); for(int i = 0; i < ND; i++) { N1(i) = eigen_vector(i,0); N2(i) = eigen_vector(i,1); N3(i) = eigen_vector(i,2); } const Real lamda1 = std::sqrt(eigen_value(0)); const Real lamda2 = std::sqrt(eigen_value(1)); const Real lamda3 = std::sqrt(eigen_value(2)); const Real log1 = std::log(lamda1); const Real log2 = std::log(lamda2); const Real log3 = std::log(lamda3); ColumnMajorMatrix Uhat = N1 * N1.transpose() * lamda1 + N2 * N2.transpose() * lamda2 + N3 * N3.transpose() * lamda3; invertMatrix(Uhat,invUhat); Rhat = Fhat * invUhat; strain_increment = N1 * N1.transpose() * log1 + N2 * N2.transpose() * log2 + N3 * N3.transpose() * log3; }
void AbaqusUmatMaterial::computeStress() { //Calculate deformation gradient - modeled from "solid_mechanics/src/materials/Nonlinear3D.C" // Fbar = 1 + grad(u(k)) ColumnMajorMatrix Fbar; Fbar(0,0) = _grad_disp_x[_qp](0); Fbar(0,1) = _grad_disp_x[_qp](1); Fbar(0,2) = _grad_disp_x[_qp](2); Fbar(1,0) = _grad_disp_y[_qp](0); Fbar(1,1) = _grad_disp_y[_qp](1); Fbar(1,2) = _grad_disp_y[_qp](2); Fbar(2,0) = _grad_disp_z[_qp](0); Fbar(2,1) = _grad_disp_z[_qp](1); Fbar(2,2) = _grad_disp_z[_qp](2); Fbar.addDiag(1); _Fbar[_qp] = Fbar; Real myDFGRD0[9] = {_Fbar_old[_qp](0,0), _Fbar_old[_qp](1,0), _Fbar_old[_qp](2,0), _Fbar_old[_qp](0,1), _Fbar_old[_qp](1,1), _Fbar_old[_qp](2,1), _Fbar_old[_qp](0,2), _Fbar_old[_qp](1,2), _Fbar_old[_qp](2,2)}; Real myDFGRD1[9] = {_Fbar[_qp](0,0), _Fbar[_qp](1,0), _Fbar[_qp](2,0), _Fbar[_qp](0,1), _Fbar[_qp](1,1), _Fbar[_qp](2,1), _Fbar[_qp](0,2), _Fbar[_qp](1,2), _Fbar[_qp](2,2)}; for (unsigned int i=0; i<9; ++i) { _DFGRD0[i] = myDFGRD0[i]; _DFGRD1[i] = myDFGRD1[i]; } //Recover "old" state variables for (unsigned int i=0; i<_num_state_vars; ++i) _STATEV[i]=_state_var_old[_qp][i]; //Pass through updated stress, total strain, and strain increment arrays for (int i=0; i<_NTENS; ++i) { _STRESS[i] = _stress_old.component(i); _STRAN[i] = _total_strain[_qp].component(i); _DSTRAN[i] = _strain_increment.component(i); } //Pass through step , time, and coordinate system information _KSTEP = _t_step; //Step number _TIME[0] = _t; //Value of step time at the beginning of the current increment - Check _TIME[1] = _t-_dt; //Value of total time at the beginning of the current increment - Check _DTIME = _dt; //Time increment for (unsigned int i=0; i<3; ++i) //Loop current coordinates in UMAT COORDS _COORDS[i] = _coord[i]; //Connection to extern statement _umat(_STRESS, _STATEV, _DDSDDE, &_SSE, &_SPD, &_SCD, &_RPL, _DDSDDT, _DRPLDE, &_DRPLDT, _STRAN, _DSTRAN, _TIME, &_DTIME, &_TEMP, &_DTEMP, _PREDEF, _DPRED, &_CMNAME, &_NDI, &_NSHR, &_NTENS, &_NSTATV, _PROPS, &_NPROPS, _COORDS, _DROT, &_PNEWDT, &_CELENT, _DFGRD0, _DFGRD1, &_NOEL, &_NPT, &_LAYER, &_KSPT, &_KSTEP, &_KINC); //Energy outputs _elastic_strain_energy[_qp] = _SSE; _plastic_dissipation[_qp] = _SPD; _creep_dissipation[_qp] = _SCD; //Update state variables for (unsigned int i=0; i<_num_state_vars; ++i) _state_var[_qp][i]=_STATEV[i]; //Get new stress tensor - UMAT should update stress SymmTensor stressnew(_STRESS[0], _STRESS[1], _STRESS[2], _STRESS[3], _STRESS[4], _STRESS[5]); _stress[_qp] = stressnew; }
void SymmElasticityTensor::rotateFromGlobalToLocal(const ColumnMajorMatrix & R) { convertFrom9x9(R.transpose() * (columnMajorMatrix9x9() * R)); }
PiecewiseBilinear::PiecewiseBilinear(const InputParameters & parameters) : Function(parameters), _data_file_name(getParam<FileName>("data_file")), _axis(getParam<int>("axis")), _yaxis(getParam<int>("yaxis")), _xaxis(getParam<int>("xaxis")), _axisValid( _axis > -1 && _axis < 3 ), _yaxisValid( _yaxis > -1 && _yaxis < 3 ), _xaxisValid( _xaxis > -1 && _xaxis < 3 ), _scale_factor( getParam<Real>("scale_factor") ), _radial(getParam<bool>("radial")) { if (!_axisValid && !_yaxisValid && !_xaxisValid) mooseError("In PiecewiseBilinear " << _name << ": None of axis, yaxis, or xaxis properly defined. Allowable range is 0-2"); if (_axisValid && (_yaxisValid || _xaxisValid)) mooseError("In PiecewiseBilinear " << _name << ": Cannot define axis with either yaxis or xaxis"); if (_radial && (!_yaxisValid || !_xaxisValid)) mooseError("In PiecewiseBilinear " << _name << ": yaxis and xaxis must be defined when radial = true"); std::vector<Real> x; std::vector<Real> y; ColumnMajorMatrix z; std::vector<Real> z_vec; if (!_data_file_name.empty()) { if ( parameters.isParamValid("x") || parameters.isParamValid("y") || parameters.isParamValid("z") ) mooseError("In PiecewiseBilinear: Cannot specify 'data_file' and 'x', 'y', or 'z' together."); else parse( x, y, z ); } else if ( !(parameters.isParamValid("x") && parameters.isParamValid("y") && parameters.isParamValid("z")) ) mooseError("In PiecewiseBilinear: 'x' and 'y' and 'z' must be specified if any one is specified."); else { x = getParam<std::vector<Real> >("x"); y = getParam<std::vector<Real> >("y"); z_vec = getParam<std::vector<Real> >("z"); //check that size of z = (size of x)*(size of y) if (z_vec.size() != x.size()*y.size()) mooseError("In PiecewiseBilinear: Size of z should be the size of x times the size of y."); //reshape and populate z matrix z.reshape(y.size(),x.size()); int idx = 0; for (unsigned int i = 0; i < y.size(); i++) for (unsigned int j = 0; j < x.size(); j++) { z(i,j) = z_vec[idx]; idx += 1; } } _bilinear_interp = libmesh_make_unique<BilinearInterpolation>(x, y, z); }
void PiecewiseBilinear::parse( std::vector<Real> & x, std::vector<Real> & y, ColumnMajorMatrix & z) { std::ifstream file(_data_file_name.c_str()); if (!file.good()) mooseError("In PiecewiseBilinear " << _name << ": Error opening file '" + _data_file_name + "'."); std::string line; unsigned int linenum= 0; unsigned int itemnum = 0; unsigned int num_cols = 0; std::vector<Real> data; while (getline (file, line)) { linenum++; std::istringstream linestream(line); std::string item; itemnum = 0; while (getline (linestream, item, ',')) { itemnum++; std::istringstream i(item); Real d; i >> d; data.push_back(d); } if (linenum == 1) num_cols = itemnum; else if (num_cols+1 != itemnum) mooseError("In PiecewiseBilinear " << _name << ": Read " << itemnum << " columns of data but expected " << num_cols+1 << " columns while reading line " << linenum << " of '" << _data_file_name << "'."); } x.resize(itemnum-1); y.resize(linenum-1); z.reshape(linenum-1,itemnum-1); unsigned int offset(0); // Extract the first line's data (the x axis data) for (unsigned int j = 0; j < itemnum-1; ++j) { x[j] = data[offset]; ++offset; } for (unsigned int i = 0; i < linenum-1; ++i) { // Extract the y axis entry for this line y[i] = data[offset]; ++offset; // Extract the function values for this row in the matrix for (unsigned int j = 0; j < itemnum-1; ++j) { z(i,j) = data[offset]; ++offset; } } if (data.size() != offset) mooseError("ERROR! Inconsistency in data read from '" + _data_file_name + "' for PiecewiseBilinear function."); }