예제 #1
0
void RigidBody::operator()(const RigidBody::InternalState &x, RigidBody::InternalState &dxdt, const double /* t */)
{
  	Eigen::Vector3d x_dot, v_dot, omega_dot;
  	Eigen::Vector4d q_dot;
  	Eigen::Vector4d q(attitude.x(), attitude.y(), attitude.z(), attitude.w());

	Eigen::Vector3d omega = angularVelocity;
	Eigen::Matrix4d omegaMat = Omega(omega);

  	x_dot = velocity;
  	v_dot = force/mass;
  	q_dot = 0.5*omegaMat*q;
  	omega_dot = inertia.inverse() *
      (torque - omega.cross(inertia*omega));

	dxdt[0]  = x_dot(0); 
	dxdt[1]  = x_dot(1); 
	dxdt[2]  = x_dot(2); 

	dxdt[3]  = v_dot(0); 
	dxdt[4]  = v_dot(1); 
	dxdt[5]  = v_dot(2); 

	dxdt[6]  = q_dot(0); 
	dxdt[7]  = q_dot(1); 
	dxdt[8]  = q_dot(2); 
	dxdt[9]  = q_dot(3); 

	dxdt[10] = omega_dot(0); 
	dxdt[11] = omega_dot(1); 
	dxdt[12] = omega_dot(2); 
}
예제 #2
0
int main(int argc, char* argv[])
{
  // Check command line count.
  if( argc < 2 )
    {
      // TODO: Need more consistent error handling.
      std::cerr << "Error: Must specify input file." << std::endl;
      exit(1);
    }

  GetPot input( argv[1] );

  GRINS::CanteraMixture mixture( input, GRINS::MaterialsParsing::material_name(input,GRINS::PhysicsNaming::reacting_low_mach_navier_stokes()) );

  GRINS::CanteraKinetics kinetics( mixture );

  libMesh::Real T0 = input( "Conditions/T0", 300.0 );
  libMesh::Real T1 = input( "Conditions/T1", 300.0 );
  libMesh::Real T_inc = input( "Conditions/T_increment", 100.0 );

  libMesh::Real rho = input( "Conditions/density", 1.0e-3 );

  const unsigned int n_species = mixture.n_species();

  std::vector<double> Y(n_species,0.0);
  for( unsigned int s = 0; s < n_species; s++ )
    {
      Y[s] = input( "Conditions/mass_fractions", 0.0, s );
    }

  std::vector<double> omega_dot(n_species,0.0);

  libMesh::Real T = T0;

  std::ofstream output;
  output.open( "omega_dot.dat", std::ios::trunc );

  output << "# Species names" << std::endl;
  for( unsigned int s = 0; s < n_species; s++ )
    {
      output << mixture.species_name( s ) << " ";
    }
  output << std::endl;
  output << "# T [K]                  omega_dot [kg/m^3-s]" << std::endl;

  output.close();

  while( T < T1 )
    {
      kinetics.omega_dot( T, rho, Y, omega_dot );

      output.open( "omega_dot.dat", std::ios::app );
      output << T << " ";

      for( unsigned int i = 0; i < n_species; i++ )
        {
          output << std::scientific << std::setprecision(16)
                 << omega_dot[i] << " ";
        }

      output << std::endl;

      output.close();

      T += T_inc;
    }


  return 0;
}
  void ReactingLowMachNavierStokesStabilizationBase<Mixture,Evaluator>::compute_res_steady( AssemblyContext& context,
                                                                                            unsigned int qp,
                                                                                            libMesh::Real& RP_s,
                                                                                            libMesh::RealGradient& RM_s,
                                                                                            libMesh::Real& RE_s,
                                                                                            std::vector<libMesh::Real>& Rs_s )
  {
    Rs_s.resize(this->n_species(),0.0);

    // Grab r-coordinate for axisymmetric terms
    // We're assuming all variables are using the same quadrature rule
    libMesh::Real r = (context.get_element_fe(this->_flow_vars.u())->get_xyz())[qp](0);

    libMesh::RealGradient grad_p = context.interior_gradient(this->_press_var.p(), qp);

    libMesh::RealGradient grad_u = context.interior_gradient(this->_flow_vars.u(), qp);
    libMesh::RealGradient grad_v = context.interior_gradient(this->_flow_vars.v(), qp);

    libMesh::RealGradient U( context.interior_value(this->_flow_vars.u(), qp),
                             context.interior_value(this->_flow_vars.v(), qp) );
    libMesh::Real divU = grad_u(0) + grad_v(1);

    if( this->_is_axisymmetric )
      divU += U(0)/r;

    if(this->mesh_dim(context) == 3)
      {
        U(2) = context.interior_value(this->_flow_vars.w(), qp);
        divU += (context.interior_gradient(this->_flow_vars.w(), qp))(2);
      }

    // We don't add axisymmetric terms here since we don't directly use hess_{u,v}
    // axisymmetric terms are built into divGradU, etc. functions below
    libMesh::RealTensor hess_u = context.interior_hessian(this->_flow_vars.u(), qp);
    libMesh::RealTensor hess_v = context.interior_hessian(this->_flow_vars.v(), qp);

    libMesh::Real T = context.interior_value(this->_temp_vars.T(), qp);

    libMesh::Gradient grad_T = context.interior_gradient(this->_temp_vars.T(), qp);
    libMesh::Tensor hess_T = context.interior_hessian(this->_temp_vars.T(), qp);

    libMesh::Real hess_T_term = hess_T(0,0) + hess_T(1,1);
#if LIBMESH_DIM > 2
    hess_T_term += hess_T(2,2);
#endif
    // Add axisymmetric terms, if needed
    if( this->_is_axisymmetric )
      hess_T_term += grad_T(0)/r;

    std::vector<libMesh::Real> ws(this->n_species());
    std::vector<libMesh::RealGradient> grad_ws(this->n_species());
    std::vector<libMesh::RealTensor> hess_ws(this->n_species());
    for(unsigned int s=0; s < this->_n_species; s++ )
      {
        ws[s] = context.interior_value(this->_species_vars.species(s), qp);
        grad_ws[s] = context.interior_gradient(this->_species_vars.species(s), qp);
        hess_ws[s] = context.interior_hessian(this->_species_vars.species(s), qp);
      }

    Evaluator gas_evaluator( this->_gas_mixture );
    const libMesh::Real R_mix = gas_evaluator.R_mix(ws);
    const libMesh::Real p0 = this->get_p0_steady(context,qp);
    libMesh::Real rho = this->rho(T, p0, R_mix );
    libMesh::Real cp = gas_evaluator.cp(T,p0,ws);
    libMesh::Real M = gas_evaluator.M_mix( ws );

    std::vector<libMesh::Real> D( this->n_species() );
    libMesh::Real mu, k;

    gas_evaluator.mu_and_k_and_D( T, rho, cp, ws, mu, k, D );


    // grad_rho = drho_dT*gradT + \sum_s drho_dws*grad_ws
    const libMesh::Real drho_dT = -p0/(R_mix*T*T);
    libMesh::RealGradient grad_rho = drho_dT*grad_T;
    for(unsigned int s=0; s < this->_n_species; s++ )
      {
        libMesh::Real Ms = gas_evaluator.M(s);
        libMesh::Real R_uni = Constants::R_universal/1000.0; /* J/kmol-K --> J/mol-K */

        // drho_dws = -p0/(T*R_mix*R_mix)*dR_dws
        // dR_dws = R_uni*d_dws(1/M)
        // d_dws(1/M) = d_dws(\sum_s w_s/Ms) =  1/Ms
        const libMesh::Real drho_dws = -p0/(R_mix*R_mix*T)*R_uni/Ms;
        grad_rho += drho_dws*grad_ws[s];
      }

    libMesh::RealGradient rhoUdotGradU;
    libMesh::RealGradient divGradU;
    libMesh::RealGradient divGradUT;
    libMesh::RealGradient divdivU;

    if( this->mesh_dim(context) < 3 )
      {
        rhoUdotGradU = rho*_stab_helper.UdotGradU( U, grad_u, grad_v );

        // Call axisymmetric versions if we are doing an axisymmetric run
        if( this->_is_axisymmetric )
          {
            divGradU  = _stab_helper.div_GradU_axi( r, U, grad_u, grad_v, hess_u, hess_v );
            divGradUT = _stab_helper.div_GradU_T_axi( r, U, grad_u, hess_u, hess_v );
            divdivU   = _stab_helper.div_divU_I_axi( r, U, grad_u, hess_u, hess_v );
          }
        else
          {
            divGradU  = _stab_helper.div_GradU( hess_u, hess_v );
            divGradUT = _stab_helper.div_GradU_T( hess_u, hess_v );
            divdivU   = _stab_helper.div_divU_I( hess_u, hess_v );
          }
      }
    else
      {
        libMesh::RealGradient grad_w = context.interior_gradient(this->_flow_vars.w(), qp);
        libMesh::RealTensor hess_w = context.interior_hessian(this->_flow_vars.w(), qp);

        rhoUdotGradU = rho*_stab_helper.UdotGradU( U, grad_u, grad_v, grad_w );

        divGradU  = _stab_helper.div_GradU( hess_u, hess_v, hess_w );
        divGradUT = _stab_helper.div_GradU_T( hess_u, hess_v, hess_w );
        divdivU   = _stab_helper.div_divU_I( hess_u, hess_v, hess_w );
      }



    // Terms if we have vicosity derivatives w.r.t. temp.
    /*
    if( this->_mu.deriv(T) != 0.0 )
      {
        libMesh::Gradient gradTgradu( grad_T*grad_u, grad_T*grad_v );

        libMesh::Gradient gradTgraduT( grad_T(0)*grad_u(0) + grad_T(1)*grad_u(1),
                                       grad_T(0)*grad_v(0) + grad_T(1)*grad_v(1) );

        libMesh::Real divU = grad_u(0) + grad_v(1);

        libMesh::Gradient gradTdivU( grad_T(0)*divU, grad_T(1)*divU );

        if(this->mesh_dim(context) == 3)
          {
            libMesh::Gradient grad_w = context.interior_gradient(this->_flow_vars.w(), qp);

            gradTgradu(2) = grad_T*grad_w;

            gradTgraduT(0) += grad_T(2)*grad_u(2);
            gradTgraduT(1) += grad_T(2)*grad_v(2);
            gradTgraduT(2) = grad_T(0)*grad_w(0) + grad_T(1)*grad_w(1) + grad_T(2)*grad_w(2);

            divU += grad_w(2);
            gradTdivU(0) += grad_T(0)*grad_w(2);
            gradTdivU(1) += grad_T(1)*grad_w(2);
            gradTdivU(2) += grad_T(2)*divU;
          }

        divT += this->_mu.deriv(T)*( gradTgradu + gradTgraduT - 2.0/3.0*gradTdivU );
      }
    */

    // Axisymmetric terms already built in
    libMesh::RealGradient div_stress = mu*(divGradU + divGradUT - 2.0/3.0*divdivU);

    std::vector<libMesh::Real> omega_dot(this->n_species());
    gas_evaluator.omega_dot(T,rho,ws,omega_dot);

    libMesh::Real chem_term = 0.0;
    libMesh::Gradient mass_term(0.0,0.0,0.0);
    for(unsigned int s=0; s < this->_n_species; s++ )
      {
        // Start accumulating chemistry term for energy residual
        libMesh::Real h_s=gas_evaluator.h_s(T,s);
        chem_term += h_s*omega_dot[s];

        /* Accumulate mass term for continuity residual
           mass_term = grad_M/M */
        mass_term += grad_ws[s]/this->_gas_mixture.M(s);

        libMesh::Real hess_s_term = hess_ws[s](0,0) + hess_ws[s](1,1);
#if LIBMESH_DIM > 2
        hess_s_term += hess_ws[s](2,2);
#endif
        // Add axisymmetric terms, if needed
        if( this->_is_axisymmetric )
          hess_s_term += grad_ws[s](0)/r;

        // Species residual
        /*! \todo Still missing derivative of species diffusion coefficient.
                  rho*grad_D[s]*grad_ws[s] */
        Rs_s[s] = rho*U*grad_ws[s] - rho*D[s]*hess_s_term - grad_rho*D[s]*grad_ws[s]
                  - omega_dot[s];
      }
    mass_term *= M;

    // Continuity residual
    RP_s = divU - (U*grad_T)/T - U*mass_term;

    // Momentum residual
    RM_s = rhoUdotGradU + grad_p - div_stress - rho*(this->_g);

    // Energy residual
    // - this->_k.deriv(T)*(grad_T*grad_T)
    RE_s = rho*U*cp*grad_T  - k*(hess_T_term) + chem_term;

    return;
  }