dof_id_type PartitionerWeightTest::computeElementWeight(Elem & elem) { auto centroid = elem.centroid(); if (centroid(0) < 0.5) return 2; else return 1; }
void CentroidPartitioner::compute_centroids (MeshBase::element_iterator it, MeshBase::element_iterator end) { _elem_centroids.clear(); for (; it != end; ++it) { Elem * elem = *it; _elem_centroids.push_back(std::make_pair(elem->centroid(), elem)); } }
void CentroidPartitioner::compute_centroids (MeshBase& mesh) { _elem_centroids.clear(); _elem_centroids.reserve(mesh.n_elem()); // elem_iterator it(mesh.elements_begin()); // const elem_iterator it_end(mesh.elements_end()); MeshBase::element_iterator it = mesh.elements_begin(); const MeshBase::element_iterator it_end = mesh.elements_end(); for (; it != it_end; ++it) { Elem* elem = *it; _elem_centroids.push_back(std::make_pair(elem->centroid(), elem)); } }
Point GrainTracker::centerOfMass(UniqueGrain & grain) const { // NOTE: Does not work with Parallel Mesh yet if (!_is_elemental) mooseError("Not intended to work with Nodal Floods"); Point center_of_mass; for (std::set<dof_id_type>::const_iterator entity_it = grain.entities_ptr->begin(); entity_it != grain.entities_ptr->end(); ++entity_it) { Elem *elem = _mesh.elem(*entity_it); if (!elem) mooseError("Couldn't find element " << *entity_it << " in centerOfMass calculation."); center_of_mass += elem->centroid(); } center_of_mass /= static_cast<Real>(grain.entities_ptr->size()); return center_of_mass; }
void StripeMesh::buildMesh() { GeneratedMesh::buildMesh(); Real h = (getParam<Real>("xmax") - getParam<Real>("xmin")) / _n_stripes; // width of the stripe for (unsigned int en = 0; en < nElem(); en++) { // get an element Elem * e = elemPtr(en); if (!e) { mooseError("Error getting element " << en << ". StripeMesh only works with ReplicatedMesh..."); } else { Point centroid = e->centroid(); // get its centroid subdomain_id_type sid = floor((centroid(0) - getParam<Real>("xmin")) / h); // figure out the subdomain ID e->subdomain_id() = sid; } } }
void MultiAppMeshFunctionTransfer::execute() { Moose::out << "Beginning MeshFunctionTransfer " << name() << std::endl; getAppInfo(); /** * For every combination of global "from" problem and local "to" problem, find * which "from" bounding boxes overlap with which "to" elements. Keep track * of which processors own bounding boxes that overlap with which elements. * Build vectors of node locations/element centroids to send to other * processors for mesh function evaluations. */ // Get the bounding boxes for the "from" domains. std::vector<MeshTools::BoundingBox> bboxes = getFromBoundingBoxes(); // Figure out how many "from" domains each processor owns. std::vector<unsigned int> froms_per_proc = getFromsPerProc(); std::vector<std::vector<Point> > outgoing_points(n_processors()); std::vector<std::map<std::pair<unsigned int, unsigned int>, unsigned int> > point_index_map(n_processors()); // point_index_map[i_to, element_id] = index // outgoing_points[index] is the first quadrature point in element for (unsigned int i_to = 0; i_to < _to_problems.size(); i_to++) { System * to_sys = find_sys(*_to_es[i_to], _to_var_name); unsigned int sys_num = to_sys->number(); unsigned int var_num = to_sys->variable_number(_to_var_name); MeshBase * to_mesh = & _to_meshes[i_to]->getMesh(); bool is_nodal = to_sys->variable_type(var_num).family == LAGRANGE; if (is_nodal) { MeshBase::const_node_iterator node_it = to_mesh->local_nodes_begin(); MeshBase::const_node_iterator node_end = to_mesh->local_nodes_end(); for (; node_it != node_end; ++node_it) { Node * node = *node_it; // Skip this node if the variable has no dofs at it. if (node->n_dofs(sys_num, var_num) < 1) continue; // Loop over the "froms" on processor i_proc. If the node is found in // any of the "froms", add that node to the vector that will be sent to // i_proc. unsigned int from0 = 0; for (processor_id_type i_proc = 0; i_proc < n_processors(); from0 += froms_per_proc[i_proc], i_proc++) { bool point_found = false; for (unsigned int i_from = from0; i_from < from0 + froms_per_proc[i_proc] && ! point_found; i_from++) { if (bboxes[i_from].contains_point(*node + _to_positions[i_to])) { std::pair<unsigned int, unsigned int> key(i_to, node->id()); point_index_map[i_proc][key] = outgoing_points[i_proc].size(); outgoing_points[i_proc].push_back(*node + _to_positions[i_to]); point_found = true; } } } } } else // Elemental { MeshBase::const_element_iterator elem_it = to_mesh->local_elements_begin(); MeshBase::const_element_iterator elem_end = to_mesh->local_elements_end(); for (; elem_it != elem_end; ++elem_it) { Elem * elem = *elem_it; Point centroid = elem->centroid(); // Skip this element if the variable has no dofs at it. if (elem->n_dofs(sys_num, var_num) < 1) continue; // Loop over the "froms" on processor i_proc. If the elem is found in // any of the "froms", add that elem to the vector that will be sent to // i_proc. unsigned int from0 = 0; for (processor_id_type i_proc = 0; i_proc < n_processors(); from0 += froms_per_proc[i_proc], i_proc++) { bool point_found = false; for (unsigned int i_from = from0; i_from < from0 + froms_per_proc[i_proc] && ! point_found; i_from++) { if (bboxes[i_from].contains_point(centroid + _to_positions[i_to])) { std::pair<unsigned int, unsigned int> key(i_to, elem->id()); point_index_map[i_proc][key] = outgoing_points[i_proc].size(); outgoing_points[i_proc].push_back(centroid + _to_positions[i_to]); point_found = true; } } } } } } /** * Request point evaluations from other processors and handle requests sent to * this processor. */ // Get the local bounding boxes. std::vector<MeshTools::BoundingBox> local_bboxes(froms_per_proc[processor_id()]); { // Find the index to the first of this processor's local bounding boxes. unsigned int local_start = 0; for (processor_id_type i_proc = 0; i_proc < n_processors() && i_proc != processor_id(); i_proc++) { local_start += froms_per_proc[i_proc]; } // Extract the local bounding boxes. for (unsigned int i_from = 0; i_from < froms_per_proc[processor_id()]; i_from++) { local_bboxes[i_from] = bboxes[local_start + i_from]; } } // Setup the local mesh functions. std::vector<MooseSharedPointer<MeshFunction> > local_meshfuns; for (unsigned int i_from = 0; i_from < _from_problems.size(); i_from++) { FEProblem & from_problem = *_from_problems[i_from]; MooseVariable & from_var = from_problem.getVariable(0, _from_var_name); System & from_sys = from_var.sys().system(); unsigned int from_var_num = from_sys.variable_number(from_var.name()); MooseSharedPointer<MeshFunction> from_func; //TODO: make MultiAppTransfer give me the right es if (_displaced_source_mesh && from_problem.getDisplacedProblem()) from_func.reset(new MeshFunction(from_problem.getDisplacedProblem()->es(), *from_sys.current_local_solution, from_sys.get_dof_map(), from_var_num)); else from_func.reset(new MeshFunction(from_problem.es(), *from_sys.current_local_solution, from_sys.get_dof_map(), from_var_num)); from_func->init(Trees::ELEMENTS); from_func->enable_out_of_mesh_mode(OutOfMeshValue); local_meshfuns.push_back(from_func); } // Send points to other processors. std::vector<std::vector<Real> > incoming_evals(n_processors()); std::vector<std::vector<unsigned int> > incoming_app_ids(n_processors()); for (processor_id_type i_proc = 0; i_proc < n_processors(); i_proc++) { if (i_proc == processor_id()) continue; _communicator.send(i_proc, outgoing_points[i_proc]); } // Recieve points from other processors, evaluate mesh frunctions at those // points, and send the values back. for (processor_id_type i_proc = 0; i_proc < n_processors(); i_proc++) { std::vector<Point> incoming_points; if (i_proc == processor_id()) incoming_points = outgoing_points[i_proc]; else _communicator.receive(i_proc, incoming_points); std::vector<Real> outgoing_evals(incoming_points.size(), OutOfMeshValue); std::vector<unsigned int> outgoing_ids(incoming_points.size(), -1); // -1 = largest unsigned int for (unsigned int i_pt = 0; i_pt < incoming_points.size(); i_pt++) { Point pt = incoming_points[i_pt]; // Loop until we've found the lowest-ranked app that actually contains // the quadrature point. for (unsigned int i_from = 0; i_from < _from_problems.size() && outgoing_evals[i_pt] == OutOfMeshValue; i_from++) { if (local_bboxes[i_from].contains_point(pt)) { outgoing_evals[i_pt] = (* local_meshfuns[i_from])(pt - _from_positions[i_from]); if (_direction == FROM_MULTIAPP) outgoing_ids[i_pt] = _local2global_map[i_from]; } } } if (i_proc == processor_id()) { incoming_evals[i_proc] = outgoing_evals; if (_direction == FROM_MULTIAPP) incoming_app_ids[i_proc] = outgoing_ids; } else { _communicator.send(i_proc, outgoing_evals); if (_direction == FROM_MULTIAPP) _communicator.send(i_proc, outgoing_ids); } } /** * Gather all of the evaluations, pick out the best ones for each point, and * apply them to the solution vector. When we are transferring from * multiapps, there may be multiple overlapping apps for a particular point. * In that case, we'll try to use the value from the app with the lowest id. */ for (processor_id_type i_proc = 0; i_proc < n_processors(); i_proc++) { if (i_proc == processor_id()) continue; _communicator.receive(i_proc, incoming_evals[i_proc]); if (_direction == FROM_MULTIAPP) _communicator.receive(i_proc, incoming_app_ids[i_proc]); } for (unsigned int i_to = 0; i_to < _to_problems.size(); i_to++) { System * to_sys = find_sys(*_to_es[i_to], _to_var_name); unsigned int sys_num = to_sys->number(); unsigned int var_num = to_sys->variable_number(_to_var_name); NumericVector<Real> * solution; switch (_direction) { case TO_MULTIAPP: solution = & getTransferVector(i_to, _to_var_name); break; case FROM_MULTIAPP: solution = to_sys->solution.get(); break; } MeshBase * to_mesh = & _to_meshes[i_to]->getMesh(); bool is_nodal = to_sys->variable_type(var_num).family == LAGRANGE; if (is_nodal) { MeshBase::const_node_iterator node_it = to_mesh->local_nodes_begin(); MeshBase::const_node_iterator node_end = to_mesh->local_nodes_end(); for (; node_it != node_end; ++node_it) { Node * node = *node_it; // Skip this node if the variable has no dofs at it. if (node->n_dofs(sys_num, var_num) < 1) continue; unsigned int lowest_app_rank = libMesh::invalid_uint; Real best_val = 0.; bool point_found = false; for (unsigned int i_proc = 0; i_proc < incoming_evals.size(); i_proc++) { // Skip this proc if the node wasn't in it's bounding boxes. std::pair<unsigned int, unsigned int> key(i_to, node->id()); if (point_index_map[i_proc].find(key) == point_index_map[i_proc].end()) continue; unsigned int i_pt = point_index_map[i_proc][key]; // Ignore this proc if it's app has a higher rank than the // previously found lowest app rank. if (_direction == FROM_MULTIAPP) { if (incoming_app_ids[i_proc][i_pt] >= lowest_app_rank) continue; } // Ignore this proc if the point was actually outside its meshes. if (incoming_evals[i_proc][i_pt] == OutOfMeshValue) continue; best_val = incoming_evals[i_proc][i_pt]; point_found = true; } if (_error_on_miss && ! point_found) mooseError("Point not found! " << *node + _to_positions[i_to]); dof_id_type dof = node->dof_number(sys_num, var_num, 0); solution->set(dof, best_val); } } else // Elemental { MeshBase::const_element_iterator elem_it = to_mesh->local_elements_begin(); MeshBase::const_element_iterator elem_end = to_mesh->local_elements_end(); for (; elem_it != elem_end; ++elem_it) { Elem * elem = *elem_it; // Skip this element if the variable has no dofs at it. if (elem->n_dofs(sys_num, var_num) < 1) continue; unsigned int lowest_app_rank = libMesh::invalid_uint; Real best_val = 0; bool point_found = false; for (unsigned int i_proc = 0; i_proc < incoming_evals.size(); i_proc++) { // Skip this proc if the elem wasn't in it's bounding boxes. std::pair<unsigned int, unsigned int> key(i_to, elem->id()); if (point_index_map[i_proc].find(key) == point_index_map[i_proc].end()) continue; unsigned int i_pt = point_index_map[i_proc][key]; // Ignore this proc if it's app has a higher rank than the // previously found lowest app rank. if (_direction == FROM_MULTIAPP) { if (incoming_app_ids[i_proc][i_pt] >= lowest_app_rank) continue; } // Ignore this proc if the point was actually outside its meshes. if (incoming_evals[i_proc][i_pt] == OutOfMeshValue) continue; best_val = incoming_evals[i_proc][i_pt]; point_found = true; } if (_error_on_miss && ! point_found) mooseError("Point not found! " << elem->centroid() + _to_positions[i_to]); dof_id_type dof = elem->dof_number(sys_num, var_num, 0); solution->set(dof, best_val); } } solution->close(); to_sys->update(); } _console << "Finished MeshFunctionTransfer " << name() << std::endl; }
void MultiAppUserObjectTransfer::execute() { _console << "Beginning MultiAppUserObjectTransfer " << name() << std::endl; switch (_direction) { case TO_MULTIAPP: { for (unsigned int i=0; i<_multi_app->numGlobalApps(); i++) { if (_multi_app->hasLocalApp(i)) { MPI_Comm swapped = Moose::swapLibMeshComm(_multi_app->comm()); // Loop over the master nodes and set the value of the variable System * to_sys = find_sys(_multi_app->appProblem(i).es(), _to_var_name); unsigned int sys_num = to_sys->number(); unsigned int var_num = to_sys->variable_number(_to_var_name); NumericVector<Real> & solution = _multi_app->appTransferVector(i, _to_var_name); MeshBase * mesh = NULL; if (_displaced_target_mesh && _multi_app->appProblem(i).getDisplacedProblem()) { mesh = &_multi_app->appProblem(i).getDisplacedProblem()->mesh().getMesh(); } else mesh = &_multi_app->appProblem(i).mesh().getMesh(); bool is_nodal = to_sys->variable_type(var_num).family == LAGRANGE; const UserObject & user_object = _multi_app->problem().getUserObjectBase(_user_object_name); if (is_nodal) { MeshBase::const_node_iterator node_it = mesh->local_nodes_begin(); MeshBase::const_node_iterator node_end = mesh->local_nodes_end(); for (; node_it != node_end; ++node_it) { Node * node = *node_it; if (node->n_dofs(sys_num, var_num) > 0) // If this variable has dofs at this node { // The zero only works for LAGRANGE! dof_id_type dof = node->dof_number(sys_num, var_num, 0); // Swap back Moose::swapLibMeshComm(swapped); Real from_value = user_object.spatialValue(*node+_multi_app->position(i)); // Swap again swapped = Moose::swapLibMeshComm(_multi_app->comm()); solution.set(dof, from_value); } } } else // Elemental { MeshBase::const_element_iterator elem_it = mesh->local_elements_begin(); MeshBase::const_element_iterator elem_end = mesh->local_elements_end(); for (; elem_it != elem_end; ++elem_it) { Elem * elem = *elem_it; Point centroid = elem->centroid(); if (elem->n_dofs(sys_num, var_num) > 0) // If this variable has dofs at this elem { // The zero only works for LAGRANGE! dof_id_type dof = elem->dof_number(sys_num, var_num, 0); // Swap back Moose::swapLibMeshComm(swapped); Real from_value = user_object.spatialValue(centroid+_multi_app->position(i)); // Swap again swapped = Moose::swapLibMeshComm(_multi_app->comm()); solution.set(dof, from_value); } } } solution.close(); to_sys->update(); // Swap back Moose::swapLibMeshComm(swapped); } } break; } case FROM_MULTIAPP: { FEProblem & to_problem = _multi_app->problem(); MooseVariable & to_var = to_problem.getVariable(0, _to_var_name); SystemBase & to_system_base = to_var.sys(); System & to_sys = to_system_base.system(); unsigned int to_sys_num = to_sys.number(); // Only works with a serialized mesh to transfer to! mooseAssert(to_sys.get_mesh().is_serial(), "MultiAppUserObjectTransfer only works with SerialMesh!"); unsigned int to_var_num = to_sys.variable_number(to_var.name()); _console << "Transferring to: " << to_var.name() << std::endl; // EquationSystems & to_es = to_sys.get_equation_systems(); //Create a serialized version of the solution vector NumericVector<Number> * to_solution = to_sys.solution.get(); MeshBase * to_mesh = NULL; if (_displaced_target_mesh && to_problem.getDisplacedProblem()) to_mesh = &to_problem.getDisplacedProblem()->mesh().getMesh(); else to_mesh = &to_problem.mesh().getMesh(); bool is_nodal = to_sys.variable_type(to_var_num).family == LAGRANGE; for (unsigned int i=0; i<_multi_app->numGlobalApps(); i++) { if (!_multi_app->hasLocalApp(i)) continue; Point app_position = _multi_app->position(i); MeshTools::BoundingBox app_box = _multi_app->getBoundingBox(i); const UserObject & user_object = _multi_app->appUserObjectBase(i, _user_object_name); if (is_nodal) { MeshBase::const_node_iterator node_it = to_mesh->nodes_begin(); MeshBase::const_node_iterator node_end = to_mesh->nodes_end(); for (; node_it != node_end; ++node_it) { Node * node = *node_it; if (node->n_dofs(to_sys_num, to_var_num) > 0) // If this variable has dofs at this node { // See if this node falls in this bounding box if (app_box.contains_point(*node)) { dof_id_type dof = node->dof_number(to_sys_num, to_var_num, 0); MPI_Comm swapped = Moose::swapLibMeshComm(_multi_app->comm()); Real from_value = user_object.spatialValue(*node-app_position); Moose::swapLibMeshComm(swapped); to_solution->set(dof, from_value); } } } } else // Elemental { MeshBase::const_element_iterator elem_it = to_mesh->elements_begin(); MeshBase::const_element_iterator elem_end = to_mesh->elements_end(); for (; elem_it != elem_end; ++elem_it) { Elem * elem = *elem_it; if (elem->n_dofs(to_sys_num, to_var_num) > 0) // If this variable has dofs at this elem { Point centroid = elem->centroid(); // See if this elem falls in this bounding box if (app_box.contains_point(centroid)) { dof_id_type dof = elem->dof_number(to_sys_num, to_var_num, 0); MPI_Comm swapped = Moose::swapLibMeshComm(_multi_app->comm()); Real from_value = user_object.spatialValue(centroid-app_position); Moose::swapLibMeshComm(swapped); to_solution->set(dof, from_value); } } } } } to_solution->close(); to_sys.update(); break; } } _console << "Finished MultiAppUserObjectTransfer " << name() << std::endl; }
// Begin the main program. int main (int argc, char ** argv) { // Initialize libMesh and any dependent libaries, like in example 2. LibMeshInit init (argc, argv); // Only our PETSc interface currently supports solves restricted to // subdomains libmesh_example_requires(libMesh::default_solver_package() == PETSC_SOLVERS, "--enable-petsc"); // Skip adaptive examples on a non-adaptive libMesh build #ifndef LIBMESH_ENABLE_AMR libmesh_example_requires(false, "--enable-amr"); #else // Declare a performance log for the main program // PerfLog perf_main("Main Program"); // Create a GetPot object to parse the command line GetPot command_line (argc, argv); // Check for proper calling arguments. if (argc < 3) { // This handy function will print the file name, line number, // specified message, and then throw an exception. libmesh_error_msg("Usage:\n" << "\t " << argv[0] << " -d 2(3)" << " -n 15"); } // Brief message to the user regarding the program name // and command line arguments. else { libMesh::out << "Running " << argv[0]; for (int i=1; i<argc; i++) libMesh::out << " " << argv[i]; libMesh::out << std::endl << std::endl; } // Read problem dimension from command line. Use int // instead of unsigned since the GetPot overload is ambiguous // otherwise. int dim = 2; if (command_line.search(1, "-d")) dim = command_line.next(dim); // Skip higher-dimensional examples on a lower-dimensional libMesh build libmesh_example_requires(dim <= LIBMESH_DIM, "2D/3D support"); // Create a mesh with user-defined dimension. // Read number of elements from command line int ps = 15; if (command_line.search(1, "-n")) ps = command_line.next(ps); // Read FE order from command line std::string order = "FIRST"; if (command_line.search(2, "-Order", "-o")) order = command_line.next(order); // Read FE Family from command line std::string family = "LAGRANGE"; if (command_line.search(2, "-FEFamily", "-f")) family = command_line.next(family); // Cannot use discontinuous basis. if ((family == "MONOMIAL") || (family == "XYZ")) libmesh_error_msg("This example requires a C^0 (or higher) FE basis."); // Create a mesh, with dimension to be overridden later, on the // default MPI communicator. Mesh mesh(init.comm()); // Use the MeshTools::Generation mesh generator to create a uniform // grid on the square [-1,1]^D. We instruct the mesh generator // to build a mesh of 8x8 Quad9 elements in 2D, or Hex27 // elements in 3D. Building these higher-order elements allows // us to use higher-order approximation, as in example 3. Real halfwidth = dim > 1 ? 1. : 0.; Real halfheight = dim > 2 ? 1. : 0.; if ((family == "LAGRANGE") && (order == "FIRST")) { // No reason to use high-order geometric elements if we are // solving with low-order finite elements. MeshTools::Generation::build_cube (mesh, ps, (dim>1) ? ps : 0, (dim>2) ? ps : 0, -1., 1., -halfwidth, halfwidth, -halfheight, halfheight, (dim==1) ? EDGE2 : ((dim == 2) ? QUAD4 : HEX8)); } else { MeshTools::Generation::build_cube (mesh, ps, (dim>1) ? ps : 0, (dim>2) ? ps : 0, -1., 1., -halfwidth, halfwidth, -halfheight, halfheight, (dim==1) ? EDGE3 : ((dim == 2) ? QUAD9 : HEX27)); } // To demonstate solving on a subdomain, we will solve only on the // interior of a circle (ball in 3d) with radius 0.8. So show that // this also works well on locally refined meshes, we refine once // all elements that are located on the boundary of this circle (or // ball). { // A MeshRefinement object is needed to refine meshes. MeshRefinement meshRefinement(mesh); // Loop over all elements. MeshBase::element_iterator elem_it = mesh.elements_begin(); const MeshBase::element_iterator elem_end = mesh.elements_end(); for (; elem_it != elem_end; ++elem_it) { Elem * elem = *elem_it; if (elem->active()) { // Just check whether the current element has at least one // node inside and one node outside the circle. bool node_in = false; bool node_out = false; for (unsigned int i=0; i<elem->n_nodes(); i++) { double d = elem->point(i).norm(); if (d<0.8) { node_in = true; } else { node_out = true; } } if (node_in && node_out) { elem->set_refinement_flag(Elem::REFINE); } else { elem->set_refinement_flag(Elem::DO_NOTHING); } } else { elem->set_refinement_flag(Elem::INACTIVE); } } // Now actually refine. meshRefinement.refine_elements(); } // Print information about the mesh to the screen. mesh.print_info(); // Now set the subdomain_id of all elements whose centroid is inside // the circle to 1. { // Loop over all elements. MeshBase::element_iterator elem_it = mesh.elements_begin(); const MeshBase::element_iterator elem_end = mesh.elements_end(); for (; elem_it != elem_end; ++elem_it) { Elem * elem = *elem_it; double d = elem->centroid().norm(); if (d<0.8) { elem->subdomain_id() = 1; } } } // Create an equation systems object. EquationSystems equation_systems (mesh); // Declare the system and its variables. // Create a system named "Poisson" LinearImplicitSystem & system = equation_systems.add_system<LinearImplicitSystem> ("Poisson"); // Add the variable "u" to "Poisson". "u" // will be approximated using second-order approximation. system.add_variable("u", Utility::string_to_enum<Order> (order), Utility::string_to_enum<FEFamily>(family)); // Give the system a pointer to the matrix assembly // function. system.attach_assemble_function (assemble_poisson); // Initialize the data structures for the equation system. equation_systems.init(); // Print information about the system to the screen. equation_systems.print_info(); mesh.print_info(); // Restrict solves to those elements that have subdomain_id set to 1. std::set<subdomain_id_type> id_list; id_list.insert(1); SystemSubsetBySubdomain::SubdomainSelectionByList selection(id_list); SystemSubsetBySubdomain subset(system, selection); system.restrict_solve_to(&subset, SUBSET_ZERO); // Note that using SUBSET_ZERO will cause all dofs outside the // subdomain to be cleared. This will, however, cause some hanging // nodes outside the subdomain to have inconsistent values. // Solve the system "Poisson", just like example 2. equation_systems.get_system("Poisson").solve(); // After solving the system write the solution // to a GMV-formatted plot file. if (dim == 1) { GnuPlotIO plot(mesh, "Subdomains Example 1, 1D", GnuPlotIO::GRID_ON); plot.write_equation_systems("gnuplot_script", equation_systems); } else { GMVIO (mesh).write_equation_systems ((dim == 3) ? "out_3.gmv" : "out_2.gmv", equation_systems); #ifdef LIBMESH_HAVE_EXODUS_API ExodusII_IO (mesh).write_equation_systems ((dim == 3) ? "out_3.e" : "out_2.e", equation_systems); #endif // #ifdef LIBMESH_HAVE_EXODUS_API } #endif // #ifndef LIBMESH_ENABLE_AMR // All done. return 0; }
void MultiAppMeshFunctionTransfer::execute() { Moose::out << "Beginning MeshFunctionTransfer " << _name << std::endl; switch(_direction) { case TO_MULTIAPP: { FEProblem & from_problem = *_multi_app->problem(); MooseVariable & from_var = from_problem.getVariable(0, _from_var_name); SystemBase & from_system_base = from_var.sys(); System & from_sys = from_system_base.system(); // Only works with a serialized mesh to transfer from! mooseAssert(from_sys.get_mesh().is_serial(), "MultiAppMeshFunctionTransfer only works with SerialMesh!"); unsigned int from_var_num = from_sys.variable_number(from_var.name()); EquationSystems & from_es = from_sys.get_equation_systems(); //Create a serialized version of the solution vector NumericVector<Number> * serialized_solution = NumericVector<Number>::build().release(); serialized_solution->init(from_sys.n_dofs(), false, SERIAL); // Need to pull down a full copy of this vector on every processor so we can get values in parallel from_sys.solution->localize(*serialized_solution); MeshFunction from_func(from_es, *serialized_solution, from_sys.get_dof_map(), from_var_num); from_func.init(Trees::ELEMENTS); from_func.enable_out_of_mesh_mode(NOTFOUND); for(unsigned int i=0; i<_multi_app->numGlobalApps(); i++) { if (_multi_app->hasLocalApp(i)) { MPI_Comm swapped = Moose::swapLibMeshComm(_multi_app->comm()); // Loop over the master nodes and set the value of the variable System * to_sys = find_sys(_multi_app->appProblem(i)->es(), _to_var_name); if (!to_sys) mooseError("Cannot find variable "<<_to_var_name<<" for "<<_name<<" Transfer"); unsigned int sys_num = to_sys->number(); unsigned int var_num = to_sys->variable_number(_to_var_name); NumericVector<Real> & solution = _multi_app->appTransferVector(i, _to_var_name); MeshBase & mesh = _multi_app->appProblem(i)->mesh().getMesh(); bool is_nodal = to_sys->variable_type(var_num).family == LAGRANGE; if (is_nodal) { MeshBase::const_node_iterator node_it = mesh.local_nodes_begin(); MeshBase::const_node_iterator node_end = mesh.local_nodes_end(); for(; node_it != node_end; ++node_it) { Node * node = *node_it; if (node->n_dofs(sys_num, var_num) > 0) // If this variable has dofs at this node { // The zero only works for LAGRANGE! dof_id_type dof = node->dof_number(sys_num, var_num, 0); // Swap back Moose::swapLibMeshComm(swapped); Real from_value = from_func(*node+_multi_app->position(i)); // Swap again swapped = Moose::swapLibMeshComm(_multi_app->comm()); if (from_value != NOTFOUND) solution.set(dof, from_value); else if (_error_on_miss) mooseError("Point not found! " << *node+_multi_app->position(i) << std::endl); } } } else // Elemental { MeshBase::const_element_iterator elem_it = mesh.local_elements_begin(); MeshBase::const_element_iterator elem_end = mesh.local_elements_end(); for(; elem_it != elem_end; ++elem_it) { Elem * elem = *elem_it; Point centroid = elem->centroid(); if (elem->n_dofs(sys_num, var_num) > 0) // If this variable has dofs at this elem { // The zero only works for LAGRANGE! dof_id_type dof = elem->dof_number(sys_num, var_num, 0); // Swap back Moose::swapLibMeshComm(swapped); Real from_value = from_func(centroid+_multi_app->position(i)); // Swap again swapped = Moose::swapLibMeshComm(_multi_app->comm()); if (from_value != NOTFOUND) solution.set(dof, from_value); else if (_error_on_miss) mooseError("Point not found! " << centroid+_multi_app->position(i) << std::endl); } } } solution.close(); to_sys->update(); // Swap back Moose::swapLibMeshComm(swapped); } } delete serialized_solution; break; } case FROM_MULTIAPP: { FEProblem & to_problem = *_multi_app->problem(); MooseVariable & to_var = to_problem.getVariable(0, _to_var_name); SystemBase & to_system_base = to_var.sys(); System & to_sys = to_system_base.system(); unsigned int to_sys_num = to_sys.number(); // Only works with a serialized mesh to transfer to! mooseAssert(to_sys.get_mesh().is_serial(), "MultiAppMeshFunctionTransfer only works with SerialMesh!"); unsigned int to_var_num = to_sys.variable_number(to_var.name()); EquationSystems & to_es = to_sys.get_equation_systems(); NumericVector<Number> * to_solution = to_sys.solution.get(); MeshBase & to_mesh = to_es.get_mesh(); bool is_nodal = to_sys.variable_type(to_var_num).family == LAGRANGE; for(unsigned int i=0; i<_multi_app->numGlobalApps(); i++) { if (!_multi_app->hasLocalApp(i)) continue; MPI_Comm swapped = Moose::swapLibMeshComm(_multi_app->comm()); FEProblem & from_problem = *_multi_app->appProblem(i); MooseVariable & from_var = from_problem.getVariable(0, _from_var_name); SystemBase & from_system_base = from_var.sys(); System & from_sys = from_system_base.system(); // Only works with a serialized mesh to transfer from! mooseAssert(from_sys.get_mesh().is_serial(), "MultiAppMeshFunctionTransfer only works with SerialMesh!"); unsigned int from_var_num = from_sys.variable_number(from_var.name()); EquationSystems & from_es = from_sys.get_equation_systems(); //Create a serialized version of the solution vector NumericVector<Number> * serialized_from_solution = NumericVector<Number>::build().release(); serialized_from_solution->init(from_sys.n_dofs(), false, SERIAL); // Need to pull down a full copy of this vector on every processor so we can get values in parallel from_sys.solution->localize(*serialized_from_solution); MeshBase & from_mesh = from_es.get_mesh(); MeshTools::BoundingBox app_box = MeshTools::processor_bounding_box(from_mesh, libMesh::processor_id()); Point app_position = _multi_app->position(i); MeshFunction from_func(from_es, *serialized_from_solution, from_sys.get_dof_map(), from_var_num); from_func.init(Trees::ELEMENTS); from_func.enable_out_of_mesh_mode(NOTFOUND); Moose::swapLibMeshComm(swapped); if (is_nodal) { MeshBase::const_node_iterator node_it = to_mesh.nodes_begin(); MeshBase::const_node_iterator node_end = to_mesh.nodes_end(); for(; node_it != node_end; ++node_it) { Node * node = *node_it; if (node->n_dofs(to_sys_num, to_var_num) > 0) // If this variable has dofs at this node { // See if this node falls in this bounding box if (app_box.contains_point(*node-app_position)) { // The zero only works for LAGRANGE! dof_id_type dof = node->dof_number(to_sys_num, to_var_num, 0); MPI_Comm swapped = Moose::swapLibMeshComm(_multi_app->comm()); Real from_value = from_func(*node-app_position); Moose::swapLibMeshComm(swapped); if (from_value != NOTFOUND) to_solution->set(dof, from_value); else if (_error_on_miss) mooseError("Point not found! " << *node-app_position <<std::endl); } } } } else // Elemental { MeshBase::const_element_iterator elem_it = to_mesh.elements_begin(); MeshBase::const_element_iterator elem_end = to_mesh.elements_end(); for(; elem_it != elem_end; ++elem_it) { Elem * elem = *elem_it; if (elem->n_dofs(to_sys_num, to_var_num) > 0) // If this variable has dofs at this elem { Point centroid = elem->centroid(); // See if this elem falls in this bounding box if (app_box.contains_point(centroid-app_position)) { // The zero only works for LAGRANGE! dof_id_type dof = elem->dof_number(to_sys_num, to_var_num, 0); MPI_Comm swapped = Moose::swapLibMeshComm(_multi_app->comm()); Real from_value = from_func(centroid-app_position); Moose::swapLibMeshComm(swapped); if (from_value != NOTFOUND) to_solution->set(dof, from_value); else if (_error_on_miss) mooseError("Point not found! " << centroid-app_position << std::endl); } } } } delete serialized_from_solution; } to_solution->close(); to_sys.update(); break; } } Moose::out << "Finished MeshFunctionTransfer " << _name << std::endl; }
void GrainTracker::buildBoundingSpheres() { // Don't track grains if the current simulation step is before the specified tracking step if (_t_step < _tracking_step) return; MeshBase & mesh = _mesh.getMesh(); unsigned long total_node_count = 0; for (unsigned int map_num = 0; map_num < _maps_size; ++map_num) { /** * Create a pair of vectors of real values that is 3 (for the x,y,z components) times * the length of the current _bubble_sets length. Each processor will update the * vector for the nodes that it owns (parallel_mesh case). Then a parallel exchange * will all for the global min/maxs of each bubble. */ std::vector<Real> min_points(_bubble_sets[map_num].size()*3, std::numeric_limits<Real>::max()); std::vector<Real> max_points(_bubble_sets[map_num].size()*3, -std::numeric_limits<Real>::max()); unsigned int set_counter = 0; for (std::list<BubbleData>::const_iterator it1 = _bubble_sets[map_num].begin(); it1 != _bubble_sets[map_num].end(); ++it1) { total_node_count += it1->_entity_ids.size(); // Find the min/max of our bounding box to calculate our bounding sphere for (std::set<dof_id_type>::iterator it2 = it1->_entity_ids.begin(); it2 != it1->_entity_ids.end(); ++it2) { Point point; Point * p_ptr = NULL; if (_is_elemental) { Elem *elem = mesh.query_elem(*it2); if (elem) { point = elem->centroid(); p_ptr = &point; } } else p_ptr = mesh.query_node_ptr(*it2); if (p_ptr) for (unsigned int i = 0; i < mesh.spatial_dimension(); ++i) { min_points[set_counter*3+i] = std::min(min_points[set_counter*3+i], (*p_ptr)(i)); max_points[set_counter*3+i] = std::max(max_points[set_counter*3+i], (*p_ptr)(i)); } } ++set_counter; } _communicator.min(min_points); _communicator.max(max_points); set_counter = 0; for (std::list<BubbleData>::const_iterator it1 = _bubble_sets[map_num].begin(); it1 != _bubble_sets[map_num].end(); ++it1) { Point min(min_points[set_counter*3], min_points[set_counter*3+1], min_points[set_counter*3+2]); Point max(max_points[set_counter*3], max_points[set_counter*3+1], max_points[set_counter*3+2]); // Calulate our bounding sphere Point center(min + ((max - min) / 2.0)); // The radius is the different between the outer edge of the "bounding box" // and the center plus the "hull buffer" value Real radius = (max - center).size() + _hull_buffer; unsigned int some_node_id = *(it1->_entity_ids.begin()); _bounding_spheres[map_num].push_back(new BoundingSphereInfo(some_node_id, center, radius)); ++set_counter; } } }
void MultiAppInterpolationTransfer::execute() { _console << "Beginning InterpolationTransfer " << _name << std::endl; switch (_direction) { case TO_MULTIAPP: { FEProblem & from_problem = *_multi_app->problem(); MooseVariable & from_var = from_problem.getVariable(0, _from_var_name); MeshBase * from_mesh = NULL; if (_displaced_source_mesh && from_problem.getDisplacedProblem()) from_mesh = &from_problem.getDisplacedProblem()->mesh().getMesh(); else from_mesh = &from_problem.mesh().getMesh(); SystemBase & from_system_base = from_var.sys(); System & from_sys = from_system_base.system(); unsigned int from_sys_num = from_sys.number(); unsigned int from_var_num = from_sys.variable_number(from_var.name()); bool from_is_nodal = from_sys.variable_type(from_var_num).family == LAGRANGE; // EquationSystems & from_es = from_sys.get_equation_systems(); NumericVector<Number> & from_solution = *from_sys.solution; InverseDistanceInterpolation<LIBMESH_DIM> * idi; switch (_interp_type) { case 0: idi = new InverseDistanceInterpolation<LIBMESH_DIM>(from_sys.comm(), _num_points, _power); break; case 1: idi = new RadialBasisInterpolation<LIBMESH_DIM>(from_sys.comm(), _radius); break; default: mooseError("Unknown interpolation type!"); } std::vector<Point> &src_pts (idi->get_source_points()); std::vector<Number> &src_vals (idi->get_source_vals()); std::vector<std::string> field_vars; field_vars.push_back(_to_var_name); idi->set_field_variables(field_vars); std::vector<std::string> vars; vars.push_back(_to_var_name); if (from_is_nodal) { MeshBase::const_node_iterator from_nodes_it = from_mesh->local_nodes_begin(); MeshBase::const_node_iterator from_nodes_end = from_mesh->local_nodes_end(); for (; from_nodes_it != from_nodes_end; ++from_nodes_it) { Node * from_node = *from_nodes_it; // Assuming LAGRANGE! dof_id_type from_dof = from_node->dof_number(from_sys_num, from_var_num, 0); src_pts.push_back(*from_node); src_vals.push_back(from_solution(from_dof)); } } else { MeshBase::const_element_iterator from_elements_it = from_mesh->local_elements_begin(); MeshBase::const_element_iterator from_elements_end = from_mesh->local_elements_end(); for (; from_elements_it != from_elements_end; ++from_elements_it) { Elem * from_elem = *from_elements_it; // Assuming CONSTANT MONOMIAL dof_id_type from_dof = from_elem->dof_number(from_sys_num, from_var_num, 0); src_pts.push_back(from_elem->centroid()); src_vals.push_back(from_solution(from_dof)); } } // We have only set local values - prepare for use by gathering remote gata idi->prepare_for_use(); for (unsigned int i=0; i<_multi_app->numGlobalApps(); i++) { if (_multi_app->hasLocalApp(i)) { MPI_Comm swapped = Moose::swapLibMeshComm(_multi_app->comm()); // Loop over the master nodes and set the value of the variable System * to_sys = find_sys(_multi_app->appProblem(i)->es(), _to_var_name); unsigned int sys_num = to_sys->number(); unsigned int var_num = to_sys->variable_number(_to_var_name); NumericVector<Real> & solution = _multi_app->appTransferVector(i, _to_var_name); MeshBase * mesh = NULL; if (_displaced_target_mesh && _multi_app->appProblem(i)->getDisplacedProblem()) mesh = &_multi_app->appProblem(i)->getDisplacedProblem()->mesh().getMesh(); else mesh = &_multi_app->appProblem(i)->mesh().getMesh(); bool is_nodal = to_sys->variable_type(var_num).family == LAGRANGE; if (is_nodal) { MeshBase::const_node_iterator node_it = mesh->local_nodes_begin(); MeshBase::const_node_iterator node_end = mesh->local_nodes_end(); for (; node_it != node_end; ++node_it) { Node * node = *node_it; Point actual_position = *node+_multi_app->position(i); if (node->n_dofs(sys_num, var_num) > 0) // If this variable has dofs at this node { std::vector<Point> pts; std::vector<Number> vals; pts.push_back(actual_position); vals.resize(1); idi->interpolate_field_data(vars, pts, vals); Real value = vals.front(); // The zero only works for LAGRANGE! dof_id_type dof = node->dof_number(sys_num, var_num, 0); solution.set(dof, value); } } } else // Elemental { MeshBase::const_element_iterator elem_it = mesh->local_elements_begin(); MeshBase::const_element_iterator elem_end = mesh->local_elements_end(); for (; elem_it != elem_end; ++elem_it) { Elem * elem = *elem_it; Point centroid = elem->centroid(); Point actual_position = centroid+_multi_app->position(i); if (elem->n_dofs(sys_num, var_num) > 0) // If this variable has dofs at this elem { std::vector<Point> pts; std::vector<Number> vals; pts.push_back(actual_position); vals.resize(1); idi->interpolate_field_data(vars, pts, vals); Real value = vals.front(); dof_id_type dof = elem->dof_number(sys_num, var_num, 0); solution.set(dof, value); } } } solution.close(); to_sys->update(); // Swap back Moose::swapLibMeshComm(swapped); } } delete idi; break; } case FROM_MULTIAPP: { FEProblem & to_problem = *_multi_app->problem(); MooseVariable & to_var = to_problem.getVariable(0, _to_var_name); SystemBase & to_system_base = to_var.sys(); System & to_sys = to_system_base.system(); NumericVector<Real> & to_solution = *to_sys.solution; unsigned int to_sys_num = to_sys.number(); // Only works with a serialized mesh to transfer to! mooseAssert(to_sys.get_mesh().is_serial(), "MultiAppInterpolationTransfer only works with SerialMesh!"); unsigned int to_var_num = to_sys.variable_number(to_var.name()); // EquationSystems & to_es = to_sys.get_equation_systems(); MeshBase * to_mesh = NULL; if (_displaced_target_mesh && to_problem.getDisplacedProblem()) to_mesh = &to_problem.getDisplacedProblem()->mesh().getMesh(); else to_mesh = &to_problem.mesh().getMesh(); bool is_nodal = to_sys.variable_type(to_var_num).family == LAGRANGE; InverseDistanceInterpolation<LIBMESH_DIM> * idi; switch (_interp_type) { case 0: idi = new InverseDistanceInterpolation<LIBMESH_DIM>(to_sys.comm(), _num_points, _power); break; case 1: idi = new RadialBasisInterpolation<LIBMESH_DIM>(to_sys.comm(), _radius); break; default: mooseError("Unknown interpolation type!"); } std::vector<Point> &src_pts (idi->get_source_points()); std::vector<Number> &src_vals (idi->get_source_vals()); std::vector<std::string> field_vars; field_vars.push_back(_to_var_name); idi->set_field_variables(field_vars); std::vector<std::string> vars; vars.push_back(_to_var_name); for (unsigned int i=0; i<_multi_app->numGlobalApps(); i++) { if (!_multi_app->hasLocalApp(i)) continue; MPI_Comm swapped = Moose::swapLibMeshComm(_multi_app->comm()); FEProblem & from_problem = *_multi_app->appProblem(i); MooseVariable & from_var = from_problem.getVariable(0, _from_var_name); SystemBase & from_system_base = from_var.sys(); System & from_sys = from_system_base.system(); unsigned int from_sys_num = from_sys.number(); unsigned int from_var_num = from_sys.variable_number(from_var.name()); bool from_is_nodal = from_sys.variable_type(from_var_num).family == LAGRANGE; // EquationSystems & from_es = from_sys.get_equation_systems(); NumericVector<Number> & from_solution = *from_sys.solution; MeshBase * from_mesh = NULL; if (_displaced_source_mesh && from_problem.getDisplacedProblem()) from_mesh = &from_problem.getDisplacedProblem()->mesh().getMesh(); else from_mesh = &from_problem.mesh().getMesh(); Point app_position = _multi_app->position(i); if (from_is_nodal) { MeshBase::const_node_iterator from_nodes_it = from_mesh->local_nodes_begin(); MeshBase::const_node_iterator from_nodes_end = from_mesh->local_nodes_end(); for (; from_nodes_it != from_nodes_end; ++from_nodes_it) { Node * from_node = *from_nodes_it; // Assuming LAGRANGE! dof_id_type from_dof = from_node->dof_number(from_sys_num, from_var_num, 0); src_pts.push_back(*from_node+app_position); src_vals.push_back(from_solution(from_dof)); } } else { MeshBase::const_element_iterator from_elements_it = from_mesh->local_elements_begin(); MeshBase::const_element_iterator from_elements_end = from_mesh->local_elements_end(); for (; from_elements_it != from_elements_end; ++from_elements_it) { Elem * from_element = *from_elements_it; // Assuming LAGRANGE! dof_id_type from_dof = from_element->dof_number(from_sys_num, from_var_num, 0); src_pts.push_back(from_element->centroid()+app_position); src_vals.push_back(from_solution(from_dof)); } } Moose::swapLibMeshComm(swapped); } // We have only set local values - prepare for use by gathering remote gata idi->prepare_for_use(); // Now do the interpolation to the target system if (is_nodal) { MeshBase::const_node_iterator node_it = to_mesh->local_nodes_begin(); MeshBase::const_node_iterator node_end = to_mesh->local_nodes_end(); for (; node_it != node_end; ++node_it) { Node * node = *node_it; if (node->n_dofs(to_sys_num, to_var_num) > 0) // If this variable has dofs at this node { std::vector<Point> pts; std::vector<Number> vals; pts.push_back(*node); vals.resize(1); idi->interpolate_field_data(vars, pts, vals); Real value = vals.front(); // The zero only works for LAGRANGE! dof_id_type dof = node->dof_number(to_sys_num, to_var_num, 0); to_solution.set(dof, value); } } } else // Elemental { MeshBase::const_element_iterator elem_it = to_mesh->local_elements_begin(); MeshBase::const_element_iterator elem_end = to_mesh->local_elements_end(); for (; elem_it != elem_end; ++elem_it) { Elem * elem = *elem_it; Point centroid = elem->centroid(); if (elem->n_dofs(to_sys_num, to_var_num) > 0) // If this variable has dofs at this elem { std::vector<Point> pts; std::vector<Number> vals; pts.push_back(centroid); vals.resize(1); idi->interpolate_field_data(vars, pts, vals); Real value = vals.front(); dof_id_type dof = elem->dof_number(to_sys_num, to_var_num, 0); to_solution.set(dof, value); } } } to_solution.close(); to_sys.update(); delete idi; break; } } _console << "Finished InterpolationTransfer " << _name << std::endl; }
// Begin the main program. int main (int argc, char** argv) { // Initialize libMesh and any dependent libaries, like in example 2. LibMeshInit init (argc, argv); // Declare a performance log for the main program // PerfLog perf_main("Main Program"); // Create a GetPot object to parse the command line GetPot command_line (argc, argv); // Check for proper calling arguments. if (argc < 3) { // This handy function will print the file name, line number, // specified message, and then throw an exception. libmesh_error_msg("Usage:\n" << "\t " << argv[0] << " -d 2(3)" << " -n 15"); } // Brief message to the user regarding the program name // and command line arguments. else { std::cout << "Running " << argv[0]; for (int i=1; i<argc; i++) std::cout << " " << argv[i]; std::cout << std::endl << std::endl; } // Read problem dimension from command line. Use int // instead of unsigned since the GetPot overload is ambiguous // otherwise. int dim = 2; if ( command_line.search(1, "-d") ) dim = command_line.next(dim); // Skip higher-dimensional examples on a lower-dimensional libMesh build libmesh_example_requires(dim <= LIBMESH_DIM, "2D/3D support"); // Create a mesh with user-defined dimension on the default MPI // communicator. Mesh mesh (init.comm(), dim); // Read number of elements from command line int ps = 15; if ( command_line.search(1, "-n") ) ps = command_line.next(ps); // Read FE order from command line std::string order = "SECOND"; if ( command_line.search(2, "-Order", "-o") ) order = command_line.next(order); // Read FE Family from command line std::string family = "LAGRANGE"; if ( command_line.search(2, "-FEFamily", "-f") ) family = command_line.next(family); // Cannot use discontinuous basis. if ((family == "MONOMIAL") || (family == "XYZ")) { if (mesh.processor_id() == 0) libmesh_error_msg("This example requires a C^0 (or higher) FE basis."); } // Use the MeshTools::Generation mesh generator to create a uniform // grid on the square [-1,1]^D. We instruct the mesh generator // to build a mesh of 8x8 \p Quad9 elements in 2D, or \p Hex27 // elements in 3D. Building these higher-order elements allows // us to use higher-order approximation, as in example 3. Real halfwidth = dim > 1 ? 1. : 0.; Real halfheight = dim > 2 ? 1. : 0.; if ((family == "LAGRANGE") && (order == "FIRST")) { // No reason to use high-order geometric elements if we are // solving with low-order finite elements. MeshTools::Generation::build_cube (mesh, ps, (dim>1) ? ps : 0, (dim>2) ? ps : 0, -1., 1., -halfwidth, halfwidth, -halfheight, halfheight, (dim==1) ? EDGE2 : ((dim == 2) ? QUAD4 : HEX8)); } else { MeshTools::Generation::build_cube (mesh, ps, (dim>1) ? ps : 0, (dim>2) ? ps : 0, -1., 1., -halfwidth, halfwidth, -halfheight, halfheight, (dim==1) ? EDGE3 : ((dim == 2) ? QUAD9 : HEX27)); } { MeshBase::element_iterator el = mesh.elements_begin(); const MeshBase::element_iterator end_el = mesh.elements_end(); for ( ; el != end_el; ++el) { Elem* elem = *el; const Point cent = elem->centroid(); if (dim > 1) { if ((cent(0) > 0) == (cent(1) > 0)) elem->subdomain_id() = 1; } else { if (cent(0) > 0) elem->subdomain_id() = 1; } } } // Print information about the mesh to the screen. mesh.print_info(); // Create an equation systems object. EquationSystems equation_systems (mesh); // Declare the system and its variables. // Create a system named "Poisson" LinearImplicitSystem& system = equation_systems.add_system<LinearImplicitSystem> ("Poisson"); std::set<subdomain_id_type> active_subdomains; // Add the variable "u" to "Poisson". "u" // will be approximated using second-order approximation. active_subdomains.clear(); active_subdomains.insert(0); system.add_variable("u", Utility::string_to_enum<Order> (order), Utility::string_to_enum<FEFamily>(family), &active_subdomains); // Add the variable "v" to "Poisson". "v" // will be approximated using second-order approximation. active_subdomains.clear(); active_subdomains.insert(1); system.add_variable("v", Utility::string_to_enum<Order> (order), Utility::string_to_enum<FEFamily>(family), &active_subdomains); // Give the system a pointer to the matrix assembly // function. system.attach_assemble_function (assemble_poisson); // Initialize the data structures for the equation system. equation_systems.init(); // Print information about the system to the screen. equation_systems.print_info(); mesh.print_info(); // Solve the system "Poisson", just like example 2. equation_systems.get_system("Poisson").solve(); // After solving the system write the solution // to a GMV-formatted plot file. if(dim == 1) { GnuPlotIO plot(mesh,"Subdomains Example 2, 1D",GnuPlotIO::GRID_ON); plot.write_equation_systems("gnuplot_script",equation_systems); } else { #ifdef LIBMESH_HAVE_EXODUS_API ExodusII_IO (mesh).write_equation_systems ((dim == 3) ? "out_3.e" : "out_2.e",equation_systems); #endif // #ifdef LIBMESH_HAVE_EXODUS_API } // All done. return 0; }
void UnstructuredMesh::find_neighbors (const bool reset_remote_elements, const bool reset_current_list) { // We might actually want to run this on an empty mesh // (e.g. the boundary mesh for a nonexistant bcid!) // libmesh_assert_not_equal_to (this->n_nodes(), 0); // libmesh_assert_not_equal_to (this->n_elem(), 0); // This function must be run on all processors at once parallel_object_only(); LOG_SCOPE("find_neighbors()", "Mesh"); const element_iterator el_end = this->elements_end(); //TODO:[BSK] This should be removed later?! if (reset_current_list) for (element_iterator el = this->elements_begin(); el != el_end; ++el) { Elem * e = *el; for (unsigned int s=0; s<e->n_neighbors(); s++) if (e->neighbor_ptr(s) != remote_elem || reset_remote_elements) e->set_neighbor(s, libmesh_nullptr); } // Find neighboring elements by first finding elements // with identical side keys and then check to see if they // are neighbors { // data structures -- Use the hash_multimap if available typedef unsigned int key_type; typedef std::pair<Elem *, unsigned char> val_type; typedef std::pair<key_type, val_type> key_val_pair; typedef LIBMESH_BEST_UNORDERED_MULTIMAP<key_type, val_type> map_type; // A map from side keys to corresponding elements & side numbers map_type side_to_elem_map; for (element_iterator el = this->elements_begin(); el != el_end; ++el) { Elem * element = *el; for (unsigned char ms=0; ms<element->n_neighbors(); ms++) { next_side: // If we haven't yet found a neighbor on this side, try. // Even if we think our neighbor is remote, that // information may be out of date. if (element->neighbor_ptr(ms) == libmesh_nullptr || element->neighbor_ptr(ms) == remote_elem) { // Get the key for the side of this element const unsigned int key = element->key(ms); // Look for elements that have an identical side key std::pair <map_type::iterator, map_type::iterator> bounds = side_to_elem_map.equal_range(key); // May be multiple keys, check all the possible // elements which _might_ be neighbors. if (bounds.first != bounds.second) { // Get the side for this element const UniquePtr<Elem> my_side(element->side_ptr(ms)); // Look at all the entries with an equivalent key while (bounds.first != bounds.second) { // Get the potential element Elem * neighbor = bounds.first->second.first; // Get the side for the neighboring element const unsigned int ns = bounds.first->second.second; const UniquePtr<Elem> their_side(neighbor->side_ptr(ns)); //libmesh_assert(my_side.get()); //libmesh_assert(their_side.get()); // If found a match with my side // // We need special tests here for 1D: // since parents and children have an equal // side (i.e. a node), we need to check // ns != ms, and we also check level() to // avoid setting our neighbor pointer to // any of our neighbor's descendants if( (*my_side == *their_side) && (element->level() == neighbor->level()) && ((element->dim() != 1) || (ns != ms)) ) { // So share a side. Is this a mixed pair // of subactive and active/ancestor // elements? // If not, then we're neighbors. // If so, then the subactive's neighbor is if (element->subactive() == neighbor->subactive()) { // an element is only subactive if it has // been coarsened but not deleted element->set_neighbor (ms,neighbor); neighbor->set_neighbor(ns,element); } else if (element->subactive()) { element->set_neighbor(ms,neighbor); } else if (neighbor->subactive()) { neighbor->set_neighbor(ns,element); } side_to_elem_map.erase (bounds.first); // get out of this nested crap goto next_side; } ++bounds.first; } } // didn't find a match... // Build the map entry for this element key_val_pair kvp; kvp.first = key; kvp.second.first = element; kvp.second.second = ms; // use the lower bound as a hint for // where to put it. #if defined(LIBMESH_HAVE_UNORDERED_MAP) || defined(LIBMESH_HAVE_TR1_UNORDERED_MAP) || defined(LIBMESH_HAVE_HASH_MAP) || defined(LIBMESH_HAVE_EXT_HASH_MAP) side_to_elem_map.insert (kvp); #else side_to_elem_map.insert (bounds.first,kvp); #endif } } } } #ifdef LIBMESH_ENABLE_AMR /** * Here we look at all of the child elements which * don't already have valid neighbors. * * If a child element has a NULL neighbor it is * either because it is on the boundary or because * its neighbor is at a different level. In the * latter case we must get the neighbor from the * parent. * * If a child element has a remote_elem neighbor * on a boundary it shares with its parent, that * info may have become out-dated through coarsening * of the neighbor's parent. In this case, if the * parent's neighbor is active then the child should * share it. * * Furthermore, that neighbor better be active, * otherwise we missed a child somewhere. * * * We also need to look through children ordered by increasing * refinement level in order to add new interior_parent() links in * boundary elements which have just been generated by refinement, * and fix links in boundary elements whose previous * interior_parent() has just been coarsened away. */ const unsigned int n_levels = MeshTools::n_levels(*this); for (unsigned int level = 1; level < n_levels; ++level) { element_iterator end = this->level_elements_end(level); for (element_iterator el = this->level_elements_begin(level); el != end; ++el) { Elem * current_elem = *el; libmesh_assert(current_elem); Elem * parent = current_elem->parent(); libmesh_assert(parent); const unsigned int my_child_num = parent->which_child_am_i(current_elem); for (unsigned int s=0; s < current_elem->n_neighbors(); s++) { if (current_elem->neighbor_ptr(s) == libmesh_nullptr || (current_elem->neighbor_ptr(s) == remote_elem && parent->is_child_on_side(my_child_num, s))) { Elem * neigh = parent->neighbor_ptr(s); // If neigh was refined and had non-subactive children // made remote earlier, then a non-subactive elem should // actually have one of those remote children as a // neighbor if (neigh && (neigh->ancestor()) && (!current_elem->subactive())) { #ifdef DEBUG // Let's make sure that "had children made remote" // situation is actually the case libmesh_assert(neigh->has_children()); bool neigh_has_remote_children = false; for (unsigned int c = 0; c != neigh->n_children(); ++c) { if (neigh->child_ptr(c) == remote_elem) neigh_has_remote_children = true; } libmesh_assert(neigh_has_remote_children); // And let's double-check that we don't have // a remote_elem neighboring a local element libmesh_assert_not_equal_to (current_elem->processor_id(), this->processor_id()); #endif // DEBUG neigh = const_cast<RemoteElem *>(remote_elem); } if (!current_elem->subactive()) current_elem->set_neighbor(s, neigh); #ifdef DEBUG if (neigh != libmesh_nullptr && neigh != remote_elem) // We ignore subactive elements here because // we don't care about neighbors of subactive element. if ((!neigh->active()) && (!current_elem->subactive())) { libMesh::err << "On processor " << this->processor_id() << std::endl; libMesh::err << "Bad element ID = " << current_elem->id() << ", Side " << s << ", Bad neighbor ID = " << neigh->id() << std::endl; libMesh::err << "Bad element proc_ID = " << current_elem->processor_id() << ", Bad neighbor proc_ID = " << neigh->processor_id() << std::endl; libMesh::err << "Bad element size = " << current_elem->hmin() << ", Bad neighbor size = " << neigh->hmin() << std::endl; libMesh::err << "Bad element center = " << current_elem->centroid() << ", Bad neighbor center = " << neigh->centroid() << std::endl; libMesh::err << "ERROR: " << (current_elem->active()?"Active":"Ancestor") << " Element at level " << current_elem->level() << std::endl; libMesh::err << "with " << (parent->active()?"active": (parent->subactive()?"subactive":"ancestor")) << " parent share " << (neigh->subactive()?"subactive":"ancestor") << " neighbor at level " << neigh->level() << std::endl; NameBasedIO(*this).write ("bad_mesh.gmv"); libmesh_error_msg("Problematic mesh written to bad_mesh.gmv."); } #endif // DEBUG } } // We can skip to the next element if we're full-dimension // and therefore don't have any interior parents if (current_elem->dim() >= LIBMESH_DIM) continue; // We have no interior parents unless we can find one later current_elem->set_interior_parent(libmesh_nullptr); Elem * pip = parent->interior_parent(); if (!pip) continue; // If there's no interior_parent children, whether due to a // remote element or a non-conformity, then there's no // children to search. if (pip == remote_elem || pip->active()) { current_elem->set_interior_parent(pip); continue; } // For node comparisons we'll need a sensible tolerance Real node_tolerance = current_elem->hmin() * TOLERANCE; // Otherwise our interior_parent should be a child of our // parent's interior_parent. for (unsigned int c=0; c != pip->n_children(); ++c) { Elem * child = pip->child_ptr(c); // If we have a remote_elem, that might be our // interior_parent. We'll set it provisionally now and // keep trying to find something better. if (child == remote_elem) { current_elem->set_interior_parent (const_cast<RemoteElem *>(remote_elem)); continue; } bool child_contains_our_nodes = true; for (unsigned int n=0; n != current_elem->n_nodes(); ++n) { bool child_contains_this_node = false; for (unsigned int cn=0; cn != child->n_nodes(); ++cn) if (child->point(cn).absolute_fuzzy_equals (current_elem->point(n), node_tolerance)) { child_contains_this_node = true; break; } if (!child_contains_this_node) { child_contains_our_nodes = false; break; } } if (child_contains_our_nodes) { current_elem->set_interior_parent(child); break; } } // We should have found *some* interior_parent at this // point, whether semilocal or remote. libmesh_assert(current_elem->interior_parent()); } } #endif // AMR #ifdef DEBUG MeshTools::libmesh_assert_valid_neighbors(*this, !reset_remote_elements); MeshTools::libmesh_assert_valid_amr_interior_parents(*this); #endif }
void MultiAppNearestNodeTransfer::execute() { _console << "Beginning NearestNodeTransfer " << name() << std::endl; getAppInfo(); // Get the bounding boxes for the "from" domains. std::vector<MeshTools::BoundingBox> bboxes = getFromBoundingBoxes(); // Figure out how many "from" domains each processor owns. std::vector<unsigned int> froms_per_proc = getFromsPerProc(); //////////////////// // For every point in the local "to" domain, figure out which "from" domains // might contain it's nearest neighbor, and send that point to the processors // that own those "from" domains. // // How do we know which "from" domains might contain the nearest neighbor, you // ask? Well, consider two "from" domains, A and B. If every point in A is // closer than every point in B, then we know that B cannot possibly contain // the nearest neighbor. Hence, we'll only check A for the nearest neighbor. // We'll use the functions bboxMaxDistance and bboxMinDistance to figure out // if every point in A is closer than every point in B. //////////////////// // outgoing_qps = nodes/centroids we'll send to other processors. std::vector<std::vector<Point> > outgoing_qps(n_processors()); // When we get results back, node_index_map will tell us which results go with // which points std::vector<std::map<std::pair<unsigned int, unsigned int>, unsigned int> > node_index_map(n_processors()); if (! _neighbors_cached) { for (unsigned int i_to = 0; i_to < _to_problems.size(); i_to++) { System * to_sys = find_sys(*_to_es[i_to], _to_var_name); unsigned int sys_num = to_sys->number(); unsigned int var_num = to_sys->variable_number(_to_var_name); MeshBase * to_mesh = & _to_meshes[i_to]->getMesh(); bool is_nodal = to_sys->variable_type(var_num).family == LAGRANGE; if (is_nodal) { std::vector<Node *> target_local_nodes; if (isParamValid("target_boundary")) { BoundaryID target_bnd_id = _to_meshes[i_to]->getBoundaryID(getParam<BoundaryName>("target_boundary")); ConstBndNodeRange & bnd_nodes = *(_to_meshes[i_to])->getBoundaryNodeRange(); for (const auto & bnode : bnd_nodes) if (bnode->_bnd_id == target_bnd_id && bnode->_node->processor_id() == processor_id()) target_local_nodes.push_back(bnode->_node); } else { target_local_nodes.resize(to_mesh->n_local_nodes()); MeshBase::const_node_iterator nodes_begin = to_mesh->local_nodes_begin(); MeshBase::const_node_iterator nodes_end = to_mesh->local_nodes_end(); unsigned int i = 0; for (MeshBase::const_node_iterator nodes_it = nodes_begin; nodes_it != nodes_end; ++nodes_it, ++i) target_local_nodes[i] = *nodes_it; } for (const auto & node : target_local_nodes) { // Skip this node if the variable has no dofs at it. if (node->n_dofs(sys_num, var_num) < 1) continue; // Find which bboxes might have the nearest node to this point. Real nearest_max_distance = std::numeric_limits<Real>::max(); for (const auto & bbox : bboxes) { Real distance = bboxMaxDistance(*node, bbox); if (distance < nearest_max_distance) nearest_max_distance = distance; } unsigned int from0 = 0; for (processor_id_type i_proc = 0; i_proc < n_processors(); from0 += froms_per_proc[i_proc], i_proc++) { bool qp_found = false; for (unsigned int i_from = from0; i_from < from0 + froms_per_proc[i_proc] && ! qp_found; i_from++) { Real distance = bboxMinDistance(*node, bboxes[i_from]); if (distance < nearest_max_distance || bboxes[i_from].contains_point(*node)) { std::pair<unsigned int, unsigned int> key(i_to, node->id()); node_index_map[i_proc][key] = outgoing_qps[i_proc].size(); outgoing_qps[i_proc].push_back(*node + _to_positions[i_to]); qp_found = true; } } } } } else // Elemental { MeshBase::const_element_iterator elem_it = to_mesh->local_elements_begin(); MeshBase::const_element_iterator elem_end = to_mesh->local_elements_end(); for (; elem_it != elem_end; ++elem_it) { Elem * elem = *elem_it; Point centroid = elem->centroid(); // Skip this element if the variable has no dofs at it. if (elem->n_dofs(sys_num, var_num) < 1) continue; // Find which bboxes might have the nearest node to this point. Real nearest_max_distance = std::numeric_limits<Real>::max(); for (const auto & bbox : bboxes) { Real distance = bboxMaxDistance(centroid, bbox); if (distance < nearest_max_distance) nearest_max_distance = distance; } unsigned int from0 = 0; for (processor_id_type i_proc = 0; i_proc < n_processors(); from0 += froms_per_proc[i_proc], i_proc++) { bool qp_found = false; for (unsigned int i_from = from0; i_from < from0 + froms_per_proc[i_proc] && ! qp_found; i_from++) { Real distance = bboxMinDistance(centroid, bboxes[i_from]); if (distance < nearest_max_distance || bboxes[i_from].contains_point(centroid)) { std::pair<unsigned int, unsigned int> key(i_to, elem->id()); node_index_map[i_proc][key] = outgoing_qps[i_proc].size(); outgoing_qps[i_proc].push_back(centroid + _to_positions[i_to]); qp_found = true; } } } } } } } //////////////////// // Send local node/centroid positions off to the other processors and take // care of points sent to this processor. We'll need to check the points // against all of the "from" domains that this processor owns. For each // point, we'll find the nearest node, then we'll send the value at that node // and the distance between the node and the point back to the processor that // requested that point. //////////////////// std::vector<std::vector<Real> > incoming_evals(n_processors()); std::vector<Parallel::Request> send_qps(n_processors()); std::vector<Parallel::Request> send_evals(n_processors()); if (! _neighbors_cached) { for (processor_id_type i_proc = 0; i_proc < n_processors(); i_proc++) { if (i_proc == processor_id()) continue; _communicator.send(i_proc, outgoing_qps[i_proc], send_qps[i_proc]); } // Build an array of pointers to all of this processor's local nodes. We // need to do this to avoid the expense of using LibMesh iterators. This // step also takes care of limiting the search to boundary nodes, if // applicable. std::vector< std::vector<Node *> > local_nodes(froms_per_proc[processor_id()]); for (unsigned int i = 0; i < froms_per_proc[processor_id()]; i++) { getLocalNodes(_from_meshes[i], local_nodes[i]); } if (_fixed_meshes) { _cached_froms.resize(n_processors()); _cached_dof_ids.resize(n_processors()); } for (processor_id_type i_proc = 0; i_proc < n_processors(); i_proc++) { std::vector<Point> incoming_qps; if (i_proc == processor_id()) incoming_qps = outgoing_qps[i_proc]; else _communicator.receive(i_proc, incoming_qps); if (_fixed_meshes) { _cached_froms[i_proc].resize(incoming_qps.size()); _cached_dof_ids[i_proc].resize(incoming_qps.size()); } std::vector<Real> outgoing_evals(2 * incoming_qps.size()); for (unsigned int qp = 0; qp < incoming_qps.size(); qp++) { Point qpt = incoming_qps[qp]; outgoing_evals[2*qp] = std::numeric_limits<Real>::max(); for (unsigned int i_local_from = 0; i_local_from < froms_per_proc[processor_id()]; i_local_from++) { MooseVariable & from_var = _from_problems[i_local_from]->getVariable(0, _from_var_name); System & from_sys = from_var.sys().system(); unsigned int from_sys_num = from_sys.number(); unsigned int from_var_num = from_sys.variable_number(from_var.name()); for (unsigned int i_node = 0; i_node < local_nodes[i_local_from].size(); i_node++) { Real current_distance = (qpt - *(local_nodes[i_local_from][i_node]) - _from_positions[i_local_from]).norm(); if (current_distance < outgoing_evals[2*qp]) { // Assuming LAGRANGE! if (local_nodes[i_local_from][i_node]->n_dofs(from_sys_num, from_var_num) > 0) { dof_id_type from_dof = local_nodes[i_local_from][i_node]->dof_number(from_sys_num, from_var_num, 0); outgoing_evals[2*qp] = current_distance; outgoing_evals[2*qp + 1] = (*from_sys.solution)(from_dof); if (_fixed_meshes) { // Cache the nearest nodes. _cached_froms[i_proc][qp] = i_local_from; _cached_dof_ids[i_proc][qp] = from_dof; } } } } } } if (i_proc == processor_id()) incoming_evals[i_proc] = outgoing_evals; else _communicator.send(i_proc, outgoing_evals, send_evals[i_proc]); } } else // We've cached the nearest nodes. { for (processor_id_type i_proc = 0; i_proc < n_processors(); i_proc++) { std::vector<Real> outgoing_evals(_cached_froms[i_proc].size()); for (unsigned int qp = 0; qp < outgoing_evals.size(); qp++) { MooseVariable & from_var = _from_problems[_cached_froms[i_proc][qp]]->getVariable(0, _from_var_name); System & from_sys = from_var.sys().system(); dof_id_type from_dof = _cached_dof_ids[i_proc][qp]; //outgoing_evals[qp] = (*from_sys.solution)(_cached_dof_ids[i_proc][qp]); outgoing_evals[qp] = (*from_sys.solution)(from_dof); } if (i_proc == processor_id()) incoming_evals[i_proc] = outgoing_evals; else _communicator.send(i_proc, outgoing_evals, send_evals[i_proc]); } } //////////////////// // Gather all of the evaluations, find the nearest one for each node/element, // and apply the values. //////////////////// for (processor_id_type i_proc = 0; i_proc < n_processors(); i_proc++) { if (i_proc == processor_id()) continue; _communicator.receive(i_proc, incoming_evals[i_proc]); } for (unsigned int i_to = 0; i_to < _to_problems.size(); i_to++) { // Loop over the master nodes and set the value of the variable System * to_sys = find_sys(*_to_es[i_to], _to_var_name); unsigned int sys_num = to_sys->number(); unsigned int var_num = to_sys->variable_number(_to_var_name); NumericVector<Real> * solution = nullptr; switch (_direction) { case TO_MULTIAPP: solution = & getTransferVector(i_to, _to_var_name); break; case FROM_MULTIAPP: solution = to_sys->solution.get(); break; } MeshBase * to_mesh = & _to_meshes[i_to]->getMesh(); bool is_nodal = to_sys->variable_type(var_num).family == LAGRANGE; if (is_nodal) { std::vector<Node *> target_local_nodes; if (isParamValid("target_boundary")) { BoundaryID target_bnd_id = _to_meshes[i_to]->getBoundaryID(getParam<BoundaryName>("target_boundary")); ConstBndNodeRange & bnd_nodes = *(_to_meshes[i_to])->getBoundaryNodeRange(); for (const auto & bnode : bnd_nodes) if (bnode->_bnd_id == target_bnd_id && bnode->_node->processor_id() == processor_id()) target_local_nodes.push_back(bnode->_node); } else { target_local_nodes.resize(to_mesh->n_local_nodes()); MeshBase::const_node_iterator nodes_begin = to_mesh->local_nodes_begin(); MeshBase::const_node_iterator nodes_end = to_mesh->local_nodes_end(); unsigned int i = 0; for (MeshBase::const_node_iterator nodes_it = nodes_begin; nodes_it != nodes_end; ++nodes_it, ++i) target_local_nodes[i] = *nodes_it; } for (const auto & node : target_local_nodes) { // Skip this node if the variable has no dofs at it. if (node->n_dofs(sys_num, var_num) < 1) continue; Real best_val = 0; if (! _neighbors_cached) { Real min_dist = std::numeric_limits<Real>::max(); for (unsigned int i_from = 0; i_from < incoming_evals.size(); i_from++) { std::pair<unsigned int, unsigned int> key(i_to, node->id()); if (node_index_map[i_from].find(key) == node_index_map[i_from].end()) continue; unsigned int qp_ind = node_index_map[i_from][key]; if (incoming_evals[i_from][2*qp_ind] >= min_dist) continue; min_dist = incoming_evals[i_from][2*qp_ind]; best_val = incoming_evals[i_from][2*qp_ind + 1]; if (_fixed_meshes) { // Cache these indices. _cached_from_inds[node->id()] = i_from; _cached_qp_inds[node->id()] = qp_ind; } } } else { best_val = incoming_evals[_cached_from_inds[node->id()]][_cached_qp_inds[node->id()]]; } dof_id_type dof = node->dof_number(sys_num, var_num, 0); solution->set(dof, best_val); } } else // Elemental { MeshBase::const_element_iterator elem_it = to_mesh->local_elements_begin(); MeshBase::const_element_iterator elem_end = to_mesh->local_elements_end(); for (; elem_it != elem_end; ++elem_it) { Elem * elem = *elem_it; // Skip this element if the variable has no dofs at it. if (elem->n_dofs(sys_num, var_num) < 1) continue; Real best_val = 0; if (! _neighbors_cached) { Real min_dist = std::numeric_limits<Real>::max(); for (unsigned int i_from = 0; i_from < incoming_evals.size(); i_from++) { std::pair<unsigned int, unsigned int> key(i_to, elem->id()); if (node_index_map[i_from].find(key) == node_index_map[i_from].end()) continue; unsigned int qp_ind = node_index_map[i_from][key]; if (incoming_evals[i_from][2*qp_ind] >= min_dist) continue; min_dist = incoming_evals[i_from][2*qp_ind]; best_val = incoming_evals[i_from][2*qp_ind + 1]; if (_fixed_meshes) { // Cache these indices. _cached_from_inds[elem->id()] = i_from; _cached_qp_inds[elem->id()] = qp_ind; } } } else { best_val = incoming_evals[_cached_from_inds[elem->id()]][_cached_qp_inds[elem->id()]]; } dof_id_type dof = elem->dof_number(sys_num, var_num, 0); solution->set(dof, best_val); } } solution->close(); to_sys->update(); } if (_fixed_meshes) _neighbors_cached = true; // Make sure all our sends succeeded. for (processor_id_type i_proc = 0; i_proc < n_processors(); i_proc++) { if (i_proc == processor_id()) continue; send_qps[i_proc].wait(); send_evals[i_proc].wait(); } _console << "Finished NearestNodeTransfer " << name() << std::endl; }
void MultiAppNearestNodeTransfer::execute() { Moose::out << "Beginning NearestNodeTransfer " << _name << std::endl; switch(_direction) { case TO_MULTIAPP: { FEProblem & from_problem = *_multi_app->problem(); MooseVariable & from_var = from_problem.getVariable(0, _from_var_name); MeshBase * from_mesh = NULL; if (_displaced_source_mesh && from_problem.getDisplacedProblem()) { mooseError("Cannot use a NearestNode transfer from a displaced mesh to a MultiApp!"); from_mesh = &from_problem.getDisplacedProblem()->mesh().getMesh(); } else from_mesh = &from_problem.mesh().getMesh(); SystemBase & from_system_base = from_var.sys(); System & from_sys = from_system_base.system(); unsigned int from_sys_num = from_sys.number(); // Only works with a serialized mesh to transfer from! mooseAssert(from_sys.get_mesh().is_serial(), "MultiAppNearestNodeTransfer only works with SerialMesh!"); unsigned int from_var_num = from_sys.variable_number(from_var.name()); // EquationSystems & from_es = from_sys.get_equation_systems(); //Create a serialized version of the solution vector NumericVector<Number> * serialized_solution = NumericVector<Number>::build().release(); serialized_solution->init(from_sys.n_dofs(), false, SERIAL); // Need to pull down a full copy of this vector on every processor so we can get values in parallel from_sys.solution->localize(*serialized_solution); for(unsigned int i=0; i<_multi_app->numGlobalApps(); i++) { if (_multi_app->hasLocalApp(i)) { MPI_Comm swapped = Moose::swapLibMeshComm(_multi_app->comm()); // Loop over the master nodes and set the value of the variable System * to_sys = find_sys(_multi_app->appProblem(i)->es(), _to_var_name); if (!to_sys) mooseError("Cannot find variable "<<_to_var_name<<" for "<<_name<<" Transfer"); unsigned int sys_num = to_sys->number(); unsigned int var_num = to_sys->variable_number(_to_var_name); NumericVector<Real> & solution = _multi_app->appTransferVector(i, _to_var_name); MeshBase * mesh = NULL; if (_displaced_target_mesh && _multi_app->appProblem(i)->getDisplacedProblem()) mesh = &_multi_app->appProblem(i)->getDisplacedProblem()->mesh().getMesh(); else mesh = &_multi_app->appProblem(i)->mesh().getMesh(); bool is_nodal = to_sys->variable_type(var_num).family == LAGRANGE; if (is_nodal) { MeshBase::const_node_iterator node_it = mesh->local_nodes_begin(); MeshBase::const_node_iterator node_end = mesh->local_nodes_end(); for(; node_it != node_end; ++node_it) { Node * node = *node_it; Point actual_position = *node+_multi_app->position(i); if (node->n_dofs(sys_num, var_num) > 0) // If this variable has dofs at this node { // The zero only works for LAGRANGE! dof_id_type dof = node->dof_number(sys_num, var_num, 0); // Swap back Moose::swapLibMeshComm(swapped); Real distance = 0; // Just to satisfy the last argument MeshBase::const_node_iterator from_nodes_begin = from_mesh->nodes_begin(); MeshBase::const_node_iterator from_nodes_end = from_mesh->nodes_end(); Node * nearest_node = NULL; if (_fixed_meshes) { if (_node_map.find(node->id()) == _node_map.end()) // Haven't cached it yet { nearest_node = getNearestNode(actual_position, distance, from_nodes_begin, from_nodes_end); _node_map[node->id()] = nearest_node; _distance_map[node->id()] = distance; } else { nearest_node = _node_map[node->id()]; //distance = _distance_map[node->id()]; } } else nearest_node = getNearestNode(actual_position, distance, from_nodes_begin, from_nodes_end); // Assuming LAGRANGE! dof_id_type from_dof = nearest_node->dof_number(from_sys_num, from_var_num, 0); Real from_value = (*serialized_solution)(from_dof); // Swap again swapped = Moose::swapLibMeshComm(_multi_app->comm()); solution.set(dof, from_value); } } } else // Elemental { MeshBase::const_element_iterator elem_it = mesh->local_elements_begin(); MeshBase::const_element_iterator elem_end = mesh->local_elements_end(); for(; elem_it != elem_end; ++elem_it) { Elem * elem = *elem_it; Point centroid = elem->centroid(); Point actual_position = centroid+_multi_app->position(i); if (elem->n_dofs(sys_num, var_num) > 0) // If this variable has dofs at this elem { // The zero only works for LAGRANGE! dof_id_type dof = elem->dof_number(sys_num, var_num, 0); // Swap back Moose::swapLibMeshComm(swapped); Real distance = 0; // Just to satisfy the last argument MeshBase::const_node_iterator from_nodes_begin = from_mesh->nodes_begin(); MeshBase::const_node_iterator from_nodes_end = from_mesh->nodes_end(); Node * nearest_node = NULL; if (_fixed_meshes) { if (_node_map.find(elem->id()) == _node_map.end()) // Haven't cached it yet { nearest_node = getNearestNode(actual_position, distance, from_nodes_begin, from_nodes_end); _node_map[elem->id()] = nearest_node; _distance_map[elem->id()] = distance; } else { nearest_node = _node_map[elem->id()]; //distance = _distance_map[elem->id()]; } } else nearest_node = getNearestNode(actual_position, distance, from_nodes_begin, from_nodes_end); // Assuming LAGRANGE! dof_id_type from_dof = nearest_node->dof_number(from_sys_num, from_var_num, 0); Real from_value = (*serialized_solution)(from_dof); // Swap again swapped = Moose::swapLibMeshComm(_multi_app->comm()); solution.set(dof, from_value); } } } solution.close(); to_sys->update(); // Swap back Moose::swapLibMeshComm(swapped); } } delete serialized_solution; break; } case FROM_MULTIAPP: { FEProblem & to_problem = *_multi_app->problem(); MooseVariable & to_var = to_problem.getVariable(0, _to_var_name); SystemBase & to_system_base = to_var.sys(); System & to_sys = to_system_base.system(); NumericVector<Real> & to_solution = *to_sys.solution; unsigned int to_sys_num = to_sys.number(); // Only works with a serialized mesh to transfer to! mooseAssert(to_sys.get_mesh().is_serial(), "MultiAppNearestNodeTransfer only works with SerialMesh!"); unsigned int to_var_num = to_sys.variable_number(to_var.name()); // EquationSystems & to_es = to_sys.get_equation_systems(); MeshBase * to_mesh = NULL; if (_displaced_target_mesh && to_problem.getDisplacedProblem()) to_mesh = &to_problem.getDisplacedProblem()->mesh().getMesh(); else to_mesh = &to_problem.mesh().getMesh(); bool is_nodal = to_sys.variable_type(to_var_num) == FEType(); dof_id_type n_nodes = to_mesh->n_nodes(); dof_id_type n_elems = to_mesh->n_elem(); ///// All of the following are indexed off to_node->id() or to_elem->id() ///// // Minimum distances from each node in the "to" mesh to a node in std::vector<Real> min_distances; // The node ids in the "from" mesh that this processor has found to be the minimum distances to the "to" nodes std::vector<dof_id_type> min_nodes; // After the call to maxloc() this will tell us which processor actually has the minimum std::vector<unsigned int> min_procs; // The global multiapp ID that this processor found had the minimum distance node in it. std::vector<unsigned int> min_apps; if (is_nodal) { min_distances.resize(n_nodes, std::numeric_limits<Real>::max()); min_nodes.resize(n_nodes); min_procs.resize(n_nodes); min_apps.resize(n_nodes); } else { min_distances.resize(n_elems, std::numeric_limits<Real>::max()); min_nodes.resize(n_elems); min_procs.resize(n_elems); min_apps.resize(n_elems); } for(unsigned int i=0; i<_multi_app->numGlobalApps(); i++) { if (!_multi_app->hasLocalApp(i)) continue; MPI_Comm swapped = Moose::swapLibMeshComm(_multi_app->comm()); FEProblem & from_problem = *_multi_app->appProblem(i); MooseVariable & from_var = from_problem.getVariable(0, _from_var_name); SystemBase & from_system_base = from_var.sys(); System & from_sys = from_system_base.system(); // Only works with a serialized mesh to transfer from! mooseAssert(from_sys.get_mesh().is_serial(), "MultiAppNearestNodeTransfer only works with SerialMesh!"); // unsigned int from_var_num = from_sys.variable_number(from_var.name()); // EquationSystems & from_es = from_sys.get_equation_systems(); MeshBase * from_mesh = NULL; if (_displaced_source_mesh && from_problem.getDisplacedProblem()) from_mesh = &from_problem.getDisplacedProblem()->mesh().getMesh(); else from_mesh = &from_problem.mesh().getMesh(); MeshTools::BoundingBox app_box = MeshTools::processor_bounding_box(*from_mesh, libMesh::processor_id()); Point app_position = _multi_app->position(i); Moose::swapLibMeshComm(swapped); if (is_nodal) { MeshBase::const_node_iterator to_node_it = to_mesh->nodes_begin(); MeshBase::const_node_iterator to_node_end = to_mesh->nodes_end(); for(; to_node_it != to_node_end; ++to_node_it) { Node * to_node = *to_node_it; unsigned int to_node_id = to_node->id(); Real current_distance = 0; MPI_Comm swapped = Moose::swapLibMeshComm(_multi_app->comm()); MeshBase::const_node_iterator from_nodes_begin = from_mesh->local_nodes_begin(); MeshBase::const_node_iterator from_nodes_end = from_mesh->local_nodes_end(); Node * nearest_node = NULL; if (_fixed_meshes) { if (_node_map.find(to_node->id()) == _node_map.end()) // Haven't cached it yet { nearest_node = getNearestNode(*to_node-app_position, current_distance, from_nodes_begin, from_nodes_end); _node_map[to_node->id()] = nearest_node; _distance_map[to_node->id()] = current_distance; } else { nearest_node = _node_map[to_node->id()]; current_distance = _distance_map[to_node->id()]; } } else nearest_node = getNearestNode(*to_node-app_position, current_distance, from_nodes_begin, from_nodes_end); Moose::swapLibMeshComm(swapped); // TODO: Logic bug when we are using caching. "current_distance" is set by a call to getNearestNode which is // skipped in that case. We shouldn't be relying on it or stuffing it in another data structure if (current_distance < min_distances[to_node->id()]) { min_distances[to_node_id] = current_distance; min_nodes[to_node_id] = nearest_node->id(); min_apps[to_node_id] = i; } } } else // Elemental { MeshBase::const_element_iterator to_elem_it = to_mesh->elements_begin(); MeshBase::const_element_iterator to_elem_end = to_mesh->elements_end(); for(; to_elem_it != to_elem_end; ++to_elem_it) { Elem * to_elem = *to_elem_it; unsigned int to_elem_id = to_elem->id(); Point actual_position = to_elem->centroid()-app_position; Real current_distance = 0; MPI_Comm swapped = Moose::swapLibMeshComm(_multi_app->comm()); MeshBase::const_node_iterator from_nodes_begin = from_mesh->local_nodes_begin(); MeshBase::const_node_iterator from_nodes_end = from_mesh->local_nodes_end(); Node * nearest_node = NULL; if (_fixed_meshes) { if (_node_map.find(to_elem->id()) == _node_map.end()) // Haven't cached it yet { nearest_node = getNearestNode(actual_position, current_distance, from_nodes_begin, from_nodes_end); _node_map[to_elem->id()] = nearest_node; _distance_map[to_elem->id()] = current_distance; } else { nearest_node = _node_map[to_elem->id()]; current_distance = _distance_map[to_elem->id()]; } } else nearest_node = getNearestNode(actual_position, current_distance, from_nodes_begin, from_nodes_end); Moose::swapLibMeshComm(swapped); // TODO: Logic bug when we are using caching. "current_distance" is set by a call to getNearestNode which is // skipped in that case. We shouldn't be relying on it or stuffing it in another data structure if (current_distance < min_distances[to_elem->id()]) { min_distances[to_elem_id] = current_distance; min_nodes[to_elem_id] = nearest_node->id(); min_apps[to_elem_id] = i; } } } } /* // We're going to need serialized solution vectors for each app // We could try to only do it for the apps that have mins in them... // but it's tough because this is a collective operation... so that would have to be coordinated std::vector<NumericVector<Number> *> serialized_from_solutions(_multi_app->numGlobalApps()); if (_multi_app->hasApp()) { // Swap MPI_Comm swapped = Moose::swapLibMeshComm(_multi_app->comm()); for(unsigned int i=0; i<_multi_app->numGlobalApps(); i++) { if (!_multi_app->hasLocalApp(i)) continue; FEProblem & from_problem = *_multi_app->appProblem(i); MooseVariable & from_var = from_problem.getVariable(0, _from_var_name); SystemBase & from_system_base = from_var.sys(); System & from_sys = from_system_base.system(); //Create a serialized version of the solution vector serialized_from_solutions[i] = NumericVector<Number>::build().release(); serialized_from_solutions[i]->init(from_sys.n_dofs(), false, SERIAL); // Need to pull down a full copy of this vector on every processor so we can get values in parallel from_sys.solution->localize(*serialized_from_solutions[i]); } // Swap back Moose::swapLibMeshComm(swapped); } */ // We've found the nearest nodes for this processor. We need to see which processor _actually_ found the nearest though Parallel::minloc(min_distances, min_procs); // Now loop through min_procs and see if _this_ processor had the actual minimum for any nodes. // If it did then we're going to go get the value from that nearest node and transfer its value processor_id_type proc_id = libMesh::processor_id(); for(unsigned int j=0; j<min_procs.size(); j++) { if (min_procs[j] == proc_id) // This means that this processor really did find the minumum so we need to transfer the value { // The zero only works for LAGRANGE! dof_id_type to_dof = 0; if (is_nodal) { Node & to_node = to_mesh->node(j); to_dof = to_node.dof_number(to_sys_num, to_var_num, 0); } else { Elem & to_elem = *to_mesh->elem(j); to_dof = to_elem.dof_number(to_sys_num, to_var_num, 0); } // The app that has the nearest node in it unsigned int from_app_num = min_apps[j]; mooseAssert(_multi_app->hasLocalApp(from_app_num), "Something went very wrong!"); // Swap MPI_Comm swapped = Moose::swapLibMeshComm(_multi_app->comm()); FEProblem & from_problem = *_multi_app->appProblem(from_app_num); MooseVariable & from_var = from_problem.getVariable(0, _from_var_name); SystemBase & from_system_base = from_var.sys(); System & from_sys = from_system_base.system(); unsigned int from_sys_num = from_sys.number(); unsigned int from_var_num = from_sys.variable_number(from_var.name()); // EquationSystems & from_es = from_sys.get_equation_systems(); MeshBase * from_mesh = NULL; if (_displaced_source_mesh && from_problem.getDisplacedProblem()) from_mesh = &from_problem.getDisplacedProblem()->mesh().getMesh(); else from_mesh = &from_problem.mesh().getMesh(); Node & from_node = from_mesh->node(min_nodes[j]); // Assuming LAGRANGE! dof_id_type from_dof = from_node.dof_number(from_sys_num, from_var_num, 0); Real from_value = (*from_sys.solution)(from_dof); // Swap back Moose::swapLibMeshComm(swapped); to_solution.set(to_dof, from_value); } } to_solution.close(); to_sys.update(); break; } } Moose::out << "Finished NearestNodeTransfer " << _name << std::endl; }
Point LocationMap<Elem>::point_of(const Elem & elem) const { return elem.centroid(); }
int main (int argc, char** argv){ LibMeshInit init (argc, argv); //initialize libmesh library std::cout << "Running " << argv[0]; for (int i=1; i<argc; i++) std::cout << " " << argv[i]; std::cout << std::endl << std::endl; Mesh mesh(init.comm()); //T-channel //mesh.read("mesh.e"); //MeshRefinement meshRefinement(mesh); //meshRefinement.uniformly_refine(0); //1D - for debugging //int n = 20; //MeshTools::Generation::build_line(mesh, n, 0.0, 1.0, EDGE2); //n linear elements from 0 to 1 //nice geometry (straight channel) MeshTools::Generation::build_square (mesh, 250, 50, -0.0, 5.0, -0.0, 1.0, QUAD9); //read in subdomain assignments std::vector<double> prev_assign(mesh.n_elem(), 0.); std::string read_assign = "do_divvy.txt"; if(FILE *fp=fopen(read_assign.c_str(),"r")){ int flag = 1; int elemNum, assign; int ind = 0; while(flag != -1){ flag = fscanf(fp, "%d %d",&elemNum,&assign); if(flag != -1){ prev_assign[ind] = assign; ind += 1; } } fclose(fp); } //to stash subdomain assignments std::string stash_assign = "divvy.txt"; std::ofstream output(stash_assign.c_str()); MeshBase::element_iterator elem_it = mesh.elements_begin(); const MeshBase::element_iterator elem_end = mesh.elements_end(); for (; elem_it != elem_end; ++elem_it){ Elem* elem = *elem_it; Point c = elem->centroid(); //Point cshift1(c(0)-0.63, c(1)-0.5); elem->subdomain_id() = prev_assign[elem->id()]; //TEST/DEBUG //if(fabs(c(0)-3.0) < 0.35 && fabs(c(1)-0.5) < 0.35) // elem->subdomain_id() = 1; if(output.is_open()){ output << elem->id() << " " << elem->subdomain_id() << "\n"; } } output.close(); EquationSystems equation_systems (mesh); #ifdef LIBMESH_HAVE_EXODUS_API ExodusII_IO (mesh).write_equation_systems("meep.exo",equation_systems); #endif // #ifdef LIBMESH_HAVE_EXODUS_API return 0; } // end main
// StoreMaterialSystem/StressSystem/ bool CMaterialInfo::StoreMaterialInfo() { cout<<STRING_WRITE_BEGIN << "store material info" << endl; MeshBase& mesh = d_es->get_mesh(); Mesh::element_iterator it_el = mesh.active_local_elements_begin();//mesh.elements_begin(); const Mesh::element_iterator it_last_el = mesh.active_local_elements_end();//mesh.elements_end(); // part 1: we store the Material Info ExplicitSystem& material_system = d_es->get_system<ExplicitSystem>("MaterialSystem"); const DofMap& material_dof_map = material_system.get_dof_map(); // need to put values from the file vector<double> mat_values; mat_values.resize(d_mat_paras_num); //std::vector< std::vector<unsigned int> > dof_indices_var(system.n_vars()); std::vector<unsigned int> mat_dof_indices_var; string var_pre = "Mat"; for ( ; it_el != it_last_el ; ++it_el) { Elem* elem = *it_el; int domain_id= elem->subdomain_id(); const vector<double> & mat_values = d_material_info[domain_id].mat_paras; for (int it_para = 0; it_para < d_mat_paras_num; it_para ++) { stringstream ss; ss << it_para; string Name_para = var_pre + ss.str();//to_string(it_para); unsigned int mat_vars = material_system.variable_number (Name_para); material_dof_map.dof_indices (elem, mat_dof_indices_var, mat_vars); unsigned int dof_index = mat_dof_indices_var[0]; if( (material_system.solution->first_local_index() <= dof_index) && (dof_index < material_system.solution->last_local_index()) ) { material_system.solution->set(dof_index, mat_values[it_para]); } } } material_system.solution->close(); material_system.update(); Xdr my_mat_io("material.xdr",libMeshEnums::WRITE); material_system.write_serialized_data(my_mat_io,false); // part 2: we store the Fiber info if (d_have_fibers) { if (d_have_fiber_file) { DenseMatrix<Number> Fiber_data; // part 1) have fiber file for store info cout << STRING_CHECK_IMPORTANT << "fiber info is from file: " << endl; if (!ReadFile2Matrix(Fiber_data,d_fiber_file) || Fiber_data.m() < d_Elem_num) { cout << STRING_ERROR << "check fiber file: element num < rows" << d_fiber_file << endl; return false; } else if (Fiber_data.n() < d_fiber_para_num * d_fiber_types) { cout << STRING_ERROR << "check fiber file: fiber total paras < cols" << d_fiber_file << endl; return false; } ExplicitSystem& Fiber_system = d_es->get_system<ExplicitSystem>("FiberSystem"); const DofMap& Fiber_dof_map = Fiber_system.get_dof_map(); it_el = mesh.active_local_elements_begin(); var_pre = "Fiber"; string var_middle = "Para"; vector<string> fiber_vars; fiber_vars.resize(d_fiber_para_num * d_fiber_types); int it_id = -1; for (int it_fiber =0 ; it_fiber < d_fiber_types; it_fiber ++) { for (int it_para = 0; it_para < d_fiber_para_num; it_para ++ ) { // each fiber: a0, a1, a2, C, alpha it_id ++; stringstream ss; ss << it_para; stringstream ss1; ss1 << it_fiber; fiber_vars[ it_id]= var_pre + ss1.str() + var_middle + ss.str(); } } //std::vector< std::vector<unsigned int> > dof_indices_var(system.n_vars()); std::vector<unsigned int> fiber_dof_indices_var; for ( ; it_el != it_last_el ; ++it_el) { Elem* elem = *it_el; int domain_id= elem->subdomain_id(); // mat_values = int global_id =elem->id(); for (int it_para = 0; it_para < d_fiber_para_num * d_fiber_types; it_para ++) { unsigned int vars = Fiber_system.variable_number (fiber_vars[it_para]); Fiber_dof_map.dof_indices (elem, fiber_dof_indices_var, vars); unsigned int dof_index = fiber_dof_indices_var[0]; if( (Fiber_system.solution->first_local_index() <= dof_index) && (dof_index < Fiber_system.solution->last_local_index()) ) { Fiber_system.solution->set(dof_index, Fiber_data(global_id,it_para)); } } } Fiber_system.solution->close(); Fiber_system.update(); } else // part 2) we use parameters: currently, we use tube geometry { cout << STRING_CHECK_IMPORTANT <<"use parameters based on tube geometry only" << "; orientation based on the element center" << endl; d_fiber_types = d_fiberPara_info[0].num_fiber_family; d_fiber_para_num = d_fiberPara_info[0].num_para_per_fiber; ExplicitSystem& Fiber_system = d_es->get_system<ExplicitSystem>("FiberSystem"); const DofMap& Fiber_dof_map = Fiber_system.get_dof_map(); it_el = mesh.active_local_elements_begin(); var_pre = "Fiber"; string var_middle = "Para"; vector<string> fiber_vars; fiber_vars.resize(d_fiber_para_num * d_fiber_types); int it_id = -1; for (int it_fiber =0 ; it_fiber < d_fiber_types; it_fiber ++) { for (int it_para = 0; it_para < d_fiber_para_num; it_para ++ ) { stringstream ss; ss << it_fiber; stringstream ss1; ss1 << it_para; // each fiber: a0, a1, a2, C, alpha it_id ++; fiber_vars[ it_id]= var_pre + ss.str() + var_middle + ss1.str();//::to_string(it_para); } } //std::vector< std::vector<unsigned int> > dof_indices_var(system.n_vars()); std::vector<unsigned int> fiber_dof_indices_var; for ( ; it_el != it_last_el ; ++it_el) { Elem* elem = *it_el; int domain_id= elem->subdomain_id(); Fiber_info a_fiber_info = d_fiberPara_info[domain_id]; FiberPara2Data(a_fiber_info, elem->centroid()); // mat_values = //int global_id =elem->id(); for (int it_para = 0; it_para < d_fiber_para_num * d_fiber_types; it_para ++) { unsigned int vars = Fiber_system.variable_number (fiber_vars[it_para]); Fiber_dof_map.dof_indices (elem, fiber_dof_indices_var, vars); unsigned int dof_index = fiber_dof_indices_var[0]; if( (Fiber_system.solution->first_local_index() <= dof_index) && (dof_index < Fiber_system.solution->last_local_index()) ) { Fiber_system.solution-> set(dof_index,a_fiber_info.fiber_paras[it_para] ); //Fiber_data(global_id)(it_para)); } } } Fiber_system.solution->close(); Fiber_system.update(); Xdr my_io("fiber.xdr",libMeshEnums::WRITE); Fiber_system.write_serialized_data(my_io,false); } } // part 3: we store auxiliary info if (d_have_other) { DenseMatrix<Number> other_data; if (!ReadFile2Matrix(other_data,d_other_file) || other_data.m() < d_Elem_num); { cout << STRING_ERROR << "check other file:" << d_other_file << endl; return false; } d_other_para_num = other_data.n(); ExplicitSystem& other_system = d_es->get_system<ExplicitSystem>("OtherSystem"); const DofMap& other_dof_map = other_system.get_dof_map(); it_el = mesh.active_local_elements_begin(); std::vector<unsigned int> other_dof_indices_var; var_pre = "Other"; for ( ; it_el != it_last_el ; ++it_el) { Elem* elem = *it_el; int domain_id= elem->subdomain_id(); // mat_values = for (int it_para = 0; it_para < d_other_para_num; it_para ++) { stringstream ss; ss << it_para; string Name_para = var_pre + ss.str();//to_string(it_para); unsigned int other_vars = other_system.variable_number (Name_para); other_dof_map.dof_indices (elem, other_dof_indices_var, other_vars); unsigned int dof_index = other_dof_indices_var[0]; if( (other_system.solution->first_local_index() <= dof_index) && (dof_index < other_system.solution->last_local_index()) ) { other_system.solution->set(dof_index, other_data(elem->id(),it_para)); } } } other_system.solution->close(); other_system.update(); } cout<<STRING_WRITE_END << "store material info" << endl; return true; } // StoreMaterialInfo