MOAB: Mesh Oriented datABase  (version 5.4.1)
DeformingDomainWrapper.hpp
Go to the documentation of this file.
00001 /* *****************************************************************
00002     MESQUITE -- The Mesh Quality Improvement Toolkit
00003 
00004     Copyright 2010 Sandia National Laboratories.  Developed at the
00005     University of Wisconsin--Madison under SNL contract number
00006     624796.  The U.S. Government and the University of Wisconsin
00007     retain certain rights to this software.
00008 
00009     This library is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU Lesser General Public
00011     License as published by the Free Software Foundation; either
00012     version 2.1 of the License, or (at your option) any later version.
00013 
00014     This library is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017     Lesser General Public License for more details.
00018 
00019     You should have received a copy of the GNU Lesser General Public License
00020     (lgpl.txt) along with this library; if not, write to the Free Software
00021     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 
00023     (2010) [email protected]
00024 
00025   ***************************************************************** */
00026 
00027 /** \file DeformingDomainWrapper.hpp
00028  *  \brief Define DeformingDomainWrapper class
00029  *  \author Jason Kraftcheck
00030  */
00031 
00032 #ifndef MSQ_DEFORMING_DOMAIN_WRAPPER_HPP
00033 #define MSQ_DEFORMING_DOMAIN_WRAPPER_HPP
00034 
00035 #include "Wrapper.hpp"
00036 #include "MeshInterface.hpp"
00037 #include <string>
00038 
00039 namespace MBMesquite
00040 {
00041 
00042 class CurveDomain;
00043 
00044 /**\brief Smooth mesh with deforming domain (deforming geometry)
00045  *
00046  * This wrapper stores the initial mesh on/in an undeformed domain
00047  * and uses the characteristics of that mesh to guide the optimization
00048  * of the mesh after deformation of the domain.
00049  *
00050  * The caller must ensure that the wrapper has the initial mesh
00051  * description.  The simplest way to do this is to call \c store_initial_mesh
00052  * prior to the deformation of the geometric domain.
00053  *
00054  * Application using this wrapper should preform the following steps.
00055  * -# Change any wrapper settings
00056  * -# Call \c store_initial_mesh with a mesh object containing all vertices in the mesh
00057  * -# If using \c DeformingCurveSmoother, call DeformingCurveSmoother::store_initial_mesh
00058  *      separately for each geometric curve in the mesh.
00059  * -# Optionally export mesh to file if \c Mesh implementation can save tag data
00060  * -# Deform domain
00061  * -# Optionally restore mesh from file
00062  * -# Move any vertices bound to geometric points/vertices to their new location
00063  * -# If using \c DeformingCurveSmoother, call \c smooth_curve separately for each geometric curve
00064  * -# If doing free smooth call \c run_instructions for entire mesh.  Otherwise
00065  *       call run_instructions separately for each geometric surface and each
00066  *       volume.
00067  *
00068  *\NOTE This algorithm uses non-barrier metrics which makes it possible, if
00069  *      unlikely, that the result mesh will contain more/different inverted
00070  *      elements than the input mesh.
00071  *
00072  *\NOTE Mesquite does not do edge/curve smoothing.  The caller may either
00073  *      set up a "free" smooth where vertices on geometric curves are
00074  *      smoothed as a part of teh surface or volume optimization or simply
00075  *      redistribute the vertices along the curves outside of mesquite.
00076  *      The DeformingCurveSmoother class is provided below to facilitate
00077  *      redistributing nodes on a curve such that fractional arc length
00078  *      is preserved for edges.  However, this it is as a stand-alone utility
00079  *      that must be invoked independently for each curve.
00080  */
00081 class DeformingDomainWrapper : public Wrapper
00082 {
00083   public:
00084     MESQUITE_EXPORT
00085     DeformingDomainWrapper();
00086 
00087     MESQUITE_EXPORT virtual ~DeformingDomainWrapper();
00088 
00089     /**\brief Specify tag used to get/set cached initial mesh vertex coordinates
00090      *
00091      * This optimizer uses the initial mesh (prior to deformation of the
00092      * domain) as a reference when smoothing the mesh on the deformed domain.
00093      * The initial mesh is stored/accessed as alternate vertex coordinates
00094      * stored in a Tag on the mesh.  This function can be used to specify
00095      * the tag used to store those initial coordinates.  If the named tag
00096      * already exists then it must have a type of DOUBLE and a size of three values.
00097      *
00098      * If the application already has the initial coordinates stored in some
00099      * tag, then calling this function with the tag handle is sufficient to
00100      * to set up the optmizer.  Otherwise \c store_initial_mesh can be called
00101      * to copy the initial vertex coordinates into a tag.  If both this function
00102      * is called to set the tag handle and \c store_initial_mesh is called, then
00103      * \c store_initial_mesh will copy the vertices into the specified tag.
00104      * Otherwise \c store_initial_mesh, if called, will create a new tag.
00105      */
00106     inline void set_initial_coord_tag( const std::string& tag_name )
00107     {
00108         initVertexCoords = tag_name;
00109     }
00110 
00111     /**\brief Get tag used to store vertex coordinates of initial mesh
00112      *
00113      * Return the tag passed to \c set_initial_coord_tag or if
00114      * \c store_initial_mesh has been called, the the tag created by
00115      * \c store_initial_mesh .
00116      */
00117     inline std::string get_initial_coord_tag() const
00118     {
00119         return initVertexCoords;
00120     }
00121 
00122     /**\brief Store the initial mesh before deformation as a reference
00123      *
00124      * Store the initial mesh for use as a reference when smoothing
00125      * mesh on deformed geometry.
00126      *\param mesh The mesh instance to be operated on.  Initial mesh
00127      *      data is stored by copying vertex coordinates to
00128      *\Note This must be called prior to the optimization with the
00129      *      mesh in its undeformed state.
00130      *\Note This function need not be called if the application cal
00131      *      provide access to the coordinates of vertices of the initial
00132      *      mesh through the tag mechanism already.
00133      *      See \c set_initial_coord_tag
00134      */
00135     MESQUITE_EXPORT
00136     void store_initial_mesh( Mesh* mesh, MsqError& err );
00137 
00138     /**\brief Mesh characteristics to attempt to preserve */
00139     enum MeshCharacteristic
00140     {
00141         SHAPE,             //!< Attempt to preserve element shape (TShapeNB1 metric)
00142         SHAPE_SIZE,        //!< Attempt to preserve element shape and size (TShapeSize2DNB1 &
00143                            //!< TShapeSize3DNB1)
00144         SHAPE_SIZE_ORIENT  //!< Attempt to preserve element shape, size, and orientation
00145                            //!< (TShapeSizeOrientNB1)
00146     };
00147 
00148     /**\brief Specify which mesh characteristics to preserve
00149      *
00150      * It typically works the best to preserve whichever quantities can
00151      * be preserved.  For example, if the overall area/volume of the domain
00152      * didn't change much, attempt to preserve size.  If the deformation of
00153      * the domain doesn't require rotation of the elements relative to the
00154      * global coordinate system, then preserve orientation.
00155      *
00156      * The default is \c SHAPE.
00157      */
00158     inline void set_mesh_characteristic( MeshCharacteristic t )
00159     {
00160         metricType = t;
00161     }
00162 
00163     inline MeshCharacteristic get_mesh_characteristic() const
00164     {
00165         return metricType;
00166     }
00167 
00168     /**\brief Check if vertex culling will be used */
00169     inline bool is_culling_enabled() const
00170     {
00171         return doCulling;
00172     }
00173 
00174     /**\brief Enable vertex culling.
00175      *
00176      * Culling will be enabled by default.
00177      */
00178     inline void enable_culling( bool yesno )
00179     {
00180         doCulling = yesno;
00181     }
00182 
00183     /**\brief Specify timeout after which optimization will exit */
00184     inline void set_cpu_time_limit( double seconds )
00185     {
00186         cpuTime = seconds;
00187     }
00188 
00189     /**\brief No timeout */
00190     inline void clear_cpu_time_limit()
00191     {
00192         cpuTime = 0.0;
00193     }
00194 
00195     /**\brief Get timeout after which optimization will exit
00196      *\return false if no timeout specified, true otherwise */
00197     inline bool get_cpu_time_limit( double& seconds ) const
00198     {
00199         seconds = cpuTime;
00200         return cpuTime > 0.0;
00201     }
00202 
00203     /**\brief Specify factor by which to minimum distance a vertex must
00204      *        move in an iteration to avoid termination of the optimization.
00205      *
00206      * Value must be greater than zero, and should be less 1.0
00207      * The optimizer will calculated a representative edge length
00208      * from the mesh.  It will terminate the optimization when an
00209      * iteration moves no vertex more than this factor times the
00210      * characteristic edge length.
00211      */
00212     MESQUITE_EXPORT
00213     void set_vertex_movement_limit_factor( double f );
00214 
00215     inline double get_vertex_movement_limit_factor() const
00216     {
00217         return movementFactor;
00218     }
00219 
00220   protected:
00221     MESQUITE_EXPORT
00222     void run_wrapper( MeshDomainAssoc* mesh_and_domain,
00223                       ParallelMesh* pmesh,
00224                       Settings* settings,
00225                       QualityAssessor* qa,
00226                       MsqError& err );
00227 
00228     MESQUITE_EXPORT
00229     void move_to_domain( Mesh* mesh, MeshDomain* geom, MsqError& err );
00230 
00231   private:
00232     MeshCharacteristic metricType;
00233     std::string initVertexCoords;  //!< name of tag used to store coordinates of initial mesh
00234     bool doCulling;
00235     double cpuTime, movementFactor;
00236 };
00237 
00238 /**\brief Utility to do curve smoothing
00239  *
00240  * This class implements a simple utility to redistribute vertices
00241  * on a curve (1D domain).  It can operate in two modes.  If the
00242  * charactristic is \c EQUAL, it will redistribute the vertices such
00243  * that the arc length between each vertex is equal. In the
00244  * \c PROPORTIONAL mode the application must call \c store_initial_mesh
00245  * for each curve before the domain is deformed.  \c store_initial_mesh
00246  * will record the fractional arc length between vertices so that
00247  * \c smooth_curve can redistribute the vertices such that the space
00248  * between the vertices is the same fractional arc length.
00249  */
00250 class DeformingCurveSmoother
00251 {
00252   public:
00253     MESQUITE_EXPORT
00254     DeformingCurveSmoother();
00255 
00256     MESQUITE_EXPORT
00257     ~DeformingCurveSmoother();
00258 
00259     /**\brief Mesh characteristics to attempt to preserve */
00260     enum Scheme
00261     {
00262         EQUAL,        //!< space curve vertices equally
00263         PROPORTIONAL  //!< preserve relative spacing from initial mesh
00264     };
00265 
00266     /**\brief Specify tag used to get/set cached initial mesh data
00267      *
00268      * This optimizer uses the initial mesh (prior to deformation of the
00269      * domain) as a reference when smoothing the mesh on the deformed domain.
00270      * This function can be used to store initial mesh data.  If the tag
00271      * already exists then t must have a type of DOUBLE and a size of one value.
00272      * the tag used to store those initial coordinates.  It must have a type
00273      * of DOUBLE and a size of one value.
00274      */
00275     inline void set_initial_fraction_tag( const std::string& tag_name )
00276     {
00277         initFractTag = tag_name;
00278     }
00279 
00280     /**\brief Get tag used to store initial mesh characteristics
00281      *
00282      * Return the tag handle passed to \c set_initial_fraction_tag or if
00283      * \c store_initial_mesh, the the tag created by in.
00284      */
00285     inline std::string get_initial_fraction_tag() const
00286     {
00287         return initFractTag;
00288     }
00289 
00290     /**\brief Specify which mesh characteristics to preserve */
00291     inline void set_mesh_characteristic( Scheme t )
00292     {
00293         metricType = t;
00294     }
00295 
00296     inline Scheme get_mesh_characteristic() const
00297     {
00298         return metricType;
00299     }
00300 
00301     /**\brief Record relative edge length from initial mesh
00302      *
00303      * Record the necessary characteristics of the initial mesh required
00304      * for a later all to \c smooth_curve using the \c PROPORTIONAL mode.
00305      *\param mesh_instance  This mesh instance need not contain only the
00306      *               vertices of this curve, but it must preserve tag data
00307      *               on the curve vertices for use in \c smooth_curve.
00308      *\param vertex_array   The array of handles corresponding to vertices
00309      *               on the curve and its end points.  Vertices must be
00310      *               ordered and in the forward direction along the curve,
00311      *               where the forward direction is whichever direction
00312      *               the \c CurveDomain instance considers a positive arc
00313      *               length for the \c position_from_length call.  The array
00314      *               must also contain both the start and end vertex for
00315      *               the curve, and if the curve is closed, the single start/end
00316      *               vertex must occur at both the start and end of the list.
00317      *\param vertex_array_length The number of handles in \c vertex_array.
00318      *\param geometry The curve or 1D domain geometry.
00319      */
00320     MESQUITE_EXPORT
00321     void store_initial_mesh( Mesh* mesh_instance,
00322                              const Mesh::VertexHandle* vertex_array,
00323                              int vertex_array_length,
00324                              CurveDomain* geometry,
00325                              MsqError& err );
00326 
00327     /**\brief Redistribute vertices along a curve or 1D domain.
00328      *
00329      * Smooth the curve mesh by redistributing the vertices using one of
00330      * the schemes defined in \c Scheme.
00331      *
00332      *\param mesh_instance  This mesh instance need not contain only the
00333      *               vertices of this curve, but if using the
00334      *               \c PROPORTIONAL scheme it must have the tag data
00335      *               defined by the earlier call to \c store_initial_mesh.
00336      *\param vertex_array   The array of handles corresponding to vertices
00337      *               on the curve and its end points.  Vertices must be
00338      *               ordered and in the forward direction along the curve,
00339      *               where the forward direction is whichever direction
00340      *               the \c CurveDomain instance considers a positive arc
00341      *               length for the \c position_from_length call.  The array
00342      *               must also contain both the start and end vertex for
00343      *               the curve, and if the curve is closed, the single start/end
00344      *               vertex must occur at both the start and end of the list.
00345      *               The first and last vertex in the array will *not* be moved.
00346      *               If the geometric points (0D domains) they are constrained
00347      *               to lie on have moved, the caller must move them to those
00348      *               new locations before calling this function.
00349      *\param vertex_array_length The number of handles in \c vertex_array.
00350      *\param geometry The curve or 1D domain geometry.
00351      *\param type    The scheme to use.  If using \c PROPORTIONAL,
00352      *               then \c store_initial_mesh must be called for the same
00353      *               vertices and mesh instance before any deformation.
00354      */
00355     MESQUITE_EXPORT
00356     void smooth_curve( Mesh* mesh_instance,
00357                        const Mesh::VertexHandle* vertex_array,
00358                        int vertex_array_length,
00359                        CurveDomain* geometry,
00360                        Scheme type,
00361                        MsqError& err );
00362 
00363   private:
00364     Scheme metricType;
00365     std::string initFractTag;  //!< name of tag used to store arc length fractions
00366     TagHandle get_tag( Mesh* mesh, MsqError& err );
00367 };
00368 
00369 }  // namespace MBMesquite
00370 
00371 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines