- Timestamp:
- Aug 3, 2009, 4:48:46 PM (15 years ago)
- 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
- Location:
- src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/boundary.cpp
ree1b16 r8c54a3 1804 1804 */ 1805 1805 int Tesselation::CheckPresenceOfTriangle(ofstream *out, atom *Candidates[3]) { 1806 // TODO: use findTriangles here and return result.size(); 1806 1807 LineMap::iterator FindLine; 1807 1808 PointMap::iterator FindPoint; … … 2240 2241 int N[NDIM], Nlower[NDIM], Nupper[NDIM]; 2241 2242 2242 if (LC->SetIndexToAtom( a)) { // get cell for the starting atom2243 if (LC->SetIndexToAtom(*a)) { // get cell for the starting atom 2243 2244 for(int i=0;i<NDIM;i++) // store indices of this cell 2244 2245 N[i] = LC->n[i]; … … 2746 2747 */ 2747 2748 bool sortCandidates(CandidateForTesselation* candidate1, CandidateForTesselation* candidate2) { 2748 Vector BaseLineVector, OrthogonalVector, helper; 2749 // TODO: use get angle and remove duplicate code 2750 Vector BaseLineVector, OrthogonalVector, helper; 2749 2751 if (candidate1->BaseLine != candidate2->BaseLine) { // sanity check 2750 2752 cout << Verbose(0) << "ERROR: sortCandidates was called for two different baselines: " << candidate1->BaseLine << " and " << candidate2->BaseLine << "." << endl; … … 2784 2786 // return comparison 2785 2787 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 */ 2798 bool 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 */ 2852 atom* 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 */ 2898 list<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(¤t->x); 2926 currentPoint.ProjectOntoPlane(&planeNorm); 2927 center.AddVector(¤tPoint); 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(¢er, &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 */ 2975 list<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 */ 3041 double 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(¢er); 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(¢er); 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 */ 3077 bool 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; 2786 3086 } 2787 3087 … … 2870 3170 cout << Verbose(2) << "None." << endl; 2871 3171 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 2872 3205 if (freeTess) 2873 3206 delete(Tess); -
src/boundary.hpp
ree1b16 r8c54a3 104 104 int CheckPresenceOfTriangle(ofstream *out, atom *Candidates[3]); 105 105 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]); 106 108 107 109 PointMap PointsOnBoundary; … … 132 134 bool existsIntersection(Vector point1, Vector point2, Vector point3, Vector point4); 133 135 bool sortCandidates(CandidateForTesselation* candidate1, CandidateForTesselation* candidate2); 136 bool IsInnerPoint(Vector Point, class Tesselation *Tess, LinkedCell* LC); 137 bool IsInnerAtom(atom *Atom, class Tesselation *Tess, LinkedCell* LC); 138 atom* findClosestAtom(const atom* Atom, LinkedCell* LC); 139 double getAngle(Vector point, Vector reference, Vector center, Vector OrthogonalVector); 134 140 135 141 #endif /*BOUNDARY_HPP_*/
Note:
See TracChangeset
for help on using the changeset viewer.