Changeset 2319ed for src


Ignore:
Timestamp:
Aug 3, 2009, 8:10:09 AM (15 years ago)
Author:
Frederik Heber <heber@…>
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, 357fba
Parents:
e1589e
Message:

We are one step further in fixing the convex hull: There are two functions of Saskia Metzler missing, but then we may proceed with testing whether the simple correction scheme of the convex envelope works, but one thing: Right now we cannot associate a Tesselation to its molecule as the snake bites it's one tail. Hence, the next commit will consist of fixing this bad-OOP issue.

  • Makefile.am: Just some alphabetical resorting.
  • atom::atom() new copy constructor
  • builder.cpp: some output for cluster volume, molecule::AddCopyAtom() uses new copy constructor
  • FillBoxWithMolecule() - new function to fill the remainder of the simulation box with some given filler molecules. Makes explicit use of the tesselated surfaces
  • find_convex_border() - InsertStraddlingPoints() and CorrectConcaveBaselines() is called to correct for atoms outside the envelope and caused-by concave points
  • Tesselation::InsertStraddlingPoints() enlarges the envelope for all atoms found outside, Tesselation::CorrectConcaveBaselines() corrects all found baselines if the adjacent triangles are concave by flipping.
  • boundary.cpp: Lots of helper routines for stuff further below:
  • The following routines are needed to check whether point is in- or outside:
  • FIX: Tesselation::AddPoint() - newly created BoundaryPoint is removed if already present.

Problem: We want to associate a Tesselation class with each molecule class. However, so far we have to know about atoms and bond and molecules inside the Tesselation. We have to remove this dependency and create some intermediate class which enables/encapsulates the access to Vectors, e.g. hidden inside the atom class. This is also good OOP! The Tesselation also only needs a set of Vectors, not more!

