source: src/border.cpp@ 03648b

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
Last change on this file since 03648b was 03648b, checked in by Christian Neuen <neuen@…>, 16 years ago

In vector a function for calculation of the vector-(cross-)product has been added.
In Boundary a new way for finding the non-convex boundary is implemented.
Currently problem with comparison of the return value of the map::find routine.

  • Property mode set to 100644
File size: 7.3 KB
Line 
1#include "molecules.hpp"
2#include "boundary.hpp"
3
4
5
6
7
8
9void Find_next_suitable_point(atom a, atom b, atom Candidate, int n, Vector *d1, Vector *d2, double *Storage, const double RADIUS, molecule mol)
10{
11 /* d2 ist der Normalenvektor auf dem Dreieck,
12 * d1 ist der Vektor, der normal auf der Kante und d2 steht.
13 */
14 Vector *dif_a;
15 Vector *dif_b;
16 Vector *Chord;
17 Vector *AngleCheck;
18 atom *Walker;
19
20 dif_a.CopyVector(a.x);
21 dif_a.SubtractVector(Candidate->x);
22 dif_b.CopyVector(b.x);
23 dif.b.SubtractVector(Candidate->x);
24 Chord.CopyVector(a.x);
25 Chord.SubtractVector(b.x);
26 AngleCheck.CopyVector(dif_a);
27 AngleCheck.ProjectOntoPlane(Chord);
28
29 //Storage eintrag fuer aktuelles Atom
30 if (Chord.Norm/(2*sin(dif_a.Angle(dif.b)))<RADIUS) //Using Formula for relation of chord length with inner angle to find of Ball will touch atom
31 {
32
33 if (dif_a.ScalarProduct(d1)/fabs(dif_a.ScalarProduct(d1))>Storage[1]) //This will give absolute preference to those in "right-hand" quadrants
34 {
35 Storage[0]=(double)Candidate.nr;
36 Storage[1]=1;
37 Storage[2]=AngleCheck.Angle(d2);
38 }
39 else
40 {
41 if ((dif_a.ScalarProduct(d1)/fabs(dif_a.ScalarProduct(d1)) == Storage[1] && Storage[1]>0 && Storage[2]< AngleCheck.Angle(d2)) or \
42 (dif_a.ScalarProduct(d1)/fabs(dif_a.ScalarProduct(d1)) == Storage[1] && Storage[1]<0 && Storage[2]> AngleCheck.Angle(d2)))
43 //Depending on quadrant we prefer higher or lower atom with respect to Triangle normal first.
44 {
45 Storage[0]=(double)Candidate.nr;
46 Storage[1]=dif_a.ScalarProduct(d1)/fabs(dif.ScalarProduct(d1));
47 Storage[2]=AngleCheck.Angle(d2);
48 }
49 }
50 }
51
52 if (n<5)
53 {
54 for(i=0; i<mol.NumberOfBondsPerAtom[Candidate.nr];i++)
55 {
56 while (Candidate.nr != mol->ListOfBonds[Candidate.nr][i])
57 {
58 Walker = Walker.next;
59 }
60
61 Find_next_suitable_point(a, b, Walker, n+1, d1, d2, RADIUS, mol);
62 }
63 }
64}
65
66
67void Find_next_suitable_triangle(molecule mol, BoundaryLineSet Line, BoundaryTriangleSet T)
68{
69 Vector CenterOfLine = Line->endpoints.node[0].x;
70 Vector direction1;
71 Vector direction2;
72 Vector helper;
73
74 double *Storage[3];
75 Storage[0]=-1; // Id must be positive, we see should nothing be done
76 Storage[1]=-1; // This direction is either +1 or -1 one, so any result will take precedence over initial values
77 Storage[2]=-10; // This is also lower then any value produced by an eligible atom, which are all positive
78
79
80 helper.CopyVector(Line->endpoints[0].x);
81 for (int i =0; i<3; i++)
82 {
83 if (T->endpoints[i].node.nr != Line->endpoints[0].node.nr && T->endpoints[i].node.nr!=Line->endpoints[1].node.nr)
84 {
85 helper.SubtractVector(T->endpoints[i].x);
86 break;
87 }
88 }
89
90
91 direction1.CopyVector(Line->endpoints.node[0].x);
92 direction1.Subtract(Line->endpoints.node[1].x);
93 direction1.Crossproduct(T.NormalVector);
94
95 if (direction1.ScalarProduct(helper)>0)
96 {
97 direction1.Scale(-1);
98 }
99
100 Find_next_suitable_point(Line->endpoints.node[0], Line->endpoints.node[1], Line->endpoints->node[0], 0, direction1, T.NormalVector, Storage, RADIUS);
101
102 // Konstruiere nun neues Dreieck am Ende der Liste der Dreiecke
103 // Next Triangle is Line, atom with number in Storage[0]
104
105 Walker=mol->start;
106 while (Walker.nr != (int)Storage[0])
107 {
108 Walker = Walker->next;
109 }
110
111 AddPoint(Walker);
112
113 BPS[0] = BoundaryPointSet(Walker);
114 BPS[1] = Line->enpoints.node[0];
115 BLS[0] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
116 BPS[0] = Walker;
117 BPS[1] = Line->endpoints.node[1];
118 BLS[1] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
119 BLS[2] = line;
120
121 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
122 TrianglesOnBoundary.insert( TrianglePair(TrianglesOnBoundaryCount, BTS) );
123 TrianglesOnBoundaryCount++;
124
125 for(int i=0;i<NDIM;i++) // sind Linien bereits vorhanden ???
126 {
127 if (LinesOnBoundary.find(BTS->lines[i]) == LinesOnBoundary->end)
128 {
129 LinesOnBoundary.insert( LinePair(LinesOnBoundaryCount, BTS->lines[i]) );
130 LinesOnBoundaryCount++;
131 }
132 }
133 GetNormalVector(BTS.NormalVector);
134
135 if( (BTS.NormalVector.ScalarProduct(T.NormalVecotr)<0 && Storage[1]>0) || \
136 (BTS.NormalVector.ScalarProduct(T.NormalVecotr)>0 && Storage[1]<0))
137 {
138 BTS.NormalVector.Scale(-1);
139 }
140
141}
142
143
144void Find_starting_triangle(molecule mol)
145{
146 atom Walker;
147 atom Walker2;
148 atom Walker3;
149 int max_index[3];
150 double max_coordinate[3];
151 Vector Oben;
152 Vector helper;
153
154 Oben.Zero;
155
156
157 for(int i =0; i<3; i++)
158 {
159 max_index[i] =-1;
160 max_coordinate[i] =-1;
161 }
162
163 Walker = mol->start;
164 while (Walker->next != NULL)
165 {
166 for (i=0; i<3; i++)
167 {
168 if (Walker.x[i]>max_coordinate[i])
169 {
170 max_coordinate[i]=Walker.x[i];
171 max_index[i]=Walker.nr;
172 }
173 }
174 }
175
176 //Koennen dies fuer alle Richtungen, legen hier erstmal Richtung auf k=0
177 const int k=0;
178
179 Oben.x[k]=1;
180 Walker = mol->start;
181 while (Walker.nr != max_index[k])
182 {
183 Walker =Walker->next;
184 }
185
186 double *Storage[3];
187 Storage[0]=-1; // Id must be positive, we see should nothing be done
188 Storage[1]=-2; // This will contain the angle, which will be always positive (when looking for second point), when looking for third point this will be the quadrant.
189 Storage[2]=-10; // This will be an angle looking for the third point.
190
191
192 for (i=0; i< mol->NumberOfBondsPerAtoms[Walker.nr]; i++)
193 {
194 Walker2 = mol->start;
195 while (Walker2.nr != mol->ListOfBondsPerAtoms[Walker.nr][i]) // Stimmt die Ueberpruefung $$$
196 {
197 Walker2 =Walker2->next;
198 }
199
200 Find_second_point_for_Tesselation(Walker, Walker2, Oben, Storage);
201 }
202
203 Walker2=mol->start;
204
205 while (Walker2.nr != int(Storage[0]))
206 {
207 Walker = Walker.next;
208 }
209
210 helper.copyVector(Walker.x);
211 helper.Subtract(Walker2.x);
212 Oben.ProjectOntoPlane(helper.x);
213 helper.VectorProduct(Oben);
214
215 Find_next_suitable_point(Walker, Walker2, Candidate, 0, helper, Oben, Storage, Radius);
216 Walker3 = mol->start;
217 while (Walker3.nr != int(Storage[0]))
218 {
219 Walker3 = Walker3->next;
220 }
221
222 //Starting Triangle is Walker, Walker2, index Storage[0]
223
224 AddPoint(Walker);
225 AddPoint(Walker2);
226 AddPoint(Walker3);
227
228 BPS[0] = BoundaryPointSet(Walker);
229 BPS[1] = BoundaryPointSet(Walker2);
230 BLS[0] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
231 BPS[0] = Walker;
232 BPS[1] = Walker3;
233 BLS[1] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
234 BPS[0] = Walker;
235 BPS[1] = Walker2;
236 BLS[2] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
237
238 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
239 TrianglesOnBoundary.insert( TrianglePair(TrianglesOnBoundaryCount, BTS) );
240 TrianglesOnBoundaryCount++;
241
242 for(int i=0;i<NDIM;i++)
243 {
244 LinesOnBoundary.insert( LinePair(LinesOnBoundaryCount, BTS->lines[i]) );
245 LinesOnBoundaryCount++;
246 }
247
248}
249
250
251void Find_non_convex_border(Tesselation Tess, molecule mol) // this needs input of type molecule
252{
253
254 Tess.Find_starting_triangle(mol);
255
256 for (LineMap::iterator baseline = LinesOnBoundary.begin(); baseline != LinesOnBoundary.end(); baseline++)
257 if (baseline->second->TrianglesCount == 1)
258 {
259 Find_next_suitable_triangle(mol, baseline->second, baseline->second->triangles.begin()->second); //the line is there, so there is a triangle, but only one.
260
261 }
262 else
263 {
264 printf("There is a line with %d triangles adjacent", baseline->second->TrianglesCount);
265 }
266}
Note: See TracBrowser for help on using the repository browser.