Changeset 8c54a3 for src


Ignore:
Timestamp:
Aug 3, 2009, 4:48:46 PM (15 years ago)
Author:
Saskia Metzler <metzler@…>
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:
0dbddc
Parents:
ee1b16
Message:

Adding functions IsInnerAtom() and IsInnerPoint() which can check whether an atom (or a point) is inside or outside the tesselation structure.

Location:
src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/boundary.cpp

    ree1b16 r8c54a3  
    18041804 */
    18051805int Tesselation::CheckPresenceOfTriangle(ofstream *out, atom *Candidates[3]) {
     1806// TODO: use findTriangles here and return result.size();
    18061807  LineMap::iterator FindLine;
    18071808  PointMap::iterator FindPoint;
     
    22402241  int N[NDIM], Nlower[NDIM], Nupper[NDIM];
    22412242
    2242   if (LC->SetIndexToAtom(a)) {  // get cell for the starting atom
     2243  if (LC->SetIndexToAtom(*a)) {  // get cell for the starting atom
    22432244    for(int i=0;i<NDIM;i++) // store indices of this cell
    22442245      N[i] = LC->n[i];
     
    27462747 */
    27472748bool sortCandidates(CandidateForTesselation* candidate1, CandidateForTesselation* candidate2) {
    2748         Vector BaseLineVector, OrthogonalVector, helper;
     2749  // TODO: use get angle and remove duplicate code
     2750  Vector BaseLineVector, OrthogonalVector, helper;
    27492751        if (candidate1->BaseLine != candidate2->BaseLine) {  // sanity check
    27502752          cout << Verbose(0) << "ERROR: sortCandidates was called for two different baselines: " << candidate1->BaseLine << " and " << candidate2->BaseLine << "." << endl;
     
    27842786        // return comparison
    27852787        return phi < psi;
     2788}
     2789
     2790/**
     2791 * Checks whether the provided atom is within the tesselation structure.
     2792 *
     2793 * @param atom of which to check the position
     2794 * @param tesselation structure
     2795 *
     2796 * @return true if the atom is inside the tesselation structure, false otherwise
     2797 */
     2798bool IsInnerAtom(atom *Atom, class Tesselation *Tess, LinkedCell* LC) {
     2799  if (Tess->LinesOnBoundary.begin() == Tess->LinesOnBoundary.end()) {
     2800    cout << Verbose(0) << "Error: There is no tesselation structure to compare the atom with, "
     2801        << "please create one first.";
     2802    exit(1);
     2803  }
     2804
     2805  class atom *trianglePoints[3];
     2806  trianglePoints[0] = findClosestAtom(Atom, LC);
     2807  // check whether closest atom is "too close" :), then it's inside
     2808  if (trianglePoints[0]->x.DistanceSquared(&Atom->x) < MYEPSILON)
     2809    return true;
     2810  list<atom*> *connectedClosestAtoms = Tess->getClosestConnectedAtoms(trianglePoints[0], Atom);
     2811  trianglePoints[1] = connectedClosestAtoms->front();
     2812  trianglePoints[2] = connectedClosestAtoms->back();
     2813  for (int i=0;i<3;i++) {
     2814    if (trianglePoints[i] == NULL) {
     2815      cout << Verbose(1) << "IsInnerAtom encounters serious error, point " << i << " not found." << endl;
     2816    }
     2817
     2818    cout << Verbose(1) << "List of possible atoms:" << endl;
     2819    cout << *trianglePoints[i] << endl;
     2820
     2821//    for(list<atom*>::iterator runner = connectedClosestAtoms->begin(); runner != connectedClosestAtoms->end(); runner++)
     2822//      cout << Verbose(2) << *(*runner) << endl;
     2823  }
     2824  delete(connectedClosestAtoms);
     2825
     2826  list<BoundaryTriangleSet*> *triangles = Tess->FindTriangles(trianglePoints);
     2827
     2828  if (triangles->empty()) {
     2829    cout << Verbose(0) << "Error: There is no nearest triangle. Please check the tesselation structure.";
     2830    exit(1);
     2831  }
     2832
     2833  Vector helper;
     2834  helper.CopyVector(&Atom->x);
     2835
     2836  // Only in case of degeneration, there will be two different scalar products.
     2837  // If at least one scalar product is positive, the point is considered to be outside.
     2838  bool status = (helper.ScalarProduct(&triangles->front()->NormalVector) < 0)
     2839      && (helper.ScalarProduct(&triangles->back()->NormalVector) < 0);
     2840  delete(triangles);
     2841  return status;
     2842}
     2843
     2844/**
     2845 * Finds the atom which is closest to the provided one.
     2846 *
     2847 * @param atom to which to find the closest other atom
     2848 * @param linked cell structure
     2849 *
     2850 * @return atom which is closest to the provided one
     2851 */
     2852atom* findClosestAtom(const atom* Atom, LinkedCell* LC) {
     2853  LinkedAtoms *List = NULL;
     2854  atom* closestAtom = NULL;
     2855  double distance = 1e16;
     2856  Vector helper;
     2857  int N[NDIM], Nlower[NDIM], Nupper[NDIM];
     2858
     2859  LC->SetIndexToVector(&Atom->x); // ignore status as we calculate bounds below sensibly
     2860  for(int i=0;i<NDIM;i++) // store indices of this cell
     2861    N[i] = LC->n[i];
     2862  //cout << Verbose(2) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl;
     2863
     2864  LC->GetNeighbourBounds(Nlower, Nupper);
     2865  //cout << endl;
     2866  for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++)
     2867    for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++)
     2868      for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) {
     2869        List = LC->GetCurrentCell();
     2870        //cout << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << endl;
     2871        if (List != NULL) {
     2872          for (LinkedAtoms::iterator Runner = List->begin(); Runner != List->end(); Runner++) {
     2873            helper.CopyVector(&Atom->x);
     2874            helper.SubtractVector(&(*Runner)->x);
     2875            double currentNorm = helper. Norm();
     2876            if (currentNorm < distance) {
     2877              distance = currentNorm;
     2878              closestAtom = (*Runner);
     2879            }
     2880          }
     2881        } else {
     2882          cerr << "ERROR: The current cell " << LC->n[0] << "," << LC->n[1] << ","
     2883            << LC->n[2] << " is invalid!" << endl;
     2884        }
     2885      }
     2886
     2887  return closestAtom;
     2888}
     2889
     2890/**
     2891 * Gets all atoms connected to the provided atom by triangulation lines.
     2892 *
     2893 * @param atom of which get all connected atoms
     2894 * @param atom to be checked whether it is an inner atom
     2895 *
     2896 * @return list of the two atoms linked to the provided one and closest to the atom to be checked,
     2897 */
     2898list<atom*> * Tesselation::getClosestConnectedAtoms(atom* Atom, atom* AtomToCheck) {
     2899  list<atom*> connectedAtoms;
     2900  map<double, atom*> anglesOfAtoms;
     2901  map<double, atom*>::iterator runner;
     2902  LineMap::iterator findLines = LinesOnBoundary.begin();
     2903  list<atom*>::iterator listRunner;
     2904  Vector center, planeNorm, currentPoint, OrthogonalVector, helper;
     2905  atom* current;
     2906  bool takeAtom = false;
     2907
     2908  planeNorm.CopyVector(&Atom->x);
     2909  planeNorm.SubtractVector(&AtomToCheck->x);
     2910  planeNorm.Normalize();
     2911
     2912  while (findLines != LinesOnBoundary.end()) {
     2913    takeAtom = false;
     2914
     2915    if (findLines->second->endpoints[0]->Nr == Atom->nr) {
     2916      takeAtom = true;
     2917      current = findLines->second->endpoints[1]->node;
     2918    } else if (findLines->second->endpoints[1]->Nr == Atom->nr) {
     2919      takeAtom = true;
     2920      current = findLines->second->endpoints[0]->node;
     2921    }
     2922
     2923    if (takeAtom) {
     2924      connectedAtoms.push_back(current);
     2925      currentPoint.CopyVector(&current->x);
     2926      currentPoint.ProjectOntoPlane(&planeNorm);
     2927      center.AddVector(&currentPoint);
     2928    }
     2929
     2930    findLines++;
     2931  }
     2932
     2933  cout << "Summed vectors " << center << "; number of atoms " << connectedAtoms.size()
     2934    << "; scale factor " << 1.0/connectedAtoms.size();
     2935
     2936  center.Scale(1.0/connectedAtoms.size());
     2937  listRunner = connectedAtoms.begin();
     2938
     2939  cout << " calculated center " << center <<  endl;
     2940
     2941  // construct one orthogonal vector
     2942  helper.CopyVector(&AtomToCheck->x);
     2943  helper.ProjectOntoPlane(&planeNorm);
     2944  OrthogonalVector.MakeNormalVector(&center, &helper, &(*listRunner)->x);
     2945  while (listRunner != connectedAtoms.end()) {
     2946    double angle = getAngle((*listRunner)->x, AtomToCheck->x, center, OrthogonalVector);
     2947    cout << "Calculated angle " << angle << " for atom " << **listRunner << endl;
     2948    anglesOfAtoms.insert(pair<double, atom*>(angle, (*listRunner)));
     2949    listRunner++;
     2950  }
     2951
     2952  list<atom*> *result = new list<atom*>;
     2953  runner = anglesOfAtoms.begin();
     2954  cout << "First value is " << *runner->second << endl;
     2955  result->push_back(runner->second);
     2956  runner = anglesOfAtoms.end();
     2957  runner--;
     2958  cout << "Second value is " << *runner->second << endl;
     2959  result->push_back(runner->second);
     2960
     2961  cout << "List of closest atoms has " << result->size() << " elements, which are "
     2962    << *(result->front()) << " and " << *(result->back()) << endl;
     2963
     2964  return result;
     2965}
     2966
     2967/**
     2968 * Finds triangles belonging to the three provided atoms.
     2969 *
     2970 * @param atom list, is expected to contain three atoms
     2971 *
     2972 * @return triangles which belong to the provided atoms, will be empty if there are none,
     2973 *         will usually be one, in case of degeneration, there will be two
     2974 */
     2975list<BoundaryTriangleSet*> *Tesselation::FindTriangles(atom* Points[3]) {
     2976  list<BoundaryTriangleSet*> *result = new list<BoundaryTriangleSet*>;
     2977  LineMap::iterator FindLine;
     2978  PointMap::iterator FindPoint;
     2979  TriangleMap::iterator FindTriangle;
     2980  class BoundaryPointSet *TrianglePoints[3];
     2981
     2982  for (int i = 0; i < 3; i++) {
     2983    FindPoint = PointsOnBoundary.find(Points[i]->nr);
     2984    if (FindPoint != PointsOnBoundary.end()) {
     2985      TrianglePoints[i] = FindPoint->second;
     2986    } else {
     2987      TrianglePoints[i] = NULL;
     2988    }
     2989  }
     2990
     2991  // checks lines between the points in the Points for their adjacent triangles
     2992  for (int i = 0; i < 3; i++) {
     2993    if (TrianglePoints[i] != NULL) {
     2994      for (int j = i; j < 3; j++) {
     2995        if (TrianglePoints[j] != NULL) {
     2996          FindLine = TrianglePoints[i]->lines.find(TrianglePoints[j]->node->nr);
     2997          if (FindLine != TrianglePoints[i]->lines.end()) {
     2998            for (; FindLine->first == TrianglePoints[j]->node->nr; FindLine++) {
     2999              FindTriangle = FindLine->second->triangles.begin();
     3000              for (; FindTriangle != FindLine->second->triangles.end(); FindTriangle++) {
     3001                if ((
     3002                  (FindTriangle->second->endpoints[0] == TrianglePoints[0])
     3003                    || (FindTriangle->second->endpoints[0] == TrianglePoints[1])
     3004                    || (FindTriangle->second->endpoints[0] == TrianglePoints[2])
     3005                  ) && (
     3006                    (FindTriangle->second->endpoints[1] == TrianglePoints[0])
     3007                    || (FindTriangle->second->endpoints[1] == TrianglePoints[1])
     3008                    || (FindTriangle->second->endpoints[1] == TrianglePoints[2])
     3009                  ) && (
     3010                    (FindTriangle->second->endpoints[2] == TrianglePoints[0])
     3011                    || (FindTriangle->second->endpoints[2] == TrianglePoints[1])
     3012                    || (FindTriangle->second->endpoints[2] == TrianglePoints[2])
     3013                  )
     3014                ) {
     3015                  result->push_back(FindTriangle->second);
     3016                }
     3017              }
     3018            }
     3019            // Is it sufficient to consider one of the triangle lines for this.
     3020            return result;
     3021
     3022          }
     3023        }
     3024      }
     3025    }
     3026  }
     3027
     3028  return result;
     3029}
     3030
     3031/**
     3032 * Gets the angle between a point and a reference relative to the provided center.
     3033 *
     3034 * @param point to calculate the angle for
     3035 * @param reference to which to calculate the angle
     3036 * @param center for which to calculate the angle between the vectors
     3037 * @param OrthogonalVector helps discern between [0,pi] and [pi,2pi] in acos()
     3038 *
     3039 * @return angle between point and reference
     3040 */
     3041double getAngle(Vector point, Vector reference, Vector center, Vector OrthogonalVector) {
     3042  Vector ReferenceVector, helper;
     3043  cout << Verbose(2) << reference << " is our reference " << endl;
     3044  cout << Verbose(2) << center << " is our center " << endl;
     3045  // create baseline vector
     3046  ReferenceVector.CopyVector(&reference);
     3047  ReferenceVector.SubtractVector(&center);
     3048  if (ReferenceVector.IsNull())
     3049    return M_PI;
     3050
     3051  // calculate both angles and correct with in-plane vector
     3052  helper.CopyVector(&point);
     3053  helper.SubtractVector(&center);
     3054  if (helper.IsNull())
     3055    return M_PI;
     3056  double phi = ReferenceVector.Angle(&helper);
     3057  if (OrthogonalVector.ScalarProduct(&helper) > 0) {
     3058    phi = 2.*M_PI - phi;
     3059  }
     3060
     3061  cout << Verbose(2) << point << " has angle " << phi << endl;
     3062
     3063  return phi;
     3064}
     3065
     3066/**
     3067 * Checks whether the provided point is within the tesselation structure.
     3068 *
     3069 * This is a wrapper function for IsInnerAtom, so it can be used with a simple
     3070 * vector, too.
     3071 *
     3072 * @param point of which to check the position
     3073 * @param tesselation structure
     3074 *
     3075 * @return true if the point is inside the tesselation structure, false otherwise
     3076 */
     3077bool IsInnerPoint(Vector Point, class Tesselation *Tess, LinkedCell* LC) {
     3078  atom *temp_atom = new atom;
     3079  bool status = false;
     3080  temp_atom->x.CopyVector(&Point);
     3081
     3082  status = IsInnerAtom(temp_atom, Tess, LC);
     3083  delete(temp_atom);
     3084
     3085  return status;
    27863086}
    27873087
     
    28703170    cout << Verbose(2) << "None." << endl;
    28713171
     3172  // Tests the IsInnerAtom() function.
     3173  Vector x (0, 0, 0);
     3174  cout << Verbose(0) << "Point to check: " << x << endl;
     3175  cout << Verbose(0) << "Check: IsInnerPoint() returns " << IsInnerPoint(x, Tess, LCList)
     3176    << "for vector " << x << "." << endl;
     3177  atom* a = Tess->PointsOnBoundary.begin()->second->node;
     3178  cout << Verbose(0) << "Point to check: " << *a << " (on boundary)." << endl;
     3179  cout << Verbose(0) << "Check: IsInnerAtom() returns " << IsInnerAtom(a, Tess, LCList)
     3180    << "for atom " << a << " (on boundary)." << endl;
     3181  LinkedAtoms *List = NULL;
     3182  for (int i=0;i<NDIM;i++) { // each axis
     3183    LCList->n[i] = LCList->N[i]-1; // current axis is topmost cell
     3184    for (LCList->n[(i+1)%NDIM]=0;LCList->n[(i+1)%NDIM]<LCList->N[(i+1)%NDIM];LCList->n[(i+1)%NDIM]++)
     3185      for (LCList->n[(i+2)%NDIM]=0;LCList->n[(i+2)%NDIM]<LCList->N[(i+2)%NDIM];LCList->n[(i+2)%NDIM]++) {
     3186        List = LCList->GetCurrentCell();
     3187        //cout << Verbose(2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << "." << endl;
     3188        if (List != NULL) {
     3189          for (LinkedAtoms::iterator Runner = List->begin();Runner != List->end();Runner++) {
     3190            if (Tess->PointsOnBoundary.find((*Runner)->nr) == Tess->PointsOnBoundary.end()) {
     3191              a = *Runner;
     3192              i=3;
     3193              for (int j=0;j<NDIM;j++)
     3194                LCList->n[j] = LCList->N[j];
     3195              break;
     3196            }
     3197          }
     3198        }
     3199      }
     3200  }
     3201  cout << Verbose(0) << "Check: IsInnerAtom() returns " << IsInnerAtom(a, Tess, LCList)
     3202    << "for atom " << a << " (inside)." << endl;
     3203
     3204
    28723205  if (freeTess)
    28733206    delete(Tess);
  • src/boundary.hpp

    ree1b16 r8c54a3  
    104104    int CheckPresenceOfTriangle(ofstream *out, atom *Candidates[3]);
    105105    void Find_next_suitable_point_via_Angle_of_Sphere(atom* a, atom* b, atom* c, atom* Candidate, atom* Parent, int RecursionLevel, Vector *Chord, Vector *direction1, Vector *OldNormal, Vector ReferencePoint, atom*& Opt_Candidate, double *Storage, const double RADIUS, molecule* mol);
     106    list<atom*> *getClosestConnectedAtoms(atom* Atom, atom* AtomToCheck);
     107    list<BoundaryTriangleSet*> *FindTriangles(atom* TrianglePoints[3]);
    106108
    107109    PointMap PointsOnBoundary;
     
    132134bool existsIntersection(Vector point1, Vector point2, Vector point3, Vector point4);
    133135bool sortCandidates(CandidateForTesselation* candidate1, CandidateForTesselation* candidate2);
     136bool IsInnerPoint(Vector Point, class Tesselation *Tess, LinkedCell* LC);
     137bool IsInnerAtom(atom *Atom, class Tesselation *Tess, LinkedCell* LC);
     138atom* findClosestAtom(const atom* Atom, LinkedCell* LC);
     139double getAngle(Vector point, Vector reference, Vector center, Vector OrthogonalVector);
    134140
    135141#endif /*BOUNDARY_HPP_*/
Note: See TracChangeset for help on using the changeset viewer.