MOAB: Mesh Oriented datABase
(version 5.2.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) kraftche@cae.wisc.edu 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*, Vector3D coordinates[], unsigned count, 00055 MsqError& err ) const 00056 { 00057 std::fill( coordinates, coordinates + count, Vector3D( 0, 0, 0 ) ); 00058 MSQ_SETERR( err )( "Cannot get normal for PointDomain", MsqError::INTERNAL_ERROR ); 00059 } 00060 00061 void PointDomain::closest_point( Mesh::VertexHandle, const Vector3D&, Vector3D& closest, Vector3D& normal, 00062 MsqError& err ) const 00063 { 00064 closest = geom(); 00065 normal.set( 0, 0, 0 ); 00066 MSQ_SETERR( err )( "Cannot get normal for PointDomain", MsqError::INTERNAL_ERROR ); 00067 } 00068 00069 void PointDomain::domain_DoF( const Mesh::VertexHandle*, unsigned short* dof_array, size_t num_handles, 00070 MsqError& ) const 00071 { 00072 std::fill( dof_array, dof_array + num_handles, 0 ); 00073 } 00074 00075 void LineDomain::snap_to( Mesh::VertexHandle, Vector3D& coordinate ) const 00076 { 00077 coordinate = geom().point( geom().closest( coordinate ) ); 00078 } 00079 00080 void LineDomain::vertex_normal_at( Mesh::VertexHandle, Vector3D& coordinate ) const 00081 // no normal, return tangent instead. 00082 { 00083 coordinate = geom().direction(); 00084 } 00085 00086 void LineDomain::element_normal_at( Mesh::ElementHandle, Vector3D& coordinate ) const 00087 // no normal, return tangent instead. 00088 { 00089 coordinate = geom().direction(); 00090 } 00091 00092 void LineDomain::vertex_normal_at( const Mesh::VertexHandle*, Vector3D coordinates[], unsigned count, 00093 MsqError& err ) const 00094 { 00095 std::fill( coordinates, coordinates + count, geom().direction() ); 00096 MSQ_SETERR( err )( "Cannot get normal for LineDomain", MsqError::INTERNAL_ERROR ); 00097 } 00098 00099 void LineDomain::closest_point( Mesh::VertexHandle, const Vector3D& position, Vector3D& closest, Vector3D& normal, 00100 MsqError& err ) const 00101 { 00102 closest = geom().point( geom().closest( position ) ); 00103 normal = geom().direction(); 00104 MSQ_SETERR( err )( "Cannot get normal for LineDomain", MsqError::INTERNAL_ERROR ); 00105 } 00106 00107 void LineDomain::domain_DoF( const Mesh::VertexHandle*, unsigned short* dof_array, size_t num_handles, MsqError& ) const 00108 { 00109 std::fill( dof_array, dof_array + num_handles, 1 ); 00110 } 00111 00112 double LineDomain::arc_length( const double position1[3], const double position2[3], MsqError& ) 00113 { 00114 double p1 = mGeom.closest( position1 ); 00115 double p2 = mGeom.closest( position2 ); 00116 return p2 - p1; 00117 } 00118 00119 void LineDomain::position_from_length( const double from_here[3], double length, double result_point[3], MsqError& ) 00120 { 00121 const double param = mGeom.closest( from_here ); 00122 mGeom.point( param + length ).get_coordinates( result_point ); 00123 } 00124 00125 void CircleDomain::snap_to( Mesh::VertexHandle, Vector3D& coordinate ) const 00126 { 00127 coordinate = geom().closest( coordinate ); 00128 } 00129 00130 void CircleDomain::vertex_normal_at( Mesh::VertexHandle, Vector3D& coordinate ) const 00131 { 00132 // no normal, return tangent instead. 00133 Vector3D junk, copy( coordinate ); 00134 if( !geom().closest( copy, junk, coordinate ) ) // at center? 00135 coordinate = geom().radial_vector(); 00136 } 00137 00138 void CircleDomain::element_normal_at( Mesh::ElementHandle h, Vector3D& coordinate ) const 00139 { 00140 CircleDomain::vertex_normal_at( h, coordinate ); 00141 } 00142 00143 void CircleDomain::vertex_normal_at( const Mesh::VertexHandle* handles, Vector3D coordinates[], unsigned count, 00144 MsqError& err ) const 00145 { 00146 for( unsigned i = 0; i < count; ++i ) 00147 vertex_normal_at( handles[i], coordinates[i] ); 00148 MSQ_SETERR( err )( "Cannot get normal for CircleDomain", MsqError::INTERNAL_ERROR ); 00149 } 00150 00151 void CircleDomain::closest_point( Mesh::VertexHandle, const Vector3D& position, Vector3D& closest, Vector3D& normal, 00152 MsqError& err ) const 00153 { 00154 // no normal, get tangent instead 00155 if( !geom().closest( position, closest, normal ) ) 00156 { // at center? 00157 normal = geom().radial_vector(); 00158 closest = geom().center() + normal; 00159 } 00160 MSQ_SETERR( err )( "Cannot get normal for CircleDomain", MsqError::INTERNAL_ERROR ); 00161 } 00162 00163 void CircleDomain::domain_DoF( const Mesh::VertexHandle*, unsigned short* dof_array, size_t num_handles, 00164 MsqError& ) const 00165 { 00166 std::fill( dof_array, dof_array + num_handles, 1 ); 00167 } 00168 00169 double CircleDomain::arc_length( const double position1[3], const double position2[3], MsqError& ) 00170 { 00171 Vector3D p1 = Vector3D( position1 ) - mGeom.center(); 00172 Vector3D p2 = Vector3D( position2 ) - mGeom.center(); 00173 Vector3D vy = mGeom.normal() * p1; 00174 Vector3D vx = vy * mGeom.normal(); 00175 double x = p2 % vx; 00176 double y = p2 % vy; 00177 double angle = atan2( y, x ); 00178 return angle * mGeom.radius(); 00179 } 00180 00181 void CircleDomain::position_from_length( const double from_here[3], double length, double result_point[3], MsqError& ) 00182 { 00183 Vector3D b = Vector3D( from_here ) - mGeom.center(); 00184 Vector3D vy = mGeom.normal() * b; 00185 Vector3D vx = vy * mGeom.normal(); 00186 double angle = length / mGeom.radius(); 00187 double x = std::cos( angle ); 00188 double y = std::sin( angle ); 00189 vy *= y / vy.length(); 00190 vx *= x / vx.length(); 00191 Vector3D result = vx + vy; 00192 result *= mGeom.radius(); 00193 result += mGeom.center(); 00194 result.get_coordinates( result_point ); 00195 } 00196 00197 } // namespace MBMesquite