bool MAST::StructuralElementBase::inertial_force (bool request_jacobian, DenseRealVector& f, DenseRealMatrix& jac) { FEMOperatorMatrix Bmat; const std::vector<Real>& JxW = _fe->get_JxW(); const std::vector<libMesh::Point>& xyz = _fe->get_xyz(); const std::vector<std::vector<Real> >& phi = _fe->get_phi(); const unsigned int n_phi = (unsigned int)phi.size(), n1=6, n2=6*n_phi; DenseRealMatrix material_mat, mat1_n1n2, mat2_n2n2, local_jac; DenseRealVector phi_vec, vec1_n1, vec2_n2, local_f; mat1_n1n2.resize(n1, n2); mat2_n2n2.resize(n2, n2); local_jac.resize(n2, n2); phi_vec.resize(n_phi); vec1_n1.resize(n1); vec2_n2.resize(n2); local_f.resize(n2); std::auto_ptr<MAST::FieldFunction<DenseRealMatrix > > mat_inertia (_property.get_property(MAST::SECTION_INTEGRATED_MATERIAL_INERTIA_MATRIX, *this).release()); if (_property.if_diagonal_mass_matrix()) { // as an approximation, get matrix at the first quadrature point (*mat_inertia)(xyz[0], _system.time, material_mat); Real vol = 0.; const unsigned int nshp = _fe->n_shape_functions(); for (unsigned int i=0; i<JxW.size(); i++) vol += JxW[i]; vol /= (1.* nshp); for (unsigned int i_var=0; i_var<6; i_var++) for (unsigned int i=0; i<nshp; i++) local_jac(i_var*nshp+i, i_var*nshp+i) = vol*material_mat(i_var, i_var); local_jac.vector_mult(local_f, local_acceleration); } else { libMesh::Point p; for (unsigned int qp=0; qp<JxW.size(); qp++) { this->global_coordinates(xyz[qp], p); (*mat_inertia)(p, _system.time, material_mat); // now set the shape function values for ( unsigned int i_nd=0; i_nd<n_phi; i_nd++ ) phi_vec(i_nd) = phi[i_nd][qp]; Bmat.reinit(_system.n_vars(), phi_vec); Bmat.left_multiply(mat1_n1n2, material_mat); mat1_n1n2.vector_mult(vec1_n1, local_acceleration); Bmat.vector_mult_transpose(vec2_n2, vec1_n1); local_f.add(JxW[qp], vec2_n2); if (request_jacobian) { Bmat.right_multiply_transpose(mat2_n2n2, mat1_n1n2); local_jac.add(JxW[qp], mat2_n2n2); } } } // now transform to the global coorodinate system if (_elem.dim() < 3) { transform_to_global_system(local_f, vec2_n2); f.add(1., vec2_n2); if (request_jacobian) { transform_to_global_system(local_jac, mat2_n2n2); jac.add(1., mat2_n2n2); } } else { f.add(1., local_f); if (request_jacobian) jac.add(1., local_jac); } return request_jacobian; }
bool MAST::HeatConductionElementBase::internal_residual (bool request_jacobian, RealVectorX& f, RealMatrixX& jac) { const std::vector<Real>& JxW = _fe->get_JxW(); const std::vector<libMesh::Point>& xyz = _fe->get_xyz(); const unsigned int n_phi = _fe->n_shape_functions(), dim = _elem.dim(); RealMatrixX material_mat = RealMatrixX::Zero(dim, dim), dmaterial_mat = RealMatrixX::Zero(dim, dim), // for calculation of Jac when k is temp. dep. mat_n2n2 = RealMatrixX::Zero(n_phi, n_phi); RealVectorX vec1 = RealVectorX::Zero(1), vec2_n2 = RealVectorX::Zero(n_phi), flux = RealVectorX::Zero(dim); std::auto_ptr<MAST::FieldFunction<RealMatrixX> > conductance = _property.thermal_conductance_matrix(*this); libMesh::Point p; std::vector<MAST::FEMOperatorMatrix> dBmat(dim); MAST::FEMOperatorMatrix Bmat; // for calculation of Jac when k is temp. dep. for (unsigned int qp=0; qp<JxW.size(); qp++) { // initialize the Bmat operator for this term _initialize_mass_fem_operator(qp, Bmat); Bmat.right_multiply(vec1, _sol); if (_active_sol_function) dynamic_cast<MAST::MeshFieldFunction<RealVectorX>*> (_active_sol_function)->set_element_quadrature_point_solution(vec1); _local_elem->global_coordinates_location(xyz[qp], p); (*conductance)(p, _time, material_mat); _initialize_flux_fem_operator(qp, dBmat); // calculate the flux for each dimension and add its weighted // component to the residual flux.setZero(); for (unsigned int j=0; j<dim; j++) { dBmat[j].right_multiply(vec1, _sol); // dT_dxj for (unsigned int i=0; i<dim; i++) flux(i) += vec1(0) * material_mat(i,j); // q_i = k_ij dT_dxj } // now add to the residual vector for (unsigned int i=0; i<dim; i++) { vec1(0) = flux(i); dBmat[i].vector_mult_transpose(vec2_n2, vec1); f += JxW[qp] * vec2_n2; } if (request_jacobian) { // Jacobian contribution from int_omega dB_dxi^T k_ij dB_dxj for (unsigned int i=0; i<dim; i++) for (unsigned int j=0; j<dim; j++) { dBmat[i].right_multiply_transpose(mat_n2n2, dBmat[j]); jac += JxW[qp] * material_mat(i,j) * mat_n2n2; } // Jacobian contribution from int_omega dB_dxi dT_dxj dk_ij/dT B if (_active_sol_function) { // get derivative of the conductance matrix wrt temperature conductance->derivative(MAST::PARTIAL_DERIVATIVE, *_active_sol_function, p, _time, dmaterial_mat); for (unsigned int j=0; j<dim; j++) { dBmat[j].right_multiply(vec1, _sol); // dT_dxj for (unsigned int i=0; i<dim; i++) if (dmaterial_mat(i,j) != 0.) { // no need to process for zero terms // dB_dxi^T B dBmat[i].right_multiply_transpose(mat_n2n2, Bmat); // dB_dxi^T (dT_dxj dk_ij/dT) B jac += JxW[qp] * vec1(0) * dmaterial_mat(i,j) * mat_n2n2; } } } } } if (_active_sol_function) dynamic_cast<MAST::MeshFieldFunction<RealVectorX>*> (_active_sol_function)->clear_element_quadrature_point_solution(); return request_jacobian; }
bool MAST::StructuralElementBase::inertial_force_sensitivity(bool request_jacobian, DenseRealVector& f, DenseRealMatrix& jac) { // this should be true if the function is called libmesh_assert(this->sensitivity_param); libmesh_assert(!this->sensitivity_param->is_shape_parameter()); // this is not implemented for now // check if the material property or the provided exterior // values, like temperature, are functions of the sensitivity parameter bool calculate = false; calculate = calculate || _property.depends_on(*(this->sensitivity_param)); // nothing to be calculated if the element does not depend on the // sensitivity parameter. if (!calculate) return false; FEMOperatorMatrix Bmat; const std::vector<Real>& JxW = _fe->get_JxW(); const std::vector<libMesh::Point>& xyz = _fe->get_xyz(); const std::vector<std::vector<Real> >& phi = _fe->get_phi(); const unsigned int n_phi = (unsigned int)phi.size(), n1=6, n2=6*n_phi; DenseRealMatrix material_mat, mat1_n1n2, mat2_n2n2, local_jac; DenseRealVector phi_vec, vec1_n1, vec2_n2, local_f; mat1_n1n2.resize(n1, n2); mat2_n2n2.resize(n2, n2); local_jac.resize(n2, n2); phi_vec.resize(n_phi); vec1_n1.resize(n1); vec2_n2.resize(n2); local_f.resize(n2); std::auto_ptr<MAST::FieldFunction<DenseRealMatrix > > mat_inertia (_property.get_property(MAST::SECTION_INTEGRATED_MATERIAL_INERTIA_MATRIX, *this).release()); if (_property.if_diagonal_mass_matrix()) { mat_inertia->total(*this->sensitivity_param, xyz[0], _system.time, material_mat); Real vol = 0.; const unsigned int nshp = _fe->n_shape_functions(); for (unsigned int i=0; i<JxW.size(); i++) vol += JxW[i]; vol /= (1.* nshp); for (unsigned int i_var=0; i_var<6; i_var++) for (unsigned int i=0; i<nshp; i++) local_jac(i_var*nshp+i, i_var*nshp+i) = vol*material_mat(i_var, i_var); local_jac.vector_mult(local_f, local_acceleration); } else { libMesh::Point p; for (unsigned int qp=0; qp<JxW.size(); qp++) { this->global_coordinates(xyz[qp], p); mat_inertia->total(*this->sensitivity_param, p, _system.time, material_mat); // now set the shape function values for ( unsigned int i_nd=0; i_nd<n_phi; i_nd++ ) phi_vec(i_nd) = phi[i_nd][qp]; Bmat.reinit(_system.n_vars(), phi_vec); Bmat.left_multiply(mat1_n1n2, material_mat); mat1_n1n2.vector_mult(vec1_n1, local_acceleration); Bmat.vector_mult_transpose(vec2_n2, vec1_n1); local_f.add(JxW[qp], vec2_n2); if (request_jacobian) { Bmat.right_multiply_transpose(mat2_n2n2, mat1_n1n2); local_jac.add(JxW[qp], mat2_n2n2); } } } // now transform to the global coorodinate system if (_elem.dim() < 3) { transform_to_global_system(local_f, vec2_n2); f.add(1., vec2_n2); if (request_jacobian) { transform_to_global_system(local_jac, mat2_n2n2); jac.add(1., mat2_n2n2); } } else { f.add(1., local_f); if (request_jacobian) jac.add(1., local_jac); } return request_jacobian; }
bool MAST::HeatConductionElementBase::velocity_residual (bool request_jacobian, RealVectorX& f, RealMatrixX& jac_xdot, RealMatrixX& jac) { MAST::FEMOperatorMatrix Bmat; const std::vector<Real>& JxW = _fe->get_JxW(); const std::vector<libMesh::Point>& xyz = _fe->get_xyz(); const unsigned int n_phi = _fe->n_shape_functions(), dim = _elem.dim(); RealMatrixX material_mat = RealMatrixX::Zero(dim, dim), mat_n2n2 = RealMatrixX::Zero(n_phi, n_phi); RealVectorX vec1 = RealVectorX::Zero(1), vec2_n2 = RealVectorX::Zero(n_phi); std::auto_ptr<MAST::FieldFunction<RealMatrixX> > capacitance = _property.thermal_capacitance_matrix(*this); libMesh::Point p; for (unsigned int qp=0; qp<JxW.size(); qp++) { _initialize_mass_fem_operator(qp, Bmat); Bmat.right_multiply(vec1, _sol); // B * T if (_active_sol_function) dynamic_cast<MAST::MeshFieldFunction<RealVectorX>*> (_active_sol_function)->set_element_quadrature_point_solution(vec1); _local_elem->global_coordinates_location(xyz[qp], p); (*capacitance)(p, _time, material_mat); Bmat.right_multiply(vec1, _vel); // B * T_dot Bmat.vector_mult_transpose(vec2_n2, vec1); // B^T * B * T_dot f += JxW[qp] * material_mat(0,0) * vec2_n2; // (rho*cp)*JxW B^T B T_dot if (request_jacobian) { Bmat.right_multiply_transpose(mat_n2n2, Bmat); // B^T B jac_xdot += JxW[qp] * material_mat(0,0) * mat_n2n2; // B^T B * JxW (rho*cp) // Jacobian contribution from int_omega B T d(rho*cp)/dT B if (_active_sol_function) { // get derivative of the conductance matrix wrt temperature capacitance->derivative(MAST::PARTIAL_DERIVATIVE, *_active_sol_function, p, _time, material_mat); if (material_mat(0,0) != 0.) { // no need to process for zero terms // B^T (T d(rho cp)/dT) B jac += JxW[qp] * vec1(0) * material_mat(0,0) * mat_n2n2; } } } } if (_active_sol_function) dynamic_cast<MAST::MeshFieldFunction<RealVectorX>*> (_active_sol_function)->clear_element_quadrature_point_solution(); return request_jacobian; }