Location:
src
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • src/Makefile.am

    re1589e r2319ed  
    1 SOURCE = atom.cpp bond.cpp boundary.cpp builder.cpp config.cpp element.cpp ellipsoid.cpp helpers.cpp molecules.cpp linkedcell.cpp moleculelist.cpp parser.cpp periodentafel.cpp vector.cpp verbose.cpp
     1SOURCE = atom.cpp bond.cpp boundary.cpp builder.cpp config.cpp element.cpp ellipsoid.cpp helpers.cpp linkedcell.cpp moleculelist.cpp molecules.cpp parser.cpp periodentafel.cpp vector.cpp verbose.cpp
    22HEADER = boundary.hpp defs.hpp ellipsoid.hpp helpers.hpp linkedcell.hpp molecules.hpp parser.hpp periodentafel.hpp stackclass.hpp vector.hpp
    33
  • src/atom.cpp

    re1589e r2319ed  
    3030  MaxOrder = false;
    3131};
     32
     33/** Constructor of class atom.
     34 *
     35 */
     36atom::atom(atom *pointer)
     37{
     38  Name = NULL;
     39  previous = NULL;
     40  next = NULL;
     41  father = this;  // generally, father is itself
     42  Ancestor = NULL;
     43  type = pointer->type;  // copy element of atom
     44  x.CopyVector(&pointer->x); // copy coordination
     45  v.CopyVector(&pointer->v); // copy velocity
     46  FixedIon = pointer->FixedIon;
     47  nr = -1;
     48  sort = &nr;
     49}
     50
    3251
    3352/** Destructor of class atom.
  • src/boundary.cpp

    re1589e r2319ed  
    132132;
    133133
     134/** Checks whether we have a common endpoint with given \a *line.
     135 * \param *line other line to test
     136 * \return true - common endpoint present, false - not connected
     137 */
     138bool BoundaryLineSet::IsConnectedTo(class BoundaryLineSet *line)
     139{
     140  if ((endpoints[0] == line->endpoints[0]) || (endpoints[1] == line->endpoints[0]) || (endpoints[0] == line->endpoints[1]) || (endpoints[1] == line->endpoints[1]))
     141    return true;
     142  else
     143    return false;
     144};
     145
     146/** Checks whether the adjacent triangles of a baseline are convex or not.
     147 * We sum the two angles of each normal vector with a ficticious normnal vector from this baselinbe pointing outwards.
     148 * If greater/equal M_PI than we are convex.
     149 * \param *out output stream for debugging
     150 * \return true - triangles are convex, false - concave or less than two triangles connected
     151 */
     152bool BoundaryLineSet::CheckConvexityCriterion(ofstream *out)
     153{
     154  Vector BaseLineNormal;
     155  double angle = 0;
     156  // get the two triangles
     157  if (TrianglesCount != 2) {
     158    *out << Verbose(1) << "ERROR: Baseline " << this << " is connect to less than two triangles, Tesselation incomplete!" << endl;
     159    return false;
     160  }
     161  // have a normal vector on the base line pointing outwards
     162  BaseLineNormal.Zero();
     163  for(TriangleMap::iterator runner = triangles.begin(); runner != triangles.end(); runner++)
     164    BaseLineNormal.AddVector(&runner->second->NormalVector);
     165  BaseLineNormal.Normalize();
     166  // and calculate the sum of the angles with this normal vector and each of the triangle ones'
     167  for(TriangleMap::iterator runner = triangles.begin(); runner != triangles.end(); runner++)
     168    angle += BaseLineNormal.Angle(&runner->second->NormalVector);
     169
     170  if ((angle - M_PI) > -MYEPSILON)
     171    return true;
     172  else
     173    return false;
     174}
     175
     176/** Checks whether point is any of the two endpoints this line contains.
     177 * \param *point point to test
     178 * \return true - point is of the line, false - is not
     179 */
     180bool BoundaryLineSet::ContainsBoundaryPoint(class BoundaryPointSet *point)
     181{
     182  for(int i=0;i<2;i++)
     183    if (point == endpoints[i])
     184      return true;
     185  return false;
     186};
     187
    134188ostream &
    135189operator <<(ostream &ost, BoundaryLineSet &a)
     
    214268;
    215269
    216 void
    217 BoundaryTriangleSet::GetNormalVector(Vector &OtherVector)
     270/** Calculates the normal vector for this triangle.
     271 * Is made unique by comparison with \a OtherVector to point in the other direction.
     272 * \param &OtherVector direction vector to make normal vector unique.
     273 */
     274void BoundaryTriangleSet::GetNormalVector(Vector &OtherVector)
    218275{
    219276  // get normal vector
     
    224281  if (NormalVector.Projection(&OtherVector) > 0)
    225282    NormalVector.Scale(-1.);
    226 }
    227 ;
     283};
     284
     285/** Finds the point on the triangle \a *BTS the line defined by \a *MolCenter and \a *x crosses through.
     286 * We call Vector::GetIntersectionWithPlane() to receive the intersection point with the plane
     287 * This we test if it's really on the plane and whether it's inside the triangle on the plane or not.
     288 * The latter is done as follows: if it's really outside, then for any endpoint of the triangle and it's opposite
     289 * base line, the intersection between the line from endpoint to intersection and the base line will have a Vector::NormSquared()
     290 * smaller than the first line.
     291 * \param *out output stream for debugging
     292 * \param *MolCenter offset vector of line
     293 * \param *x second endpoint of line, minus \a *MolCenter is directional vector of line
     294 * \param *Intersection intersection on plane on return
     295 * \return true - \a *Intersection contains intersection on plane defined by triangle, false - zero vector if outside of triangle.
     296 */
     297bool BoundaryTriangleSet::GetIntersectionInsideTriangle(ofstream *out, Vector *MolCenter, Vector *x, Vector *Intersection)
     298{
     299  Vector CrossPoint;
     300  Vector helper;
     301  int i=0;
     302
     303  if (Intersection->GetIntersectionWithPlane(out, &NormalVector, &endpoints[0]->node->x, MolCenter, x)) {
     304    *out << Verbose(1) << "Alas! [Bronstein] failed - at least numerically - the intersection is not on the plane!" << endl;
     305    return false;
     306  }
     307
     308  // Calculate cross point between one baseline and the line from the third endpoint to intersection
     309  do {
     310    CrossPoint.GetIntersectionOfTwoLinesOnPlane(out, &endpoints[i%3]->node->x, &endpoints[(i+1)%3]->node->x, &endpoints[(i+2)%3]->node->x, Intersection);
     311    helper.CopyVector(&endpoints[(i+1)%3]->node->x);
     312    helper.SubtractVector(&endpoints[i%3]->node->x);
     313    i++;
     314    if (i>3)
     315      break;
     316  } while (CrossPoint.NormSquared() < MYEPSILON);
     317  if (i>3) {
     318    *out << Verbose(1) << "ERROR: Could not find any cross points, something's utterly wrong here!" << endl;
     319    exit(255);
     320  }
     321  CrossPoint.SubtractVector(&endpoints[i%3]->node->x);
     322
     323  // check whether intersection is inside or not by comparing length of intersection and length of cross point
     324  if ((CrossPoint.NormSquared() - helper.NormSquared()) > -MYEPSILON) { // inside
     325    return true;
     326  } else { // outside!
     327    Intersection->Zero();
     328    return false;
     329  }
     330};
     331
     332/** Checks whether lines is any of the three boundary lines this triangle contains.
     333 * \param *line line to test
     334 * \return true - line is of the triangle, false - is not
     335 */
     336bool BoundaryTriangleSet::ContainsBoundaryLine(class BoundaryLineSet *line)
     337{
     338  for(int i=0;i<3;i++)
     339    if (line == lines[i])
     340      return true;
     341  return false;
     342};
     343
     344/** Checks whether point is any of the three endpoints this triangle contains.
     345 * \param *point point to test
     346 * \return true - point is of the triangle, false - is not
     347 */
     348bool BoundaryTriangleSet::ContainsBoundaryPoint(class BoundaryPointSet *point)
     349{
     350  for(int i=0;i<3;i++)
     351    if (point == endpoints[i])
     352      return true;
     353  return false;
     354};
    228355
    229356ostream &
     
    774901  TesselStruct->TesselateOnBoundary(out, mol);
    775902
    776   *out << Verbose(2) << "I created " << TesselStruct->TrianglesOnBoundaryCount << " triangles with " << TesselStruct->LinesOnBoundaryCount << " lines and " << TesselStruct->PointsOnBoundaryCount << " points." << endl;
     903  // 3c. check whether all atoms lay inside the boundary, if not, add to boundary points, segment triangle into three with the new point
     904  if (!TesselStruct->InsertStraddlingPoints(out, mol))
     905    *out << Verbose(1) << "Insertion of straddling points failed!" << endl;
     906
     907  // 3d. check all baselines whether the peaks of the two adjacent triangles with respect to center of baseline are convex, if not, make the baseline between the two peaks and baseline endpoints become the new peaks
     908  if (!TesselStruct->CorrectConcaveBaselines(out))
     909    *out << Verbose(1) << "Correction of concave baselines failed!" << endl;
     910
     911  *out << Verbose(2) << "I created " << TesselStruct->TrianglesOnBoundary.size() << " triangles with " << TesselStruct->LinesOnBoundary.size() << " lines and " << TesselStruct->PointsOnBoundary.size() << " points." << endl;
    777912
    778913  // 4. Store triangles in tecplot file
     
    9801115}
    9811116;
     1117
     1118
     1119/** Fills the empty space of the simulation box with water/
     1120 * \param *out output stream for debugging
     1121 * \param *List list of molecules already present in box
     1122 * \param *TesselStruct contains tesselated surface
     1123 * \param *filler molecule which the box is to be filled with
     1124 * \param configuration contains box dimensions
     1125 * \param distance[NDIM] distance between filling molecules in each direction
     1126 * \param RandAtomDisplacement maximum distance for random displacement per atom
     1127 * \param RandMolDisplacement maximum distance for random displacement per filler molecule
     1128 * \param DoRandomRotation true - do random rotiations, false - don't
     1129 * \return *mol pointer to new molecule with filled atoms
     1130 */
     1131molecule * FillBoxWithMolecule(ofstream *out, MoleculeListClass *List, molecule *filler, config &configuration, double distance[NDIM], double RandomAtomDisplacement, double RandomMolDisplacement, bool DoRandomRotation)
     1132{
     1133  molecule *Filling = new molecule(filler->elemente);
     1134  Vector CurrentPosition;
     1135  int N[NDIM];
     1136  int n[NDIM];
     1137  double *M =  filler->ReturnFullMatrixforSymmetric(filler->cell_size);
     1138  double Rotations[NDIM*NDIM];
     1139  Vector AtomTranslations;
     1140  Vector FillerTranslations;
     1141  Vector FillerDistance;
     1142  double FillIt = false;
     1143  atom *Walker = NULL, *Runner = NULL;
     1144  bond *Binder = NULL;
     1145
     1146  // Center filler at origin
     1147  filler->CenterOrigin(out);
     1148  filler->Center.Zero();
     1149
     1150  // calculate filler grid in [0,1]^3
     1151  FillerDistance.Init(distance[0], distance[1], distance[2]);
     1152  FillerDistance.InverseMatrixMultiplication(M);
     1153  for(int i=0;i<NDIM;i++)
     1154    N[i] = ceil(1./FillerDistance.x[i]);
     1155
     1156  // go over [0,1]^3 filler grid
     1157  for (n[0] = 0; n[0] < N[0]; n[0]++)
     1158    for (n[1] = 0; n[1] < N[1]; n[1]++)
     1159      for (n[2] = 0; n[2] < N[2]; n[2]++) {
     1160        // calculate position of current grid vector in untransformed box
     1161        CurrentPosition.Init(n[0], n[1], n[2]);
     1162        CurrentPosition.MatrixMultiplication(M);
     1163        // Check whether point is in- or outside
     1164        FillIt = true;
     1165        for (MoleculeList::iterator ListRunner = List->ListOfMolecules.begin(); ListRunner != List->ListOfMolecules.end(); ListRunner++) {
     1166          FillIt = FillIt && (!(*ListRunner)->TesselStruct->IsInside(&CurrentPosition));
     1167        }
     1168
     1169        if (FillIt) {
     1170          // fill in Filler
     1171          *out << Verbose(2) << "Space at " << CurrentPosition << " is unoccupied by any molecule, filling in." << endl;
     1172
     1173          // create molecule random translation vector ...
     1174          for (int i=0;i<NDIM;i++)
     1175            FillerTranslations.x[i] = RandomMolDisplacement*(rand()/(RAND_MAX/2.) - 1.);
     1176
     1177          // go through all atoms
     1178          Walker = filler->start;
     1179          while (Walker != filler->end) {
     1180            Walker = Walker->next;
     1181            // copy atom ...
     1182            *Runner = new atom(Walker);
     1183
     1184            // create atomic random translation vector ...
     1185            for (int i=0;i<NDIM;i++)
     1186              AtomTranslations.x[i] = RandomAtomDisplacement*(rand()/(RAND_MAX/2.) - 1.);
     1187
     1188            // ... and rotation matrix
     1189            if (DoRandomRotation) {
     1190              double phi[NDIM];
     1191              for (int i=0;i<NDIM;i++) {
     1192                phi[i] = rand()/(RAND_MAX/(2.*M_PI));
     1193              }
     1194
     1195              Rotations[0] =   cos(phi[0])            *cos(phi[2]) + (sin(phi[0])*sin(phi[1])*sin(phi[2]));
     1196              Rotations[3] =   sin(phi[0])            *cos(phi[2]) - (cos(phi[0])*sin(phi[1])*sin(phi[2]));
     1197              Rotations[6] =               cos(phi[1])*sin(phi[2])                                     ;
     1198              Rotations[1] = - sin(phi[0])*cos(phi[1])                                                ;
     1199              Rotations[4] =   cos(phi[0])*cos(phi[1])                                                ;
     1200              Rotations[7] =               sin(phi[1])                                                ;
     1201              Rotations[3] = - cos(phi[0])            *sin(phi[2]) + (sin(phi[0])*sin(phi[1])*cos(phi[2]));
     1202              Rotations[5] = - sin(phi[0])            *sin(phi[2]) - (cos(phi[0])*sin(phi[1])*cos(phi[2]));
     1203              Rotations[8] =               cos(phi[1])*cos(phi[2])                                     ;
     1204            }
     1205
     1206            // ... and put at new position
     1207            if (DoRandomRotation)
     1208              Runner->x.MatrixMultiplication(Rotations);
     1209            Runner->x.AddVector(&AtomTranslations);
     1210            Runner->x.AddVector(&FillerTranslations);
     1211            Runner->x.AddVector(&CurrentPosition);
     1212            // insert into Filling
     1213            Filling->AddAtom(Runner);
     1214          }
     1215
     1216          // go through all bonds and add as well
     1217          Binder = filler->first;
     1218          while(Binder != filler->last) {
     1219            Binder = Binder->next;
     1220          }
     1221        } else {
     1222          // leave empty
     1223          *out << Verbose(2) << "Space at " << CurrentPosition << " is occupied." << endl;
     1224        }
     1225      }
     1226  return Filling;
     1227};
     1228
    9821229
    9831230// =========================================================== class TESSELATION ===========================================
     
    11961443
    11971444  MolCenter = mol->DetermineCenterOfAll(out);
     1445  // create a first tesselation with the given BoundaryPoints
    11981446  do {
    11991447    flag = false;
     
    13681616        *out << Verbose(2) << "Baseline candidate " << *(baseline->second) << " has a triangle count of " << baseline->second->TrianglesCount << "." << endl;
    13691617  } while (flag);
     1618
     1619  // exit
    13701620  delete(MolCenter);
     1621};
     1622
     1623/** Inserts all atoms outside of the tesselated surface into it by adding new triangles.
     1624 * \param *out output stream for debugging
     1625 * \param *mol molecule structure with atoms
     1626 * \return true - all straddling points insert, false - something went wrong
     1627 */
     1628bool Tesselation::InsertStraddlingPoints(ofstream *out, molecule *mol)
     1629{
     1630  Vector Intersection;
     1631  atom *Walker = mol->start;
     1632  Vector *MolCenter = mol->DetermineCenterOfAll(out);
     1633  while (Walker->next != mol->end) {  // we only have to go once through all points, as boundary can become only bigger
     1634    // get the next triangle
     1635    BTS = FindClosestTriangleToPoint(out, &Walker->x);
     1636    if (BTS == NULL) {
     1637      *out << Verbose(1) << "ERROR: No triangle closest to " << Walker << " was found." << endl;
     1638      return false;
     1639    }
     1640    // get the intersection point
     1641    if (BTS->GetIntersectionInsideTriangle(out, MolCenter, &Walker->x, &Intersection)) {
     1642      // we have the intersection, check whether in- or outside of boundary
     1643      if ((MolCenter->DistanceSquared(&Walker->x) - MolCenter->DistanceSquared(&Intersection)) < -MYEPSILON) {
     1644        // inside, next!
     1645        *out << Verbose(4) << Walker << " is inside wrt triangle " << BTS << "." << endl;
     1646      } else {
     1647        // outside!
     1648        *out << Verbose(3) << Walker << " is outside wrt triangle " << BTS << "." << endl;
     1649        class BoundaryLineSet *OldLines[3], *NewLines[3];
     1650        class BoundaryPointSet *OldPoints[3], *NewPoint;
     1651        // store the three old lines and old points
     1652        for (int i=0;i<3;i++) {
     1653          OldLines[i] = BTS->lines[i];
     1654          OldPoints[i] = BTS->endpoints[i];
     1655        }
     1656        // add Walker to boundary points
     1657        AddPoint(Walker);
     1658        if (BPS[0] == NULL)
     1659          NewPoint = BPS[0];
     1660        else
     1661          continue;
     1662        // remove triangle
     1663        TrianglesOnBoundary.erase(BTS->Nr);
     1664        // create three new boundary lines
     1665        for (int i=0;i<3;i++) {
     1666          BPS[0] = NewPoint;
     1667          BPS[1] = OldPoints[i];
     1668          NewLines[i] = new class BoundaryLineSet(BPS, LinesOnBoundaryCount);
     1669          LinesOnBoundary.insert(LinePair(LinesOnBoundaryCount, NewLines[i])); // no need for check for unique insertion as BPS[0] is definitely a new one
     1670          LinesOnBoundaryCount++;
     1671        }
     1672        // create three new triangle with new point
     1673        for (int i=0;i<3;i++) { // find all baselines
     1674          BLS[0] = OldLines[i];
     1675          int n = 1;
     1676          for (int j=0;j<3;j++) {
     1677            if (NewLines[j]->IsConnectedTo(BLS[0])) {
     1678              if (n>2) {
     1679                *out << Verbose(1) << "ERROR: " << BLS[0] << " connects to all of the new lines?!" << endl;
     1680                return false;
     1681              } else
     1682                BLS[n++] = NewLines[j];
     1683            }
     1684          }
     1685          // create the triangle
     1686          BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
     1687          TrianglesOnBoundary.insert(TrianglePair(TrianglesOnBoundaryCount, BTS));
     1688          TrianglesOnBoundaryCount++;
     1689        }
     1690      }
     1691    } else { // something is wrong with FindClosestTriangleToPoint!
     1692      *out << Verbose(1) << "ERROR: The closest triangle did not produce an intersection!" << endl;
     1693      return false;
     1694    }
     1695  }
     1696
     1697  // exit
     1698  delete(MolCenter);
     1699  return true;
     1700};
     1701
     1702/** Goes over all baselines and checks whether adjacent triangles and convex to each other.
     1703 * \param *out output stream for debugging
     1704 * \return true - all baselines were corrected, false - there are still concave pieces
     1705 */
     1706bool Tesselation::CorrectConcaveBaselines(ofstream *out)
     1707{
     1708  class BoundaryTriangleSet *triangle[2];
     1709  class BoundaryLineSet *OldLines[4], *NewLine;
     1710  class BoundaryPointSet *OldPoints[2];
     1711  Vector BaseLineNormal;
     1712  class BoundaryLineSet *Base = NULL;
     1713  int OldTriangles[2], OldBaseLine;
     1714  int i;
     1715  for (LineMap::iterator baseline = LinesOnBoundary.begin(); baseline != LinesOnBoundary.end(); baseline++) {
     1716    Base = baseline->second;
     1717
     1718    // check convexity
     1719    if (Base->CheckConvexityCriterion(out)) { // triangles are convex
     1720      *out << Verbose(3) << Base << " has two convex triangles." << endl;
     1721    } else { // not convex!
     1722      // get the two triangles
     1723      i=0;
     1724      for(TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++)
     1725        triangle[i++] = runner->second;
     1726      // gather four endpoints and four lines
     1727      for (int j=0;j<4;j++)
     1728        OldLines[j] = NULL;
     1729      for (int j=0;j<2;j++)
     1730        OldPoints[j] = NULL;
     1731      i=0;
     1732      for (int m=0;m<2;m++) { // go over both triangles
     1733        for (int j=0;j<3;j++) { // all of their endpoints and baselines
     1734          if (triangle[m]->lines[j] != Base) // pick not the central baseline
     1735            OldLines[i++] = triangle[m]->lines[j];
     1736          if (!Base->ContainsBoundaryPoint(triangle[m]->endpoints[j])) // and neither of its endpoints
     1737            OldPoints[m] = triangle[m]->endpoints[j];
     1738        }
     1739      }
     1740      if (i<4) {
     1741        *out << Verbose(1) << "ERROR: We have not gathered enough baselines!" << endl;
     1742        return false;
     1743      }
     1744      for (int j=0;j<4;j++)
     1745        if (OldLines[j] == NULL) {
     1746          *out << Verbose(1) << "ERROR: We have not gathered enough baselines!" << endl;
     1747          return false;
     1748        }
     1749      for (int j=0;j<2;j++)
     1750        if (OldPoints[j] == NULL) {
     1751          *out << Verbose(1) << "ERROR: We have not gathered enough endpoints!" << endl;
     1752          return false;
     1753        }
     1754
     1755      // remove triangles
     1756      for (int j=0;j<2;j++) {
     1757        OldTriangles[j] = triangle[j]->Nr;
     1758        TrianglesOnBoundary.erase(OldTriangles[j]);
     1759        triangle[j] = NULL;
     1760      }
     1761
     1762      // remove baseline
     1763      OldBaseLine = Base->Nr;
     1764      LinesOnBoundary.erase(OldBaseLine);
     1765      Base = NULL;
     1766
     1767      // construct new baseline (with same number as old one)
     1768      BPS[0] = OldPoints[0];
     1769      BPS[1] = OldPoints[1];
     1770      NewLine = new class BoundaryLineSet(BPS, OldBaseLine);
     1771      LinesOnBoundary.insert(LinePair(OldBaseLine, NewLine)); // no need for check for unique insertion as NewLine is definitely a new one
     1772
     1773      // construct new triangles with flipped baseline
     1774      i=-1;
     1775      if (BLS[0]->IsConnectedTo(OldLines[2]))
     1776        i=2;
     1777      if (BLS[0]->IsConnectedTo(OldLines[2]))
     1778        i=3;
     1779      if (i!=-1) {
     1780        BLS[0] = OldLines[0];
     1781        BLS[1] = OldLines[i];
     1782        BLS[2] = NewLine;
     1783        BTS = new class BoundaryTriangleSet(BLS, OldTriangles[0]);
     1784        TrianglesOnBoundary.insert(TrianglePair(OldTriangles[0], BTS));
     1785
     1786        BLS[0] = (i==2 ? OldLines[3] : OldLines[2]);
     1787        BLS[1] = OldLines[1];
     1788        BLS[2] = NewLine;
     1789        BTS = new class BoundaryTriangleSet(BLS, OldTriangles[1]);
     1790        TrianglesOnBoundary.insert(TrianglePair(OldTriangles[1], BTS));
     1791      } else {
     1792        *out << Verbose(1) << "The four old lines do not connect, something's utterly wrong here!" << endl;
     1793        return false;
     1794      }
     1795    }
     1796  }
     1797  return true;
     1798};
     1799
     1800
     1801/** States whether point is in- or outside of a tesselated surface.
     1802 * \param *pointer point to be checked
     1803 * \return true - is inside, false - is outside
     1804 */
     1805bool Tesselation::IsInside(Vector *pointer)
     1806{
     1807
     1808  // hier kommt dann Saskias Routine hin...
     1809
     1810  return true;
     1811};
     1812
     1813/** Finds the closest triangle to a given point.
     1814 * \param *out output stream for debugging
     1815 * \param *x second endpoint of line
     1816 * \return pointer triangle that is closest, NULL if none was found
     1817 */
     1818class BoundaryTriangleSet * Tesselation::FindClosestTriangleToPoint(ofstream *out, Vector *x)
     1819{
     1820  class BoundaryTriangleSet *triangle = NULL;
     1821
     1822  // hier kommt dann Saskias Routine hin...
     1823
     1824  return triangle;
    13711825};
    13721826
     
    13821836  if (InsertUnique.second) // if new point was not present before, increase counter
    13831837    PointsOnBoundaryCount++;
     1838  else {
     1839    delete(BPS[0]);
     1840    BPS[0] = NULL;
     1841  }
    13841842}
    13851843;
  • src/boundary.hpp

    re1589e r2319ed  
    5454
    5555    void AddTriangle(class BoundaryTriangleSet *triangle);
     56    bool IsConnectedTo(class BoundaryLineSet *line);
     57    bool ContainsBoundaryPoint(class BoundaryPointSet *point);
     58    bool CheckConvexityCriterion(ofstream *out);
    5659
    5760    class BoundaryPointSet *endpoints[2];
     
    6871
    6972    void GetNormalVector(Vector &NormalVector);
     73    bool GetIntersectionInsideTriangle(ofstream *out, Vector *MolCenter, Vector *x, Vector *Intersection);
     74    bool ContainsBoundaryLine(class BoundaryLineSet *line);
     75    bool ContainsBoundaryPoint(class BoundaryPointSet *point);
    7076
    7177    class BoundaryPointSet *endpoints[3];
     
    104110    int CheckPresenceOfTriangle(ofstream *out, atom *Candidates[3]);
    105111    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);
     112    class BoundaryTriangleSet * FindClosestTriangleToPoint(ofstream *out, Vector *x);
     113    bool IsInside(Vector *pointer);
     114    bool InsertStraddlingPoints(ofstream *out, molecule *mol);
     115    bool CorrectConcaveBaselines(ofstream *out);
    106116
    107117    PointMap PointsOnBoundary;
     
    127137double * GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol, bool IsAngstroem);
    128138void PrepareClustersinWater(ofstream *out, config *configuration, molecule *mol, double ClusterVolume, double celldensity);
     139molecule * FillBoxWithMolecule(ofstream *out, MoleculeListClass *List, molecule *filler, config &configuration, double distance[NDIM], double RandAtomDisplacement, double RandMolDisplacement, bool DoRandomRotation);
    129140void Find_convex_border(ofstream *out, molecule* mol, class Tesselation *&TesselStruct, class LinkedCell *LCList, const char *filename);
    130141void Find_non_convex_border(ofstream *out, molecule* mol, class Tesselation *T, class LinkedCell *LC, const char *tempbasename, const double RADIUS);
  • src/builder.cpp

    re1589e r2319ed  
    5454#include "helpers.hpp"
    5555#include "molecules.hpp"
    56 
    5756/********************************************* Subsubmenu routine ************************************/
    5857
     
    587586        Find_convex_border((ofstream *)&cout, mol, TesselStruct, &LCList, NULL);
    588587        double clustervolume = VolumeOfConvexEnvelope((ofstream *)&cout, TesselStruct, configuration);
     588        cout << Verbose(0) << "The tesselated surface area is " << clustervolume << "." << endl;
    589589        delete(TesselStruct);
    590590      }
     
    18151815                Find_convex_border((ofstream *)&cout, mol, TesselStruct, &LCList, argv[argptr]);
    18161816                double clustervolume = VolumeOfConvexEnvelope((ofstream *)&cout, TesselStruct, &configuration);
     1817                cout << Verbose(0) << "The tesselated surface area is " << clustervolume << "." << endl;
    18171818                delete(TesselStruct);
    18181819                argptr+=1;
  • src/molecules.cpp

    re1589e r2319ed  
    120120{
    121121  if (pointer != NULL) {
    122     atom *walker = new atom();
    123     walker->type = pointer->type;  // copy element of atom
    124     walker->x.CopyVector(&pointer->x); // copy coordination
    125     walker->v.CopyVector(&pointer->v); // copy velocity
    126     walker->FixedIon = pointer->FixedIon;
    127     walker->sort = &walker->nr;
     122    atom *walker = new atom(pointer);
     123    walker->Name = (char *) Malloc(sizeof(char)*strlen(pointer->Name)+1, "atom::atom: *Name");
     124    strcpy (walker->Name, pointer->Name);
    128125    walker->nr = last_atom++;  // increase number within molecule
    129     walker->father = pointer; //->GetTrueFather();
    130     walker->Name = (char *) Malloc(sizeof(char)*strlen(pointer->Name)+1, "molecule::AddCopyAtom: *Name");
    131     strcpy (walker->Name, pointer->Name);
    132126    add(walker, end);
    133127    if ((pointer->type != NULL) && (pointer->type->Z != 1))
  • src/molecules.hpp

    re1589e r2319ed  
    3535class config;
    3636class molecule;
     37class MoleculeLeafClass;
    3738class MoleculeListClass;
    3839class Verbose;
     40class Tesselation;
    3941
    4042/******************************** Some definitions for easier reading **********************************/
     
    148150
    149151  atom();
     152  atom(class atom *pointer);
    150153  ~atom();
    151154
     
    199202
    200203ostream & operator << (ostream &ost, const bond &b);
    201 
    202 class MoleculeLeafClass;
    203 
    204204
    205205#define MaxThermostats 6      //!< maximum number of thermostat entries in Ions#ThermostatNames and Ions#ThermostatImplemented
  • src/vector.cpp

    re1589e r2319ed  
    196196};
    197197
     198/** Calculates the intersection point between a line defined by \a *LineVector and \a *LineVector2 and a plane defined by \a *Normal and \a *PlaneOffset.
     199 * According to [Bronstein] the vectorial plane equation is:
     200 *   -# \f$\stackrel{r}{\rightarrow} \cdot \stackrel{N}{\rightarrow} + D = 0\f$,
     201 * where \f$\stackrel{r}{\rightarrow}\f$ is the vector to be testet, \f$\stackrel{N}{\rightarrow}\f$ is the plane's normal vector and
     202 * \f$D = - \stackrel{a}{\rightarrow} \stackrel{N}{\rightarrow}\f$, the offset with respect to origin, if \f$\stackrel{a}{\rightarrow}\f$,
     203 * is an offset vector onto the plane. The line is parametrized by \f$\stackrel{x}{\rightarrow} + k \stackrel{t}{\rightarrow}\f$, where
     204 * \f$\stackrel{x}{\rightarrow}\f$ is the offset and \f$\stackrel{t}{\rightarrow}\f$ the directional vector (NOTE: No need to normalize
     205 * the latter). Inserting the parametrized form into the plane equation and solving for \f$k\f$, which we insert then into the parametrization
     206 * of the line yields the intersection point on the plane.
     207 * \param *out output stream for debugging
     208 * \param *PlaneNormal Plane's normal vector
     209 * \param *PlaneOffset Plane's offset vector
     210 * \param *LineVector first vector of line
     211 * \param *LineVector2 second vector of line
     212 * \return true -  \a this contains intersection point on return, false - line is parallel to plane
     213 */
     214bool Vector::GetIntersectionWithPlane(ofstream *out, Vector *PlaneNormal, Vector *PlaneOffset, Vector *LineVector, Vector *LineVector2)
     215{
     216  double factor;
     217  Vector Direction;
     218
     219  // find intersection of a line defined by Offset and Direction with a  plane defined by triangle
     220  Direction.CopyVector(LineVector2);
     221  Direction.SubtractVector(LineVector);
     222  if (Direction.ScalarProduct(PlaneNormal) < MYEPSILON)
     223    return false;
     224  factor = LineVector->ScalarProduct(PlaneNormal)*(-PlaneOffset->ScalarProduct(PlaneNormal))/(Direction.ScalarProduct(PlaneNormal));
     225  Direction.Scale(factor);
     226  CopyVector(LineVector);
     227  SubtractVector(&Direction);
     228
     229  // test whether resulting vector really is on plane
     230  Direction.CopyVector(this);
     231  Direction.SubtractVector(PlaneOffset);
     232  if (Direction.ScalarProduct(PlaneNormal) > MYEPSILON)
     233    return true;
     234  else
     235    return false;
     236};
     237
     238/** Calculates the intersection of the two lines that are both on the same plane.
     239 * Note that we do not check whether they are on the same plane.
     240 * \param *out output stream for debugging
     241 * \param *Line1a first vector of first line
     242 * \param *Line1b second vector of first line
     243 * \param *Line2a first vector of second line
     244 * \param *Line2b second vector of second line
     245 * \return true - \a this will contain the intersection on return, false - lines are parallel
     246 */
     247bool Vector::GetIntersectionOfTwoLinesOnPlane(ofstream *out, Vector *Line1a, Vector *Line1b, Vector *Line2a, Vector *Line2b)
     248{
     249  double k1,a1,h1,b1,k2,a2,h2,b2;
     250  // equation for line 1
     251  if (fabs(Line1a->x[0] - Line2a->x[0]) < MYEPSILON) {
     252    k1 = 0;
     253    h1 = 0;
     254  } else {
     255    k1 = (Line1a->x[1] - Line2a->x[1])/(Line1a->x[0] - Line2a->x[0]);
     256    h1 = (Line1a->x[2] - Line2a->x[2])/(Line1a->x[0] - Line2a->x[0]);
     257  }
     258  a1 = 0.5*((Line1a->x[1] + Line2a->x[1]) - k1*(Line1a->x[0] + Line2a->x[0]));
     259  b1 = 0.5*((Line1a->x[2] + Line2a->x[2]) - h1*(Line1a->x[0] + Line2a->x[0]));
     260
     261  // equation for line 2
     262  if (fabs(Line2a->x[0] - Line2a->x[0]) < MYEPSILON) {
     263    k1 = 0;
     264    h1 = 0;
     265  } else {
     266    k1 = (Line2a->x[1] - Line2a->x[1])/(Line2a->x[0] - Line2a->x[0]);
     267    h1 = (Line2a->x[2] - Line2a->x[2])/(Line2a->x[0] - Line2a->x[0]);
     268  }
     269  a1 = 0.5*((Line2a->x[1] + Line2a->x[1]) - k1*(Line2a->x[0] + Line2a->x[0]));
     270  b1 = 0.5*((Line2a->x[2] + Line2a->x[2]) - h1*(Line2a->x[0] + Line2a->x[0]));
     271
     272  // calculate cross point
     273  if (fabs((a1-a2)*(h1-h2) - (b1-b2)*(k1-k2)) < MYEPSILON) {
     274    x[0] = (a2-a1)/(k1-k2);
     275    x[1] = (k1*a2-k2*a1)/(k1-k2);
     276    x[2] = (h1*b2-h2*b1)/(h1-h2);
     277    *out << Verbose(4) << "Lines do intersect at " << this << "." << endl;
     278    return true;
     279  } else {
     280    *out << Verbose(4) << "Lines do not intersect." << endl;
     281    return false;
     282  }
     283};
     284
    198285/** Calculates the projection of a vector onto another \a *y.
    199286 * \param *y array to second vector
     
    453540};
    454541
    455 /** Do a matrix multiplication with \a *matrix' inverse.
     542/** Do a matrix multiplication with the \a *A' inverse.
    456543 * \param *matrix NDIM_NDIM array
    457544 */
  • src/vector.hpp

    re1589e r2319ed  
    4646  void LinearCombinationOfVectors(const Vector *x1, const Vector *x2, const Vector *x3, double *factors);
    4747  double CutsPlaneAt(Vector *A, Vector *B, Vector *C);
     48  bool GetIntersectionWithPlane(ofstream *out, Vector *PlaneNormal, Vector *PlaneOffset, Vector *LineVector, Vector *LineVector2);
     49  bool GetIntersectionOfTwoLinesOnPlane(ofstream *out, Vector *Line1a, Vector *Line1b, Vector *Line2a, Vector *Line2b);
    4850  bool GetOneNormalVector(const Vector *x1);
    4951  bool MakeNormalVector(const Vector *y1);
Note: See TracChangeset for help on using the changeset viewer.