void GasRecombinationCatalyticWall<Chemistry>::init( const libMesh::FEMSystem& system ) { libmesh_do_once(libmesh_deprecated()); const std::string r_var_name = std::string("w_"+this->_chemistry.species_name( this->_reactant_species_idx ) ); const std::string p_var_name = std::string("w_"+this->_chemistry.species_name( this->_product_species_idx ) ); libmesh_assert( system.has_variable( r_var_name ) ); libmesh_assert( system.has_variable( p_var_name ) ); this->_reactant_var_idx = system.variable_number( r_var_name ); this->_product_var_idx = system.variable_number( p_var_name ); }
/* * FIXME: This is known to write nonsense on AMR meshes * and it strips the imaginary parts of complex Numbers */ void VTKIO::system_vectors_to_vtk(const EquationSystems& es, vtkUnstructuredGrid*& grid) { if (MeshOutput<MeshBase>::mesh().processor_id() == 0) { std::map<std::string, std::vector<Number> > vecs; for (unsigned int i=0; i<es.n_systems(); ++i) { const System& sys = es.get_system(i); System::const_vectors_iterator v_end = sys.vectors_end(); System::const_vectors_iterator it = sys.vectors_begin(); for (; it!= v_end; ++it) { // for all vectors on this system std::vector<Number> values; // libMesh::out<<"it "<<it->first<<std::endl; it->second->localize_to_one(values, 0); // libMesh::out<<"finish localize"<<std::endl; vecs[it->first] = values; } } std::map<std::string, std::vector<Number> >::iterator it = vecs.begin(); for (; it!=vecs.end(); ++it) { vtkDoubleArray *data = vtkDoubleArray::New(); data->SetName(it->first.c_str()); libmesh_assert_equal_to (it->second.size(), es.get_mesh().n_nodes()); data->SetNumberOfValues(it->second.size()); for (unsigned int i=0; i<it->second.size(); ++i) { #ifdef LIBMESH_USE_COMPLEX_NUMBERS libmesh_do_once (libMesh::err << "Only writing the real part for complex numbers!\n" << "if you need this support contact " << LIBMESH_PACKAGE_BUGREPORT << std::endl); data->SetValue(i, it->second[i].real()); #else data->SetValue(i, it->second[i]); #endif } grid->GetPointData()->AddArray(data); data->Delete(); } } }
void GasRecombinationCatalyticWall<Chemistry>::apply_fluxes( AssemblyContext& context, const CachedValues& cache, const bool request_jacobian ) { libmesh_do_once(libmesh_deprecated()); libMesh::FEGenericBase<libMesh::Real>* side_fe = NULL; context.get_side_fe( _reactant_var_idx, side_fe ); // The number of local degrees of freedom in each variable. const unsigned int n_var_dofs = context.get_dof_indices(_reactant_var_idx).size(); libmesh_assert_equal_to( n_var_dofs, context.get_dof_indices(_product_var_idx).size() ); // Element Jacobian * quadrature weight for side integration. const std::vector<libMesh::Real> &JxW_side = side_fe->get_JxW(); // The var shape functions at side quadrature points. const std::vector<std::vector<libMesh::Real> >& var_phi_side = side_fe->get_phi(); // Physical location of the quadrature points const std::vector<libMesh::Point>& var_qpoint = side_fe->get_xyz(); // reactant residual libMesh::DenseSubVector<libMesh::Number> &F_r_var = context.get_elem_residual(_reactant_var_idx); // product residual libMesh::DenseSubVector<libMesh::Number> &F_p_var = context.get_elem_residual(_product_var_idx); unsigned int n_qpoints = context.get_side_qrule().n_points(); for (unsigned int qp=0; qp != n_qpoints; qp++) { libMesh::Real jac = JxW_side[qp]; if(Physics::is_axisymmetric()) { const libMesh::Number r = var_qpoint[qp](0); jac *= r; } const libMesh::Real rho = cache.get_cached_values(Cache::MIXTURE_DENSITY)[qp]; const libMesh::Real Y_r = cache.get_cached_vector_values(Cache::MASS_FRACTIONS)[qp][this->_reactant_species_idx]; const libMesh::Real T = cache.get_cached_values(Cache::TEMPERATURE)[qp]; const libMesh::Real r_value = this->compute_reactant_mass_flux(rho, Y_r, T); const libMesh::Real p_value = -r_value; for (unsigned int i=0; i != n_var_dofs; i++) { F_r_var(i) += r_value*var_phi_side[i][qp]*jac; F_p_var(i) += p_value*var_phi_side[i][qp]*jac; if( request_jacobian ) { libmesh_not_implemented(); } } } }
void VTKIO::write_nodal_data (const std::string & fname, const std::vector<Number> & soln, const std::vector<std::string> & names) { const MeshBase & mesh = MeshOutput<MeshBase>::mesh(); // Warn that the .pvtu file extension should be used. Paraview // recognizes this, and it works in both serial and parallel. Only // warn about this once. if (fname.substr(fname.rfind("."), fname.size()) != ".pvtu") libmesh_do_once(libMesh::err << "The .pvtu extension should be used when writing VTK files in libMesh."); // If there are variable names being written, the solution vector // should not be empty, it should have been broadcast to all // processors by the MeshOutput base class, since VTK is a parallel // format. Verify this before going further. if (!names.empty() && soln.empty()) libmesh_error_msg("Empty soln vector in VTKIO::write_nodal_data()."); // we only use Unstructured grids _vtk_grid = vtkUnstructuredGrid::New(); vtkSmartPointer<vtkXMLPUnstructuredGridWriter> writer = vtkSmartPointer<vtkXMLPUnstructuredGridWriter>::New(); // add nodes to the grid and update _local_node_map _local_node_map.clear(); this->nodes_to_vtk(); // add cells to the grid this->cells_to_vtk(); // add nodal solutions to the grid, if solutions are given if (names.size() > 0) { std::size_t num_vars = names.size(); dof_id_type num_nodes = mesh.n_nodes(); for (std::size_t variable=0; variable<num_vars; ++variable) { vtkSmartPointer<vtkDoubleArray> data = vtkSmartPointer<vtkDoubleArray>::New(); data->SetName(names[variable].c_str()); // number of local and ghost nodes data->SetNumberOfValues(_local_node_map.size()); // loop over all nodes and get the solution for the current // variable, if the node is in the current partition for (dof_id_type k=0; k<num_nodes; ++k) { std::map<dof_id_type, dof_id_type>::iterator local_node_it = _local_node_map.find(k); if (local_node_it == _local_node_map.end()) continue; // not a local node #ifdef LIBMESH_USE_COMPLEX_NUMBERS libmesh_do_once (libMesh::err << "Only writing the real part for complex numbers!\n" << "if you need this support contact " << LIBMESH_PACKAGE_BUGREPORT << std::endl); data->SetValue(local_node_it->second, soln[k*num_vars + variable].real()); #else data->SetValue(local_node_it->second, soln[k*num_vars + variable]); #endif } _vtk_grid->GetPointData()->AddArray(data); } } // Tell the writer how many partitions exist and on which processor // we are currently writer->SetNumberOfPieces(MeshOutput<MeshBase>::mesh().n_processors()); writer->SetStartPiece(MeshOutput<MeshBase>::mesh().processor_id()); writer->SetEndPiece(MeshOutput<MeshBase>::mesh().processor_id()); // partitions overlap by one node // FIXME: According to this document // http://paraview.org/Wiki/images/5/51/SC07_tut107_ParaView_Handouts.pdf // the ghosts are cells rather than nodes. writer->SetGhostLevel(1); // Not sure exactly when this changed, but SetInput() is not a // method on vtkXMLPUnstructuredGridWriter as of VTK 6.1.0 #if VTK_VERSION_LESS_THAN(6,0,0) writer->SetInput(_vtk_grid); #else writer->SetInputData(_vtk_grid); #endif writer->SetFileName(fname.c_str()); writer->SetDataModeToAscii(); // compress the output, if desired (switches also to binary) if (this->_compress) { #if !VTK_VERSION_LESS_THAN(5,6,0) writer->SetCompressorTypeToZLib(); #else libmesh_do_once(libMesh::err << "Compression not implemented with old VTK libs!" << std::endl;);
void InfFE<Dim,T_radial,T_map>::init_shape_functions(const Elem * inf_elem) { libmesh_assert(inf_elem); // Start logging the radial shape function initialization START_LOG("init_shape_functions()", "InfFE"); // ----------------------------------------------------------------- // fast access to some const int's for the radial data const unsigned int n_radial_mapping_sf = cast_int<unsigned int>(radial_map.size()); const unsigned int n_radial_approx_sf = cast_int<unsigned int>(mode.size()); const unsigned int n_radial_qp = cast_int<unsigned int>(som.size()); // ----------------------------------------------------------------- // initialize most of the things related to mapping // The element type and order to use in the base map const Order base_mapping_order ( base_elem->default_order() ); const ElemType base_mapping_elem_type ( base_elem->type() ); // the number of base shape functions used to construct the map // (Lagrange shape functions are used for mapping in the base) unsigned int n_base_mapping_shape_functions = Base::n_base_mapping_sf(base_mapping_elem_type, base_mapping_order); const unsigned int n_total_mapping_shape_functions = n_radial_mapping_sf * n_base_mapping_shape_functions; // ----------------------------------------------------------------- // initialize most of the things related to physical approximation unsigned int n_base_approx_shape_functions; if (Dim > 1) n_base_approx_shape_functions = base_fe->n_shape_functions(); else n_base_approx_shape_functions = 1; const unsigned int n_total_approx_shape_functions = n_radial_approx_sf * n_base_approx_shape_functions; // update class member field _n_total_approx_sf = n_total_approx_shape_functions; // The number of the base quadrature points. const unsigned int n_base_qp = base_qrule->n_points(); // The total number of quadrature points. const unsigned int n_total_qp = n_radial_qp * n_base_qp; // update class member field _n_total_qp = n_total_qp; // ----------------------------------------------------------------- // initialize the node and shape numbering maps { // these vectors work as follows: the i-th entry stores // the associated base/radial node number _radial_node_index.resize (n_total_mapping_shape_functions); _base_node_index.resize (n_total_mapping_shape_functions); // similar for the shapes: the i-th entry stores // the associated base/radial shape number _radial_shape_index.resize (n_total_approx_shape_functions); _base_shape_index.resize (n_total_approx_shape_functions); const ElemType inf_elem_type (inf_elem->type()); // fill the node index map for (unsigned int n=0; n<n_total_mapping_shape_functions; n++) { compute_node_indices (inf_elem_type, n, _base_node_index[n], _radial_node_index[n]); libmesh_assert_less (_base_node_index[n], n_base_mapping_shape_functions); libmesh_assert_less (_radial_node_index[n], n_radial_mapping_sf); } // fill the shape index map for (unsigned int n=0; n<n_total_approx_shape_functions; n++) { compute_shape_indices (this->fe_type, inf_elem_type, n, _base_shape_index[n], _radial_shape_index[n]); libmesh_assert_less (_base_shape_index[n], n_base_approx_shape_functions); libmesh_assert_less (_radial_shape_index[n], n_radial_approx_sf); } } // ----------------------------------------------------------------- // resize the base data fields dist.resize(n_base_mapping_shape_functions); // ----------------------------------------------------------------- // resize the total data fields // the phase term varies with xi, eta and zeta(v): store it for _all_ qp // // when computing the phase, we need the base approximations // therefore, initialize the phase here, but evaluate it // in combine_base_radial(). // // the weight, though, is only needed at the radial quadrature points, n_radial_qp. // but for a uniform interface to the protected data fields // the weight data field (which are accessible from the outside) are expanded to n_total_qp. weight.resize (n_total_qp); dweightdv.resize (n_total_qp); dweight.resize (n_total_qp); dphase.resize (n_total_qp); dphasedxi.resize (n_total_qp); dphasedeta.resize (n_total_qp); dphasedzeta.resize (n_total_qp); // this vector contains the integration weights for the combined quadrature rule _total_qrule_weights.resize(n_total_qp); // ----------------------------------------------------------------- // InfFE's data fields phi, dphi, dphidx, phi_map etc hold the _total_ // shape and mapping functions, respectively { phi.resize (n_total_approx_shape_functions); dphi.resize (n_total_approx_shape_functions); dphidx.resize (n_total_approx_shape_functions); dphidy.resize (n_total_approx_shape_functions); dphidz.resize (n_total_approx_shape_functions); dphidxi.resize (n_total_approx_shape_functions); #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES libmesh_do_once(libMesh::err << "Second derivatives for Infinite elements" << " are not yet implemented!" << std::endl); d2phi.resize (n_total_approx_shape_functions); d2phidx2.resize (n_total_approx_shape_functions); d2phidxdy.resize (n_total_approx_shape_functions); d2phidxdz.resize (n_total_approx_shape_functions); d2phidy2.resize (n_total_approx_shape_functions); d2phidydz.resize (n_total_approx_shape_functions); d2phidz2.resize (n_total_approx_shape_functions); d2phidxi2.resize (n_total_approx_shape_functions); if (Dim > 1) { d2phidxideta.resize (n_total_approx_shape_functions); d2phideta2.resize (n_total_approx_shape_functions); } if (Dim > 2) { d2phidetadzeta.resize (n_total_approx_shape_functions); d2phidxidzeta.resize (n_total_approx_shape_functions); d2phidzeta2.resize (n_total_approx_shape_functions); } #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES if (Dim > 1) dphideta.resize (n_total_approx_shape_functions); if (Dim == 3) dphidzeta.resize (n_total_approx_shape_functions); std::vector<std::vector<Real> > & phi_map = this->_fe_map->get_phi_map(); std::vector<std::vector<Real> > & dphidxi_map = this->_fe_map->get_dphidxi_map(); phi_map.resize (n_total_mapping_shape_functions); dphidxi_map.resize (n_total_mapping_shape_functions); #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES std::vector<std::vector<Real> > & d2phidxi2_map = this->_fe_map->get_d2phidxi2_map(); d2phidxi2_map.resize (n_total_mapping_shape_functions); if (Dim > 1) { std::vector<std::vector<Real> > & d2phidxideta_map = this->_fe_map->get_d2phidxideta_map(); std::vector<std::vector<Real> > & d2phideta2_map = this->_fe_map->get_d2phideta2_map(); d2phidxideta_map.resize (n_total_mapping_shape_functions); d2phideta2_map.resize (n_total_mapping_shape_functions); } if (Dim == 3) { std::vector<std::vector<Real> > & d2phidxidzeta_map = this->_fe_map->get_d2phidxidzeta_map(); std::vector<std::vector<Real> > & d2phidetadzeta_map = this->_fe_map->get_d2phidetadzeta_map(); std::vector<std::vector<Real> > & d2phidzeta2_map = this->_fe_map->get_d2phidzeta2_map(); d2phidxidzeta_map.resize (n_total_mapping_shape_functions); d2phidetadzeta_map.resize (n_total_mapping_shape_functions); d2phidzeta2_map.resize (n_total_mapping_shape_functions); } #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES if (Dim > 1) { std::vector<std::vector<Real> > & dphideta_map = this->_fe_map->get_dphideta_map(); dphideta_map.resize (n_total_mapping_shape_functions); } if (Dim == 3) { std::vector<std::vector<Real> > & dphidzeta_map = this->_fe_map->get_dphidzeta_map(); dphidzeta_map.resize (n_total_mapping_shape_functions); } } // ----------------------------------------------------------------- // collect all the for loops, where inner vectors are // resized to the appropriate number of quadrature points { for (unsigned int i=0; i<n_total_approx_shape_functions; i++) { phi[i].resize (n_total_qp); dphi[i].resize (n_total_qp); dphidx[i].resize (n_total_qp); dphidy[i].resize (n_total_qp); dphidz[i].resize (n_total_qp); dphidxi[i].resize (n_total_qp); #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES d2phi[i].resize (n_total_qp); d2phidx2[i].resize (n_total_qp); d2phidxdy[i].resize (n_total_qp); d2phidxdz[i].resize (n_total_qp); d2phidy2[i].resize (n_total_qp); d2phidydz[i].resize (n_total_qp); d2phidy2[i].resize (n_total_qp); d2phidxi2[i].resize (n_total_qp); if (Dim > 1) { d2phidxideta[i].resize (n_total_qp); d2phideta2[i].resize (n_total_qp); } if (Dim > 2) { d2phidxidzeta[i].resize (n_total_qp); d2phidetadzeta[i].resize (n_total_qp); d2phidzeta2[i].resize (n_total_qp); } #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES if (Dim > 1) dphideta[i].resize (n_total_qp); if (Dim == 3) dphidzeta[i].resize (n_total_qp); } for (unsigned int i=0; i<n_total_mapping_shape_functions; i++) { std::vector<std::vector<Real> > & phi_map = this->_fe_map->get_phi_map(); std::vector<std::vector<Real> > & dphidxi_map = this->_fe_map->get_dphidxi_map(); phi_map[i].resize (n_total_qp); dphidxi_map[i].resize (n_total_qp); #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES std::vector<std::vector<Real> > & d2phidxi2_map = this->_fe_map->get_d2phidxi2_map(); d2phidxi2_map[i].resize (n_total_qp); if (Dim > 1) { std::vector<std::vector<Real> > & d2phidxideta_map = this->_fe_map->get_d2phidxideta_map(); std::vector<std::vector<Real> > & d2phideta2_map = this->_fe_map->get_d2phideta2_map(); d2phidxideta_map[i].resize (n_total_qp); d2phideta2_map[i].resize (n_total_qp); } if (Dim > 2) { std::vector<std::vector<Real> > & d2phidxidzeta_map = this->_fe_map->get_d2phidxidzeta_map(); std::vector<std::vector<Real> > & d2phidetadzeta_map = this->_fe_map->get_d2phidetadzeta_map(); std::vector<std::vector<Real> > & d2phidzeta2_map = this->_fe_map->get_d2phidzeta2_map(); d2phidxidzeta_map[i].resize (n_total_qp); d2phidetadzeta_map[i].resize (n_total_qp); d2phidzeta2_map[i].resize (n_total_qp); } #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES if (Dim > 1) { std::vector<std::vector<Real> > & dphideta_map = this->_fe_map->get_dphideta_map(); dphideta_map[i].resize (n_total_qp); } if (Dim == 3) { std::vector<std::vector<Real> > & dphidzeta_map = this->_fe_map->get_dphidzeta_map(); dphidzeta_map[i].resize (n_total_qp); } } } { // ----------------------------------------------------------------- // (a) compute scalar values at _all_ quadrature points -- for uniform // access from the outside to these fields // (b) form a std::vector<Real> which contains the appropriate weights // of the combined quadrature rule! const std::vector<Point> & radial_qp = radial_qrule->get_points(); libmesh_assert_equal_to (radial_qp.size(), n_radial_qp); const std::vector<Real> & radial_qw = radial_qrule->get_weights(); const std::vector<Real> & base_qw = base_qrule->get_weights(); libmesh_assert_equal_to (radial_qw.size(), n_radial_qp); libmesh_assert_equal_to (base_qw.size(), n_base_qp); for (unsigned int rp=0; rp<n_radial_qp; rp++) for (unsigned int bp=0; bp<n_base_qp; bp++) { weight [ bp+rp*n_base_qp ] = Radial::D (radial_qp[rp](0)); dweightdv[ bp+rp*n_base_qp ] = Radial::D_deriv (radial_qp[rp](0)); _total_qrule_weights[ bp+rp*n_base_qp ] = radial_qw[rp] * base_qw[bp]; } } /** * Stop logging the radial shape function initialization */ STOP_LOG("init_shape_functions()", "InfFE"); }