Changeset 03648b for src/boundary.cpp


Ignore:
Timestamp:
Nov 27, 2008, 9:55:08 AM (16 years ago)
Author:
Christian Neuen <neuen@…>
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
Message:

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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/boundary.cpp

    r51695c r03648b  
    11#include "molecules.hpp"
    22#include "boundary.hpp"
     3
     4
     5// =================spaeter gebrauchte
     6void Find_next_suitable_point(atom a, atom b, atom Candidate, int n, Vector *d1, Vector *d2, double *Storage, const double RADIUS, molecule mol);
     7void Find_non_convex_border(Tesselation Tess, molecule mol);
     8
    39
    410// ======================================== Points on Boundary =================================
     
    471477  double volume = 0.;
    472478  double PyramidVolume = 0.;
    473   double G,h;
     479  double G,h; 
    474480  Vector x,y;
    475481  double a,b,c;
    476482
     483  Find_non_convex_border(*TesselStruct, *mol);
     484  /*
    477485  // 1. calculate center of gravity
    478486  *out << endl;
     
    518526
    519527  *out << Verbose(2) << "I created " << TesselStruct->TrianglesOnBoundaryCount << " triangles with " << TesselStruct->LinesOnBoundaryCount << " lines and " << TesselStruct->PointsOnBoundaryCount << " points." << endl;
     528  */
     529
    520530
    521531  // 6a. Every triangle forms a pyramid with the center of gravity as its peak, sum up the volumes
     
    539549  *out << Verbose(0) << "RESULT: The summed volume is " << setprecision(10) << volume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
    540550
    541 
     551  /*
    542552  // 7. translate all points back from CoG
    543553  *out << Verbose(1) << "Translating system back from Center of Gravity." << endl;
     
    548558    Walker->x.Translate(CenterOfGravity);
    549559  }
    550  
     560  */
     561
     562
     563
     564
     565
    551566  // 8. Store triangles in tecplot file
    552567  if (tecplot != NULL) {
     
    9941009    PointsOnBoundaryCount++;
    9951010};
     1011
     1012
     1013
     1014
     1015
     1016
     1017//====================================================================================================================
     1018//
     1019// ab hier habe ich das verzapft.
     1020//
     1021//====================================================================================================================
     1022
     1023
     1024void 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
     1082void 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
     1160void 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
     1192void 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
     1306void 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.