From: guido Date: Mon, 21 Jun 1999 21:08:07 +0000 (+0000) Subject: multiple boundaries X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bcb53636eb3a8c0b3670981ecac486091514ef3a;p=dealii-svn.git multiple boundaries git-svn-id: https://svn.dealii.org/trunk@1428 0785d39b-7218-0410-832d-ea1e28bc413d --- diff --git a/deal.II/deal.II/include/grid/tria.h b/deal.II/deal.II/include/grid/tria.h index 56d912bc97..c50e1c74b5 100644 --- a/deal.II/deal.II/include/grid/tria.h +++ b/deal.II/deal.II/include/grid/tria.h @@ -11,11 +11,10 @@ #include #include #include +//#include #include - - /** * Declare some symbolic names for mesh smoothing algorithms. The meaning of * these flags is documented in the #Triangulation# class. @@ -992,6 +991,8 @@ class TriaDimensionInfo<3> { * * \subsection{Boundary approximation} * + * To be updated! + * * You can specify a boundary function: if a new vertex is created on a * side or face at the boundary, this function is used to compute where * it will be placed. See \Ref{Boundary} for the details. Usage with @@ -1393,7 +1394,17 @@ class TriaDimensionInfo<3> { * @see TriaRawIterator * @author Wolfgang Bangerth, 1998 */ template -class Triangulation : public TriaDimensionInfo, public Subscriptor { +class Triangulation + : public TriaDimensionInfo, + public Subscriptor +{ + private: + /** + * Default boundary object. This declaration is used + * for the default argument in #set_boundary#. + */ + static const StraightBoundary& straight_boundary; + public: typedef typename TriaDimensionInfo::raw_line_iterator raw_line_iterator; typedef typename TriaDimensionInfo::line_iterator line_iterator; @@ -1446,68 +1457,41 @@ class Triangulation : public TriaDimensionInfo, public Subscriptor { /** * Assign a boundary object to the - * triangulation, which is used to find - * the point where to place new vertices - * on the boundary. Ownership of the - * object remains with the caller of this - * function, i.e. you have to make sure - * that it is not destroyed before - * #Triangulation<>::execute_refinement_and_refinement()# - * is called the last time. Checking this - * is mostly done by the library by - * using a #Subscriptor# object as base - * class for boundary objects. - * - * If you copy this triangulation to - * another one using the - * #copy_triangulation# function, you must - * make sure that the lifetime of boundary - * object extends to the lifetime of the - * new triangulation as well. - * - * Because of the use of the #Subscriptor# - * base class, you must wait for the - * #Triangulation# object to release the - * lock to the boundary object before - * destroying that. This usually happens - * when the destructor of the - * triangulation is executed, but you may - * manually do so by calling - * #set_boundary(0)#, passing a Null - * pointer as new boundary object. This - * is the interpreted as "take the - * default boundary object", which - * actually is a #StraightBoundary# - * object. - * - * You are allowed to remove or replace + * triangulation. If a face with boundary number #number# + * is refined, this object is used to find + * the location of new vertices + * on the boundary. This will also be true for non-linear + * transformations of cells to the unit cell in shape + * function calculations. Multiple calls to this function are + * allowed to store different boundary curves or surfaces. + * + * Numbers of boundary object correspond to material numbers of + * faces at the boundary, for instance the material id in a UCD + * input file. They are not necessarily consecutive but must be + * in the range 0-254. + * + * The #boundary_object# is not copied and MUST persist + * until the triangulation is destroyed. Otherwise, + * the #Subscriptor# class will issue #ExcObjectInUse#. + * This is also true for triangulations generated from this + * one by #copy_triangulation#. + * + * It is possible to remove or replace * the boundary object during the lifetime - * of a non-empty triangulation, but - * you should be sure about what you do. - */ - void set_boundary (const Boundary *boundary_object); - - /** - * Return a constant reference to the boundary - * object used for this triangulation. This - * is necessary for a host of applications - * that need to use the exact shape of the - * boundary. Since the boundary used by all - * these applications, it is useful to ask - * the triangulation rather than asking - * for another parameter for each of these - * functions. - * - * If you need to store a pointer to the - * boundary somewhere, for example - * in the constructor of an object, for - * later use in the member functions, - * you should consider calling #subscribe# - * on the boundary to guarantee that the - * boundary object is still alive during - * the lifetime of your object. - */ - const Boundary & get_boundary () const; + * of a non-empty triangulation. Usually, this is done + * before the first refinement and is dangerous afterwards. + * Removal of a boundary object is done by + * #set_boundary(number)#. + */ + void set_boundary (unsigned int number, + const Boundary& boundary_object = straight_boundary); + + /** + * Return a constant reference to a boundary + * object used for this triangulation. + * Number is the same as in #set_boundary# + */ + const Boundary & get_boundary (unsigned int number) const; /** * Copy a triangulation. This operation is @@ -2992,9 +2976,9 @@ class Triangulation : public TriaDimensionInfo, public Subscriptor { vector vertices_used; /** - * Pointer to a boundary object. + * Collection of boundary objects. */ - const Boundary *boundary; + const Boundary* boundary[255]; /** * Do some smoothing in the process diff --git a/deal.II/deal.II/source/grid/tria.cc b/deal.II/deal.II/source/grid/tria.cc index 984b40bedd..f29b4f2e85 100644 --- a/deal.II/deal.II/source/grid/tria.cc +++ b/deal.II/deal.II/source/grid/tria.cc @@ -18,17 +18,25 @@ +template +const StraightBoundary& Triangulation::straight_boundary += StraightBoundary(); + + template Triangulation::Triangulation (const MeshSmoothing smooth_grid) : Subscriptor (), - boundary (0), smooth_grid(smooth_grid) { - // set default boundary - set_boundary (0); + // set default boundary for all possible components + for (unsigned int i=0;i<255;++i) + { + boundary[i] = &straight_boundary; + straight_boundary.subscribe(); + } levels.push_back (new TriangulationLevel); }; @@ -36,7 +44,8 @@ Triangulation::Triangulation (const MeshSmoothing smooth_grid) : template -Triangulation::Triangulation (const Triangulation &) : +Triangulation::Triangulation (const Triangulation &) + : Subscriptor () // do not set any subscriptors; anyway, // calling this constructor is an error! { @@ -46,38 +55,38 @@ Triangulation::Triangulation (const Triangulation &) : template -Triangulation::~Triangulation () { +Triangulation::~Triangulation () +{ for (unsigned int i=0; iunsubscribe (); + for (unsigned int i=0;i<255;++i) + boundary[i]->unsubscribe (); levels.clear (); }; - template -void Triangulation::set_boundary (const Boundary *boundary_object) { - static StraightBoundary default_boundary; - - if (boundary != 0) - boundary->unsubscribe (); - - if (boundary_object != 0) - boundary = boundary_object; - else - boundary = &default_boundary; - - boundary->subscribe (); +void +Triangulation::set_boundary (unsigned int number, + const Boundary& boundary_object) +{ + Assert(number<255, ExcIndexRange(number,0,255)); + + boundary[number]->unsubscribe (); + boundary[number] = &boundary_object; + boundary_object.subscribe(); }; template const Boundary & -Triangulation::get_boundary () const +Triangulation::get_boundary (unsigned int number) const { - return *boundary; + Assert(number<255, ExcIndexRange(number,0,255)); + + return *(boundary[number]); }; @@ -150,7 +159,8 @@ Triangulation<3>::end () const { template -void Triangulation::copy_triangulation (const Triangulation &old_tria) { +void Triangulation::copy_triangulation (const Triangulation &old_tria) +{ Assert (vertices.size() == 0, ExcTriangulationNotEmpty()); Assert (n_cells () == 0, ExcTriangulationNotEmpty()); Assert (levels.size () == 1, ExcTriangulationNotEmpty()); @@ -160,11 +170,12 @@ void Triangulation::copy_triangulation (const Triangulation &old_tria) vertices_used = old_tria.vertices_used; smooth_grid = old_tria.smooth_grid; - if (boundary) - boundary->unsubscribe (); - boundary = old_tria.boundary; - boundary->subscribe (); - + for (unsigned i=0;i<255;++i) + { + boundary[i]->unsubscribe (); + boundary[i] = old_tria.boundary[i]; + boundary[i]->subscribe (); + } // delete only level previously existing, // reserve space for new and copy delete levels[0]; @@ -4302,10 +4313,15 @@ void Triangulation<2>::execute_refinement () { // where shall we put the new // vertex? Point<2> new_point; - if (cell->at_boundary(nb)) + + face_iterator face=cell->line(nb); + + if ( face->boundary_indicator() != 255 ) + { // boundary vertex - new_point = boundary->get_new_point_on_line (cell->line(nb)); - else { + new_point = boundary[face->boundary_indicator()]-> + get_new_point_on_line (face); + } else { // vertex between two // normal cells new_point = vertices[new_vertices[2*nb]]; @@ -4773,7 +4789,7 @@ void Triangulation<3>::execute_refinement () { if (line->at_boundary()) vertices[next_unused_vertex] - = boundary->get_new_point_on_line (line); + = boundary[line->boundary_indicator()]->get_new_point_on_line (line); else vertices[next_unused_vertex] = (line->vertex(0) + line->vertex(1)) / 2; @@ -4855,7 +4871,7 @@ void Triangulation<3>::execute_refinement () { if (quad->at_boundary()) vertices[next_unused_vertex] - = boundary->get_new_point_on_quad (quad); + = boundary[quad->boundary_indicator()]->get_new_point_on_quad (quad); else vertices[next_unused_vertex] = (quad->vertex(0) + quad->vertex(1) +