1 /* *****************************************************************
2     MESQUITE -- The Mesh Quality Improvement Toolkit
3 
4     Copyright 2005 Lawrence Livermore National Laboratory.  Under
5     the terms of Contract B545069 with the University of Wisconsin --
6     Madison, Lawrence Livermore National Laboratory retains certain
7     rights in this software.
8 
9     This library is free software; you can redistribute it and/or
10     modify it under the terms of the GNU Lesser General Public
11     License as published by the Free Software Foundation; either
12     version 2.1 of the License, or (at your option) any later version.
13 
14     This library is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17     Lesser General Public License for more details.
18 
19     You should have received a copy of the GNU Lesser General Public License
20     (lgpl.txt) along with this library; if not, write to the Free Software
21     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22 
23     kraftche@cae.wisc.edu
24 
25   ***************************************************************** */
26 
27 #ifndef MSQ_CYLINDER_DOMAIN_CPP
28 #define MSQ_CYLINDER_DOMAIN_CPP
29 
30 #include "Mesquite.hpp"
31 #include "CylinderDomain.hpp"
32 #include <limits>
33 
34 namespace MBMesquite {
35 
~CylinderDomain()36 CylinderDomain::~CylinderDomain() {}
37 
evaluate(Mesh::VertexHandle,const Vector3D & point,Vector3D & closest,Vector3D & normal) const38 void CylinderDomain::evaluate( Mesh::VertexHandle,
39                                const Vector3D& point,
40                                Vector3D& closest,
41                                Vector3D& normal ) const
42 {
43   const double EPSILON = std::numeric_limits<double>::epsilon();
44   double t = mAxis % (point - mCenter);
45   const Vector3D axis_point = mCenter + t * mAxis;
46 
47   normal = point - axis_point;
48   const double len = normal.length();
49   if (len < EPSILON)
50   {
51     Vector3D v( 1, 0, 0 );
52     if ((v * mAxis).length() < EPSILON)
53       v.set( 0, 1, 0 );
54     normal = v * mAxis;
55     normal.normalize();
56   }
57   else
58   {
59     normal /= len;
60   }
61 
62   closest = axis_point + mRadius * normal;
63   normal *= outwardSign;
64 }
65 
snap_to(Mesh::VertexHandle h,Vector3D & v) const66 void CylinderDomain::snap_to( Mesh::VertexHandle h, Vector3D& v ) const
67 {
68   Vector3D p(v), n;
69   evaluate( h, p, v, n );
70 }
71 
vertex_normal_at(Mesh::VertexHandle h,Vector3D & v) const72 void CylinderDomain::vertex_normal_at( Mesh::VertexHandle h, Vector3D& v ) const
73 {
74   Vector3D p(v), l;
75   evaluate( h, p, l, v );
76 }
77 
element_normal_at(Mesh::ElementHandle h,Vector3D & v) const78 void CylinderDomain::element_normal_at( Mesh::ElementHandle h, Vector3D& v ) const
79 {
80   Vector3D p(v), l;
81     // NOTE: Explicitly invoke this class's evaluate method for elements.
82     //       BoundedCylindarDomain overrides evaluate for vertices only.
83   CylinderDomain::evaluate( h, p, l, v );
84 }
85 
vertex_normal_at(const Mesh::VertexHandle * h,Vector3D coords[],unsigned count,MsqError &) const86 void CylinderDomain::vertex_normal_at( const Mesh::VertexHandle* h,
87                                        Vector3D coords[],
88                                        unsigned count,
89                                        MsqError& ) const
90 {
91   for (unsigned i = 0; i < count; ++i)
92     vertex_normal_at( h[i], coords[i] );
93 }
94 
closest_point(Mesh::VertexHandle handle,const Vector3D & position,Vector3D & closest,Vector3D & normal,MsqError &) const95 void CylinderDomain::closest_point( Mesh::VertexHandle handle,
96                                     const Vector3D& position,
97                                     Vector3D& closest,
98                                     Vector3D& normal,
99                                     MsqError&  ) const
100 {
101   evaluate( handle, position, closest, normal );
102 }
103 
domain_DoF(const Mesh::VertexHandle *,unsigned short * dof_array,size_t count,MsqError &) const104 void CylinderDomain::domain_DoF( const Mesh::VertexHandle* ,
105                                  unsigned short* dof_array,
106                                  size_t count,
107                                  MsqError&  ) const
108 {
109   std::fill( dof_array, dof_array + count, (unsigned short)2 );
110 }
111 
112 
113 
114 } // namespace MBMesquite
115 
116 #endif
117