MOAB: Mesh Oriented datABase  (version 5.4.1)
LVQDTargetCalculator.cpp
Go to the documentation of this file.
00001 /* *****************************************************************
00002     MESQUITE -- The Mesh Quality Improvement Toolkit
00003 
00004     Copyright 2006 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     (2006) [email protected]
00024 
00025   ***************************************************************** */
00026 
00027 /** \file LVQDTargetCalculator.cpp
00028  *  \brief
00029  *  \author Jason Kraftcheck
00030  */
00031 
00032 #include "Mesquite.hpp"
00033 #include "LVQDTargetCalculator.hpp"
00034 #include "MsqMatrix.hpp"
00035 #include "MsqError.hpp"
00036 #include <algorithm>
00037 #include <cassert>
00038 
00039 namespace MBMesquite
00040 {
00041 
00042 int LVQDTargetCalculator::add_source( TargetCalculator* source )
00043 {
00044     if( !source ) return -1;
00045     int idx = std::find( uniqueGuides, uniqueGuides + numUniqueGuides, source ) - uniqueGuides;
00046     if( idx == numUniqueGuides )
00047     {
00048         assert( idx < 4 );
00049         uniqueGuides[idx] = source;
00050         ++numUniqueGuides;
00051     }
00052     return idx;
00053 }
00054 
00055 LVQDTargetCalculator::LVQDTargetCalculator( TargetCalculator* lambda_source,
00056                                             TargetCalculator* V_source,
00057                                             TargetCalculator* Q_source,
00058                                             TargetCalculator* delta_source )
00059     : numUniqueGuides( 0 )
00060 {
00061     lambdaIdx = add_source( lambda_source );
00062     vIdx      = add_source( V_source );
00063     qIdx      = add_source( Q_source );
00064     deltaIdx  = add_source( delta_source );
00065 }
00066 
00067 LVQDTargetCalculator::~LVQDTargetCalculator() {}
00068 
00069 bool LVQDTargetCalculator::have_surface_orient() const
00070 {
00071     return ( vIdx >= 0 );
00072 }
00073 
00074 bool LVQDTargetCalculator::get_3D_target( PatchData& pd,
00075                                           size_t element,
00076                                           Sample sample,
00077                                           MsqMatrix< 3, 3 >& W_out,
00078                                           MsqError& err )
00079 {
00080     double lambda[4];
00081     MsqMatrix< 3, 3 > V[4], Q[4], delta[4], W;
00082     bool valid;
00083 
00084     for( int i = 0; i < numUniqueGuides; ++i )
00085     {
00086         valid = uniqueGuides[i]->get_3D_target( pd, element, sample, W, err );
00087         if( MSQ_CHKERR( err ) || !valid ) return false;
00088         valid = factor_3D( W, lambda[i], V[i], Q[i], delta[i], err );
00089         if( MSQ_CHKERR( err ) || !valid ) return false;
00090     }
00091 
00092     if( vIdx >= 0 )
00093     {
00094         W_out = V[vIdx];
00095         if( lambdaIdx >= 0 ) W_out *= lambda[lambdaIdx];
00096         if( qIdx >= 0 ) W_out = W_out * Q[qIdx];
00097         if( deltaIdx >= 0 ) W_out = W_out * delta[deltaIdx];
00098     }
00099     else if( qIdx >= 0 )
00100     {
00101         W_out = Q[qIdx];
00102         if( lambdaIdx >= 0 ) W_out *= lambda[lambdaIdx];
00103         if( deltaIdx >= 0 ) W_out = W_out * delta[deltaIdx];
00104     }
00105     else if( deltaIdx >= 0 )
00106     {
00107         W_out = delta[deltaIdx];
00108         if( lambdaIdx >= 0 ) W_out *= lambda[lambdaIdx];
00109     }
00110     else if( lambdaIdx >= 0 )
00111     {
00112         W_out = MsqMatrix< 3, 3 >( lambda[lambdaIdx] );
00113     }
00114     else
00115     {
00116         W_out = MsqMatrix< 3, 3 >( 1.0 );
00117     }
00118 
00119     return true;
00120 }
00121 
00122 bool LVQDTargetCalculator::evaluate_guide_2D( PatchData& pd,
00123                                               size_t element,
00124                                               Sample sample,
00125                                               int idx,
00126                                               double& lambda,
00127                                               MsqMatrix< 3, 2 >& V,
00128                                               MsqMatrix< 2, 2 >& Q,
00129                                               MsqMatrix< 2, 2 >& delta,
00130                                               MsqError& err )
00131 {
00132     bool valid;
00133     if( uniqueGuides[idx]->have_surface_orient() )
00134     {
00135         MsqMatrix< 3, 2 > W;
00136         valid = uniqueGuides[idx]->get_surface_target( pd, element, sample, W, err );
00137         if( MSQ_CHKERR( err ) || !valid ) return false;
00138         valid = factor_surface( W, lambda, V, Q, delta, err );
00139         if( MSQ_CHKERR( err ) || !valid ) return false;
00140     }
00141     else
00142     {
00143         MsqMatrix< 2, 2 > W;
00144         valid = uniqueGuides[idx]->get_2D_target( pd, element, sample, W, err );
00145         if( MSQ_CHKERR( err ) || !valid ) return false;
00146         MsqMatrix< 2, 2 > junk;
00147         valid = factor_2D( W, lambda, junk, Q, delta, err );
00148         if( MSQ_CHKERR( err ) || !valid ) return false;
00149         V = MsqMatrix< 3, 2 >( 1.0 );
00150     }
00151     return true;
00152 }
00153 
00154 bool LVQDTargetCalculator::get_2D_target( PatchData& pd,
00155                                           size_t element,
00156                                           Sample sample,
00157                                           MsqMatrix< 2, 2 >& W_out,
00158                                           MsqError& err )
00159 {
00160     double lambda[4];
00161     MsqMatrix< 3, 2 > V[4];
00162     MsqMatrix< 2, 2 > W, Q[4], delta[4];
00163     bool valid;
00164 
00165     if( have_surface_orient() )
00166     {
00167         MSQ_SETERR( err )( "Incorrect surface mesh target type", MsqError::INTERNAL_ERROR );
00168         return false;
00169     }
00170 
00171     for( int i = 0; i < numUniqueGuides; ++i )
00172     {
00173         valid = evaluate_guide_2D( pd, element, sample, i, lambda[i], V[i], Q[i], delta[i], err );
00174         if( MSQ_CHKERR( err ) || !valid ) return false;
00175     }
00176 
00177     if( qIdx >= 0 )
00178     {
00179         W_out = Q[qIdx];
00180         if( lambdaIdx >= 0 ) W_out *= lambda[lambdaIdx];
00181         if( deltaIdx >= 0 ) W_out = W_out * delta[deltaIdx];
00182     }
00183     else if( deltaIdx >= 0 )
00184     {
00185         W_out = delta[deltaIdx];
00186         if( lambdaIdx >= 0 ) W_out *= lambda[lambdaIdx];
00187     }
00188     else if( lambdaIdx >= 0 )
00189     {
00190         W_out = MsqMatrix< 2, 2 >( lambda[lambdaIdx] );
00191     }
00192     else
00193     {
00194         W_out = MsqMatrix< 2, 2 >( 1.0 );
00195     }
00196 
00197     return true;
00198 }
00199 
00200 bool LVQDTargetCalculator::get_surface_target( PatchData& pd,
00201                                                size_t element,
00202                                                Sample sample,
00203                                                MsqMatrix< 3, 2 >& W_out,
00204                                                MsqError& err )
00205 {
00206     double lambda[4];
00207     MsqMatrix< 3, 2 > V[4], W;
00208     MsqMatrix< 2, 2 > Q[4], delta[4], junk, W2;
00209     bool valid;
00210 
00211     if( !have_surface_orient() )
00212     {
00213         MSQ_SETERR( err )( "Incorrect surface mesh target type", MsqError::INTERNAL_ERROR );
00214         return false;
00215     }
00216 
00217     for( int i = 0; i < numUniqueGuides; ++i )
00218     {
00219         valid = evaluate_guide_2D( pd, element, sample, i, lambda[i], V[i], Q[i], delta[i], err );
00220         if( MSQ_CHKERR( err ) || !valid ) return false;
00221     }
00222 
00223     if( vIdx >= 0 )
00224     {
00225         W_out = V[vIdx];
00226         if( lambdaIdx >= 0 ) W_out *= lambda[lambdaIdx];
00227         if( qIdx >= 0 ) W_out = W_out * Q[qIdx];
00228         if( deltaIdx >= 0 ) W_out = W_out * delta[deltaIdx];
00229     }
00230     else if( qIdx >= 0 )
00231     {
00232         W_out( 0, 0 ) = Q[qIdx]( 0, 0 );
00233         W_out( 0, 1 ) = Q[qIdx]( 0, 1 );
00234         W_out( 1, 0 ) = Q[qIdx]( 1, 0 );
00235         W_out( 1, 1 ) = Q[qIdx]( 1, 1 );
00236         W_out( 2, 0 ) = 0.0;
00237         W_out( 2, 1 ) = 0.0;
00238         if( lambdaIdx >= 0 ) W_out *= lambda[lambdaIdx];
00239         if( deltaIdx >= 0 ) W_out = W_out * delta[deltaIdx];
00240     }
00241     else if( deltaIdx >= 0 )
00242     {
00243         W_out( 0, 0 ) = delta[deltaIdx]( 0, 0 );
00244         W_out( 0, 1 ) = delta[deltaIdx]( 0, 1 );
00245         W_out( 1, 0 ) = delta[deltaIdx]( 1, 0 );
00246         W_out( 1, 1 ) = delta[deltaIdx]( 1, 1 );
00247         W_out( 2, 0 ) = 0.0;
00248         W_out( 2, 1 ) = 0.0;
00249         if( lambdaIdx >= 0 ) W_out *= lambda[lambdaIdx];
00250     }
00251     else if( lambdaIdx >= 0 )
00252     {
00253         W_out = MsqMatrix< 3, 2 >( lambda[lambdaIdx] );
00254     }
00255     else
00256     {
00257         W_out = MsqMatrix< 3, 2 >( 1.0 );
00258     }
00259 
00260     return true;
00261 }
00262 
00263 }  // namespace MBMesquite
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines