void ExodusII_IO::write_global_data (const std::vector<Number> & soln, const std::vector<std::string> & names) { if(MeshOutput<MeshBase>::mesh().processor_id()) return; if (!exio_helper->opened_for_writing) libmesh_error_msg("ERROR, ExodusII file must be initialized before outputting global variables."); #ifdef LIBMESH_USE_COMPLEX_NUMBERS std::vector<std::string> complex_names = exio_helper->get_complex_names(names); exio_helper->initialize_global_variables(complex_names); unsigned int num_values = soln.size(); unsigned int num_vars = names.size(); unsigned int num_elems = num_values / num_vars; // This will contain the real and imaginary parts and the magnitude // of the values in soln std::vector<Real> complex_soln(3*num_values); for (unsigned i=0; i<num_vars; ++i) { for (unsigned int j=0; j<num_elems; ++j) { Number value = soln[i*num_vars + j]; complex_soln[3*i*num_elems + j] = value.real(); } for (unsigned int j=0; j<num_elems; ++j) { Number value = soln[i*num_vars + j]; complex_soln[3*i*num_elems + num_elems +j] = value.imag(); } for (unsigned int j=0; j<num_elems; ++j) { Number value = soln[i*num_vars + j]; complex_soln[3*i*num_elems + 2*num_elems + j] = std::abs(value); } } exio_helper->write_global_values(complex_soln, _timestep); #else exio_helper->initialize_global_variables(names); exio_helper->write_global_values(soln, _timestep); #endif }
void LinearElasticityWithContact::move_mesh (MeshBase & input_mesh, const NumericVector<Number> & input_solution) { // Maintain a set of node ids that we've encountered. LIBMESH_BEST_UNORDERED_SET<dof_id_type> encountered_node_ids; // Localize input_solution so that we have the data to move all // elements (not just elements local to this processor). UniquePtr< NumericVector<Number> > localized_input_solution = NumericVector<Number>::build(input_solution.comm()); localized_input_solution->init (input_solution.size(), false, SERIAL); input_solution.localize(*localized_input_solution); MeshBase::const_element_iterator el = input_mesh.active_elements_begin(); const MeshBase::const_element_iterator end_el = input_mesh.active_elements_end(); for ( ; el != end_el; ++el) { Elem * elem = *el; Elem * orig_elem = _sys.get_mesh().elem_ptr(elem->id()); for (unsigned int node_id=0; node_id<elem->n_nodes(); node_id++) { Node & node = elem->node_ref(node_id); if (encountered_node_ids.find(node.id()) != encountered_node_ids.end()) continue; encountered_node_ids.insert(node.id()); std::vector<std::string> uvw_names(3); uvw_names[0] = "u"; uvw_names[1] = "v"; uvw_names[2] = "w"; { const Point master_point = elem->master_point(node_id); Point uvw; for (unsigned int index=0; index<uvw_names.size(); index++) { const unsigned int var = _sys.variable_number(uvw_names[index]); const FEType & fe_type = _sys.get_dof_map().variable_type(var); FEComputeData data (_sys.get_equation_systems(), master_point); FEInterface::compute_data(elem->dim(), fe_type, elem, data); std::vector<dof_id_type> dof_indices_var; _sys.get_dof_map().dof_indices (orig_elem, dof_indices_var, var); for (unsigned int i=0; i<dof_indices_var.size(); i++) { Number value = (*localized_input_solution)(dof_indices_var[i]) * data.shape[i]; #ifdef LIBMESH_USE_COMPLEX_NUMBERS // We explicitly store the real part in uvw uvw(index) += value.real(); #else uvw(index) += value; #endif } } // Update the node's location node += uvw; } } } }
void ExodusII_IO::write_element_data (const EquationSystems & es) { // Be sure the file has been opened for writing! if (MeshOutput<MeshBase>::mesh().processor_id() == 0 && !exio_helper->opened_for_writing) libmesh_error_msg("ERROR, ExodusII file must be initialized before outputting element variables."); // This function currently only works on SerialMeshes. We rely on // having a reference to a non-const MeshBase object from our // MeshInput parent class to construct a MeshSerializer object, // similar to what is done in ExodusII_IO::write(). Note that // calling ExodusII_IO::write_timestep() followed by // ExodusII_IO::write_element_data() when the underlying Mesh is a // ParallelMesh will result in an unnecessary additional // serialization/re-parallelization step. MeshSerializer serialize(MeshInput<MeshBase>::mesh(), !MeshOutput<MeshBase>::_is_parallel_format); // To be (possibly) filled with a filtered list of variable names to output. std::vector<std::string> names; // If _output_variables is populated, only output the monomials which are // also in the _output_variables vector. if (_output_variables.size() > 0) { std::vector<std::string> monomials; const FEType type(CONSTANT, MONOMIAL); // Create a list of monomial variable names es.build_variable_names(monomials, &type); // Filter that list against the _output_variables list. Note: if names is still empty after // all this filtering, all the monomial variables will be gathered std::vector<std::string>::iterator it = monomials.begin(); for (; it!=monomials.end(); ++it) if (std::find(_output_variables.begin(), _output_variables.end(), *it) != _output_variables.end()) names.push_back(*it); } // If we pass in a list of names to "get_solution" it'll filter the variables coming back std::vector<Number> soln; es.get_solution(soln, names); if(soln.empty()) // If there is nothing to write just return return; // The data must ultimately be written block by block. This means that this data // must be sorted appropriately. if(MeshOutput<MeshBase>::mesh().processor_id()) return; const MeshBase & mesh = MeshOutput<MeshBase>::mesh(); #ifdef LIBMESH_USE_COMPLEX_NUMBERS std::vector<std::string> complex_names = exio_helper->get_complex_names(names); exio_helper->initialize_element_variables(complex_names); unsigned int num_values = soln.size(); unsigned int num_vars = names.size(); unsigned int num_elems = num_values / num_vars; // This will contain the real and imaginary parts and the magnitude // of the values in soln std::vector<Real> complex_soln(3*num_values); for (unsigned i=0; i<num_vars; ++i) { for (unsigned int j=0; j<num_elems; ++j) { Number value = soln[i*num_vars + j]; complex_soln[3*i*num_elems + j] = value.real(); } for (unsigned int j=0; j<num_elems; ++j) { Number value = soln[i*num_vars + j]; complex_soln[3*i*num_elems + num_elems +j] = value.imag(); } for (unsigned int j=0; j<num_elems; ++j) { Number value = soln[i*num_vars + j]; complex_soln[3*i*num_elems + 2*num_elems + j] = std::abs(value); } } exio_helper->write_element_values(mesh, complex_soln, _timestep); #else exio_helper->initialize_element_variables(names); exio_helper->write_element_values(mesh, soln, _timestep); #endif }