SundanceCurveIntegralCalc.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 /*
00044  * SundanceCurveIntagralCalc.cpp
00045  *
00046  *  Created on: Sep 2, 2010
00047  *      Author: benk
00048  */
00049 
00050 #include "SundanceCurveIntegralCalc.hpp"
00051 #include "SundanceOut.hpp"
00052 #include "PlayaTabs.hpp"
00053 #include "SundanceCellJacobianBatch.hpp"
00054 #include "SundancePolygon2D.hpp"
00055 #include "SundancePolygonQuadrature.hpp"
00056 #include "SundanceSurf3DCalc.hpp"
00057 #include "SundanceSurfQuadrature.hpp"
00058 
00059 using namespace Sundance;
00060 
00061 CurveIntegralCalc::CurveIntegralCalc() {
00062   //nothing to do
00063 }
00064 
00065 void CurveIntegralCalc::getCurveQuadPoints(CellType  maxCellType ,
00066                  int maxCellLID ,
00067                  const Mesh& mesh ,
00068                  const ParametrizedCurve& paramCurve,
00069                  const QuadratureFamily& quad ,
00070                  Array<Point>& curvePoints ,
00071                  Array<Point>& curveDerivs ,
00072                  Array<Point>& curveNormals ){
00073 
00074   int verb = 0;
00075   Tabs tabs;
00076 
00077     // get all the points from the maxDimCell
00078   int nr_point = mesh.numFacets( mesh.spatialDim() , 0 , 0);
00079   Array<Point> maxCellsPoints(nr_point);
00080   int tmp_i , point_LID;
00081 
00082   SUNDANCE_MSG3(verb, tabs << "CurveIntegralCalc::getCurveQuadPoints nr points per cell: " << nr_point)
00083   for (int jj = 0 ; jj < nr_point ; jj++){
00084     point_LID = mesh.facetLID( mesh.spatialDim() , maxCellLID , 0 , jj , tmp_i );
00085     maxCellsPoints[jj] = mesh.nodePosition(point_LID);
00086     SUNDANCE_MSG3(verb, tabs << " max cell point p[" << jj << "]:"<< maxCellsPoints[jj]);
00087   }
00088 
00089   // if we have a polygon in 2D then use specialized curve integrals
00090   if (usePolygoneCurveQuadrature( maxCellType , mesh , paramCurve)){
00091     // specialized curve integral
00092     CurveIntegralCalc::getCurveQuadPoints_polygon( maxCellLID , maxCellType , mesh , maxCellsPoints , paramCurve,
00093                     quad , curvePoints , curveDerivs , curveNormals);
00094   } else {
00095     // general curve integral
00096     if ( use3DSurfQuadrature( maxCellType , mesh ) ){
00097       CurveIntegralCalc::getSurfQuadPoints(maxCellLID , maxCellType , mesh , maxCellsPoints , paramCurve,
00098           quad , curvePoints , curveDerivs , curveNormals);
00099        //CurveIntegralCalc::getCurveQuadPoints_line( maxCellLID , maxCellType , mesh , maxCellsPoints , paramCurve,
00100         //                quad , curvePoints , curveDerivs , curveNormals);
00101     } else {
00102         CurveIntegralCalc::getCurveQuadPoints_line( maxCellLID , maxCellType , mesh , maxCellsPoints , paramCurve,
00103                   quad , curvePoints , curveDerivs , curveNormals);
00104     }
00105   }
00106 
00107 }
00108 
00109 void CurveIntegralCalc::getCurveQuadPoints_line(
00110                                    int  maxCellLID ,
00111                                    CellType  maxCellType ,
00112                                    const Mesh& mesh ,
00113                                    const Array<Point>& cellPoints,
00114                    const ParametrizedCurve& paramCurve,
00115                    const QuadratureFamily& quad ,
00116                    Array<Point>& curvePoints ,
00117                    Array<Point>& curveDerivs ,
00118                    Array<Point>& curveNormals ){
00119 
00120   int verb = 0;
00121   Tabs tabs;
00122 
00123     // select the dimension of the curve
00124   switch (paramCurve.getCurveDim()){
00125     case 1: {
00126 
00127       SUNDANCE_MSG3(verb, tabs << "CurveIntegralCalc::getCurveQuadPoints_line, curve has ONE dimnesion")
00128       // 1D curve integral in 2D or 3D
00129 
00130       // first determine the two intersection points with the edges
00131       Point startPoint(0.0,0.0);
00132       Point endPoint(0.0,0.0);
00133         int nrPoints , total_points = 0 ;
00134 
00135       switch (maxCellType){
00136         case QuadCell:{
00137           // loop over each edge and detect intersection point
00138           // there can be only one
00139           TEUCHOS_TEST_FOR_EXCEPTION( cellPoints.size() != 4 ,
00140               std::runtime_error ," CurveIntegralCalc::getCurveQuadPoints , QuadCell must have 4 points" );
00141         SUNDANCE_MSG3(verb, tabs << "CurveIntegralCalc::getCurveQuadPoints_line, on QuadCell")
00142           Array<Point> result(0);
00143           int edegIndex[4][2] = { {0,1} , {0,2} , {1,3} , {2,3} };
00144 
00145           // loop over the edges
00146           for (int jj = 0 ; jj < 4 ; jj++ ){
00147           paramCurve.returnIntersectPoints(cellPoints[edegIndex[jj][0]], cellPoints[edegIndex[jj][1]], nrPoints , result);
00148           // test if we have intersection point
00149             if (nrPoints == 1){
00150               if (total_points == 0) startPoint = result[0];
00151               else endPoint = result[0];
00152               SUNDANCE_MSG3(verb, tabs << "found Int. point:" << result[0]);
00153             total_points += nrPoints;
00154             }
00155           SUNDANCE_MSG3(verb, tabs << "ind:" << jj << ", nr Int points :" << nrPoints
00156               << " , start:" << startPoint << ", end:"<< endPoint);
00157           // if we have more than one intersection point then just ignore that edge
00158           TEUCHOS_TEST_FOR_EXCEPTION( nrPoints > 1 ,
00159               std::runtime_error , " CurveIntegralCalc::getCurveQuadPoints , QuadCell one edge " << jj << " , can have only one intersection point"
00160               << " edgeP0:" << cellPoints[edegIndex[jj][0]] << " edgeP1:" << cellPoints[edegIndex[jj][1]] );
00161           }
00162           // test if we have too much intersection points
00163           TEUCHOS_TEST_FOR_EXCEPTION( total_points > 2 ,std::runtime_error , " CurveIntegralCalc::getCurveQuadPoints total_points > 2 : " << total_points );
00164         SUNDANCE_MSG3(verb, tabs << "CurveIntegralCalc::getCurveQuadPoints_line, end finding intersection points")
00165         } break;
00166         case TriangleCell:{
00167           TEUCHOS_TEST_FOR_EXCEPTION( cellPoints.size() != 3 , std::runtime_error , " CurveIntegralCalc::getCurveQuadPoints , TriangleCell must have 3 points" );
00168           Array<Point> result;
00169           int edegIndex[3][2] = { {0,1} , {0,2} , {1,2} };
00170 
00171           // loop over the edges
00172           for (int jj = 0 ; jj < 3 ; jj++ ){
00173           paramCurve.returnIntersectPoints(cellPoints[edegIndex[jj][0]], cellPoints[edegIndex[jj][1]], nrPoints , result);
00174           // test if we have intersection point
00175             if (nrPoints == 1){
00176               if (total_points == 0) startPoint = result[0];
00177               else endPoint = result[0];
00178               SUNDANCE_MSG3(verb, tabs << "found Int. point:" << result[0]);
00179             total_points += nrPoints;
00180             }
00181             // if we have more than one intersection point then just ignore that edge
00182             TEUCHOS_TEST_FOR_EXCEPTION( nrPoints > 1 ,
00183               std::runtime_error , " CurveIntegralCalc::getCurveQuadPoints , TriangleCell one edge " << jj << " , can have only one intersection point"
00184               << " edgeP0:" << cellPoints[edegIndex[jj][0]] << " edgeP1:" << cellPoints[edegIndex[jj][1]] );
00185           }
00186           // test if we have too much intersection points
00187           TEUCHOS_TEST_FOR_EXCEPTION( total_points > 2 ,std::runtime_error , " CurveIntegralCalc::getCurveQuadPoints total_points > 2 : " << total_points );
00188         } break;
00189         default : {
00190           TEUCHOS_TEST_FOR_EXCEPTION( true , std::runtime_error , "CurveIntegralCalc::getCurveQuadPoints , Unknown Cell in 2D" );
00191         }
00192       }
00193       // test for to many intersection points
00194       TEUCHOS_TEST_FOR_EXCEPTION( total_points > 2 ,std::runtime_error , " CurveIntegralCalc::getCurveQuadPoints , no much intersection points: " << total_points);
00195 
00196       // -> having the intersection points now we have to determine the:
00197       // quad points and the gradients at the points(which norm will be in the integration)
00198       // and the normalized normal vector (normalized since we need the sin and cos for Nitsche )
00199       // -> as a very simple approach we consider the curve as a line between intersection points "startPoint -> endPoint"
00200 
00201       // in the X direction the line should always have increasing values
00202       if (startPoint[0] > endPoint[0]){
00203         Point tmp = startPoint;
00204         startPoint = endPoint;
00205         endPoint = tmp;
00206       }
00207       SUNDANCE_MSG3(verb, tabs << "start end and points , start:" << startPoint << ", end:"<< endPoint)
00208 
00209       // get the quadrature points for the line
00210       Array<Point> quadPoints;
00211       Array<double> quadWeights;
00212       quad.getPoints( LineCell , quadPoints , quadWeights );
00213       int nr_quad_points = quadPoints.size();
00214 
00215       // The intersection points , we distribute the points along the line
00216       curvePoints.resize(nr_quad_points);
00217       SUNDANCE_MSG3(verb, tabs << " setting reference quadrature points" );
00218       for (int ii = 0 ; ii < nr_quad_points ; ii++) {
00219         SUNDANCE_MSG3(verb, tabs << " nr:" << ii << " Line quad point:" << quadPoints[ii] << ", line:" << (endPoint - startPoint));
00220         curvePoints[ii] = startPoint + quadPoints[ii][0]*(endPoint - startPoint);
00221 
00222         // we transform the intersection points to the reference cell
00223         // this should work for unstructured case
00224         // - get the Jacobian of the cells
00225         // - get the inverse of this Jacobian
00226         // - apply this Jacobian to the physical points (pos0 = (0,0))of the cell
00227 
00228         Array<int> cellLID(1); cellLID[0] = maxCellLID;
00229           CellJacobianBatch JBatch;
00230           JBatch.resize(1, 2, 2);
00231         mesh.getJacobians(2, cellLID , JBatch);
00232         double pointc[2] = { curvePoints[ii][0] - cellPoints[0][0] , curvePoints[ii][1] - cellPoints[0][1]};
00233         JBatch.applyInvJ(0, pointc , 1 , false);
00234         curvePoints[ii][0] = pointc[0];
00235         curvePoints[ii][1] = pointc[1];
00236 
00237         SUNDANCE_MSG3(verb, tabs << " quad point nr:" << ii << " = " << curvePoints[ii]);
00238       }
00239 
00240 
00241       // The derivatives at points, for this simple method are simple and constant over the whole quadrature
00242       curveDerivs.resize(nr_quad_points);
00243       Point dist_point(endPoint[0] - startPoint[0] , endPoint[1] - startPoint[1]);
00244       SUNDANCE_MSG3(verb, tabs << " setting derivative values points" );
00245       for (int ii = 0 ; ii < nr_quad_points ; ii++) {
00246         curveDerivs[ii] = endPoint - startPoint;
00247         SUNDANCE_MSG3(verb, tabs << " curve Derivatives point nr:" << ii << " = " << curveDerivs[ii]);
00248       }
00249 
00250 
00251       // calculate the norms to the curve
00252       curveNormals.resize(nr_quad_points);
00253 
00254       // this is a shorter variant
00255       SUNDANCE_MSG3(verb, tabs << " setting normal values at points" );
00256       for (int ii = 0 ; ii < nr_quad_points ; ii++) {
00257         Point norm_vec = Point(-curveDerivs[ii][1], curveDerivs[ii][0]);
00258         norm_vec = norm_vec / ::sqrt(norm_vec*norm_vec);
00259         double relative_length = 1e-2 * ::sqrt((endPoint - startPoint)*(endPoint - startPoint));
00260         if ( paramCurve.curveEquation( startPoint + relative_length*norm_vec ) > 0 ) {
00261           curveNormals[ii] = -norm_vec;
00262         }
00263         else {
00264           curveNormals[ii] = norm_vec;
00265         }
00266         SUNDANCE_MSG3(verb, tabs << " curve Normals point nr:" << ii << " = " << curveNormals[ii]);
00267       }
00268 
00269 
00270     } break;
00271 
00272 //========================== END 1D curve in 2D context ==========================
00273 
00274 
00275 
00276     case 2: {
00277 // ====================2D curve integral in 3D context =============================
00278 
00279       // take the intersection with each edge,
00280       // from these intersection points construct one 3D (convex) polygon (from triangle to hexadron)
00281       //  - maybe divide the polygons into many triangles
00282       // map the quadrature points somehow inside this surface
00283 
00284       // here we consider a simple surface, as it is in bilinear interpolation
00285       Tabs tabs;
00286       switch (maxCellType){
00287         case BrickCell:{
00288           int edegIndex[12][2] = { {0,1} , {0,2} , {0,4} , {1,3} , {1,5} , {2,3} , {2,6} , {3,7} ,
00289                                {4,5} , {4,6} , {5,7} , {6,7} };
00290           int faceEdges[6][4]  = { {0,1,3,5} , {0,2,4,8} , {1,2,6,9} , {3,4,7,10} , {5,6,7,11} , {8,9,10,11} };
00291           // loop over the edges
00292           int t_inters_points = 0;
00293           int nrPoints = 0;
00294           Array<Point> edgeIntersectPoint(t_inters_points);
00295           Array<int> edgeIndex(t_inters_points);
00296           Array<int> edgePointI(12,-1);
00297 
00298           // loop over the edges and get the intersection points
00299           for (int jj = 0 ; jj < 12 ; jj++ ){
00300             Array<Point> result(0);
00301           paramCurve.returnIntersectPoints(cellPoints[edegIndex[jj][0]], cellPoints[edegIndex[jj][1]], nrPoints , result);
00302           // test if we have intersection point
00303             if (nrPoints > 0){
00304               edgeIntersectPoint.resize( t_inters_points + 1 );
00305               edgeIndex.resize( t_inters_points + 1 );
00306               edgeIntersectPoint[t_inters_points] = result[0];
00307               edgeIndex[t_inters_points] = jj;
00308               edgePointI[jj] = t_inters_points;
00309               SUNDANCE_MSG3(verb, tabs << "found Int. point [" << t_inters_points <<"]=" << result[0]);
00310               t_inters_points++;
00311             }
00312           SUNDANCE_MSG3(verb, tabs << "ind:" << jj << ", nr Int points :" << nrPoints );
00313           TEUCHOS_TEST_FOR_EXCEPTION( nrPoints > 1 ,
00314               std::runtime_error , " CurveIntegralCalc::getCurveQuadPoints , QuadCell one edge " << jj << " , can have only one intersection point" );
00315           } // getting intersection points
00316 
00317 
00318           // -------- get the point which is nearest to the other points ---------
00319           Array<double> totDist(t_inters_points);
00320           // calculate the distance from each point to each point
00321           SUNDANCE_MSG3(verb, tabs << " Calculating distances ");
00322           for (int i = 0 ; i < t_inters_points ; i++){
00323             double sum = 0.0;
00324             for (int j = 0 ; j < t_inters_points ; j++){
00325               sum = sum + ::sqrt(edgeIntersectPoint[i]*edgeIntersectPoint[j]);
00326             }
00327             totDist[i] = sum;
00328           }
00329           // find the point which is mostly in the middle
00330           int minIndex = 0;
00331           for (int i = 1 ; i < t_inters_points ; i++){
00332             if (totDist[i] < totDist[minIndex]) minIndex = i;
00333           }
00334           SUNDANCE_MSG3(verb, tabs << " minIndex = " << minIndex );
00335 
00336 
00337           // --------- discover the polygon and the triangles-----------
00338           // todo: what if there is no or only too few intersection points
00339           int intersTriangleInd = 0;
00340           int nrTriangles = t_inters_points-2;
00341           Array<int> triangles(3*nrTriangles,-1);
00342           Array<double> triangle_area(nrTriangles,0.0);
00343           double total_area = 0.0;
00344           SUNDANCE_MSG3(verb, tabs << " nrTriangles = " << nrTriangles );
00345           int intPointProc = -1;
00346           int intPointProc_lastNeigh = -1;
00347 
00348 // -------------------------------------
00349           // get one neighboring intersection point of the "minIndex", this will be the starting direction of the polygon
00350           for (int jj = 0 ; jj < 6 ; jj++ )
00351           {
00352             int nrIpointPerFace = 0;
00353             int firstPI = -1 , secondPI = -1;
00354             // loop over each edge in one face
00355             for (int ii = 0 ; ii < 4 ; ii++){
00356               // if this edge has one intersection point
00357               if ( edgePointI[faceEdges[jj][ii]] >= 0){
00358                 if (nrIpointPerFace > 0){
00359                   secondPI = edgePointI[faceEdges[jj][ii]];
00360                 }else{
00361                   firstPI = edgePointI[faceEdges[jj][ii]];
00362                 }
00363                 TEUCHOS_TEST_FOR_EXCEPTION( nrIpointPerFace > 2 , std::runtime_error,"getCurveQuadPoints , nrIpointPerFace > 2 , " << nrIpointPerFace );
00364                 nrIpointPerFace++;
00365               }
00366             }
00367             TEUCHOS_TEST_FOR_EXCEPTION( nrIpointPerFace == 1 , std::runtime_error,"getCurveQuadPoints , nrIpointPerFace == 1 , " << nrIpointPerFace );
00368             // Found the first neighboring point of "minIndex"
00369             if (( nrIpointPerFace > 1) && ((minIndex == firstPI) || (minIndex == secondPI) )){
00370                 SUNDANCE_MSG3(verb, tabs << " Found  starting line:" << firstPI << " -> " << secondPI);
00371                 intPointProc_lastNeigh = minIndex;
00372                 if (minIndex == firstPI){
00373                   intPointProc = secondPI;
00374                 }else{
00375                   intPointProc = firstPI;
00376                 }
00377                 // once we found then break the current for loop
00378                 break;
00379             }
00380           }
00381           TEUCHOS_TEST_FOR_EXCEPTION( intPointProc < 0 , std::runtime_error,"getCurveQuadPoints , intPointProc < 0 , " << intPointProc );
00382           // store this as act. point and get the next one(which is not neighbor to "minIndex") which is not the one which we already had
00383             // here we create all triangles, by traversing the polygon in one direction, so that the mapping will be continous
00384             for (int pI = 0 ; pI < nrTriangles; pI++)
00385             {
00386               // for each new
00387             for (int jj = 0 ; jj < 6 ; jj++ )
00388             {
00389               int nrIpointPerFace = 0;
00390               int firstPI = -1 , secondPI = -1;
00391               // loop over each edge in one face
00392               for (int ii = 0 ; ii < 4 ; ii++){
00393                 // if this edge has one intersection point
00394                 if ( edgePointI[faceEdges[jj][ii]] >= 0){
00395                   if (nrIpointPerFace > 0){
00396                     secondPI = edgePointI[faceEdges[jj][ii]];
00397                   }else{
00398                     firstPI = edgePointI[faceEdges[jj][ii]];
00399                   }
00400                   TEUCHOS_TEST_FOR_EXCEPTION( nrIpointPerFace > 2 , std::runtime_error,"getCurveQuadPoints , nrIpointPerFace > 2 , " << nrIpointPerFace );
00401                   nrIpointPerFace++;
00402                 }
00403               }
00404               TEUCHOS_TEST_FOR_EXCEPTION( nrIpointPerFace == 1 , std::runtime_error,"getCurveQuadPoints , nrIpointPerFace == 1 , " << nrIpointPerFace );
00405               // condition to find the neighbor of "intPointProc" but not the one which has been already found
00406               if (( nrIpointPerFace > 1) && ((intPointProc == firstPI) || (intPointProc == secondPI))
00407                   && ((intPointProc_lastNeigh != firstPI) && (intPointProc_lastNeigh != secondPI)))
00408               {
00409                   SUNDANCE_MSG3(verb, tabs << " Found next line:" << firstPI << " -> " << secondPI);
00410                   if (intPointProc == firstPI){
00411                     intPointProc = secondPI;
00412                     intPointProc_lastNeigh = firstPI;
00413                   }else{
00414                     intPointProc = firstPI;
00415                     intPointProc_lastNeigh = secondPI;
00416                   }
00417                   // add triangle
00418                   triangles[intersTriangleInd] = minIndex;
00419                   triangles[intersTriangleInd+1] = intPointProc_lastNeigh;
00420                   triangles[intersTriangleInd+2] = intPointProc;
00421                   SUNDANCE_MSG3(verb, tabs << " Found triangle:" << minIndex << " , " << firstPI << " , " << secondPI);
00422                   Point v1 = edgeIntersectPoint[firstPI] - edgeIntersectPoint[minIndex];
00423                   Point v2 = edgeIntersectPoint[secondPI] - edgeIntersectPoint[minIndex];
00424                   Point areaV = cross(v1,v2);
00425                   SUNDANCE_MSG3(verb, tabs << " TriangINdex = " << intersTriangleInd << " , area = " << ::sqrt(areaV*areaV));
00426                   triangle_area[ intersTriangleInd/3 ] = ::sqrt(areaV*areaV) / (double)2.0 ; // div by 2 to get the are of the triangle
00427                   total_area = total_area + triangle_area[ intersTriangleInd/3 ];
00428                   intersTriangleInd = intersTriangleInd + 3;
00429                   // once we found the next triangle then break the current for loop
00430                   break;
00431               }
00432             }
00433           }
00434 // ---------------------------
00435           SUNDANCE_MSG3(verb, tabs << " END Found triangle  total_area=" << total_area);
00436 
00437 
00438           // if we have only 1 triangle (3 intersection points) then add to the longest edge one middle point
00439           // so that we will have at least 2 triangles
00440           if (t_inters_points < 4){
00441             // 0,1,2
00442             SUNDANCE_MSG3(verb, tabs << " Add one additional point to have at least 2 triangles ");
00443             int longEdI1 = -1 , longEdI2 = -1;
00444             for (int ii = 0 ; ii < t_inters_points ; ii++)
00445               if ( (ii != minIndex) ){
00446                 longEdI1 = ii;
00447                 break;
00448               }
00449             for (int ii = 0 ; ii < t_inters_points ; ii++)
00450               if ( (ii != minIndex) && (ii != longEdI1) ){
00451                 longEdI2 = ii;
00452                 break;
00453               }
00454             TEUCHOS_TEST_FOR_EXCEPTION( (longEdI1 < 0)||(longEdI2 < 0), std::runtime_error," (longEdI1 < 0)||(longEdI2 < 0):" << longEdI1 << "," <<longEdI2);
00455 
00456             //add the middle point
00457             edgeIntersectPoint.resize(t_inters_points+1);
00458             edgeIntersectPoint[t_inters_points] = edgeIntersectPoint[longEdI1]/2.0 + edgeIntersectPoint[longEdI2]/2.0;
00459 
00460             int new_p = t_inters_points;
00461             t_inters_points += 1;
00462             nrTriangles += 1;
00463 
00464             // we'll have two new triangles
00465             triangles.resize(3*(nrTriangles));
00466             triangles[0] = minIndex;
00467             triangles[1] = longEdI1;
00468             triangles[2] = new_p;
00469             triangles[3] = minIndex;
00470             triangles[4] = new_p;
00471             triangles[5] = longEdI2;
00472                     // the are will be half of the original one
00473             triangle_area[0] = triangle_area[0] / 2.0;
00474             triangle_area.resize(2);
00475             triangle_area[1] = triangle_area[0];
00476           }
00477 
00478           // now map the quadrature points to the real cell (triangles)
00479         Array<Point> quadPoints;
00480         Array<double> quadWeights;
00481         quad.getPoints( QuadCell , quadPoints , quadWeights );
00482         int nr_quad_points = quadPoints.size();
00483 
00484         // --------- the quadrature points per cell ------------
00485         curvePoints.resize(nr_quad_points);
00486         Array<int> triangleInd(nr_quad_points,-1);
00487         SUNDANCE_MSG3(verb, tabs << " setting reference quadrature points" );
00488         for (int ii = 0 ; ii < nr_quad_points ; ii++) {
00489           //SUNDANCE_MSG3(verb, tabs << " nr:" << ii << " Quad quad point:" << quadPoints[ii] << ", line:" << (endPoint - startPoint));
00490           int tInd = -1;
00491           Point tmp(0.0,0.0,0.0);
00492           get3DRealCoordsOnSurf( quadPoints[ii] , cellPoints , triangles ,
00493                   nrTriangles , edgeIntersectPoint, tInd , tmp );
00494           triangleInd[ii] = tInd;
00495           curvePoints[ii] = tmp;
00496           //set the real quad points
00497           SUNDANCE_MSG3(verb, tabs << " quad point nr:" << ii << " = " << curvePoints[ii]);
00498         }
00499 
00500         // ------- The derivatives at points, for this simple method are simple and constant over the whole quadrature -----
00501         curveDerivs.resize(nr_quad_points);
00502         SUNDANCE_MSG3(verb, tabs << " setting surface values points" );
00503         for (int ii = 0 ; ii < nr_quad_points ; ii++) {
00504           // set the vector according to formula (only the vector noem will be taken in account)
00505           int tInd = triangleInd[ii] ;
00506           curveDerivs[ii] = Point( nrTriangles*triangle_area[tInd] , 0.0, 0.0 );
00507           //curveDerivs[ii] = Point( total_area , 0.0, 0.0 ); //total_area
00508           SUNDANCE_MSG3(verb, tabs << " curve Derivatives point nr:" << ii << " = " << curveDerivs[ii]);
00509         }
00510 
00511 
00512         // calculate the norms to the curve
00513         curveNormals.resize(nr_quad_points);
00514         SUNDANCE_MSG3(verb, tabs << " setting normal values at points" );
00515         for (int ii = 0 ; ii < nr_quad_points ; ii++) {
00516           int tInd = triangleInd[ii];
00517           // get the normal to the triangle
00518             Point norm_vec = cross( edgeIntersectPoint[triangles[3*tInd+1]] - edgeIntersectPoint[triangles[3*tInd]] ,
00519                 edgeIntersectPoint[triangles[3*tInd+2]] - edgeIntersectPoint[triangles[3*tInd]]);
00520             double relative_length = 1e-2 * ::sqrt(norm_vec*norm_vec);
00521             norm_vec = norm_vec / ::sqrt(norm_vec*norm_vec);
00522             if ( paramCurve.curveEquation( edgeIntersectPoint[triangles[3*tInd]] + relative_length*norm_vec ) > 0 ) {
00523               curveNormals[ii] = -norm_vec;
00524             }
00525             else {
00526               curveNormals[ii] = norm_vec;
00527             }
00528             SUNDANCE_MSG3(verb, tabs << " curve Normals point nr:" << ii << " = " << curveNormals[ii]);
00529         }
00530 
00531                 break;
00532         } // ----------- end brick cell --------------
00533         case TetCell:{
00534           // todo: later when this will be needed
00535           TEUCHOS_TEST_FOR_EXCEPTION( true, std::runtime_error,"CurveIntagralCalc::getCurveQuadPoints , not implemented for " << maxCellType );
00536           break;
00537         }
00538         default:{
00539           TEUCHOS_TEST_FOR_EXCEPTION( true, std::runtime_error,"CurveIntagralCalc::getCurveQuadPoints , not implemented for " << maxCellType );
00540         }
00541       }
00542       SUNDANCE_MSG3(verb, tabs << " END CurveIntagralCalc::getCurveQuadPoints");
00543     } break;
00544 
00545 //========================== END 2D curve in 3D context ==========================
00546 
00547     default: {
00548         // throw exception
00549     TEUCHOS_TEST_FOR_EXCEPTION( true, std::runtime_error,"CurveIntagralCalc::getCurveQuadPoints , curve dimension must be 1 or two ");
00550     }
00551   }
00552 }
00553 
00554 
00555 void CurveIntegralCalc::get3DRealCoordsOnSurf(const Point &refP ,
00556     const Array<Point>& cellPoints,
00557         const Array<int> &triangles ,
00558         const int nrTriag ,
00559         const Array<Point> edgeIntersectPoint,
00560         int &triagIndex ,
00561         Point &realPoint){
00562 
00563   Tabs tabs;
00564   int verb = 0;
00565   realPoint[0] = 0.0; realPoint[1] = 0.0; realPoint[2] = 0.0;
00566   SUNDANCE_MSG3(verb, tabs << " start get3DRealCoordsOnSurf refP="<<refP );
00567   Point v1;
00568   Point v2;
00569   // these matrixes were calculated in octave
00570   double case1[2][4] = {{1 ,-1  ,0   ,1},{ 1 , 0 ,  -1  , 1}};
00571   double case2[3][4] = {{1 ,-2, 0, 2} , { 2 , -2, -1, 2},{ 1 , 0, -1, 1}};
00572   double case3[4][4] = {{1, -2,0 , 2} , { 2 , -2, -1,2},{ 2, -1,-2, 2},{ 2 ,0, -2,  1}};
00573   double *refInv = 0;
00574   switch (nrTriag){
00575     case 2:{
00576       if (refP[0] >= refP[1]){ // first triangle
00577         triagIndex = 0; v1 = Point(1.0,0.0); v2 = Point(1.0,1.0);
00578       }else{// second triangle
00579         triagIndex = 1; v1 = Point(1.0,1.0); v2 = Point(0.0,1.0);
00580       }
00581       refInv = case1[triagIndex];
00582       break;
00583     }
00584     case 3:{
00585       if (refP[0] >= 2*refP[1]){ // first triangle
00586         triagIndex = 0; v1 = Point(1.0,0.0); v2 = Point(1.0,0.5);
00587       }else if ((refP[0] <= 2*refP[1]) && (refP[0] >= refP[1])){ // second triangle
00588         triagIndex = 1; v1 = Point(1.0,0.5); v2 = Point(1.0,1.0);
00589       }else{ // third triangle
00590         triagIndex = 2; v1 = Point(1.0,1.0); v2 = Point(0.0,1.0);
00591       }
00592       refInv = case2[triagIndex];
00593       break;
00594     }
00595     case 4:{
00596       if (refP[0] >= 2*refP[1]){ // first triangle
00597         triagIndex = 0; v1 = Point(1.0,0.0); v2 = Point(1.0,0.5);
00598       }else if ((refP[0] <= 2*refP[1]) && (refP[0] >= refP[1])){// second triangle
00599         triagIndex = 1; v1 = Point(1.0,0.5); v2 = Point(1.0,1.0);
00600       }else if ((refP[0] <= refP[1]) && (2*refP[0] >= refP[1])){// third triangle
00601         triagIndex = 2; v1 = Point(1.0,1.0); v2 = Point(0.5,1.0);
00602       }else{ // fourth triangle
00603         triagIndex = 3;v1 = Point(0.5,1.0); v2 = Point(0.0,1.0);
00604       }
00605       refInv = case3[triagIndex];
00606       break;
00607     }
00608     default:{
00609       TEUCHOS_TEST_FOR_EXCEPTION( true, std::runtime_error,"get3DRealCoordsOnSurf , too many triangles " << nrTriag);
00610     }
00611   }
00612   // get the three points of the triangle
00613   Point p0 = edgeIntersectPoint[triangles[3*triagIndex]];
00614   Point p1 = edgeIntersectPoint[triangles[3*triagIndex+1]];
00615   Point p2 = edgeIntersectPoint[triangles[3*triagIndex+2]];
00616   SUNDANCE_MSG3(verb, tabs << "get3DRealCoordsOnSurf p0="<<p0<<" , p1="<<p1<<" , p2="<<p2);
00617   SUNDANCE_MSG3(verb, tabs << "get3DRealCoordsOnSurf v1=" << v1 << " , v2=" << v2 << " , triagIndex=" << triagIndex);
00618 
00619   // transfor to the reference 2D coordinates
00620   double ref_x = refInv[0] * refP[0] + refInv[1]*refP[1];
00621   double ref_y = refInv[2] * refP[0] + refInv[3]*refP[1];
00622   SUNDANCE_MSG3(verb, tabs << " after traf to ref_x ="<<ref_x<<" , ref_y="<<ref_y );
00623 
00624   // transform from 2D ref to 3D triangle real coordinate
00625   realPoint = p0 + ref_x*(p1-p0) + ref_y*(p2-p0);
00626   SUNDANCE_MSG3(verb, tabs << " end get3DRealCoordsOnSurf , realPoint="<<realPoint );
00627   SUNDANCE_MSG3(verb, tabs << " end get3DRealCoordsOnSurf cellPoints[0]="<<cellPoints[0]<<" , cellPoints[7]="<<cellPoints[7] );
00628 
00629   // transform the point in real coordinates back to reference 3D coordinates
00630   // this works only for cubes (structured)
00631   realPoint[0] = (realPoint[0] - cellPoints[0][0]) / (cellPoints[7][0] - cellPoints[0][0]);
00632   realPoint[1] = (realPoint[1] - cellPoints[0][1]) / (cellPoints[7][1] - cellPoints[0][1]);
00633   realPoint[2] = (realPoint[2] - cellPoints[0][2]) / (cellPoints[7][2] - cellPoints[0][2]);
00634   SUNDANCE_MSG3(verb, tabs << " end get3DRealCoordsOnSurf triagIndex="<<triagIndex<<" , realPoint="<<realPoint );
00635 
00636 }
00637 
00638 
00639 bool CurveIntegralCalc::usePolygoneCurveQuadrature(
00640     const CellType& cellType ,
00641     const Mesh& mesh ,
00642     const ParametrizedCurve& paramCurve){
00643 
00644   // Maximal cell type
00645   CellType maxCellType = mesh.cellType(mesh.spatialDim());
00646 
00647   switch (maxCellType)
00648   {
00649   // We have a triangle based mesh
00650   case TriangleCell:
00651   {
00652     switch (cellType)
00653     {
00654     case TriangleCell:
00655     { break; }
00656     default: {}
00657     }
00658     break;
00659   }
00660   case QuadCell:
00661   {
00662     switch(cellType)
00663     {
00664     case QuadCell:
00665     {
00666       // this works only in 2D for polygons, it is important that we ask the underlying object and not the object itself
00667       const Polygon2D* poly = dynamic_cast<const Polygon2D* > ( paramCurve.ptr().get()->getUnderlyingCurveObj() );
00668       if ( poly != 0 ){
00669         return true;
00670       }
00671       break;
00672     }
00673     default: {}
00674     }
00675     break;
00676   }
00677   default: { }
00678   }
00679   //
00680   return false;
00681 }
00682 
00683 
00684 void CurveIntegralCalc::getCurveQuadPoints_polygon(
00685                                int  maxCellLID ,
00686                                CellType  maxCellType ,
00687                                const Mesh& mesh ,
00688                                const Array<Point>& cellPoints,
00689                  const ParametrizedCurve& paramCurve,
00690                  const QuadratureFamily& quad ,
00691                  Array<Point>& curvePoints ,
00692                  Array<Point>& curveDerivs ,
00693                  Array<Point>& curveNormals ) {
00694 
00695   // this works only in 2D for polygons, it is important that we ask the underlying object and not the object itself
00696   const Polygon2D* polygon = dynamic_cast<const Polygon2D* > ( paramCurve.ptr().get()->getUnderlyingCurveObj() );
00697   if ( (polygon == 0) || (maxCellType != QuadCell) ) {
00698     TEUCHOS_TEST_FOR_EXCEPTION( true , std::runtime_error , " getCurveQuadPoints_polygon , paramCurve must be a Polygon and the cell must be a quad" );
00699     return;
00700   }
00701 
00702   // the algorithm is to create separate line segments
00703   //(P1,P2,d1),(P2,P3,d2),(P4,P5,d3) ... d1,d2,d3 are normalized lengths
00704   // see these line segments as one continuous line and maps the quadrature points on the segments
00705 
00706   Array<Point> allIntPoints(0);
00707   Array<int> allIntPointsEdge(0);
00708   Array<Point> allPolygonPoints(0);
00709   int nrPoints , total_points , polyNrPoint ;
00710   Tabs tabs;
00711   int verb = 0;
00712   double eps = 1e-14;
00713 
00714   SUNDANCE_MSG3(verb, " ---------- START METHOD -----------  ");
00715 
00716   //
00717   switch (maxCellType){
00718     case QuadCell:{
00719       // loop over each edge and detect intersection point
00720       // there can be only one
00721     TEUCHOS_TEST_FOR_EXCEPTION( cellPoints.size() != 4 ,
00722           std::runtime_error ," CurveIntegralCalc::getCurveQuadPoints , QuadCell must have 4 points" );
00723     //SUNDANCE_MSG3(verb, tabs << "CurveIntegralCalc::getCurveQuadPoints_line, on QuadCell")
00724       Array<Point> result(5);
00725       int edegIndex[4][2] = { {0,1} , {0,2} , {1,3} , {2,3} };
00726       bool pointExists;
00727 
00728       total_points = 0;
00729       // loop over the edges
00730       for (int jj = 0 ; jj < 4 ; jj++ ){
00731       paramCurve.returnIntersectPoints(cellPoints[edegIndex[jj][0]], cellPoints[edegIndex[jj][1]], nrPoints , result);
00732       // add the intersection points to the list of intersection points
00733         for (int ptmp = 0 ; ptmp < nrPoints ; ptmp++){
00734           pointExists = false;
00735           //SUNDANCE_MSG3(verb, tabs << "getCurveQuadPoints_line  INVESTIGATE Intersect point:" << result[ptmp]);
00736           for (int tmp_r = 0 ; tmp_r < total_points ; tmp_r++){
00737             Point tmpPoint = result[ptmp];
00738             tmpPoint = tmpPoint - allIntPoints[tmp_r];
00739             if ( ::sqrt(tmpPoint * tmpPoint) < eps ) pointExists = true;
00740           }
00741           // add only if this point does not exist in the list
00742           if (!pointExists){
00743             //SUNDANCE_MSG3(verb, tabs << "getCurveQuadPoints_line  ADD  Intersect point:" << result[ptmp]);
00744             allIntPoints.resize( total_points + 1 );
00745             allIntPointsEdge.resize( total_points + 1 );
00746             allIntPoints[total_points] = result[ptmp];
00747             allIntPointsEdge[total_points] = jj;
00748             total_points = total_points + 1;
00749           }
00750         }
00751       }
00752       // test if we have too much intersection points
00753     //SUNDANCE_MSG3(verb, tabs << "CurveIntegralCalc::getCurveQuadPoints_line, end finding intersection points")
00754      } break;
00755      case TriangleCell:{
00756       TEUCHOS_TEST_FOR_EXCEPTION( true , std::runtime_error , " CurveIntegralCalc::getCurveQuadPoints_polygon , TriangleCell not implemented yet" );
00757      } break;
00758      default : {
00759       TEUCHOS_TEST_FOR_EXCEPTION( true , std::runtime_error , "CurveIntegralCalc::getCurveQuadPoints_polygon , Unknown Cell in 2D" );
00760    }
00761   }
00762 
00763   // now we have all the intersection points which are not the same (duplicates are eliminated)
00764   // we get the points from the polygon
00765   polygon->getCellsPolygonesPoint( maxCellLID ,allPolygonPoints);
00766   polyNrPoint = allPolygonPoints.size();
00767 
00768   // now we should merge the intersection points and the points from the polygon
00769   // into a line segments
00770 
00771   nrPoints = polyNrPoint + total_points;
00772   Array<Point> segmentStart(0);
00773   Array<Point> segmentEnd(0);
00774   int segmentNr = 0 , flagMode , edgeActual = 0;
00775   Array<bool> usedIntPoint( total_points , false );
00776 
00777   // todo:
00778   if (total_points < 2) {
00779     std::cout << "total_points = " << total_points << " , P0:" << allIntPoints[0] << std::endl;
00780   }
00781   if (total_points == 3) {
00782     std::cout << "total_points = " << total_points << "P0:" << allIntPoints[0] <<
00783         " , P1:" << allIntPoints[1] << " , P2:" << allIntPoints[2] << std::endl;
00784     total_points = 2;
00785   }
00786   if (total_points > 4) {
00787     std::cout << "total_points = " << total_points << "P0:" << allIntPoints[0] << " , P1:" << allIntPoints[1]
00788            << " , P2:" << allIntPoints[2] << " , P3:" << allIntPoints[3] << std::endl;
00789     total_points = 4;
00790   }
00791 
00792   TEUCHOS_TEST_FOR_EXCEPTION( (total_points != 2) && (total_points != 4) , std::runtime_error , "nr Intersect point can be eighter 2 or 4 but is " << total_points);
00793 
00794   // ---- create total_points/2 different segments ----
00795   flagMode = 0;
00796   for (int intP = 0 ; intP < total_points ; intP++ ){
00797     if (flagMode == 0){
00798       // get a point which is not used
00799       int Pind = -1;
00800       for (int stmp = 0 ; stmp < total_points ; stmp++){
00801         // this point was not used then take it
00802         if (!usedIntPoint[stmp]) { Pind = stmp; break;}
00803       }
00804       //SUNDANCE_MSG3(verb, tabs << "getCurveQuadPoints_line flag mode 0 , found Index Pind:" << Pind << " , start:"<<allIntPoints[Pind]);
00805       segmentStart.resize( segmentNr + 1);
00806       segmentEnd.resize( segmentNr + 1 );
00807       edgeActual = allIntPointsEdge[Pind];
00808       segmentStart[ segmentNr ] = allIntPoints[Pind];
00809       usedIntPoint[ Pind ] = true;
00810       flagMode = 1;
00811     } else {
00812       // here we have a start point we are looking for an end of the segment line
00813       double dist = 1e+100;
00814       int Pind = -1;
00815       for (int stmp = 0 ; stmp < total_points ; stmp++){
00816         // the condition when to test one intersection point
00817         if ( !usedIntPoint[stmp] && ( (edgeActual != allIntPointsEdge[stmp]) || total_points < 3 ) ){
00818           Point tmpPointC = (segmentStart[segmentNr] - allIntPoints[stmp]);
00819           double thisDist = ::sqrt(tmpPointC*tmpPointC);
00820           if ( thisDist < dist ) {
00821             dist = thisDist;
00822             Pind = stmp;
00823           }
00824         }
00825       }
00826       //SUNDANCE_MSG3(verb, tabs << "getCurveQuadPoints_line flag mode 1 , found Index Pind:" << Pind << " , end:"<<allIntPoints[Pind]);
00827       segmentEnd[ segmentNr ] = allIntPoints[Pind];
00828       usedIntPoint[ Pind ] = true;
00829       flagMode = 0;
00830       segmentNr = segmentNr + 1;
00831     }
00832   }
00833 
00834   // ---- at this point we have the start and end points of the segments
00835   // ---- now we should insert the polygon points
00836   for (int polyPoint = 0 ; polyPoint < polyNrPoint ; polyPoint++ ){
00837     // find the line segment which will be split
00838     double totalDist = 1e+100;
00839     int segInd = -1;
00840     for (int pl = 0; pl < segmentNr ; pl++ ){
00841       Point d1p = segmentStart[pl] - allPolygonPoints[polyPoint];
00842       double d1 = ::sqrt(d1p*d1p);
00843       Point d2p = segmentEnd[pl] - allPolygonPoints[polyPoint];
00844       double d2 = ::sqrt(d2p*d2p);
00845       Point dist_prev = segmentEnd[pl] - segmentStart[pl];
00846       double d_p = ::sqrt(dist_prev*dist_prev);
00847       //SUNDANCE_MSG3(verb, tabs << " Probe actual segment START :" << segmentStart[pl] << " , END:" << segmentEnd[pl] );
00848       //SUNDANCE_MSG3(verb, tabs << " Probe actual point to pl:" << pl << " actual dist:" << (d1+d2-d_p) << " , totalDist:" << totalDist);
00849       // test if this is the shortest segment till now where to insert the polygon point
00850       if ( (d1 + d2 - d_p < totalDist) && (d1 > eps) && (d2 > eps) ) {
00851         totalDist = d1 + d2 - d_p;
00852         segInd = pl;
00853       }
00854     }
00855 
00856     //SUNDANCE_MSG3(verb, tabs << " Add polygon point to segInd:" << segInd << " , polyPoint:" << polyPoint
00857     //    << " , allPolygonPoints[polyPoint]:" << allPolygonPoints[polyPoint]);
00858     // if the point is already in or no segment found
00859     if ( segInd < 0) continue;
00860 
00861     // "segInd" shows the segment which should be split
00862     segmentStart.resize( segmentNr + 1);
00863     segmentEnd.resize( segmentNr + 1 );
00864     // enlarge first the vector
00865     for (int tmpP = segmentNr-1; tmpP >= segInd ; tmpP--){
00866       segmentStart[tmpP+1] = segmentStart[tmpP];
00867       segmentEnd[tmpP+1] = segmentEnd[tmpP];
00868     }
00869 
00870     // insert the new line segment
00871     segmentEnd[segInd] = allPolygonPoints[polyPoint];
00872     segmentStart[segInd+1] = allPolygonPoints[polyPoint];
00873     segmentNr = segmentNr + 1;
00874   }
00875 
00876   // --- now we have all line segments now calculate each length
00877   Array<double> segmentLengthRel(0);
00878   Array<double> segmentStartLengthRel(0);
00879   segmentLengthRel.resize(segmentNr);
00880   segmentStartLengthRel.resize(segmentNr);
00881 
00882   // calculate the length of each line, so that we can find
00883   double totalLength = 0.0 , actLen = 0.0;
00884   for (int seg = 0 ; seg < segmentNr ; seg++){
00885     totalLength = totalLength + ::sqrt( (segmentEnd[seg]-segmentStart[seg])*(segmentEnd[seg]-segmentStart[seg]) );
00886     //SUNDANCE_MSG3(verb, tabs << " total length seg:" << seg << " , totalLength = " << totalLength);
00887     //SUNDANCE_MSG3(verb, tabs << "  segmentStart[seg] = " << segmentStart[seg] <<" segmentEnd[seg]:" << segmentEnd[seg] );
00888   }
00889 
00890     // update the lengths of each segment
00891   for (int seg = 0 ; seg < segmentNr ; seg++){
00892     double thisLength = ::sqrt( (segmentEnd[seg]-segmentStart[seg])*(segmentEnd[seg]-segmentStart[seg]) );
00893     segmentLengthRel[seg] = thisLength/totalLength;
00894     segmentStartLengthRel[seg] = actLen/totalLength;
00895     //SUNDANCE_MSG3(verb, tabs << " Absolute length seg:" << seg << " , segmentLengthRel[seg] = " << segmentLengthRel[seg]
00896     //                                << " , segmentStartLengthRel[seg]=" << segmentStartLengthRel[seg]);
00897     //SUNDANCE_MSG3( verb , tabs << " segmentStart[seg]: " << segmentStart[seg] << " , segmentEnd[seg]:" << segmentEnd[seg]);
00898     actLen = actLen + thisLength;
00899   }
00900 
00901   //try to convert the quadrature to a polygon curve integral class
00902   // this quadrature class is special for polygon curve integrals
00903   const PolygonQuadrature* polyquad = dynamic_cast<const PolygonQuadrature*> (quad.ptr().get());
00904   if ( polyquad == 0 ) {
00905     TEUCHOS_TEST_FOR_EXCEPTION( true , std::runtime_error ,
00906       " getCurveQuadPoints_polygon , Quadrature for a polygon curve must be PolygonQuadrature" );
00907     return;
00908   }
00909 
00910   // get the quadrature points for line segments
00911   Array<Point> quadPoints;
00912   Array<double> quadWeights;
00913   polyquad->getPoints( LineCell , quadPoints , quadWeights );
00914   int nr_quad_points = quadPoints.size();
00915   Point endPoint , startPoint;
00916   int maxLineSegments = PolygonQuadrature::getNrMaxLinePerCell();
00917   Array<int> cellLID(1); cellLID[0] = maxCellLID;
00918   CellJacobianBatch JBatch;
00919   JBatch.resize(1, 2, 2);
00920   mesh.getJacobians(2, cellLID , JBatch);
00921 
00922   TEUCHOS_TEST_FOR_EXCEPTION( maxLineSegments < segmentNr , std::runtime_error , " getCurveQuadPoints_polygon , nr of polygon lines inside one cell too high" <<
00923               " Use PolygonQuadrature::getNrMaxLinePerCell(" << segmentNr << ") , now it is only: " << maxLineSegments );
00924 
00925   // ---- at this stage we have the line segments,
00926   // we just need to map the quadrature points to the line and calculate the normal vector
00927   curvePoints.resize(nr_quad_points);
00928   curveDerivs.resize(nr_quad_points);
00929   curveNormals.resize(nr_quad_points);
00930 
00931   // get the line segment which contains this quadrature point
00932   int ii = 0;
00933   for (int seg = 0; seg < segmentNr ; seg++ )
00934   {
00935     // the start and end points of the line segment
00936     startPoint = segmentStart[seg];
00937     endPoint = segmentEnd[seg];
00938 
00939     // the calculation of the normal vector is usual, we look to the middle of the segment and see if it is inside or outside
00940     // since this is a polygon this must be determined
00941     Point curvderi = endPoint - startPoint;
00942     Point norm_vec = Point( -curvderi[1] , curvderi[0] );
00943     norm_vec = norm_vec / ::sqrt(norm_vec*norm_vec);
00944     double relative_length = 1e-2 * ::sqrt(curvderi*curvderi);
00945     bool invNormVect = false;
00946     // this segment must be a line, and we test which part is inside
00947     if ( paramCurve.curveEquation( (0.5*endPoint + 0.5*startPoint) + relative_length*norm_vec ) > 0 ) {
00948       invNormVect = true;
00949     }
00950     else {
00951       invNormVect = false;
00952     }
00953 
00954     // loop over each quadrature point for one line segment
00955     for (int pointNr = 0 ; pointNr < nr_quad_points/maxLineSegments ; pointNr++ , ii++ )
00956     {
00957       // now we have
00958       //SUNDANCE_MSG3(verb, tabs << "pointNr:" << pointNr << " , nr:" << ii << " Line quad point:" << quadPoints[ii] << ", line:" << (endPoint - startPoint)
00959       //  << " , segmentsLength: " << segmentStartLengthRel[seg] );
00960       //SUNDANCE_MSG3(verb, tabs << " nr:" << ii << " startPoint:" <<  startPoint << " , endPoint:" <<  endPoint );
00961       // here we map the quadrature point on the line segment
00962       curvePoints[ii] = startPoint + quadPoints[ii][0]*(endPoint - startPoint);
00963 
00964       // here we transform the real coordinate back to the
00965       double pointc[2] = { curvePoints[ii][0] - cellPoints[0][0] , curvePoints[ii][1] - cellPoints[0][1] };
00966       JBatch.applyInvJ(0, pointc , 1 , false);
00967       curvePoints[ii][0] = pointc[0];
00968       curvePoints[ii][1] = pointc[1];
00969       //SUNDANCE_MSG3(verb, tabs << " quad point nr:" << ii << " = " << curvePoints[ii]);
00970 
00971       // the derivative we calculate by simply take the total length
00972       // in the curve integral we use only the norm of this point
00973       curveDerivs[ii] = Point( segmentLengthRel[seg]*totalLength*((double)maxLineSegments) , 0.0 );
00974       //SUNDANCE_MSG3(verb, tabs << " curve Derivatives point nr:" << ii << " = " << curveDerivs[ii]);
00975 
00976       // set the normal vector
00977       if ( invNormVect ) {
00978         curveNormals[ii] = -norm_vec;
00979       }
00980       else {
00981         curveNormals[ii] = norm_vec;
00982       }
00983       //SUNDANCE_MSG3(verb, tabs << " curve Normals point nr:" << ii << " = " << curveNormals[ii]);
00984     }
00985   }
00986 
00987   // for the rest of the points just set zero values , these point should not have influence
00988   for  ( ; ii < nr_quad_points ; ii++ ){
00989     curvePoints[ii] = Point( 0.0 , 0.0 );
00990     curveDerivs[ii] = Point( 0.0 , 0.0 );
00991     curveNormals[ii] = Point( 0.0 , 0.0 );
00992   }
00993 
00994   SUNDANCE_MSG3(verb, " ---------- END METHOD -----------  ");
00995 }
00996 
00997 
00998 void CurveIntegralCalc::getSurfQuadPoints(
00999                                int  maxCellLID ,
01000                                CellType  maxCellType ,
01001                                const Mesh& mesh ,
01002                                const Array<Point>& cellPoints,
01003                  const ParametrizedCurve& paramCurve,
01004                  const QuadratureFamily& quad ,
01005                  Array<Point>& curvePoints ,
01006                  Array<Point>& curveDerivs ,
01007                  Array<Point>& curveNormals ) {
01008 
01009   const SurfQuadrature* surfquad = dynamic_cast<const SurfQuadrature*> (quad.ptr().get());
01010   if ( surfquad == 0 ) {
01011     TEUCHOS_TEST_FOR_EXCEPTION( true , std::runtime_error ,
01012       " getSurfQuadPoints , Surface Quadrature for a 3D must be SurfQuadrature" );
01013     return;
01014   }
01015 
01016   Array<Point> quadPoints;
01017   Array<double> quadWeights;
01018   surfquad->getPoints( TriangleCell , quadPoints , quadWeights );
01019   int nr_quad_points = quadPoints.size();
01020   int maxTriangles = SurfQuadrature::getNrMaxTrianglePerCell();
01021   int nrQuadPointPerTriag = nr_quad_points/maxTriangles;
01022   int verb = 0;
01023   curvePoints.resize(nr_quad_points);
01024   curveDerivs.resize(nr_quad_points);
01025   curveNormals.resize(nr_quad_points);
01026 
01027   Array<Point> intersectPoints;
01028   Array<int> edgeIndex;
01029   Array<int> triangleIndex;
01030     // the results in this form will be in physical coordinates
01031   SundanceSurf3DCalc::getCurveQuadPoints( maxCellType , maxCellLID , mesh , paramCurve, cellPoints,
01032              intersectPoints ,  edgeIndex , triangleIndex );
01033 
01034   int  nr_triag = triangleIndex.size()/3  ,  qind = 0;
01035   double totalArea = 0.0 , area;
01036   // first compute the total area of all triangles
01037   for (int t = 0 ; t < nr_triag ; t++){
01038     // for each triangle
01039     Point p0 = intersectPoints[triangleIndex[3*t]];
01040     Point p1 = intersectPoints[triangleIndex[3*t + 1]];
01041     Point p2 = intersectPoints[triangleIndex[3*t + 2]];
01042     Point n = cross(p1-p0,p2-p0);
01043     totalArea = totalArea + ::sqrt(n*n);
01044   }
01045 
01046 
01047   SUNDANCE_MSG3(verb, " nr_triag = " << nr_triag);
01048   // for each resulted triangles compute the quadrature points and the normal
01049   for (int t = 0 ; t < nr_triag ; t++){
01050     // for each triangle
01051     Point p0 = intersectPoints[triangleIndex[3*t]];
01052     Point p1 = intersectPoints[triangleIndex[3*t + 1]];
01053     Point p2 = intersectPoints[triangleIndex[3*t + 2]];
01054 
01055     Point n = cross(p1-p0,p2-p0);
01056     // calculate area
01057     area = ::sqrt(n*n); // / 2.0; -> no division by two
01058     // invert the normal vector if necessary
01059     if ( paramCurve.curveEquation( p0 + 5e-3*n ) > 0 ) { n = (-1)*n; }
01060     n = (1/::sqrt(n*n))*n; // normalize the normal vector
01061 
01062     // for each quadrature point on this triangle
01063     //SUNDANCE_MSG3(verb, " p0 = " << p0 << " , p1 = " << p1 << " , p2 = " << p2 );
01064     //SUNDANCE_MSG3(verb, " area = " << area << " , n = " << n );
01065     for (int q = 0 ; q < nrQuadPointPerTriag ; q++ , qind++){
01066       // this is the point in real coordinates
01067       Point pTmp = p0 + quadPoints[qind][0] * (p1-p0) + quadPoints[qind][1] * (p2-p0);
01068       //SUNDANCE_MSG3(verb, "REAL curvePoints["<<qind<<"]=" << pTmp );
01069       // here we transform it to reference coordinates
01070       curvePoints[qind] = Point( (pTmp[0] -  cellPoints[0][0])/(cellPoints[7][0] - cellPoints[0][0]),
01071                              (pTmp[1] -  cellPoints[0][1])/(cellPoints[7][1] - cellPoints[0][1]),
01072                              (pTmp[2] -  cellPoints[0][2])/(cellPoints[7][2] - cellPoints[0][2]) );
01073       //SUNDANCE_MSG3(verb, "REF curvePoints["<<qind<<"]=" << curvePoints[qind] );
01074       curveDerivs[qind] = Point( area * ((double)maxTriangles) , 0.0 , 0.0 );
01075       curveNormals[qind] = n;
01076     }
01077   }
01078 
01079   // the rest of the quadrature points we set to zero
01080   for ( ; qind < nr_quad_points ; qind++){
01081     curvePoints[qind] = Point( 0 , 0 , 0 );
01082     curveDerivs[qind] = Point( 0 , 0 , 0 );
01083     curveNormals[qind] = Point( 0 , 0 , 0 );
01084   }
01085   SUNDANCE_MSG3(verb, " ---------- END METHOD -----------  ");
01086 }

Site Contact