MOAB: Mesh Oriented datABase  (version 5.2.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) kraftche@cae.wisc.edu
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, ParallelMesh* pmesh, Settings* settings, QualityAssessor* qa,
00223                       MsqError& err );
00224 
00225     MESQUITE_EXPORT
00226     void move_to_domain( Mesh* mesh, MeshDomain* geom, MsqError& err );
00227 
00228   private:
00229     MeshCharacteristic metricType;
00230     std::string initVertexCoords;  //!< name of tag used to store coordinates of initial mesh
00231     bool doCulling;
00232     double cpuTime, movementFactor;
00233 };
00234 
00235 /**\brief Utility to do curve smoothing
00236  *
00237  * This class implements a simple utility to redistribute vertices
00238  * on a curve (1D domain).  It can operate in two modes.  If the
00239  * charactristic is \c EQUAL, it will redistribute the vertices such
00240  * that the arc length between each vertex is equal. In the
00241  * \c PROPORTIONAL mode the application must call \c store_initial_mesh
00242  * for each curve before the domain is deformed.  \c store_initial_mesh
00243  * will record the fractional arc length between vertices so that
00244  * \c smooth_curve can redistribute the vertices such that the space
00245  * between the vertices is the same fractional arc length.
00246  */
00247 class DeformingCurveSmoother
00248 {
00249   public:
00250     MESQUITE_EXPORT
00251     DeformingCurveSmoother();
00252 
00253     MESQUITE_EXPORT
00254     ~DeformingCurveSmoother();
00255 
00256     /**\brief Mesh characteristics to attempt to preserve */
00257     enum Scheme
00258     {
00259         EQUAL,        //!< space curve vertices equally
00260         PROPORTIONAL  //!< preserve relative spacing from initial mesh
00261     };
00262 
00263     /**\brief Specify tag used to get/set cached initial mesh data
00264      *
00265      * This optimizer uses the initial mesh (prior to deformation of the
00266      * domain) as a reference when smoothing the mesh on the deformed domain.
00267      * This function can be used to store initial mesh data.  If the tag
00268      * already exists then t must have a type of DOUBLE and a size of one value.
00269      * the tag used to store those initial coordinates.  It must have a type
00270      * of DOUBLE and a size of one value.
00271      */
00272     inline void set_initial_fraction_tag( const std::string& tag_name )
00273     {
00274         initFractTag = tag_name;
00275     }
00276 
00277     /**\brief Get tag used to store initial mesh characteristics
00278      *
00279      * Return the tag handle passed to \c set_initial_fraction_tag or if
00280      * \c store_initial_mesh, the the tag created by in.
00281      */
00282     inline std::string get_initial_fraction_tag() const
00283     {
00284         return initFractTag;
00285     }
00286 
00287     /**\brief Specify which mesh characteristics to preserve */
00288     inline void set_mesh_characteristic( Scheme t )
00289     {
00290         metricType = t;
00291     }
00292 
00293     inline Scheme get_mesh_characteristic() const
00294     {
00295         return metricType;
00296     }
00297 
00298     /**\brief Record relative edge length from initial mesh
00299      *
00300      * Record the necessary characteristics of the initial mesh required
00301      * for a later all to \c smooth_curve using the \c PROPORTIONAL mode.
00302      *\param mesh_instance  This mesh instance need not contain only the
00303      *               vertices of this curve, but it must preserve tag data
00304      *               on the curve vertices for use in \c smooth_curve.
00305      *\param vertex_array   The array of handles corresponding to vertices
00306      *               on the curve and its end points.  Vertices must be
00307      *               ordered and in the forward direction along the curve,
00308      *               where the forward direction is whichever direction
00309      *               the \c CurveDomain instance considers a positive arc
00310      *               length for the \c position_from_length call.  The array
00311      *               must also contain both the start and end vertex for
00312      *               the curve, and if the curve is closed, the single start/end
00313      *               vertex must occur at both the start and end of the list.
00314      *\param vertex_array_length The number of handles in \c vertex_array.
00315      *\param geometry The curve or 1D domain geometry.
00316      */
00317     MESQUITE_EXPORT
00318     void store_initial_mesh( Mesh* mesh_instance, const Mesh::VertexHandle* vertex_array, int vertex_array_length,
00319                              CurveDomain* geometry, MsqError& err );
00320 
00321     /**\brief Redistribute vertices along a curve or 1D domain.
00322      *
00323      * Smooth the curve mesh by redistributing the vertices using one of
00324      * the schemes defined in \c Scheme.
00325      *
00326      *\param mesh_instance  This mesh instance need not contain only the
00327      *               vertices of this curve, but if using the
00328      *               \c PROPORTIONAL scheme it must have the tag data
00329      *               defined by the earlier call to \c store_initial_mesh.
00330      *\param vertex_array   The array of handles corresponding to vertices
00331      *               on the curve and its end points.  Vertices must be
00332      *               ordered and in the forward direction along the curve,
00333      *               where the forward direction is whichever direction
00334      *               the \c CurveDomain instance considers a positive arc
00335      *               length for the \c position_from_length call.  The array
00336      *               must also contain both the start and end vertex for
00337      *               the curve, and if the curve is closed, the single start/end
00338      *               vertex must occur at both the start and end of the list.
00339      *               The first and last vertex in the array will *not* be moved.
00340      *               If the geometric points (0D domains) they are constrained
00341      *               to lie on have moved, the caller must move them to those
00342      *               new locations before calling this function.
00343      *\param vertex_array_length The number of handles in \c vertex_array.
00344      *\param geometry The curve or 1D domain geometry.
00345      *\param type    The scheme to use.  If using \c PROPORTIONAL,
00346      *               then \c store_initial_mesh must be called for the same
00347      *               vertices and mesh instance before any deformation.
00348      */
00349     MESQUITE_EXPORT
00350     void smooth_curve( Mesh* mesh_instance, const Mesh::VertexHandle* vertex_array, int vertex_array_length,
00351                        CurveDomain* geometry, Scheme type, MsqError& err );
00352 
00353   private:
00354     Scheme metricType;
00355     std::string initFractTag;  //!< name of tag used to store arc length fractions
00356     TagHandle get_tag( Mesh* mesh, MsqError& err );
00357 };
00358 
00359 }  // namespace MBMesquite
00360 
00361 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines