void PointLocatorTree::init (Trees::BuildType build_type) { libmesh_assert (!this->_tree); if (this->_initialized) { // Warn that we are already initialized libMesh::err << "Warning: PointLocatorTree already initialized! Will ignore this call..." << std::endl; // Further warn if we try to init() again with a different build_type if (_build_type != build_type) { libMesh::err << "Warning: PointLocatorTree is using build_type = " << _build_type << ".\n" << "Your requested build_type, " << build_type << " will not be used!" << std::endl; } } else { // Let the requested build_type override the _build_type we were // constructed with. This is no big deal since we have not been // initialized before. _build_type = build_type; if (this->_master == libmesh_nullptr) { LOG_SCOPE("init(no master)", "PointLocatorTree"); if (this->_mesh.mesh_dimension() == 3) _tree = new Trees::OctTree (this->_mesh, get_target_bin_size(), _build_type); else { // A 1D/2D mesh in 3D space needs special consideration. // If the mesh is planar XY, we want to build a QuadTree // to search efficiently. If the mesh is truly a manifold, // then we need an octree #if LIBMESH_DIM > 2 bool is_planar_xy = false; // Build the bounding box for the mesh. If the delta-z bound is // negligibly small then we can use a quadtree. { MeshTools::BoundingBox bbox = MeshTools::bounding_box(this->_mesh); const Real Dx = bbox.second(0) - bbox.first(0), Dz = bbox.second(2) - bbox.first(2); if (std::abs(Dz/(Dx + 1.e-20)) < 1e-10) is_planar_xy = true; } if (!is_planar_xy) _tree = new Trees::OctTree (this->_mesh, get_target_bin_size(), _build_type); else #endif #if LIBMESH_DIM > 1 _tree = new Trees::QuadTree (this->_mesh, get_target_bin_size(), _build_type); #else _tree = new Trees::BinaryTree (this->_mesh, get_target_bin_size(), _build_type); #endif } } else { // We are _not_ the master. Let our Tree point to // the master's tree. But for this we first transform // the master in a state for which we are friends. // And make sure the master @e has a tree! const PointLocatorTree * my_master = cast_ptr<const PointLocatorTree *>(this->_master); if (my_master->initialized()) this->_tree = my_master->_tree; else libmesh_error_msg("ERROR: Initialize master first, then servants!"); } // Not all PointLocators may own a tree, but all of them // use their own element pointer. Let the element pointer // be unique for every interpolator. // Suppose the interpolators are used concurrently // at different locations in the mesh, then it makes quite // sense to have unique start elements. this->_element = libmesh_nullptr; } // ready for take-off this->_initialized = true; }
void PostscriptIO::write (const std::string & fname) { // We may need to gather a DistributedMesh to output it, making that // const qualifier in our constructor a dirty lie MeshSerializer serialize(const_cast<MeshBase &>(this->mesh()), !_is_parallel_format); if (this->mesh().processor_id() == 0) { // Get a constant reference to the mesh. const MeshBase & the_mesh = MeshOutput<MeshBase>::mesh(); // Only works in 2D libmesh_assert_equal_to (the_mesh.mesh_dimension(), 2); // Create output file stream. // _out is now a private member of the class. _out.open(fname.c_str()); // Make sure it opened correctly if (!_out.good()) libmesh_file_error(fname.c_str()); // The mesh bounding box gives us info about what the // Postscript bounding box should be. MeshTools::BoundingBox bbox = MeshTools::bounding_box(the_mesh); // Add a little extra padding to the "true" bounding box so // that we can still see the boundary const Real percent_padding = 0.01; const Real dx=bbox.second(0)-bbox.first(0); libmesh_assert_greater (dx, 0.0); const Real dy=bbox.second(1)-bbox.first(1); libmesh_assert_greater (dy, 0.0); const Real x_min = bbox.first(0) - percent_padding*dx; const Real y_min = bbox.first(1) - percent_padding*dy; const Real x_max = bbox.second(0) + percent_padding*dx; const Real y_max = bbox.second(1) + percent_padding*dy; // Width of the output as given in postscript units. // This usually is given by the strange unit 1/72 inch. // A width of 300 represents a size of roughly 10 cm. const Real width = 300; _scale = width / (x_max-x_min); _offset(0) = x_min; _offset(1) = y_min; // Header writing stuff stolen from Deal.II std::time_t time1= std::time (0); std::tm * time = std::localtime(&time1); _out << "%!PS-Adobe-2.0 EPSF-1.2" << '\n' //<< "%!PS-Adobe-1.0" << '\n' // Lars' PS version << "%%Filename: " << fname << '\n' << "%%Title: LibMesh Output" << '\n' << "%%Creator: LibMesh: A C++ finite element library" << '\n' << "%%Creation Date: " << time->tm_year+1900 << "/" << time->tm_mon+1 << "/" << time->tm_mday << " - " << time->tm_hour << ":" << std::setw(2) << time->tm_min << ":" << std::setw(2) << time->tm_sec << '\n' << "%%BoundingBox: " // lower left corner << "0 0 " // upper right corner << static_cast<unsigned int>( rint((x_max-x_min) * _scale )) << ' ' << static_cast<unsigned int>( rint((y_max-y_min) * _scale )) << '\n'; // define some abbreviations to keep // the output small: // m=move turtle to // l=define a line // s=set rgb color // sg=set gray value // lx=close the line and plot the line // lf=close the line and fill the interior _out << "/m {moveto} bind def" << '\n' << "/l {lineto} bind def" << '\n' << "/s {setrgbcolor} bind def" << '\n' << "/sg {setgray} bind def" << '\n' << "/cs {curveto stroke} bind def" << '\n' << "/lx {lineto closepath stroke} bind def" << '\n' << "/lf {lineto closepath fill} bind def" << '\n'; _out << "%%EndProlog" << '\n'; // << '\n'; // Set line width in the postscript file. _out << line_width << " setlinewidth" << '\n'; // Set line cap and join options _out << "1 setlinecap" << '\n'; _out << "1 setlinejoin" << '\n'; // allow only five digits for output (instead of the default // six); this should suffice even for fine grids, but reduces // the file size significantly _out << std::setprecision (5); // Loop over the active elements, draw lines for the edges. We // draw even quadratic elements with straight sides, i.e. a straight // line sits between each pair of vertices. Also we draw every edge // for an element regardless of the fact that it may overlap with // another. This would probably be a useful optimization... MeshBase::const_element_iterator el = the_mesh.active_elements_begin(); const MeshBase::const_element_iterator end_el = the_mesh.active_elements_end(); for ( ; el != end_el; ++el) { this->plot_linear_elem(*el); //this->plot_quadratic_elem(*el); // Experimental } // Issue the showpage command, and we're done. _out << "showpage" << std::endl; } // end if (this->mesh().processor_id() == 0) }
void PointLocatorTree::init (const Trees::BuildType build_type) { libmesh_assert (!this->_tree); if (this->_initialized) { libMesh::err << "ERROR: Already initialized! Will ignore this call..." << std::endl; } else { if (this->_master == NULL) { START_LOG("init(no master)", "PointLocatorTree"); if (this->_mesh.mesh_dimension() == 3) _tree = new Trees::OctTree (this->_mesh, 200, build_type); else { // A 1D/2D mesh in 3D space needs special consideration. // If the mesh is planar XY, we want to build a QuadTree // to search efficiently. If the mesh is truly a manifold, // then we need an octree #if LIBMESH_DIM > 2 bool is_planar_xy = false; // Build the bounding box for the mesh. If the delta-z bound is // negligibly small then we can use a quadtree. { MeshTools::BoundingBox bbox = MeshTools::bounding_box(this->_mesh); const Real Dx = bbox.second(0) - bbox.first(0), Dz = bbox.second(2) - bbox.first(2); if (std::abs(Dz/(Dx + 1.e-20)) < 1e-10) is_planar_xy = true; } if (!is_planar_xy) _tree = new Trees::OctTree (this->_mesh, 200, build_type); else #endif #if LIBMESH_DIM > 1 _tree = new Trees::QuadTree (this->_mesh, 200, build_type); #else _tree = new Trees::BinaryTree (this->_mesh, 200, build_type); #endif } STOP_LOG("init(no master)", "PointLocatorTree"); } else { // We are _not_ the master. Let our Tree point to // the master's tree. But for this we first transform // the master in a state for which we are friends. // And make sure the master @e has a tree! const PointLocatorTree* my_master = libmesh_cast_ptr<const PointLocatorTree*>(this->_master); if (my_master->initialized()) this->_tree = my_master->_tree; else { libMesh::err << "ERROR: Initialize master first, then servants!" << std::endl; libmesh_error(); } } // Not all PointLocators may own a tree, but all of them // use their own element pointer. Let the element pointer // be unique for every interpolator. // Suppose the interpolators are used concurrently // at different locations in the mesh, then it makes quite // sense to have unique start elements. this->_element = NULL; } // ready for take-off this->_initialized = true; }