MOAB: Mesh Oriented datABase
(version 5.4.1)
|
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