source: src/#border.cpp#@ 69eb71

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 69eb71 was 69eb71, checked in by Christian Neuen <neuen@…>, 16 years ago

Multiple changes to boundary, currently not fully operational.
Molecules has a new routine to create adjacency lists, reading bonds from a dbond file instead of looking for the distances by itself.
Vector function Project onto plane has been updated.

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