MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2008 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 (2008) [email protected] 00024 00025 ***************************************************************** */ 00026 00027 /** \file MeshDomain1D.cpp 00028 * \brief 00029 * \author Jason Kraftcheck 00030 */ 00031 00032 #include "Mesquite.hpp" 00033 #include "MeshDomain1D.hpp" 00034 #include "MsqError.hpp" 00035 00036 namespace MBMesquite 00037 { 00038 00039 void PointDomain::snap_to( Mesh::VertexHandle, Vector3D& coordinate ) const 00040 { 00041 coordinate = geom(); 00042 } 00043 00044 void PointDomain::vertex_normal_at( Mesh::VertexHandle, Vector3D& coordinate ) const 00045 { 00046 coordinate.set( 0, 0, 0 ); 00047 } 00048 00049 void PointDomain::element_normal_at( Mesh::ElementHandle, Vector3D& coordinate ) const 00050 { 00051 coordinate.set( 0, 0, 0 ); 00052 } 00053 00054 void PointDomain::vertex_normal_at( const Mesh::VertexHandle*, 00055 Vector3D coordinates[], 00056 unsigned count, 00057 MsqError& err ) const 00058 { 00059 std::fill( coordinates, coordinates + count, Vector3D( 0, 0, 0 ) ); 00060 MSQ_SETERR( err )( "Cannot get normal for PointDomain", MsqError::INTERNAL_ERROR ); 00061 } 00062 00063 void PointDomain::closest_point( Mesh::VertexHandle, 00064 const Vector3D&, 00065 Vector3D& closest, 00066 Vector3D& normal, 00067 MsqError& err ) const 00068 { 00069 closest = geom(); 00070 normal.set( 0, 0, 0 ); 00071 MSQ_SETERR( err )( "Cannot get normal for PointDomain", MsqError::INTERNAL_ERROR ); 00072 } 00073 00074 void PointDomain::domain_DoF( const Mesh::VertexHandle*, 00075 unsigned short* dof_array, 00076 size_t num_handles, 00077 MsqError& ) const 00078 { 00079 std::fill( dof_array, dof_array + num_handles, 0 ); 00080 } 00081 00082 void LineDomain::snap_to( Mesh::VertexHandle, Vector3D& coordinate ) const 00083 { 00084 coordinate = geom().point( geom().closest( coordinate ) ); 00085 } 00086 00087 void LineDomain::vertex_normal_at( Mesh::VertexHandle, Vector3D& coordinate ) const 00088 // no normal, return tangent instead. 00089 { 00090 coordinate = geom().direction(); 00091 } 00092 00093 void LineDomain::element_normal_at( Mesh::ElementHandle, Vector3D& coordinate ) const 00094 // no normal, return tangent instead. 00095 { 00096 coordinate = geom().direction(); 00097 } 00098 00099 void LineDomain::vertex_normal_at( const Mesh::VertexHandle*, 00100 Vector3D coordinates[], 00101 unsigned count, 00102 MsqError& err ) const 00103 { 00104 std::fill( coordinates, coordinates + count, geom().direction() ); 00105 MSQ_SETERR( err )( "Cannot get normal for LineDomain", MsqError::INTERNAL_ERROR ); 00106 } 00107 00108 void LineDomain::closest_point( Mesh::VertexHandle, 00109 const Vector3D& position, 00110 Vector3D& closest, 00111 Vector3D& normal, 00112 MsqError& err ) const 00113 { 00114 closest = geom().point( geom().closest( position ) ); 00115 normal = geom().direction(); 00116 MSQ_SETERR( err )( "Cannot get normal for LineDomain", MsqError::INTERNAL_ERROR ); 00117 } 00118 00119 void LineDomain::domain_DoF( const Mesh::VertexHandle*, unsigned short* dof_array, size_t num_handles, MsqError& ) const 00120 { 00121 std::fill( dof_array, dof_array + num_handles, 1 ); 00122 } 00123 00124 double LineDomain::arc_length( const double position1[3], const double position2[3], MsqError& ) 00125 { 00126 double p1 = mGeom.closest( position1 ); 00127 double p2 = mGeom.closest( position2 ); 00128 return p2 - p1; 00129 } 00130 00131 void LineDomain::position_from_length( const double from_here[3], double length, double result_point[3], MsqError& ) 00132 { 00133 const double param = mGeom.closest( from_here ); 00134 mGeom.point( param + length ).get_coordinates( result_point ); 00135 } 00136 00137 void CircleDomain::snap_to( Mesh::VertexHandle, Vector3D& coordinate ) const 00138 { 00139 coordinate = geom().closest( coordinate ); 00140 } 00141 00142 void CircleDomain::vertex_normal_at( Mesh::VertexHandle, Vector3D& coordinate ) const 00143 { 00144 // no normal, return tangent instead. 00145 Vector3D junk, copy( coordinate ); 00146 if( !geom().closest( copy, junk, coordinate ) ) // at center? 00147 coordinate = geom().radial_vector(); 00148 } 00149 00150 void CircleDomain::element_normal_at( Mesh::ElementHandle h, Vector3D& coordinate ) const 00151 { 00152 CircleDomain::vertex_normal_at( h, coordinate ); 00153 } 00154 00155 void CircleDomain::vertex_normal_at( const Mesh::VertexHandle* handles, 00156 Vector3D coordinates[], 00157 unsigned count, 00158 MsqError& err ) const 00159 { 00160 for( unsigned i = 0; i < count; ++i ) 00161 vertex_normal_at( handles[i], coordinates[i] ); 00162 MSQ_SETERR( err )( "Cannot get normal for CircleDomain", MsqError::INTERNAL_ERROR ); 00163 } 00164 00165 void CircleDomain::closest_point( Mesh::VertexHandle, 00166 const Vector3D& position, 00167 Vector3D& closest, 00168 Vector3D& normal, 00169 MsqError& err ) const 00170 { 00171 // no normal, get tangent instead 00172 if( !geom().closest( position, closest, normal ) ) 00173 { // at center? 00174 normal = geom().radial_vector(); 00175 closest = geom().center() + normal; 00176 } 00177 MSQ_SETERR( err )( "Cannot get normal for CircleDomain", MsqError::INTERNAL_ERROR ); 00178 } 00179 00180 void CircleDomain::domain_DoF( const Mesh::VertexHandle*, 00181 unsigned short* dof_array, 00182 size_t num_handles, 00183 MsqError& ) const 00184 { 00185 std::fill( dof_array, dof_array + num_handles, 1 ); 00186 } 00187 00188 double CircleDomain::arc_length( const double position1[3], const double position2[3], MsqError& ) 00189 { 00190 Vector3D p1 = Vector3D( position1 ) - mGeom.center(); 00191 Vector3D p2 = Vector3D( position2 ) - mGeom.center(); 00192 Vector3D vy = mGeom.normal() * p1; 00193 Vector3D vx = vy * mGeom.normal(); 00194 double x = p2 % vx; 00195 double y = p2 % vy; 00196 double angle = atan2( y, x ); 00197 return angle * mGeom.radius(); 00198 } 00199 00200 void CircleDomain::position_from_length( const double from_here[3], double length, double result_point[3], MsqError& ) 00201 { 00202 Vector3D b = Vector3D( from_here ) - mGeom.center(); 00203 Vector3D vy = mGeom.normal() * b; 00204 Vector3D vx = vy * mGeom.normal(); 00205 double angle = length / mGeom.radius(); 00206 double x = std::cos( angle ); 00207 double y = std::sin( angle ); 00208 vy *= y / vy.length(); 00209 vx *= x / vx.length(); 00210 Vector3D result = vx + vy; 00211 result *= mGeom.radius(); 00212 result += mGeom.center(); 00213 result.get_coordinates( result_point ); 00214 } 00215 00216 } // namespace MBMesquite