void SolutionUserObject::initialSetup() { // Several aspects of SolutionUserObject won't work if the FEProblem's MooseMesh is // a ParallelMesh: // .) ExodusII_IO::copy_nodal_solution() doesn't work in parallel. // .) We don't know if directValue will be used, which may request // a value on a Node we don't have. _fe_problem.mesh().errorIfParallelDistribution("SolutionUserObject"); // Create a libmesh::Mesh object for storing the loaded data. Since // SolutionUserObject is restricted to only work with SerialMesh // (see above) we can force the Mesh used here to be a SerialMesh. _mesh = new SerialMesh(_communicator); // ExodusII mesh file supplied if (MooseUtils::hasExtension(_mesh_file, "e")) { _file_type = "exodusII"; readExodusII(); } // XDA mesh file supplied else if (MooseUtils::hasExtension(_mesh_file, "xda")) { _file_type = "xda"; readXda(); } // Produce an error for an unknown file type else mooseError("In SolutionUserObject, invalid file type (only .xda and .e supported)"); // Intilize the serial solution vector _serialized_solution = NumericVector<Number>::build(_communicator).release(); _serialized_solution->init(_system->n_dofs(), false, SERIAL); // Pull down a full copy of this vector on every processor so we can get values in parallel _system->solution->localize(*_serialized_solution); // Gather the variable numbers for the desired variables std::vector<unsigned int> var_num; var_num.reserve(_nodal_vars.size() + _elem_vars.size()); for (std::vector<std::string>::const_iterator it = _nodal_vars.begin(); it != _nodal_vars.end(); ++it) var_num.push_back(_system->variable_number(*it)); for (std::vector<std::string>::const_iterator it = _elem_vars.begin(); it != _elem_vars.end(); ++it) var_num.push_back(_system->variable_number(*it)); // Create the MeshFunction for working with the solution data _mesh_function = new MeshFunction(*_es, *_serialized_solution, _system->get_dof_map(), var_num); _mesh_function->init(); }
void SolutionUserObject::initialSetup() { // Make sure this only happens once if (_initialized) return; // Several aspects of SolutionUserObject won't work if the FEProblem's MooseMesh is // a ParallelMesh: // .) ExodusII_IO::copy_nodal_solution() doesn't work in parallel. // .) We don't know if directValue will be used, which may request // a value on a Node we don't have. _fe_problem.mesh().errorIfParallelDistribution("SolutionUserObject"); // Create a libmesh::Mesh object for storing the loaded data. Since // SolutionUserObject is restricted to only work with SerialMesh // (see above) we can force the Mesh used here to be a SerialMesh. _mesh = new SerialMesh(_communicator); // ExodusII mesh file supplied if (MooseUtils::hasExtension(_mesh_file, "e", /*strip_exodus_ext =*/ true)) { _file_type = "exodusII"; readExodusII(); } // XDA mesh file supplied else if (MooseUtils::hasExtension(_mesh_file, "xda")) { _file_type = "xda"; readXda(); } else if (MooseUtils::hasExtension(_mesh_file, "xdr")) { _file_type = "xdr"; readXda(); } // Produce an error for an unknown file type else mooseError("In SolutionUserObject, invalid file type (only .xda, .xdr, and .e supported)"); // Intilize the serial solution vector _serialized_solution = NumericVector<Number>::build(_communicator).release(); _serialized_solution->init(_system->n_dofs(), false, SERIAL); // Pull down a full copy of this vector on every processor so we can get values in parallel _system->solution->localize(*_serialized_solution); // Vector of variable numbers to apply the MeshFunction to std::vector<unsigned int> var_nums; // If no variables were given, use all of them if (_system_variables.empty()) { _system->get_all_variable_numbers(var_nums); for (std::vector<unsigned int>::const_iterator it = var_nums.begin(); it != var_nums.end(); ++it) _system_variables.push_back(_system->variable_name(*it)); } // Otherwise, gather the numbers for the variabels given else { for (std::vector<std::string>::const_iterator it = _system_variables.begin(); it != _system_variables.end(); ++it) var_nums.push_back(_system->variable_number(*it)); } // Create the MeshFunction for working with the solution data _mesh_function = new MeshFunction(*_es, *_serialized_solution, _system->get_dof_map(), var_nums); _mesh_function->init(); // Build second MeshFunction for interpolation if (_interpolate_times) { // Need to pull down a full copy of this vector on every processor so we can get values in parallel _serialized_solution2 = NumericVector<Number>::build(_communicator).release(); _serialized_solution2->init(_system2->n_dofs(), false, SERIAL); _system2->solution->localize(*_serialized_solution2); // Create the MeshFunction for the second copy of the data _mesh_function2 = new MeshFunction(*_es2, *_serialized_solution2, _system2->get_dof_map(), var_nums); _mesh_function2->init(); } // Populate the data maps that indicate if the variable is nodal and the MeshFunction variable index for (unsigned int i = 0; i < _system_variables.size(); ++i) { std::string name = _system_variables[i]; FEType type = _system->variable_type(name); if (type.order == CONSTANT) _local_variable_nodal[name] = false; else _local_variable_nodal[name] = true; _local_variable_index[name] = i; } // Set initialization flag _initialized = true; }