29 #include "grins_config.h"
35 #include "libmesh/getpot.h"
36 #include "libmesh/quadrature.h"
37 #include "libmesh/boundary_info.h"
38 #include "libmesh/fem_system.h"
39 #include "libmesh/elem.h"
43 template<
typename StressStrainLaw>
45 bool is_compressible )
51 template<
typename StressStrainLaw>
57 if( input.have_variable(section) )
59 unsigned int n_vars = input.vector_variable_size(section);
61 for(
unsigned int v = 0; v < n_vars; v++ )
63 std::string name = input(section,
"DIE!",v);
65 if( name == std::string(
"stress") )
69 _stress_indices.resize(1);
74 else if( name == std::string(
"strain") )
78 _strain_indices.resize(1);
83 else if( name == std::string(
"force") )
87 _force_indices.resize(1);
95 <<
" Found " << name << std::endl
96 <<
" Acceptable values are: stress" << std::endl
97 <<
" strain" << std::endl
98 <<
" force " << std::endl;
106 template<
typename StressStrainLaw>
109 const libMesh::Point& point,
110 libMesh::Real& value )
112 bool is_strain =
false;
113 if( !_strain_indices.empty() )
114 is_strain = ( _strain_indices[0] == quantity_index );
116 bool is_stress =
false;
117 if( !_stress_indices.empty() )
118 is_stress = ( _stress_indices[0] == quantity_index );
120 bool is_force =
false;
121 if( !_force_indices.empty() )
122 is_force = ( _force_indices[0] == quantity_index );
124 if( is_strain || is_stress || is_force )
126 const unsigned int n_u_dofs = context.get_dof_indices(this->_disp_vars.u()).size();
128 const libMesh::DenseSubVector<libMesh::Number>& u_coeffs = context.get_elem_solution( this->_disp_vars.u() );
129 const libMesh::DenseSubVector<libMesh::Number>* v_coeffs = NULL;
131 const libMesh::DenseSubVector<libMesh::Number>* w_coeffs = NULL;
133 if( this->_disp_vars.dim() >= 2 )
134 v_coeffs = &context.get_elem_solution( this->_disp_vars.v() );
136 if( this->_disp_vars.dim() == 3 )
137 w_coeffs = &context.get_elem_solution( this->_disp_vars.w() );
140 libMesh::UniquePtr<libMesh::FEGenericBase<libMesh::Real> > fe_new = this->build_new_fe( &context.get_elem(), this->get_fe(context), point );
142 const std::vector<std::vector<libMesh::Real> >& dphi_dxi = fe_new->get_dphidxi();
145 const std::vector<libMesh::RealGradient>& dxdxi = fe_new->get_dxyzdxi();
148 libMesh::Gradient grad_u, grad_v, grad_w;
149 for(
unsigned int d = 0; d < n_u_dofs; d++ )
151 libMesh::RealGradient u_gradphi( dphi_dxi[d][0] );
152 grad_u += u_coeffs(d)*u_gradphi;
154 if( this->_disp_vars.dim() >= 2 )
155 grad_v += (*v_coeffs)(d)*u_gradphi;
157 if( this->_disp_vars.dim() == 3 )
158 grad_w += (*w_coeffs)(d)*u_gradphi;
161 libMesh::RealGradient grad_x( dxdxi[0](0) );
162 libMesh::RealGradient grad_y( dxdxi[0](1) );
163 libMesh::RealGradient grad_z( dxdxi[0](2) );
166 libMesh::Real lambda_sq = 0;
168 this->compute_metric_tensors(0, *fe_new, context,
169 grad_u, grad_v, grad_w,
170 a_cov, a_contra, A_cov, A_contra, lambda_sq );
172 libMesh::Real det_a = a_cov(0,0)*a_cov(1,1) - a_cov(0,1)*a_cov(1,0);
173 libMesh::Real det_A = A_cov(0,0)*A_cov(1,1) - A_cov(0,1)*A_cov(1,0);
175 libMesh::Real I3 = lambda_sq*det_A/det_a;
178 this->_stress_strain_law.compute_stress(1,a_contra,a_cov,A_contra,A_cov,tau);
183 if( _strain_indices[0] == quantity_index )
185 value = 0.5*(A_cov(0,0) - a_cov(0,0));
197 if( _stress_indices[0] == quantity_index )
200 value = tau(0,0)/std::sqrt(I3);
210 if( _force_indices[0] == quantity_index )
213 value = tau(0,0)/std::sqrt(I3)*this->_A;
223 template<
typename StressStrainLaw>
227 const unsigned int n_u_dofs = context.get_dof_indices(this->_disp_vars.u()).size();
229 const std::vector<libMesh::Real> &JxW =
230 this->get_fe(context)->get_JxW();
233 libMesh::DenseSubVector<libMesh::Number> &Fu = context.get_elem_residual(this->_disp_vars.u());
234 libMesh::DenseSubVector<libMesh::Number>* Fv = NULL;
235 libMesh::DenseSubVector<libMesh::Number>* Fw = NULL;
237 libMesh::DenseSubMatrix<libMesh::Number>& Kuu = context.get_elem_jacobian(this->_disp_vars.u(),this->_disp_vars.u());
238 libMesh::DenseSubMatrix<libMesh::Number>* Kuv = NULL;
239 libMesh::DenseSubMatrix<libMesh::Number>* Kuw = NULL;
241 libMesh::DenseSubMatrix<libMesh::Number>* Kvu = NULL;
242 libMesh::DenseSubMatrix<libMesh::Number>* Kvv = NULL;
243 libMesh::DenseSubMatrix<libMesh::Number>* Kvw = NULL;
245 libMesh::DenseSubMatrix<libMesh::Number>* Kwu = NULL;
246 libMesh::DenseSubMatrix<libMesh::Number>* Kwv = NULL;
247 libMesh::DenseSubMatrix<libMesh::Number>* Kww = NULL;
249 if( this->_disp_vars.dim() >= 2 )
251 Fv = &context.get_elem_residual(this->_disp_vars.v());
253 Kuv = &context.get_elem_jacobian(this->_disp_vars.u(),this->_disp_vars.v());
254 Kvu = &context.get_elem_jacobian(this->_disp_vars.v(),this->_disp_vars.u());
255 Kvv = &context.get_elem_jacobian(this->_disp_vars.v(),this->_disp_vars.v());
258 if( this->_disp_vars.dim() == 3 )
260 Fw = &context.get_elem_residual(this->_disp_vars.w());
262 Kuw = &context.get_elem_jacobian(this->_disp_vars.u(),this->_disp_vars.w());
263 Kvw = &context.get_elem_jacobian(this->_disp_vars.v(),this->_disp_vars.w());
264 Kwu = &context.get_elem_jacobian(this->_disp_vars.w(),this->_disp_vars.u());
265 Kwv = &context.get_elem_jacobian(this->_disp_vars.w(),this->_disp_vars.v());
266 Kww = &context.get_elem_jacobian(this->_disp_vars.w(),this->_disp_vars.w());
270 unsigned int n_qpoints = context.get_element_qrule().n_points();
273 const std::vector<std::vector<libMesh::Real> >& dphi_dxi = this->get_fe(context)->get_dphidxi();
275 const libMesh::DenseSubVector<libMesh::Number>& u_coeffs = context.get_elem_solution( this->_disp_vars.u() );
276 const libMesh::DenseSubVector<libMesh::Number>* v_coeffs = NULL;
277 const libMesh::DenseSubVector<libMesh::Number>* w_coeffs = NULL;
279 if( this->_disp_vars.dim() >= 2 )
280 v_coeffs = &context.get_elem_solution( this->_disp_vars.v() );
282 if( this->_disp_vars.dim() == 3 )
283 w_coeffs = &context.get_elem_solution( this->_disp_vars.w() );
286 const std::vector<libMesh::RealGradient>& dxdxi = this->get_fe(context)->get_dxyzdxi();
288 const unsigned int dim = 1;
290 for (
unsigned int qp=0; qp != n_qpoints; qp++)
293 libMesh::Gradient grad_u, grad_v, grad_w;
295 for(
unsigned int d = 0; d < n_u_dofs; d++ )
297 libMesh::RealGradient u_gradphi( dphi_dxi[d][qp] );
298 grad_u += u_coeffs(d)*u_gradphi;
300 if( this->_disp_vars.dim() >= 2 )
301 grad_v += (*v_coeffs)(d)*u_gradphi;
303 if( this->_disp_vars.dim() == 3 )
304 grad_w += (*w_coeffs)(d)*u_gradphi;
307 libMesh::RealGradient grad_x( dxdxi[qp](0) );
308 libMesh::RealGradient grad_y( dxdxi[qp](1) );
309 libMesh::RealGradient grad_z( dxdxi[qp](2) );
312 libMesh::Real lambda_sq = 0;
314 this->compute_metric_tensors( qp, *(this->get_fe(context)), context,
315 grad_u, grad_v, grad_w,
316 a_cov, a_contra, A_cov, A_contra,
322 this->_stress_strain_law.compute_stress_and_elasticity(dim,a_contra,a_cov,A_contra,A_cov,tau,C);
325 libMesh::Real jac = JxW[qp];
327 for (
unsigned int i=0; i != n_u_dofs; i++)
329 libMesh::RealGradient u_gradphi( dphi_dxi[i][qp] );
331 const libMesh::Real res_term = tau(0,0)*this->_A*jac*u_gradphi(0);
333 Fu(i) += res_term*(grad_x(0) + grad_u(0));
335 if( this->_disp_vars.dim() >= 2 )
336 (*Fv)(i) += res_term*(grad_y(0) + grad_v(0));
338 if( this->_disp_vars.dim() == 3 )
339 (*Fw)(i) += res_term*(grad_z(0) + grad_w(0));
342 if( compute_jacobian )
344 for(
unsigned int i=0; i != n_u_dofs; i++)
346 libMesh::RealGradient u_gradphi_I( dphi_dxi[i][qp] );
347 for(
unsigned int j=0; j != n_u_dofs; j++)
349 libMesh::RealGradient u_gradphi_J( dphi_dxi[j][qp] );
351 const libMesh::Real diag_term = this->_A*jac*tau(0,0)*( u_gradphi_J(0)*u_gradphi_I(0))*context.get_elem_solution_derivative();
353 Kuu(i,j) += diag_term;
355 if( this->_disp_vars.dim() >= 2 )
356 (*Kvv)(i,j) += diag_term;
358 if( this->_disp_vars.dim() == 3 )
359 (*Kww)(i,j) += diag_term;
361 const libMesh::Real dgamma_du = ( u_gradphi_J(0)*(grad_x(0)+grad_u(0)) );
363 const libMesh::Real C1 = this->_A*jac*C(0,0,0,0)*context.get_elem_solution_derivative();
365 const libMesh::Real x_term = C1*( (grad_x(0)+grad_u(0))*u_gradphi_I(0) );
367 Kuu(i,j) += x_term*dgamma_du;
369 libMesh::Real y_term = 0.0;
370 libMesh::Real dgamma_dv = 0.0;
372 if( this->_disp_vars.dim() >= 2 )
374 dgamma_dv = ( u_gradphi_J(0)*(grad_y(0)+grad_v(0)) );
375 y_term = C1*( (grad_y(0)+grad_v(0))*u_gradphi_I(0) );
377 (*Kuv)(i,j) += x_term*dgamma_dv;
378 (*Kvu)(i,j) += y_term*dgamma_du;
379 (*Kvv)(i,j) += y_term*dgamma_dv;
382 libMesh::Real z_term = 0.0;
384 if( this->_disp_vars.dim() == 3 )
386 const libMesh::Real dgamma_dw = ( u_gradphi_J(0)*(grad_z(0)+grad_w(0)) );
387 z_term = C1*( (grad_z(0)+grad_w(0))*u_gradphi_I(0) );
389 (*Kuw)(i,j) += x_term*dgamma_dw;
390 (*Kvw)(i,j) += y_term*dgamma_dw;
391 (*Kwu)(i,j) += z_term*dgamma_du;
392 (*Kwv)(i,j) += z_term*dgamma_dv;
393 (*Kww)(i,j) += z_term*dgamma_dw;
unsigned int register_quantity(std::string name)
Register quantity to be postprocessed.
GRINS::ICHandlingBase * _ic_handler
virtual void compute_postprocessed_quantity(unsigned int quantity_index, const AssemblyContext &context, const libMesh::Point &point, libMesh::Real &value)
Compute the registered postprocessed quantities.
static PhysicsName elastic_cable()
Base class for reading and handling initial conditions for physics classes.
virtual void register_postprocessing_vars(const GetPot &input, PostProcessedQuantities< libMesh::Real > &postprocessing)
Register postprocessing variables for ElasticCable.
virtual void element_time_derivative(bool compute_jacobian, AssemblyContext &context)
Time dependent part(s) of physics for element interiors.