FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

searchableSurfacesQueries.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*----------------------------------------------------------------------------*/
00025 
00026 #include "searchableSurfacesQueries.H"
00027 #include <OpenFOAM/ListOps.H>
00028 #include <OpenFOAM/OFstream.H>
00029 #include <meshTools/meshTools.H>
00030 
00031 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00032 
00033 defineTypeNameAndDebug(Foam::searchableSurfacesQueries, 0);
00034 
00035 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00036 
00037 Foam::pointIndexHit Foam::searchableSurfacesQueries::tempFindNearest
00038 (
00039     const searchableSurface& surf,
00040     const point& pt,
00041     const scalar initDistSqr
00042 )
00043 {
00044     pointField onePoint(1, pt);
00045     scalarField oneDist(1, initDistSqr);
00046     List<pointIndexHit> oneHit(1);
00047     surf.findNearest(onePoint, oneDist, oneHit);
00048     return oneHit[0];
00049 }
00050 
00051 
00052 // Calculate sum of distance to surfaces.
00053 Foam::scalar Foam::searchableSurfacesQueries::sumDistSqr
00054 (
00055     const PtrList<searchableSurface>& allSurfaces,
00056     const labelList& surfacesToTest,
00057     const scalar initDistSqr,
00058     const point& pt
00059 )
00060 {
00061     scalar sum = 0;
00062 
00063     forAll(surfacesToTest, testI)
00064     {
00065         label surfI = surfacesToTest[testI];
00066 
00067         pointIndexHit hit
00068         (
00069             tempFindNearest(allSurfaces[surfI], pt, initDistSqr)
00070         );
00071 
00072         // Note: make it fall over if not hit.
00073         sum += magSqr(hit.hitPoint()-pt);
00074     }
00075     return sum;
00076 }
00077 
00078 
00079 // Reflects the point furthest away around the triangle centre by a factor fac.
00080 // (triangle centre is the average of all points but the ihi. pSum is running
00081 //  sum of all points)
00082 Foam::scalar Foam::searchableSurfacesQueries::tryMorphTet
00083 (
00084     const PtrList<searchableSurface>& allSurfaces,
00085     const labelList& surfacesToTest,
00086     const scalar initDistSqr,
00087     List<vector>& p,
00088     List<scalar>& y,
00089     vector& pSum,
00090     const label ihi,
00091     const scalar fac
00092 )
00093 {
00094     scalar fac1 = (1.0-fac)/vector::nComponents;
00095     scalar fac2 = fac1-fac;
00096 
00097     vector ptry = pSum*fac1-p[ihi]*fac2;
00098 
00099     scalar ytry = sumDistSqr(allSurfaces, surfacesToTest, initDistSqr, ptry);
00100 
00101     if (ytry < y[ihi])
00102     {
00103         y[ihi] = ytry;
00104         pSum += ptry - p[ihi];
00105         p[ihi] = ptry;
00106     }
00107     return ytry;
00108 }
00109 
00110 
00111 bool Foam::searchableSurfacesQueries::morphTet
00112 (
00113     const PtrList<searchableSurface>& allSurfaces,
00114     const labelList& surfacesToTest,
00115     const scalar initDistSqr,
00116     const scalar convergenceDistSqr,
00117     const label maxIter,
00118     List<vector>& p,
00119     List<scalar>& y
00120 )
00121 {
00122     vector pSum = sum(p);
00123 
00124     autoPtr<OFstream> str;
00125     label vertI = 0;
00126     if (debug)
00127     {
00128         wordList names(surfacesToTest.size());
00129         forAll(surfacesToTest, i)
00130         {
00131             names[i] = allSurfaces[surfacesToTest[i]].name();
00132         }
00133         Pout<< "searchableSurfacesQueries::morphTet : intersection of "
00134             << names << " starting from points:" << p << endl;
00135         str.reset(new OFstream("track.obj"));
00136         meshTools::writeOBJ(str(), p[0]);
00137         vertI++;
00138     }
00139 
00140     for (label iter = 0; iter < maxIter; iter++)
00141     {
00142         // Get the indices of lowest, highest and second-highest values.
00143         label ilo, ihi, inhi;
00144         {
00145             labelList sortedIndices;
00146             sortedOrder(y, sortedIndices);
00147             ilo  = sortedIndices[0];
00148             ihi  = sortedIndices[sortedIndices.size()-1];
00149             inhi = sortedIndices[sortedIndices.size()-2];
00150         }
00151 
00152         if (debug)
00153         {
00154             Pout<< "Iteration:" << iter
00155                 << " lowest:" << y[ilo] << " highest:" << y[ihi]
00156                 << " points:" << p << endl;
00157 
00158             meshTools::writeOBJ(str(), p[ilo]);
00159             vertI++;
00160             str()<< "l " << vertI-1 << ' ' << vertI << nl;
00161         }
00162 
00163         if (y[ihi] < convergenceDistSqr)
00164         {
00165             // Get point on 0th surface.
00166             Swap(p[0], p[ilo]);
00167             Swap(y[0], y[ilo]);
00168             return true;
00169         }
00170 
00171         // Reflection: point furthest away gets reflected.
00172         scalar ytry = tryMorphTet
00173         (
00174             allSurfaces,
00175             surfacesToTest,
00176             10*y[ihi],             // search box.
00177             p,
00178             y,
00179             pSum,
00180             ihi,
00181             -1.0
00182         );
00183 
00184         if (ytry <= y[ilo])
00185         {
00186             // If in right direction (y lower) expand by two.
00187             ytry = tryMorphTet
00188             (
00189                 allSurfaces,
00190                 surfacesToTest,
00191                 10*y[ihi],
00192                 p,
00193                 y,
00194                 pSum,
00195                 ihi,
00196                 2.0
00197             );
00198         }
00199         else if (ytry >= y[inhi])
00200         {
00201             // If inside tet try contraction.
00202 
00203             scalar ysave = y[ihi];
00204 
00205             ytry = tryMorphTet
00206             (
00207                 allSurfaces,
00208                 surfacesToTest,
00209                 10*y[ihi],
00210                 p,
00211                 y,
00212                 pSum,
00213                 ihi,
00214                 0.5
00215             );
00216 
00217             if (ytry >= ysave)
00218             {
00219                 // Contract around lowest point.
00220                 forAll(p, i)
00221                 {
00222                     if (i != ilo)
00223                     {
00224                         p[i] = 0.5*(p[i] + p[ilo]);
00225                         y[i] = sumDistSqr
00226                         (
00227                             allSurfaces,
00228                             surfacesToTest,
00229                             y[ihi],
00230                             p[i]
00231                         );
00232                     }
00233                 }
00234                 pSum = sum(p);
00235             }
00236         }
00237     }
00238 
00239     if (debug)
00240     {
00241         meshTools::writeOBJ(str(), p[0]);
00242         vertI++;
00243         str()<< "l " << vertI-1 << ' ' << vertI << nl;
00244     }
00245 
00246     // Failure to converge. Return best guess so far.
00247     label ilo = findMin(y);
00248     Swap(p[0], p[ilo]);
00249     Swap(y[0], y[ilo]);
00250     return false;
00251 }
00252 
00253 
00255 //void Foam::searchableSurfacesQueries::findAllIntersections
00256 //(
00257 //    const searchableSurface& s,
00258 //    const pointField& start,
00259 //    const pointField& end,
00260 //    const vectorField& smallVec,
00261 //    List<List<pointIndexHit> >& surfaceHitInfo
00262 //)
00263 //{
00264 //    surfaceHitInfo.setSize(start.size());
00265 //
00266 //    // Current start point of vector
00267 //    pointField p0(start);
00268 //
00269 //    List<pointIndexHit> intersectInfo(start.size());
00270 //
00271 //    // For test whether finished doing vector.
00272 //    const vectorField dirVec(end-start);
00273 //    const scalarField magSqrDirVec(magSqr(dirVec));
00274 //
00275 //    while (true)
00276 //    {
00277 //        // Find first intersection. Synced.
00278 //        s.findLine(p0, end, intersectInfo);
00279 //
00280 //        label nHits = 0;
00281 //
00282 //        forAll(intersectInfo, i)
00283 //        {
00284 //            if (intersectInfo[i].hit())
00285 //            {
00286 //                nHits++;
00287 //
00288 //                label sz = surfaceHitInfo[i].size();
00289 //                surfaceHitInfo[i].setSize(sz+1);
00290 //                surfaceHitInfo[i][sz] = intersectInfo[i];
00291 //
00292 //                p0[i] = intersectInfo[i].hitPoint() + smallVec[i];
00293 //
00294 //                // If beyond endpoint set to endpoint so as not to pick up
00295 //                // any intersections. Could instead just filter out hits.
00296 //                if (((p0[i]-start[i])&dirVec[i]) > magSqrDirVec[i])
00297 //                {
00298 //                    p0[i] = end[i];
00299 //                }
00300 //            }
00301 //            else
00302 //            {
00303 //                // Set to endpoint to stop intersection test. See above.
00304 //                p0[i] = end[i];
00305 //            }
00306 //        }
00307 //
00308 //        // returnReduce(nHits) ?
00309 //        if (nHits == 0)
00310 //        {
00311 //            break;
00312 //        }
00313 //    }
00314 //}
00315 
00316 
00317 // Given current set of hits (allSurfaces, allInfo) merge in those coming from
00318 // surface surfI.
00319 void Foam::searchableSurfacesQueries::mergeHits
00320 (
00321     const point& start,
00322     const scalar mergeDist,
00323 
00324     const label testI,                          // index of surface
00325     const List<pointIndexHit>& surfHits,  // hits on surface
00326 
00327     labelList& allSurfaces,
00328     List<pointIndexHit>& allInfo,
00329     scalarList& allDistSqr
00330 )
00331 {
00332     // Precalculate distances
00333     scalarList surfDistSqr(surfHits.size());
00334     forAll(surfHits, i)
00335     {
00336         surfDistSqr[i] = magSqr(surfHits[i].hitPoint()-start);
00337     }
00338 
00339     forAll(surfDistSqr, i)
00340     {
00341         label index = findLower(allDistSqr, surfDistSqr[i]);
00342 
00343         // Check if equal to lower.
00344         if
00345         (
00346             index >= 0
00347          && (mag(allDistSqr[index]-surfDistSqr[i]) < mergeDist)
00348         )
00349         {
00350             // Same. Do not count.
00351             //Pout<< "point:" << surfHits[i].hitPoint()
00352             //    << " considered same as:" << allInfo[index].hitPoint()
00353             //    << " within tol:" << mergeDist
00354             //    << endl;
00355         }
00356         else
00357         {
00358             // Check if equal to higher
00359             label next = index+1;
00360             if
00361             (
00362                 next < allDistSqr.size()
00363              && (mag(allDistSqr[next]-surfDistSqr[i]) < mergeDist)
00364             )
00365             {
00366                 //Pout<< "point:" << surfHits[i].hitPoint()
00367                 //    << " considered same as:" << allInfo[next].hitPoint()
00368                 //    << " within tol:" << mergeDist
00369                 //    << endl;
00370             }
00371             else
00372             {
00373                 // Insert after index
00374                 label sz = allSurfaces.size();
00375                 allSurfaces.setSize(sz+1);
00376                 allInfo.setSize(allSurfaces.size());
00377                 allDistSqr.setSize(allSurfaces.size());
00378                 // Make space.
00379                 for (label j = sz-1; j > index; --j)
00380                 {
00381                     allSurfaces[j+1] = allSurfaces[j];
00382                     allInfo[j+1] = allInfo[j];
00383                     allDistSqr[j+1] = allDistSqr[j];
00384                 }
00385                 // Insert new value
00386                 allSurfaces[index+1] = testI;
00387                 allInfo[index+1] = surfHits[i];
00388                 allDistSqr[index+1] = surfDistSqr[i];
00389             }
00390         }
00391     }
00392 }
00393 
00394 
00395 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00396 
00397 // Find any intersection
00398 void Foam::searchableSurfacesQueries::findAnyIntersection
00399 (
00400     const PtrList<searchableSurface>& allSurfaces,
00401     const labelList& surfacesToTest,
00402     const pointField& start,
00403     const pointField& end,
00404     labelList& hitSurfaces,
00405     List<pointIndexHit>& hitInfo
00406 )
00407 {
00408     hitSurfaces.setSize(start.size());
00409     hitSurfaces = -1;
00410     hitInfo.setSize(start.size());
00411 
00412     // Work arrays
00413     labelList hitMap(identity(start.size()));
00414     pointField p0(start);
00415     pointField p1(end);
00416     List<pointIndexHit> intersectInfo(start.size());
00417 
00418     forAll(surfacesToTest, testI)
00419     {
00420         // Do synchronised call to all surfaces.
00421         allSurfaces[surfacesToTest[testI]].findLineAny(p0, p1, intersectInfo);
00422 
00423         // Copy all hits into arguments, continue with misses
00424         label newI = 0;
00425         forAll(intersectInfo, i)
00426         {
00427             if (intersectInfo[i].hit())
00428             {
00429                 hitInfo[hitMap[i]] = intersectInfo[i];
00430                 hitSurfaces[hitMap[i]] = testI;
00431             }
00432             else
00433             {
00434                 if (i != newI)
00435                 {
00436                     hitMap[newI] = hitMap[i];
00437                     p0[newI] = p0[i];
00438                     p1[newI] = p1[i];
00439                 }
00440                 newI++;
00441             }
00442         }
00443 
00444         // All done? Note that this decision should be synchronised
00445         if (newI == 0)
00446         {
00447             break;
00448         }
00449 
00450         // Trim and continue
00451         hitMap.setSize(newI);
00452         p0.setSize(newI);
00453         p1.setSize(newI);
00454         intersectInfo.setSize(newI);
00455     }
00456 }
00457 
00458 
00459 void Foam::searchableSurfacesQueries::findAllIntersections
00460 (
00461     const PtrList<searchableSurface>& allSurfaces,
00462     const labelList& surfacesToTest,
00463     const pointField& start,
00464     const pointField& end,
00465     labelListList& hitSurfaces,
00466     List<List<pointIndexHit> >& hitInfo
00467 )
00468 {
00469     // Note: maybe move the single-surface all intersections test into
00470     // searchable surface? Some of the tolerance issues might be
00471     // lessened.
00472 
00473     // 2. Currently calling searchableSurface::findLine with start==end
00474     //    is expected to find no intersection. Problem if it does.
00475 
00476     hitSurfaces.setSize(start.size());
00477     hitInfo.setSize(start.size());
00478 
00479     if (surfacesToTest.empty())
00480     {
00481         return;
00482     }
00483 
00484     // Test first surface
00485     allSurfaces[surfacesToTest[0]].findLineAll(start, end, hitInfo);
00486 
00487     // Set hitSurfaces and distance
00488     List<scalarList> hitDistSqr(hitInfo.size());
00489     forAll(hitInfo, pointI)
00490     {
00491         const List<pointIndexHit>& pHits = hitInfo[pointI];
00492 
00493         labelList& pSurfaces = hitSurfaces[pointI];
00494         pSurfaces.setSize(pHits.size());
00495         pSurfaces = 0;
00496 
00497         scalarList& pDistSqr = hitDistSqr[pointI];
00498         pDistSqr.setSize(pHits.size());
00499         forAll(pHits, i)
00500         {
00501             pDistSqr[i] = magSqr(pHits[i].hitPoint() - start[pointI]);
00502         }
00503     }
00504 
00505 
00506     if (surfacesToTest.size() > 1)
00507     {
00508         // Small vector to increment start vector by to find next intersection
00509         // along line. Constant factor added to make sure that start==end still
00510         // ends iteration in findAllIntersections. Also SMALL is just slightly
00511         // too small.
00512         const vectorField smallVec
00513         (
00514             1E2*SMALL*(end-start)
00515           + vector(ROOTVSMALL,ROOTVSMALL,ROOTVSMALL)
00516         );
00517 
00518         // Tolerance used to check whether points are equal. Note: used to
00519         // compare distance^2. Note that we use the maximum possible tolerance
00520         // (reached at intersections close to the end point)
00521         const scalarField mergeDist(2*mag(smallVec)*mag(end-start));
00522 
00523         // Test the other surfaces and merge (according to distance from start).
00524         for (label testI = 1; testI < surfacesToTest.size(); testI++)
00525         {
00526             List<List<pointIndexHit> > surfHits;
00527             allSurfaces[surfacesToTest[testI]].findLineAll
00528             (
00529                 start,
00530                 end,
00531                 surfHits
00532             );
00533 
00534             forAll(surfHits, pointI)
00535             {
00536                 mergeHits
00537                 (
00538                     start[pointI],          // Current segment
00539                     mergeDist[pointI],
00540 
00541                     testI,                  // Surface and its hits
00542                     surfHits[pointI],
00543 
00544                     hitSurfaces[pointI],    // Merge into overall hit info
00545                     hitInfo[pointI],
00546                     hitDistSqr[pointI]
00547                 );
00548             }
00549         }
00550     }
00551 }
00552 
00553 
00555 //void Foam::searchableSurfacesQueries::findNearestIntersection
00556 //(
00557 //    const PtrList<searchableSurface>& allSurfaces,
00558 //    const labelList& surfacesToTest,
00559 //    const pointField& start,
00560 //    const pointField& end,
00561 //
00562 //    labelList& surface1,
00563 //    List<pointIndexHit>& hit1,
00564 //    labelList& surface2,
00565 //    List<pointIndexHit>& hit2
00566 //)
00567 //{
00568 //    // 1. intersection from start to end
00569 //    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00570 //
00571 //    // Initialize arguments
00572 //    surface1.setSize(start.size());
00573 //    surface1 = -1;
00574 //    hit1.setSize(start.size());
00575 //
00576 //    // Current end of segment to test.
00577 //    pointField nearest(end);
00578 //    // Work array
00579 //    List<pointIndexHit> nearestInfo(start.size());
00580 //
00581 //    forAll(surfacesToTest, testI)
00582 //    {
00583 //        // See if any intersection between start and current nearest
00584 //        allSurfaces[surfacesToTest[testI]].findLine
00585 //        (
00586 //            start,
00587 //            nearest,
00588 //            nearestInfo
00589 //        );
00590 //
00591 //        forAll(nearestInfo, pointI)
00592 //        {
00593 //            if (nearestInfo[pointI].hit())
00594 //            {
00595 //                hit1[pointI] = nearestInfo[pointI];
00596 //                surface1[pointI] = testI;
00597 //                nearest[pointI] = hit1[pointI].hitPoint();
00598 //            }
00599 //        }
00600 //    }
00601 //
00602 //
00603 //    // 2. intersection from end to last intersection
00604 //    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00605 //
00606 //    // Find the nearest intersection from end to start. Note that we
00607 //    // initialize to the first intersection (if any).
00608 //    surface2 = surface1;
00609 //    hit2 = hit1;
00610 //
00611 //    // Set current end of segment to test.
00612 //    forAll(nearest, pointI)
00613 //    {
00614 //        if (hit1[pointI].hit())
00615 //        {
00616 //            nearest[pointI] = hit1[pointI].hitPoint();
00617 //        }
00618 //        else
00619 //        {
00620 //            // Disable testing by setting to end.
00621 //            nearest[pointI] = end[pointI];
00622 //        }
00623 //    }
00624 //
00625 //    forAll(surfacesToTest, testI)
00626 //    {
00627 //        // See if any intersection between end and current nearest
00628 //        allSurfaces[surfacesToTest[i]].findLine(end, nearest, nearestInfo);
00629 //
00630 //        forAll(nearestInfo, pointI)
00631 //        {
00632 //            if (nearestInfo[pointI].hit())
00633 //            {
00634 //                hit2[pointI] = nearestInfo[pointI];
00635 //                surface2[pointI] = testI;
00636 //                nearest[pointI] = hit2[pointI].hitPoint();
00637 //            }
00638 //        }
00639 //    }
00640 //}
00641 
00642 
00643 // Find nearest. Return -1 or nearest point
00644 void Foam::searchableSurfacesQueries::findNearest
00645 (
00646     const PtrList<searchableSurface>& allSurfaces,
00647     const labelList& surfacesToTest,
00648     const pointField& samples,
00649     const scalarField& nearestDistSqr,
00650     labelList& nearestSurfaces,
00651     List<pointIndexHit>& nearestInfo
00652 )
00653 {
00654     // Initialise
00655     nearestSurfaces.setSize(samples.size());
00656     nearestSurfaces = -1;
00657     nearestInfo.setSize(samples.size());
00658 
00659     // Work arrays
00660     scalarField minDistSqr(nearestDistSqr);
00661     List<pointIndexHit> hitInfo(samples.size());
00662 
00663     forAll(surfacesToTest, testI)
00664     {
00665         allSurfaces[surfacesToTest[testI]].findNearest
00666         (
00667             samples,
00668             minDistSqr,
00669             hitInfo
00670         );
00671 
00672         // Update minDistSqr and arguments
00673         forAll(hitInfo, pointI)
00674         {
00675             if (hitInfo[pointI].hit())
00676             {
00677                 minDistSqr[pointI] = magSqr
00678                 (
00679                     hitInfo[pointI].hitPoint()
00680                   - samples[pointI]
00681                 );
00682                 nearestInfo[pointI] = hitInfo[pointI];
00683                 nearestSurfaces[pointI] = testI;
00684             }
00685         }
00686     }
00687 }
00688 
00689 
00690 //- Calculate point which is on a set of surfaces.
00691 Foam::pointIndexHit Foam::searchableSurfacesQueries::facesIntersection
00692 (
00693     const PtrList<searchableSurface>& allSurfaces,
00694     const labelList& surfacesToTest,
00695     const scalar initDistSqr,
00696     const scalar convergenceDistSqr,
00697     const point& start
00698 )
00699 {
00700     // Get four starting points. Take these as the projection of the
00701     // starting point onto the surfaces and the mid point
00702     List<point> nearest(surfacesToTest.size()+1);
00703 
00704     point sumNearest = vector::zero;
00705 
00706     forAll(surfacesToTest, i)
00707     {
00708         pointIndexHit hit
00709         (
00710             tempFindNearest(allSurfaces[surfacesToTest[i]], start, initDistSqr)
00711         );
00712 
00713         if (hit.hit())
00714         {
00715             nearest[i] = hit.hitPoint();
00716             sumNearest += nearest[i];
00717         }
00718         else
00719         {
00720             FatalErrorIn
00721             (
00722                 "searchableSurfacesQueries::facesIntersection"
00723                 "(const labelList&, const scalar, const scalar, const point&)"
00724             )   << "Did not find point within distance "
00725                 << initDistSqr << " of starting point " << start
00726                 << " on surface "
00727                 << allSurfaces[surfacesToTest[i]].IOobject::name()
00728                 << abort(FatalError);
00729         }
00730     }
00731 
00732     nearest[nearest.size()-1] = sumNearest / surfacesToTest.size();
00733 
00734 
00735     // Get the sum of distances (initial evaluation)
00736     List<scalar> nearestDist(nearest.size());
00737 
00738     forAll(nearestDist, i)
00739     {
00740         nearestDist[i] = sumDistSqr
00741         (
00742             allSurfaces,
00743             surfacesToTest,
00744             initDistSqr,
00745             nearest[i]
00746         );
00747     }
00748 
00749 
00750     //- Downhill Simplex method
00751 
00752     bool converged = morphTet
00753     (
00754         allSurfaces,
00755         surfacesToTest,
00756         initDistSqr,
00757         convergenceDistSqr,
00758         2000,
00759         nearest,
00760         nearestDist
00761     );
00762 
00763 
00764     pointIndexHit intersection;
00765 
00766     if (converged)
00767     {
00768         // Project nearest onto 0th surface.
00769         intersection = tempFindNearest
00770         (
00771             allSurfaces[surfacesToTest[0]],
00772             nearest[0],
00773             nearestDist[0]
00774         );
00775     }
00776 
00777     //if (!intersection.hit())
00778     //{
00779     //    // Restart
00780     //    scalar smallDist = Foam::sqr(convergenceDistSqr);
00781     //    nearest[0] = intersection.hitPoint();
00782     //    nearest[1] = nearest[0];
00783     //    nearest[1].x() += smallDist;
00784     //    nearest[2] = nearest[0];
00785     //    nearest[2].y() += smallDist;
00786     //    nearest[3] = nearest[0];
00787     //    nearest[3].z() += smallDist;
00788     //
00789     //    forAll(nearestDist, i)
00790     //    {
00791     //        nearestDist[i] = sumDistSqr
00792     //        (
00793     //            surfacesToTest,
00794     //            initDistSqr,
00795     //            nearest[i]
00796     //        );
00797     //    }
00798     //
00799     //    intersection = morphTet
00800     //    (
00801     //        allSurfaces,
00802     //        surfacesToTest,
00803     //        initDistSqr,
00804     //        convergenceDistSqr,
00805     //        1000,
00806     //        nearest,
00807     //        nearestDist
00808     //    );
00809     //}
00810 
00811     return intersection;
00812 }
00813 
00814 
00815 
00816 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines