Changeset 03648b for src/boundary.cpp
- Timestamp:
- Nov 27, 2008, 9:55:08 AM (16 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:
- 1ffa21
- Parents:
- 51695c
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/boundary.cpp
r51695c r03648b 1 1 #include "molecules.hpp" 2 2 #include "boundary.hpp" 3 4 5 // =================spaeter gebrauchte 6 void Find_next_suitable_point(atom a, atom b, atom Candidate, int n, Vector *d1, Vector *d2, double *Storage, const double RADIUS, molecule mol); 7 void Find_non_convex_border(Tesselation Tess, molecule mol); 8 3 9 4 10 // ======================================== Points on Boundary ================================= … … 471 477 double volume = 0.; 472 478 double PyramidVolume = 0.; 473 double G,h; 479 double G,h; 474 480 Vector x,y; 475 481 double a,b,c; 476 482 483 Find_non_convex_border(*TesselStruct, *mol); 484 /* 477 485 // 1. calculate center of gravity 478 486 *out << endl; … … 518 526 519 527 *out << Verbose(2) << "I created " << TesselStruct->TrianglesOnBoundaryCount << " triangles with " << TesselStruct->LinesOnBoundaryCount << " lines and " << TesselStruct->PointsOnBoundaryCount << " points." << endl; 528 */ 529 520 530 521 531 // 6a. Every triangle forms a pyramid with the center of gravity as its peak, sum up the volumes … … 539 549 *out << Verbose(0) << "RESULT: The summed volume is " << setprecision(10) << volume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl; 540 550 541 551 /* 542 552 // 7. translate all points back from CoG 543 553 *out << Verbose(1) << "Translating system back from Center of Gravity." << endl; … … 548 558 Walker->x.Translate(CenterOfGravity); 549 559 } 550 560 */ 561 562 563 564 565 551 566 // 8. Store triangles in tecplot file 552 567 if (tecplot != NULL) { … … 994 1009 PointsOnBoundaryCount++; 995 1010 }; 1011 1012 1013 1014 1015 1016 1017 //==================================================================================================================== 1018 // 1019 // ab hier habe ich das verzapft. 1020 // 1021 //==================================================================================================================== 1022 1023 1024 void Find_next_suitable_point(atom a, atom b, atom Candidate, int n, Vector *d1, Vector *d2, double *Storage, const double RADIUS, molecule mol) 1025 { 1026 /* d2 ist der Normalenvektor auf dem Dreieck, 1027 * d1 ist der Vektor, der normal auf der Kante und d2 steht. 1028 */ 1029 Vector dif_a; 1030 Vector dif_b; 1031 Vector Chord; 1032 Vector AngleCheck; 1033 atom *Walker; 1034 1035 dif_a.CopyVector(&a.x); 1036 dif_a.SubtractVector(&Candidate.x); 1037 dif_b.CopyVector(&b.x); 1038 dif_b.SubtractVector(&Candidate.x); 1039 Chord.CopyVector(&a.x); 1040 Chord.SubtractVector(&b.x); 1041 AngleCheck.CopyVector(&dif_a); 1042 AngleCheck.ProjectOntoPlane(&Chord); 1043 1044 //Storage eintrag fuer aktuelles Atom 1045 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 1046 { 1047 1048 if (dif_a.ScalarProduct(d1)/fabs(dif_a.ScalarProduct(d1))>Storage[1]) //This will give absolute preference to those in "right-hand" quadrants 1049 { 1050 Storage[0]=(double)Candidate.nr; 1051 Storage[1]=1; 1052 Storage[2]=AngleCheck.Angle(d2); 1053 } 1054 else 1055 { 1056 if ((dif_a.ScalarProduct(d1)/fabs(dif_a.ScalarProduct(d1)) == Storage[1] && Storage[1]>0 && Storage[2]< AngleCheck.Angle(d2)) or \ 1057 (dif_a.ScalarProduct(d1)/fabs(dif_a.ScalarProduct(d1)) == Storage[1] && Storage[1]<0 && Storage[2]> AngleCheck.Angle(d2))) 1058 //Depending on quadrant we prefer higher or lower atom with respect to Triangle normal first. 1059 { 1060 Storage[0]=(double)Candidate.nr; 1061 Storage[1]=dif_a.ScalarProduct(d1)/fabs(dif_a.ScalarProduct(d1)); 1062 Storage[2]=AngleCheck.Angle(d2); 1063 } 1064 } 1065 } 1066 1067 if (n<5) 1068 { 1069 for(int i=0; i<mol.NumberOfBondsPerAtom[Candidate.nr];i++) 1070 { 1071 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)) 1072 { 1073 Walker = Walker->next; 1074 } 1075 1076 Find_next_suitable_point(a, b, *Walker, n+1, d1, d2, Storage, RADIUS, mol); 1077 } 1078 } 1079 }; 1080 1081 1082 void Tesselation::Find_next_suitable_triangle(molecule *mol, BoundaryLineSet Line, BoundaryTriangleSet T, const double& RADIUS) 1083 { 1084 Vector CenterOfLine = Line.endpoints[0]->node->x; 1085 Vector direction1; 1086 Vector direction2; 1087 Vector helper; 1088 atom* Walker; 1089 1090 double Storage[3]; 1091 Storage[0]=-1.; // Id must be positive, we see should nothing be done 1092 Storage[1]=-1.; // This direction is either +1 or -1 one, so any result will take precedence over initial values 1093 Storage[2]=-10.; // This is also lower then any value produced by an eligible atom, which are all positive 1094 1095 1096 helper.CopyVector(&(Line.endpoints[0]->node->x)); 1097 for (int i =0; i<3; i++) 1098 { 1099 if (T.endpoints[i]->node->nr != Line.endpoints[0]->node->nr && T.endpoints[i]->node->nr!=Line.endpoints[1]->node->nr) 1100 { 1101 helper.SubtractVector(&T.endpoints[i]->node->x); 1102 break; 1103 } 1104 } 1105 1106 1107 direction1.CopyVector(&Line.endpoints[0]->node->x); 1108 direction1.SubtractVector(&Line.endpoints[1]->node->x); 1109 direction1.VectorProduct(T.NormalVector); 1110 1111 if (direction1.ScalarProduct(&helper)>0) 1112 { 1113 direction1.Scale(-1); 1114 } 1115 1116 Find_next_suitable_point(*Line.endpoints[0]->node, *Line.endpoints[1]->node, *Line.endpoints[0]->node, 0, &direction1, T.NormalVector, Storage, RADIUS, *mol); 1117 1118 // Konstruiere nun neues Dreieck am Ende der Liste der Dreiecke 1119 // Next Triangle is Line, atom with number in Storage[0] 1120 1121 Walker= mol->start; 1122 while (Walker->nr != (int)Storage[0]) 1123 { 1124 Walker = Walker->next; 1125 } 1126 1127 AddPoint(Walker); 1128 1129 BPS[0] = new class BoundaryPointSet(Walker); 1130 BPS[1] = new class BoundaryPointSet(Line.endpoints[0]->node); 1131 BLS[0] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount); 1132 BPS[0] = new class BoundaryPointSet(Walker); 1133 BPS[1] = new class BoundaryPointSet(Line.endpoints[1]->node); 1134 BLS[1] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount); 1135 BLS[2] = new class BoundaryLineSet(Line); 1136 1137 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 1138 TrianglesOnBoundary.insert( TrianglePair(TrianglesOnBoundaryCount, BTS) ); 1139 TrianglesOnBoundaryCount++; 1140 1141 for(int i=0;i<NDIM;i++) // sind Linien bereits vorhanden ??? 1142 { 1143 if (LinesOnBoundary.find(BTS->lines[i]) == LinesOnBoundary.end) 1144 { 1145 LinesOnBoundary.insert( LinePair(LinesOnBoundaryCount, BTS->lines[i]) ); 1146 LinesOnBoundaryCount++; 1147 } 1148 } 1149 BTS->GetNormalVector(*BTS->NormalVector); 1150 1151 if( (BTS->NormalVector->ScalarProduct(T.NormalVector)<0 && Storage[1]>0) || \ 1152 (BTS->NormalVector->ScalarProduct(T.NormalVector)>0 && Storage[1]<0)) 1153 { 1154 BTS->NormalVector->Scale(-1); 1155 } 1156 1157 }; 1158 1159 1160 void Find_second_point_for_Tesselation(atom a, atom Candidate, int n, Vector Oben, double* Storage, molecule mol) 1161 { 1162 int i; 1163 Vector *AngleCheck; 1164 atom* Walker; 1165 1166 AngleCheck->CopyVector(&Candidate.x); 1167 AngleCheck->SubtractVector(&a.x); 1168 if (AngleCheck->ScalarProduct(&Oben) < Storage[1]) 1169 { 1170 Storage[0]=(double)(Candidate.nr); 1171 Storage[1]=AngleCheck->ScalarProduct(&Oben); 1172 }; 1173 1174 if (n<5) 1175 { 1176 for (i = 0; i< mol.NumberOfBondsPerAtom[Candidate.nr]; i++) 1177 { 1178 Walker = mol.start; 1179 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)) 1180 { 1181 Walker = Walker->next; 1182 }; 1183 1184 Find_second_point_for_Tesselation(a, *Walker, n+1, Oben, Storage, mol); 1185 }; 1186 }; 1187 1188 1189 }; 1190 1191 1192 void Tesselation::Find_starting_triangle(molecule mol, const double RADIUS) 1193 { 1194 int i=0; 1195 atom Walker; 1196 atom Walker2; 1197 atom Walker3; 1198 int max_index[3]; 1199 double max_coordinate[3]; 1200 Vector Oben; 1201 Vector helper; 1202 1203 Oben.Zero(); 1204 1205 1206 for(i =0; i<3; i++) 1207 { 1208 max_index[i] =-1; 1209 max_coordinate[i] =-1; 1210 } 1211 1212 Walker = *mol.start; 1213 while (Walker.next != NULL) 1214 { 1215 for (i=0; i<3; i++) 1216 { 1217 if (Walker.x.x[i]>max_coordinate[i]) 1218 { 1219 max_coordinate[i]=Walker.x.x[i]; 1220 max_index[i]=Walker.nr; 1221 } 1222 } 1223 } 1224 1225 //Koennen dies fuer alle Richtungen, legen hier erstmal Richtung auf k=0 1226 const int k=0; 1227 1228 Oben.x[k]=1; 1229 Walker = *mol.start; 1230 while (Walker.nr != max_index[k]) 1231 { 1232 Walker = *Walker.next; 1233 } 1234 1235 double Storage[3]; 1236 Storage[0]=-1.; // Id must be positive, we see should nothing be done 1237 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. 1238 Storage[2]=-10.; // This will be an angle looking for the third point. 1239 1240 1241 for (i=0; i< mol.NumberOfBondsPerAtom[Walker.nr]; i++) 1242 { 1243 Walker2 = *mol.start; 1244 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) ) 1245 { 1246 Walker2 = *Walker2.next; 1247 } 1248 1249 Find_second_point_for_Tesselation(Walker, Walker2, 0, Oben, Storage, mol); 1250 } 1251 1252 Walker2 = *mol.start; 1253 1254 while (Walker2.nr != int(Storage[0])) 1255 { 1256 Walker = *Walker.next; 1257 } 1258 1259 helper.CopyVector(&Walker.x); 1260 helper.SubtractVector(&Walker2.x); 1261 Oben.ProjectOntoPlane(&helper); 1262 helper.VectorProduct(&Oben); 1263 1264 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); 1265 Walker3 = *mol.start; 1266 while (Walker3.nr != int(Storage[0])) 1267 { 1268 Walker3 = *Walker3.next; 1269 } 1270 1271 //Starting Triangle is Walker, Walker2, index Storage[0] 1272 1273 AddPoint(&Walker); 1274 AddPoint(&Walker2); 1275 AddPoint(&Walker3); 1276 1277 BPS[0] = new class BoundaryPointSet(&Walker); 1278 BPS[1] = new class BoundaryPointSet(&Walker2); 1279 BLS[0] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount); 1280 BPS[0] = new class BoundaryPointSet(&Walker); 1281 BPS[1] = new class BoundaryPointSet(&Walker3); 1282 BLS[1] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount); 1283 BPS[0] = new class BoundaryPointSet(&Walker); 1284 BPS[1] = new class BoundaryPointSet(&Walker2); 1285 BLS[2] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount); 1286 1287 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 1288 TrianglesOnBoundary.insert( TrianglePair(TrianglesOnBoundaryCount, BTS) ); 1289 TrianglesOnBoundaryCount++; 1290 1291 for(int i=0;i<NDIM;i++) 1292 { 1293 LinesOnBoundary.insert( LinePair(LinesOnBoundaryCount, BTS->lines[i]) ); 1294 LinesOnBoundaryCount++; 1295 }; 1296 1297 BTS->GetNormalVector(*BTS->NormalVector); 1298 1299 if( BTS->NormalVector->ScalarProduct(&Oben)<0) 1300 { 1301 BTS->NormalVector->Scale(-1); 1302 } 1303 }; 1304 1305 1306 void Find_non_convex_border(Tesselation* Tess, molecule mol) 1307 { 1308 const double RADIUS =6; 1309 Tess->Find_starting_triangle(mol, RADIUS); 1310 1311 for (LineMap::iterator baseline = Tess->LinesOnBoundary.begin(); baseline != Tess->LinesOnBoundary.end(); baseline++) 1312 if (baseline->second->TrianglesCount == 1) 1313 { 1314 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. 1315 1316 } 1317 else 1318 { 1319 printf("There is a line with %d triangles adjacent", baseline->second->TrianglesCount); 1320 } 1321 };
Note:
See TracChangeset
for help on using the changeset viewer.