Changeset 2b4a40 for src


Ignore:
Timestamp:
Oct 14, 2008, 7:14:10 PM (16 years ago)
Author:
Frederik Heber <heber@…>
Branches:
Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
Children:
57d8b0
Parents:
ca8073
Message:

new version of Tesselation::GuessStartingTriangle() seems to fix problems

+ now, we find the starting triangle in the following manner (point = boundary point!):

  1. pick a point A
  2. for all unequal pairs B,C (not A), calculate AB2+BC2+AC2 and sort into ascending list
  3. Go through list, picking thus baseline B,C along with peak A of a candidate triangle
  4. check whether all other boundary points lie only on one side
  5. check whether no boundary point is inside the triangle
  6. If all successful, starting triangle is found With this procedure, the convex hull of all SiOHCa3 clusters are found perfectly.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/boundary.cpp

    rca8073 r2b4a40  
    673673  // 4b1. create all distances
    674674  DistanceMultiMap DistanceMMap;
    675   double distance;
    676   for (PointMap::iterator runner = PointsOnBoundary.begin(); runner != PointsOnBoundary.end(); runner++) {
    677     for(PointMap::iterator sprinter = PointsOnBoundary.begin(); sprinter != PointsOnBoundary.end(); sprinter++) {
    678       if (runner->first < sprinter->first) {
    679         distance = runner->second->node->x.Distance(&sprinter->second->node->x);
    680         DistanceMMap.insert( DistanceMultiMapPair(distance, pair<PointMap::iterator, PointMap::iterator>(runner,sprinter) ) );
     675  double distance, tmp;
     676  Vector PlaneVector, TrialVector;
     677  PointMap::iterator A, B, C; // three nodes of the first triangle
     678  A = PointsOnBoundary.begin(); // the first may be chosen arbitrarily
     679
     680  // with A chosen, take each pair B,C and sort
     681  if (A != PointsOnBoundary.end()) {
     682    B = A;
     683    B++;
     684    for (; B != PointsOnBoundary.end(); B++) {
     685      C = B;
     686      C++;
     687      for (; C != PointsOnBoundary.end(); C++) {
     688        tmp = A->second->node->x.Distance(&B->second->node->x);
     689        distance = tmp*tmp;
     690        tmp = A->second->node->x.Distance(&C->second->node->x);
     691        distance += tmp*tmp;
     692        tmp = B->second->node->x.Distance(&C->second->node->x);
     693        distance += tmp*tmp;
     694        DistanceMMap.insert( DistanceMultiMapPair(distance, pair<PointMap::iterator, PointMap::iterator>(B,C) ) );
    681695      }
    682696    }
    683697  }
    684 
    685698//    // listing distances
    686699//    *out << Verbose(1) << "Listing DistanceMMap:";
     
    690703//    *out << endl;
    691704 
    692   // 4b2. take three smallest distance that form a triangle
    693   // we take the smallest distance as the base line
     705  // 4b2. pick three baselines forming a triangle
     706  // 1. we take from the smallest sum of squared distance as the base line BC (with peak A) onward as the triangle candidate
    694707  DistanceMultiMap::iterator baseline = DistanceMMap.begin();
    695   BPS[0] = baseline->second.first->second;
    696   BPS[1] = baseline->second.second->second;
    697   BLS[0] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
    698 
    699   // take the second smallest as the second base line
    700   DistanceMultiMap::iterator secondline = DistanceMMap.begin();
    701   do {
    702     secondline++;
    703   } while (!(
    704       ((BPS[0] == secondline->second.first->second) && (BPS[1] != secondline->second.second->second)) ||
    705       ((BPS[0] == secondline->second.second->second) && (BPS[1] != secondline->second.first->second)) ||
    706       ((BPS[1] == secondline->second.first->second) && (BPS[0] != secondline->second.second->second)) ||
    707       ((BPS[1] == secondline->second.second->second) && (BPS[0] != secondline->second.first->second))
    708     ));
    709   BPS[0] = secondline->second.first->second;
    710   BPS[1] = secondline->second.second->second;
    711   BLS[1] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
    712 
    713   // connection yields the third line (note: first and second endpoint are sorted!)
    714   if (baseline->second.first->second == secondline->second.first->second) {
    715     SetEndpointsOrdered(BPS, baseline->second.second->second, secondline->second.second->second);
    716   } else if (baseline->second.first->second == secondline->second.second->second) {
    717     SetEndpointsOrdered(BPS, baseline->second.second->second, secondline->second.first->second);
    718   } else if (baseline->second.second->second == secondline->second.first->second) {
    719     SetEndpointsOrdered(BPS, baseline->second.first->second, baseline->second.second->second);
    720   } else if (baseline->second.second->second == secondline->second.second->second) {
    721     SetEndpointsOrdered(BPS, baseline->second.first->second, baseline->second.first->second);
    722   }
    723   BLS[2] = new class BoundaryLineSet(BPS, LinesOnBoundaryCount);
    724  
    725   // 4b3. insert created triangle
    726   BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
    727   TrianglesOnBoundary.insert( TrianglePair(TrianglesOnBoundaryCount, BTS) );
    728   TrianglesOnBoundaryCount++;
    729   for(int i=0;i<NDIM;i++) {
    730     LinesOnBoundary.insert( LinePair(LinesOnBoundaryCount, BTS->lines[i]) );
    731     LinesOnBoundaryCount++;
    732   }
    733 
    734   *out << Verbose(1) << "Starting triangle is " << *BTS << "." << endl;
     708  for (; baseline != DistanceMMap.end(); baseline++) {
     709    // we take from the smallest sum of squared distance as the base line BC (with peak A) onward as the triangle candidate
     710    // 2. next, we have to check whether all points reside on only one side of the triangle
     711    // 3. construct plane vector
     712    PlaneVector.MakeNormalVector(&A->second->node->x, &baseline->second.first->second->node->x, &baseline->second.second->second->node->x);
     713    *out << Verbose(2) << "Plane vector of candidate triangle is ";
     714    PlaneVector.Output(out);
     715    *out << endl;
     716    // 4. loop over all points
     717    double sign = 0.;
     718    PointMap::iterator checker = PointsOnBoundary.begin();
     719    for (; checker != PointsOnBoundary.end(); checker++) {
     720      // (neglecting A,B,C)
     721      if ((checker == A) || (checker == baseline->second.first) || (checker == baseline->second.second))
     722        continue;
     723      // 4a. project onto plane vector
     724      TrialVector.CopyVector(&checker->second->node->x);
     725      TrialVector.SubtractVector(&A->second->node->x);
     726      distance = TrialVector.Projection(&PlaneVector);
     727      if (fabs(distance) < 1e-4)  // we need to have a small epsilon around 0 which is still ok
     728        continue;
     729      *out << Verbose(3) << "Projection of " << checker->second->node->Name << " yields distance of " << distance << "." << endl;
     730      tmp = distance/fabs(distance);
     731      // 4b. Any have different sign to than before? (i.e. would lie outside convex hull with this starting triangle)
     732      if ((sign != 0) && (tmp != sign)) {
     733        // 4c. If so, break 4. loop and continue with next candidate in 1. loop
     734        *out << Verbose(2) << "Current candidates: " << A->second->node->Name << "," << baseline->second.first->second->node->Name  << "," << baseline->second.second->second->node->Name << " leave " << checker->second->node->Name << " outside the convex hull." << endl;
     735        break;
     736      } else { // note the sign for later
     737        *out << Verbose(2) << "Current candidates: " << A->second->node->Name << "," << baseline->second.first->second->node->Name  << "," << baseline->second.second->second->node->Name << " leave " << checker->second->node->Name << " inside the convex hull." << endl;
     738        sign = tmp;
     739      }
     740      // 4d. Check whether the point is inside the triangle (check distance to each node
     741      tmp = checker->second->node->x.Distance(&A->second->node->x);
     742      int innerpoint = 0;
     743      if ((tmp < A->second->node->x.Distance(&baseline->second.first->second->node->x))
     744          && (tmp < A->second->node->x.Distance(&baseline->second.second->second->node->x)))
     745        innerpoint++;
     746      tmp = checker->second->node->x.Distance(&baseline->second.first->second->node->x);
     747      if ((tmp < baseline->second.first->second->node->x.Distance(&A->second->node->x))
     748          && (tmp < baseline->second.first->second->node->x.Distance(&baseline->second.second->second->node->x)))
     749        innerpoint++;
     750      tmp = checker->second->node->x.Distance(&baseline->second.second->second->node->x);
     751      if ((tmp < baseline->second.second->second->node->x.Distance(&baseline->second.first->second->node->x))
     752          && (tmp < baseline->second.second->second->node->x.Distance(&A->second->node->x)))
     753        innerpoint++;
     754      // 4e. If so, break 4. loop and continue with next candidate in 1. loop
     755      if (innerpoint == 3)
     756        break;
     757    }
     758    // 5. come this far, all on same side? Then break 1. loop and construct triangle
     759    if (checker == PointsOnBoundary.end()) {
     760      *out << "Looks like we have a candidate!" << endl;
     761      break;
     762    }
     763  }
     764  if (baseline != DistanceMMap.end()) {
     765    BPS[0] = baseline->second.first->second;
     766    BPS[1] = baseline->second.second->second;
     767    BLS[0] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
     768    BPS[0] = A->second;
     769    BPS[1] = baseline->second.second->second;
     770    BLS[1] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
     771    BPS[0] = baseline->second.first->second;
     772    BPS[1] = A->second;
     773    BLS[2] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount); 
     774   
     775    // 4b3. insert created triangle
     776    BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
     777    TrianglesOnBoundary.insert( TrianglePair(TrianglesOnBoundaryCount, BTS) );
     778    TrianglesOnBoundaryCount++;
     779    for(int i=0;i<NDIM;i++) {
     780      LinesOnBoundary.insert( LinePair(LinesOnBoundaryCount, BTS->lines[i]) );
     781      LinesOnBoundaryCount++;
     782    }
     783 
     784    *out << Verbose(1) << "Starting triangle is " << *BTS << "." << endl;
     785  } else {
     786    *out << Verbose(1) << "No starting triangle found." << endl;
     787    exit(255);
     788  }
    735789};
    736790
Note: See TracChangeset for help on using the changeset viewer.