00001
00002
00003
00004
00005
00006
00007
00008 #include "SundanceCurveIntegralCalc.hpp"
00009 #include "SundanceOut.hpp"
00010 #include "SundanceTabs.hpp"
00011
00012 using namespace Sundance;
00013
00014 CurveIntegralCalc::CurveIntegralCalc() {
00015
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
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
00043 CurveIntegralCalc::getCurveQuadPoints_line( maxCellType , maxCellsPoints , paramCurve,
00044 quad , curvePoints , curveDerivs , curveNormals);
00045
00046
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
00063 switch (paramCurve.getCurveDim()){
00064 case 1: {
00065
00066 SUNDANCE_MSG3(verb, tabs << "CurveIntegralCalc::getCurveQuadPoints_line, curve has ONE dimnesion")
00067
00068
00069
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
00077
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
00085 for (int jj = 0 ; jj < 4 ; jj++ ){
00086 paramCurve.returnIntersectPoints(cellPoints[edegIndex[jj][0]], cellPoints[edegIndex[jj][1]], nrPoints , result);
00087
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
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
00109 for (int jj = 0 ; jj < 3 ; jj++ ){
00110 paramCurve.returnIntersectPoints(cellPoints[edegIndex[jj][0]], cellPoints[edegIndex[jj][1]], nrPoints , result);
00111
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
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
00129 TEST_FOR_EXCEPTION( total_points > 2 ,RuntimeError , " CurveIntegralCalc::getCurveQuadPoints , no much intersection points: " << total_points);
00130
00131
00132
00133
00134
00135
00136
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
00145 Array<Point> quadPoints;
00146 Array<double> quadWeights;
00147 quad.getPoints( LineCell , quadPoints , quadWeights );
00148 int nr_quad_points = quadPoints.size();
00149
00150
00151
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
00158
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
00170 }
00171 }
00172 SUNDANCE_MSG3(verb, tabs << " quad point nr:" << ii << " = " << curvePoints[ii]);
00173 }
00174
00175
00176
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
00187 curveNormals.resize(nr_quad_points);
00188 double sin_line = 0.0, cos_line = 0.0;
00189
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
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
00210 if ( (startPoint[1]-endPoint[1]) > 0.0 ){
00211
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
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 }
00232
00233
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
00247
00248 case 2: {
00249
00250
00251
00252
00253 TEST_FOR_EXCEPTION( true, RuntimeError,"CurveIntagralCalc::getCurveQuadPoints , surface integral not implemented yet ");
00254
00255 } break;
00256
00257
00258
00259 default: {
00260
00261 TEST_FOR_EXCEPTION( true, RuntimeError,"CurveIntagralCalc::getCurveQuadPoints , curve dimension must be 1 or two ");
00262 }
00263 }
00264
00265 }