MOAB: Mesh Oriented datABase  (version 5.4.1)
MeshDomain1D.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines