SundanceCellCurvePredicate.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                             Sundance
00005 //                 Copyright 2011 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
00041 
00042 /*
00043  * SundanceCellCurvePredicate.cpp
00044  *
00045  *  Created on: Feb 19, 2010
00046  *      Author: benk
00047  */
00048 
00049 #include "SundanceCellCurvePredicate.hpp"
00050 #include "SundanceStdMathOps.hpp"
00051 
00052 using namespace Sundance;
00053 
00054 #define SIGN(X) ((X>0.0)?1:-1)
00055 
00056 bool CellCurvePredicate::lessThan(const CellPredicateBase* other) const
00057 {
00058   const CellCurvePredicate* S = dynamic_cast<const CellCurvePredicate*>(other);
00059 
00060   TEUCHOS_TEST_FOR_EXCEPTION( S== 0,
00061                      std::logic_error,
00062                      "argument " << other->toXML()
00063                      << " to CellCurvePredicate::lessThan() should be "
00064                      "a CellCurvePredicate pointer.");
00065   // This comparison is IMPORTANT, to determine RQCs
00066   return OrderedPair<ParametrizedCurve, int>(curve_, (int)filterMode_)
00067       < OrderedPair<ParametrizedCurve, int>(S->curve_, (int)S->filterMode_);
00068 }
00069 
00070 void CellCurvePredicate::testBatch(const Array<int>& cellLID,
00071                                         Array<int>& results) const
00072 {
00073   results.resize(cellLID.size());
00074   double eps = 1e-14;
00075 
00076   if (cellDim()==0)
00077     {
00078     switch (filterMode_){
00079     case Outside_Curve:
00080         for (int i=0; i<cellLID.size(); i++)
00081           if ( curve_.curveEquation( mesh().nodePosition(cellLID[i])) >= 0.0 )
00082                 results[i] = true;
00083           else
00084             results[i] = false;
00085       break;
00086     case Inside_Curve:
00087         for (int i=0; i<cellLID.size(); i++)
00088           if ( curve_.curveEquation( mesh().nodePosition(cellLID[i])) <= 0.0 )
00089                 results[i] = true;
00090           else
00091             results[i] = false;
00092       break;
00093     case On_Curve:
00094         for (int i=0; i<cellLID.size(); i++)
00095           if ( fabs(curve_.curveEquation( mesh().nodePosition(cellLID[i]))) < eps )
00096                 results[i] = true;
00097           else
00098             results[i] = false;
00099       break;
00100     }
00101     }
00102   else
00103     {
00104 
00105     switch (mesh().spatialDim()) {
00106     case 2:{
00107       // for 2D we test the intersection , in order to determine if the cell is cut or not
00108         // check for intersection of the edges, rework this
00109         // - we must have al least two DIFFERENT intersection point in order to have a clear intersection
00110         Array<int> facetLIDs;
00111         Array<int> facetSigns;
00112         Array<double> equSum( cellLID.size() , 0.0 );
00113         int nf = mesh().numFacets(cellDim(), cellLID[0], 0);
00114         int spaceDim = mesh().spatialDim() ;
00115         mesh().getFacetLIDs(cellDim(), cellLID, 0, facetLIDs, facetSigns);
00116         for (int c=0; c<cellLID.size(); c++)
00117           {
00118             results[c] = true;
00119             if (filterMode_ == On_Curve) results[c] = false;
00120             int curve_sign = 0;
00121             for (int f=0; f<nf; f++)
00122               {
00123               int fLID = facetLIDs[c*nf + f];
00124               double curveEqu = curve_.curveEquation( mesh().nodePosition(fLID) );
00125               //SUNDANCE_MSG3( 4 , " node: " << mesh().nodePosition(fLID) << " curveEq:" << curveEqu);
00126               switch (filterMode_){
00127               case Outside_Curve:{
00128                 if ( curveEqu <= 0.0 ) {
00129                    results[c] = false;
00130                 }
00131                 equSum[c] = equSum[c] + curveEqu;
00132                 break;}
00133               case Inside_Curve: {
00134                 if ( curveEqu >= 0.0 ) {
00135                    results[c] = false;
00136                 }
00137                 equSum[c] = equSum[c] + curveEqu;
00138                 break; }
00139               case On_Curve:
00140                 if (f == 0){
00141                   curve_sign = SIGN(curveEqu);
00142                   equSum[c] = equSum[c] + curveEqu;
00143                 } else {
00144                   if ( curve_sign != SIGN(curveEqu) ){
00145                        results[c] = true;
00146                   }
00147                     equSum[c] = equSum[c] + curveEqu;
00148                 }
00149                 break;
00150               }
00151               } // from for loop over points
00152           } // loop over cells
00153 
00154           if ( (spaceDim == 2) && (cellDim() == 2) )
00155           {
00156             int nrEdge = mesh().numFacets(cellDim(), cellLID[0], 1 ) , nrPoints = 0 ;
00157             Array<int> edgeLIDs;
00158             Array<int> edgeLID(1);
00159             Array<int> cLID(1);
00160             Array<int> edgeSigns;
00161             Array<int> pointsOfEdgeLIDs;
00162             Array<bool> hasIntersectionPoints( cellLID.size() , false );
00163             Array<Point> intPoints;
00164             // for each cell look get all edge and test for intersection
00165             for (int c=0; c<cellLID.size(); c++)
00166             {
00167               Point p0 , start, end;
00168               int nrIntPoint = 0;
00169               cLID[0] = cellLID[c];
00170               mesh().getFacetLIDs(cellDim(), cLID, 1 , edgeLIDs, edgeSigns);
00171               // for each edge test intersection
00172               for (int edgeI = 0 ; edgeI < nrEdge ; edgeI++ ){
00173                 edgeLID[0] = edgeLIDs[edgeI];
00174                 mesh().getFacetLIDs(1, edgeLID, 0 , pointsOfEdgeLIDs, edgeSigns);
00175                 start = mesh().nodePosition(pointsOfEdgeLIDs[0]);
00176                 end = mesh().nodePosition(pointsOfEdgeLIDs[1]);
00177                 // once we have the start and end point of the edge then test for intersection points
00178                 curve_.returnIntersectPoints( start , end , nrPoints , intPoints);
00179                 for (int p = 0 ;p < nrPoints ; p++){
00180                   // test if we have more than two intersection points
00181                   if (nrIntPoint == 0){
00182                     p0 = intPoints[p]; nrIntPoint++;
00183                   } else {
00184                     double dist = ::sqrt( (p0 - intPoints[p])*(p0 - intPoints[p]) );
00185                     if (dist > eps){
00186                       // here we found two different intersection points
00187                       hasIntersectionPoints[c] = true;
00188                       continue;
00189                     }
00190                   }
00191                 }
00192                 // if we already found intersection points then stop
00193                 if (hasIntersectionPoints[c]) continue;
00194               }
00195             } // for loop over cells
00196 
00197             // for each cell cell overwrite the result if there are intersection points
00198             int count = 0;
00199             switch (filterMode_){
00200             case Outside_Curve:{
00201               for (int c=0; c<cellLID.size(); c++){
00202                 //SUNDANCE_MSG3( 4 , "filterMode_ :" << filterMode_ << " , BEFORE result:" << results[c] );
00203                 if (hasIntersectionPoints[c]) results[c] = false;
00204                 // if no intersection point then the cell must be complete in or out, this we can test with the sum
00205                 else results[c] = (equSum[c] >= 0);
00206                 //SUNDANCE_MSG3( 4 , "filterMode_ :" << filterMode_ << " , result:" << results[c] << " , equSum[c]:" << equSum[c]
00207                 //                   << " , hasIntersectionPoints[c]:" << hasIntersectionPoints[c]);
00208               } }
00209               break;
00210             case Inside_Curve:{
00211               for (int c=0; c<cellLID.size(); c++){
00212                 //SUNDANCE_MSG3( 4 , "filterMode_ :" << filterMode_ << " , BEFORE result:" << results[c] );
00213                 if (hasIntersectionPoints[c]) results[c] = false;
00214                 // if no intersection point then the cell must be complete in or out, this we can test with the sum
00215                 else results[c] = (equSum[c] <= 0);
00216                 //SUNDANCE_MSG3( 4 , "filterMode_ :" << filterMode_ << " , result:" << results[c] << " , equSum[c]:" << equSum[c]
00217                 //                   << " , hasIntersectionPoints[c]:" << hasIntersectionPoints[c]);
00218               } }
00219               break;
00220             case On_Curve:{
00221               for (int c=0; c<cellLID.size(); c++){
00222                 //SUNDANCE_MSG3( 4 , "filterMode_ :" << filterMode_ << " , BEFORE result:" << results[c] );
00223                 if (hasIntersectionPoints[c]) results[c] = true;
00224                 else results[c] = false;
00225                 if (results[c]) {count++;}
00226                 //SUNDANCE_MSG3( 4 , "filterMode_ :" << filterMode_ << " cellLID["<<c<<"]=" << cellLID[c] <<
00227                 //    " , result:" << results[c] << " , equSum[c]:" << equSum[c]
00228                   //      << " , hasIntersectionPoints[c]:" << hasIntersectionPoints[c] << " cellNr=" << count);
00229               } }
00230               break;
00231             }
00232           }
00233     } break;
00234 
00235     // for 3D or 1D use the
00236     default:{
00237         Array<int> facetLIDs;
00238         Array<int> facetSigns;
00239         int nf = mesh().numFacets(cellDim(), cellLID[0], 0);
00240         mesh().getFacetLIDs(cellDim(), cellLID, 0, facetLIDs, facetSigns);
00241         for (int c=0; c<cellLID.size(); c++)
00242           {
00243             results[c] = true;
00244             if (filterMode_ == On_Curve) results[c] = false;
00245             int curve_sign = 0;
00246             for (int f=0; f<nf; f++)
00247               {
00248               int fLID = facetLIDs[c*nf + f];
00249               switch (filterMode_){
00250               case Outside_Curve:
00251                 if ( curve_.curveEquation( mesh().nodePosition(fLID) ) <= 0.0 ) {
00252                    results[c] = false;
00253                    continue;
00254                 }
00255                 break;
00256               case Inside_Curve:
00257                 if ( curve_.curveEquation( mesh().nodePosition(fLID) ) >= 0.0 ) {
00258                    results[c] = false;
00259                    continue;
00260                 }
00261                 break;
00262               case On_Curve:
00263                 if (f == 0){
00264                   curve_sign = SIGN(curve_.curveEquation( mesh().nodePosition(fLID)));
00265                 } else {
00266                   if ( curve_sign != SIGN(curve_.curveEquation( mesh().nodePosition(fLID))) ){
00267                        results[c] = true;
00268                        continue;
00269                   }
00270                 }
00271                 break;
00272               }
00273               } // from for loop
00274             //SUNDANCE_MSG3( 4 , "filterMode_ :" << filterMode_ << " cellLID=" << cellLID[c] << " , result:" << results[c]);
00275           } // loop over cells
00276     } break;
00277     }
00278 
00279 
00280     }
00281 }
00282 
00283 XMLObject CellCurvePredicate::toXML() const
00284 {
00285   XMLObject rtn("SundanceCellCurvePredicate");
00286   return rtn;
00287 }

Site Contact