00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
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
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
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
00090 if (usePolygoneCurveQuadrature( maxCellType , mesh , paramCurve)){
00091
00092 CurveIntegralCalc::getCurveQuadPoints_polygon( maxCellLID , maxCellType , mesh , maxCellsPoints , paramCurve,
00093 quad , curvePoints , curveDerivs , curveNormals);
00094 } else {
00095
00096 if ( use3DSurfQuadrature( maxCellType , mesh ) ){
00097 CurveIntegralCalc::getSurfQuadPoints(maxCellLID , maxCellType , mesh , maxCellsPoints , paramCurve,
00098 quad , curvePoints , curveDerivs , curveNormals);
00099
00100
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
00124 switch (paramCurve.getCurveDim()){
00125 case 1: {
00126
00127 SUNDANCE_MSG3(verb, tabs << "CurveIntegralCalc::getCurveQuadPoints_line, curve has ONE dimnesion")
00128
00129
00130
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
00138
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
00146 for (int jj = 0 ; jj < 4 ; jj++ ){
00147 paramCurve.returnIntersectPoints(cellPoints[edegIndex[jj][0]], cellPoints[edegIndex[jj][1]], nrPoints , result);
00148
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
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
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
00172 for (int jj = 0 ; jj < 3 ; jj++ ){
00173 paramCurve.returnIntersectPoints(cellPoints[edegIndex[jj][0]], cellPoints[edegIndex[jj][1]], nrPoints , result);
00174
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
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
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
00194 TEUCHOS_TEST_FOR_EXCEPTION( total_points > 2 ,std::runtime_error , " CurveIntegralCalc::getCurveQuadPoints , no much intersection points: " << total_points);
00195
00196
00197
00198
00199
00200
00201
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
00210 Array<Point> quadPoints;
00211 Array<double> quadWeights;
00212 quad.getPoints( LineCell , quadPoints , quadWeights );
00213 int nr_quad_points = quadPoints.size();
00214
00215
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
00223
00224
00225
00226
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
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
00252 curveNormals.resize(nr_quad_points);
00253
00254
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
00273
00274
00275
00276 case 2: {
00277
00278
00279
00280
00281
00282
00283
00284
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
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
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
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 }
00316
00317
00318
00319 Array<double> totDist(t_inters_points);
00320
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
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
00338
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
00350 for (int jj = 0 ; jj < 6 ; jj++ )
00351 {
00352 int nrIpointPerFace = 0;
00353 int firstPI = -1 , secondPI = -1;
00354
00355 for (int ii = 0 ; ii < 4 ; ii++){
00356
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
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
00378 break;
00379 }
00380 }
00381 TEUCHOS_TEST_FOR_EXCEPTION( intPointProc < 0 , std::runtime_error,"getCurveQuadPoints , intPointProc < 0 , " << intPointProc );
00382
00383
00384 for (int pI = 0 ; pI < nrTriangles; pI++)
00385 {
00386
00387 for (int jj = 0 ; jj < 6 ; jj++ )
00388 {
00389 int nrIpointPerFace = 0;
00390 int firstPI = -1 , secondPI = -1;
00391
00392 for (int ii = 0 ; ii < 4 ; ii++){
00393
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
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
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 ;
00427 total_area = total_area + triangle_area[ intersTriangleInd/3 ];
00428 intersTriangleInd = intersTriangleInd + 3;
00429
00430 break;
00431 }
00432 }
00433 }
00434
00435 SUNDANCE_MSG3(verb, tabs << " END Found triangle total_area=" << total_area);
00436
00437
00438
00439
00440 if (t_inters_points < 4){
00441
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
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
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
00473 triangle_area[0] = triangle_area[0] / 2.0;
00474 triangle_area.resize(2);
00475 triangle_area[1] = triangle_area[0];
00476 }
00477
00478
00479 Array<Point> quadPoints;
00480 Array<double> quadWeights;
00481 quad.getPoints( QuadCell , quadPoints , quadWeights );
00482 int nr_quad_points = quadPoints.size();
00483
00484
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
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
00497 SUNDANCE_MSG3(verb, tabs << " quad point nr:" << ii << " = " << curvePoints[ii]);
00498 }
00499
00500
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
00505 int tInd = triangleInd[ii] ;
00506 curveDerivs[ii] = Point( nrTriangles*triangle_area[tInd] , 0.0, 0.0 );
00507
00508 SUNDANCE_MSG3(verb, tabs << " curve Derivatives point nr:" << ii << " = " << curveDerivs[ii]);
00509 }
00510
00511
00512
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
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 }
00533 case TetCell:{
00534
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
00546
00547 default: {
00548
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
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]){
00577 triagIndex = 0; v1 = Point(1.0,0.0); v2 = Point(1.0,1.0);
00578 }else{
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]){
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])){
00588 triagIndex = 1; v1 = Point(1.0,0.5); v2 = Point(1.0,1.0);
00589 }else{
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]){
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])){
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])){
00601 triagIndex = 2; v1 = Point(1.0,1.0); v2 = Point(0.5,1.0);
00602 }else{
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
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
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
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
00630
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
00645 CellType maxCellType = mesh.cellType(mesh.spatialDim());
00646
00647 switch (maxCellType)
00648 {
00649
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
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
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
00703
00704
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
00720
00721 TEUCHOS_TEST_FOR_EXCEPTION( cellPoints.size() != 4 ,
00722 std::runtime_error ," CurveIntegralCalc::getCurveQuadPoints , QuadCell must have 4 points" );
00723
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
00730 for (int jj = 0 ; jj < 4 ; jj++ ){
00731 paramCurve.returnIntersectPoints(cellPoints[edegIndex[jj][0]], cellPoints[edegIndex[jj][1]], nrPoints , result);
00732
00733 for (int ptmp = 0 ; ptmp < nrPoints ; ptmp++){
00734 pointExists = false;
00735
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
00742 if (!pointExists){
00743
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
00753
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
00764
00765 polygon->getCellsPolygonesPoint( maxCellLID ,allPolygonPoints);
00766 polyNrPoint = allPolygonPoints.size();
00767
00768
00769
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
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
00795 flagMode = 0;
00796 for (int intP = 0 ; intP < total_points ; intP++ ){
00797 if (flagMode == 0){
00798
00799 int Pind = -1;
00800 for (int stmp = 0 ; stmp < total_points ; stmp++){
00801
00802 if (!usedIntPoint[stmp]) { Pind = stmp; break;}
00803 }
00804
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
00813 double dist = 1e+100;
00814 int Pind = -1;
00815 for (int stmp = 0 ; stmp < total_points ; stmp++){
00816
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
00827 segmentEnd[ segmentNr ] = allIntPoints[Pind];
00828 usedIntPoint[ Pind ] = true;
00829 flagMode = 0;
00830 segmentNr = segmentNr + 1;
00831 }
00832 }
00833
00834
00835
00836 for (int polyPoint = 0 ; polyPoint < polyNrPoint ; polyPoint++ ){
00837
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
00848
00849
00850 if ( (d1 + d2 - d_p < totalDist) && (d1 > eps) && (d2 > eps) ) {
00851 totalDist = d1 + d2 - d_p;
00852 segInd = pl;
00853 }
00854 }
00855
00856
00857
00858
00859 if ( segInd < 0) continue;
00860
00861
00862 segmentStart.resize( segmentNr + 1);
00863 segmentEnd.resize( segmentNr + 1 );
00864
00865 for (int tmpP = segmentNr-1; tmpP >= segInd ; tmpP--){
00866 segmentStart[tmpP+1] = segmentStart[tmpP];
00867 segmentEnd[tmpP+1] = segmentEnd[tmpP];
00868 }
00869
00870
00871 segmentEnd[segInd] = allPolygonPoints[polyPoint];
00872 segmentStart[segInd+1] = allPolygonPoints[polyPoint];
00873 segmentNr = segmentNr + 1;
00874 }
00875
00876
00877 Array<double> segmentLengthRel(0);
00878 Array<double> segmentStartLengthRel(0);
00879 segmentLengthRel.resize(segmentNr);
00880 segmentStartLengthRel.resize(segmentNr);
00881
00882
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
00887
00888 }
00889
00890
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
00896
00897
00898 actLen = actLen + thisLength;
00899 }
00900
00901
00902
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
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
00926
00927 curvePoints.resize(nr_quad_points);
00928 curveDerivs.resize(nr_quad_points);
00929 curveNormals.resize(nr_quad_points);
00930
00931
00932 int ii = 0;
00933 for (int seg = 0; seg < segmentNr ; seg++ )
00934 {
00935
00936 startPoint = segmentStart[seg];
00937 endPoint = segmentEnd[seg];
00938
00939
00940
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
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
00955 for (int pointNr = 0 ; pointNr < nr_quad_points/maxLineSegments ; pointNr++ , ii++ )
00956 {
00957
00958
00959
00960
00961
00962 curvePoints[ii] = startPoint + quadPoints[ii][0]*(endPoint - startPoint);
00963
00964
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
00970
00971
00972
00973 curveDerivs[ii] = Point( segmentLengthRel[seg]*totalLength*((double)maxLineSegments) , 0.0 );
00974
00975
00976
00977 if ( invNormVect ) {
00978 curveNormals[ii] = -norm_vec;
00979 }
00980 else {
00981 curveNormals[ii] = norm_vec;
00982 }
00983
00984 }
00985 }
00986
00987
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
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
01037 for (int t = 0 ; t < nr_triag ; t++){
01038
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
01049 for (int t = 0 ; t < nr_triag ; t++){
01050
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
01057 area = ::sqrt(n*n);
01058
01059 if ( paramCurve.curveEquation( p0 + 5e-3*n ) > 0 ) { n = (-1)*n; }
01060 n = (1/::sqrt(n*n))*n;
01061
01062
01063
01064
01065 for (int q = 0 ; q < nrQuadPointPerTriag ; q++ , qind++){
01066
01067 Point pTmp = p0 + quadPoints[qind][0] * (p1-p0) + quadPoints[qind][1] * (p2-p0);
01068
01069
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
01074 curveDerivs[qind] = Point( area * ((double)maxTriangles) , 0.0 , 0.0 );
01075 curveNormals[qind] = n;
01076 }
01077 }
01078
01079
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 }