SundanceCurveIntegralCalc.cpp
Go to the documentation of this file.
00001 /*
00002  * SundanceCurveIntagralCalc.cpp
00003  *
00004  *  Created on: Sep 2, 2010
00005  *      Author: benk
00006  */
00007 
00008 #include "SundanceCurveIntegralCalc.hpp"
00009 #include "SundanceOut.hpp"
00010 #include "SundanceTabs.hpp"
00011 
00012 using namespace Sundance;
00013 
00014 CurveIntegralCalc::CurveIntegralCalc() {
00015   //nothing to do
00016 }
00017 
00018 void CurveIntegralCalc::getCurveQuadPoints(CellType  maxCellType ,
00019                  int maxCellLID ,
00020                  const Mesh& mesh ,
00021                  const ParametrizedCurve& paramCurve,
00022                  const QuadratureFamily& quad ,
00023                  Array<Point>& curvePoints ,
00024                  Array<Point>& curveDerivs ,
00025                  Array<Point>& curveNormals ){
00026 
00027   int verb = 0;
00028   Tabs tabs;
00029 
00030     // get all the points from the maxDimCell
00031   int nr_point = mesh.numFacets( mesh.spatialDim() , 0 , 0);
00032   Array<Point> maxCellsPoints(nr_point);
00033   int tmp_i , point_LID;
00034 
00035   SUNDANCE_MSG3(verb, tabs << "CurveIntegralCalc::getCurveQuadPoints nr points per cell: " << nr_point)
00036   for (int jj = 0 ; jj < nr_point ; jj++){
00037     point_LID = mesh.facetLID( mesh.spatialDim() , maxCellLID , 0 , jj , tmp_i );
00038     maxCellsPoints[jj] = mesh.nodePosition(point_LID);
00039     SUNDANCE_MSG3(verb, tabs << " max cell point p[" << jj << "]:"<< maxCellsPoints[jj]);
00040   }
00041 
00042   // call the simple line method
00043   CurveIntegralCalc::getCurveQuadPoints_line( maxCellType , maxCellsPoints , paramCurve,
00044                   quad , curvePoints , curveDerivs , curveNormals);
00045 
00046   // later here could be more sophisticated method called instead of the simple line/plane method
00047 
00048 }
00049 
00050 void CurveIntegralCalc::getCurveQuadPoints_line(
00051                                    CellType  maxCellType ,
00052                                    const Array<Point>& cellPoints,
00053                    const ParametrizedCurve& paramCurve,
00054                    const QuadratureFamily& quad ,
00055                    Array<Point>& curvePoints ,
00056                    Array<Point>& curveDerivs ,
00057                    Array<Point>& curveNormals ){
00058 
00059   int verb = 0;
00060   Tabs tabs;
00061 
00062     // select the dimension of the curve
00063   switch (paramCurve.getCurveDim()){
00064     case 1: {
00065 
00066       SUNDANCE_MSG3(verb, tabs << "CurveIntegralCalc::getCurveQuadPoints_line, curve has ONE dimnesion")
00067       // 1D curve integral in 2D or 3D
00068 
00069       // first determine the two intersection points with the edges
00070       Point startPoint(0.0,0.0);
00071       Point endPoint(0.0,0.0);
00072         int nrPoints , total_points = 0 ;
00073 
00074       switch (maxCellType){
00075         case QuadCell:{
00076           // loop over each edge and detect intersection point
00077           // there can be only one
00078           TEST_FOR_EXCEPTION( cellPoints.size() != 4 ,
00079               RuntimeError ," CurveIntegralCalc::getCurveQuadPoints , QuadCell must have 4 points" );
00080         SUNDANCE_MSG3(verb, tabs << "CurveIntegralCalc::getCurveQuadPoints_line, on QuadCell")
00081           Array<Point> result(0);
00082           int edegIndex[4][2] = { {0,1} , {0,2} , {1,3} , {2,3} };
00083 
00084           // loop over the edges
00085           for (int jj = 0 ; jj < 4 ; jj++ ){
00086           paramCurve.returnIntersectPoints(cellPoints[edegIndex[jj][0]], cellPoints[edegIndex[jj][1]], nrPoints , result);
00087           // test if we have intersection point
00088             if (nrPoints > 0){
00089               if (total_points == 0) startPoint = result[0];
00090               else endPoint = result[0];
00091               SUNDANCE_MSG3(verb, tabs << "found Int. point:" << result[0]);
00092             }
00093           total_points += nrPoints;
00094           SUNDANCE_MSG3(verb, tabs << "ind:" << jj << ", nr Int points :" << nrPoints
00095               << " , start:" << startPoint << ", end:"<< endPoint);
00096           TEST_FOR_EXCEPTION( nrPoints > 1 ,
00097               RuntimeError , " CurveIntegralCalc::getCurveQuadPoints , QuadCell one edge " << jj << " , can have only one intersection point" );
00098           }
00099           // test if we have too much intersection points
00100           TEST_FOR_EXCEPTION( total_points > 2 ,RuntimeError , " CurveIntegralCalc::getCurveQuadPoints total_points > 2 : " << total_points );
00101         SUNDANCE_MSG3(verb, tabs << "CurveIntegralCalc::getCurveQuadPoints_line, end finding intersection points")
00102         } break;
00103         case TriangleCell:{
00104           TEST_FOR_EXCEPTION( cellPoints.size() != 3 , RuntimeError , " CurveIntegralCalc::getCurveQuadPoints , TriangleCell must have 3 points" );
00105           Array<Point> result;
00106           int edegIndex[3][2] = { {0,1} , {0,2} , {1,2} };
00107 
00108           // loop over the edges
00109           for (int jj = 0 ; jj < 3 ; jj++ ){
00110           paramCurve.returnIntersectPoints(cellPoints[edegIndex[jj][0]], cellPoints[edegIndex[jj][1]], nrPoints , result);
00111           // test if we have intersection point
00112             if (nrPoints > 0){
00113               if (total_points == 0) startPoint = result[0];
00114               else endPoint = result[0];
00115               SUNDANCE_MSG3(verb, tabs << "found Int. point:" << result[0]);
00116             }
00117           total_points += nrPoints;
00118           TEST_FOR_EXCEPTION( nrPoints > 1 ,
00119               RuntimeError , " CurveIntegralCalc::getCurveQuadPoints , TriangleCell one edge " << jj << " , can have only one intersection point" );
00120           }
00121           // test if we have too much intersection points
00122           TEST_FOR_EXCEPTION( total_points > 2 ,RuntimeError , " CurveIntegralCalc::getCurveQuadPoints total_points > 2 : " << total_points );
00123         } break;
00124         default : {
00125           TEST_FOR_EXCEPTION( true , RuntimeError , "CurveIntegralCalc::getCurveQuadPoints , Unknown Cell in 2D" );
00126         }
00127       }
00128       // test for to many intersection points
00129       TEST_FOR_EXCEPTION( total_points > 2 ,RuntimeError , " CurveIntegralCalc::getCurveQuadPoints , no much intersection points: " << total_points);
00130 
00131       // -> having the intersection points now we have to determine the:
00132       // quad points and the gradients at the points(which norm will be in the integration)
00133       // and the normalized normal vector (normalized since we need the sin and cos for Nitsche )
00134       // -> as a very simple approach we consider the curve as a line between intersection points "startPoint -> endPoint"
00135 
00136       // in the X direction the line should always have increasing values
00137       if (startPoint[0] > endPoint[0]){
00138         Point tmp = startPoint;
00139         startPoint = endPoint;
00140         endPoint = tmp;
00141       }
00142       SUNDANCE_MSG3(verb, tabs << "start end and points , start:" << startPoint << ", end:"<< endPoint)
00143 
00144       // get the quadrature points for the line
00145       Array<Point> quadPoints;
00146       Array<double> quadWeights;
00147       quad.getPoints( LineCell , quadPoints , quadWeights );
00148       int nr_quad_points = quadPoints.size();
00149 
00150 
00151       // The intersection points , we distribute the points along the line
00152       curvePoints.resize(nr_quad_points);
00153       SUNDANCE_MSG3(verb, tabs << " setting reference quadrature points" );
00154       for (int ii = 0 ; ii < nr_quad_points ; ii++) {
00155         SUNDANCE_MSG3(verb, tabs << " nr:" << ii << " Line quad point:" << quadPoints[ii] << ", line:" << (endPoint - startPoint));
00156         curvePoints[ii] = startPoint + quadPoints[ii][0]*(endPoint - startPoint);
00157         // we transform the intersection points to the reference cell
00158         // todo: THIS MIGHT NOT WORK FOR UNSTRUCTURED CASE !!!
00159         switch (maxCellType){
00160           case QuadCell:{
00161             curvePoints[ii][0] = -(cellPoints[0][0] - curvePoints[ii][0])/(cellPoints[3][0] - cellPoints[0][0]);
00162             curvePoints[ii][1] = -(cellPoints[0][1] - curvePoints[ii][1])/(cellPoints[3][1] - cellPoints[0][1]);
00163           } break;
00164           case TriangleCell:{
00165             curvePoints[ii][0] = -(cellPoints[0][0] - curvePoints[ii][0])/(cellPoints[1][0] - cellPoints[0][0]);
00166             curvePoints[ii][1] = -(cellPoints[0][1] - curvePoints[ii][1])/(cellPoints[2][1] - cellPoints[0][1]);
00167           } break;
00168           default:{
00169             // This should not happen
00170           }
00171         }
00172         SUNDANCE_MSG3(verb, tabs << " quad point nr:" << ii << " = " << curvePoints[ii]);
00173       }
00174 
00175 
00176       // The derivatives at points, for this simple method are simple and constant over the whole quadrature
00177       curveDerivs.resize(nr_quad_points);
00178       Point dist_point(endPoint[0] - startPoint[0] , endPoint[1] - startPoint[1]);
00179       SUNDANCE_MSG3(verb, tabs << " setting derivative values points" );
00180       for (int ii = 0 ; ii < nr_quad_points ; ii++) {
00181         curveDerivs[ii] = endPoint - startPoint;
00182         SUNDANCE_MSG3(verb, tabs << " curve Derivatives point nr:" << ii << " = " << curveDerivs[ii]);
00183       }
00184 
00185 
00186       // calculate the norms to the curve
00187       curveNormals.resize(nr_quad_points);
00188       double sin_line = 0.0, cos_line = 0.0;
00189       // in case we have a horizontal line
00190       if ( fabs( endPoint[0] - startPoint[0])  < 1e-8 ){
00191           Point tmp(startPoint[0],startPoint[1] - sqrt(dist_point*dist_point)*1e-2 );
00192         double inside_i =  paramCurve.curveEquation( tmp );
00193         if ( inside_i < 0.0)
00194         {
00195               sin_line = -1.0;
00196             cos_line = 0.0;
00197         }
00198         else
00199         {
00200               sin_line = 1.0;
00201             cos_line = 0.0;
00202         }
00203         SUNDANCE_MSG3(verb, tabs << "case 1.0, cos_line:" << cos_line << ", sin_line:" << sin_line);
00204       } else {
00205       // general case to determine the normal vector
00206           Point tmp(startPoint[0] - sqrt(dist_point*dist_point)*1e-2 ,startPoint[1]);
00207         double inside_i =  paramCurve.curveEquation( tmp );
00208         double r_dev = sqrt ( dist_point * dist_point);
00209         // todo: check if this is OK such
00210         if ( (startPoint[1]-endPoint[1]) > 0.0 ){
00211             // case 2.1 , positive slope
00212           if (inside_i < 0.0){
00213               cos_line = -fabs(endPoint[1]-startPoint[1]) / r_dev;
00214             sin_line = -fabs(endPoint[0]-startPoint[0]) / r_dev;
00215           } else {
00216               cos_line = fabs(endPoint[1]-startPoint[1]) / r_dev;
00217             sin_line = fabs(endPoint[0]-startPoint[0]) / r_dev;
00218           }
00219           SUNDANCE_MSG3(verb, tabs << "case 2.1, cos_line:" << cos_line << ", sin_line:" << sin_line << ", inside_i:" << inside_i);
00220         }else{
00221           // case 2.2 , negative slope
00222           if (inside_i < 0.0){
00223               cos_line = -fabs(endPoint[1]-startPoint[1]) / r_dev;
00224             sin_line = fabs(endPoint[0]-startPoint[0]) / r_dev;
00225           }else{
00226               cos_line = fabs(endPoint[1]-startPoint[1]) / r_dev;
00227             sin_line = -fabs(endPoint[0]-startPoint[0]) / r_dev;
00228           }
00229           SUNDANCE_MSG3(verb, tabs << "case 2.2, cos_line:" << cos_line << ", sin_line:" << sin_line << ", inside_i:" << inside_i);
00230         }
00231       } // - end normal direction calculation
00232 
00233       // set the normal direction in the corresponding way
00234       SUNDANCE_MSG3(verb, tabs << " setting normal values at points" );
00235       for (int ii = 0 ; ii < nr_quad_points ; ii++) {
00236         Point tmp( 0.0 , 0.0);
00237         curveNormals[ii] = tmp;
00238         curveNormals[ii][0] = cos_line;
00239         curveNormals[ii][1] = sin_line;
00240         SUNDANCE_MSG3(verb, tabs << " curve Normals point nr:" << ii << " = " << curveNormals[ii]
00241                                   << ", cos_line:" << cos_line << ", sin_line:" << sin_line);
00242       }
00243 
00244     } break;
00245 
00246 //========================== END 1D curve in 2D context ==========================
00247 
00248     case 2: {
00249       // 2D curve integral in 3D
00250 
00251       // here we consider a simple surface, as it is in bilinear interpolation
00252 
00253       TEST_FOR_EXCEPTION( true, RuntimeError,"CurveIntagralCalc::getCurveQuadPoints , surface integral not implemented yet ");
00254 
00255     } break;
00256 
00257 //========================== END 2D curve in 3D context ==========================
00258 
00259     default: {
00260         // throw exception
00261     TEST_FOR_EXCEPTION( true, RuntimeError,"CurveIntagralCalc::getCurveQuadPoints , curve dimension must be 1 or two ");
00262     }
00263   }
00264 
00265 }

Site Contact