1
/*****************************************************************************
2
TRAVIS - Trajectory Analyzer and Visualizer
3
http://www.travis-analyzer.de/
5
Copyright (c) 2009-2014 Martin Brehm
6
2012-2014 Martin Thomas
8
This file written by Martin Brehm.
10
This program is free software: you can redistribute it and/or modify
11
it under the terms of the GNU General Public License as published by
12
the Free Software Foundation, either version 3 of the License, or
13
(at your option) any later version.
15
This program is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
GNU General Public License for more details.
20
You should have received a copy of the GNU General Public License
21
along with this program. If not, see <http://www.gnu.org/licenses/>.
22
*****************************************************************************/
24
#include "voroanalysis.h"
25
#include "globalvar.h"
26
#include "maintools.h"
29
CVoroPoint::CVoroPoint()
31
m_iaVoroCells.SetName("CVoroPoint::m_iaVoroCells");
35
CVoroPoint::~CVoroPoint()
40
/*CVoroFace::CVoroFace()
45
CVoroFace::~CVoroFace()
50
CDelaunayPoint::CDelaunayPoint()
55
CDelaunayPoint::~CDelaunayPoint()
60
CDelaunayTetrahedron::CDelaunayTetrahedron()
65
CDelaunayTetrahedron::~CDelaunayTetrahedron()
70
CVoroCell::CVoroCell()
72
m_iaVoroPoints.SetName("CVoroCell::m_iaVoroPoints");
73
m_iaNeighborCells.SetName("CVoroCell::m_iaNeighborCells");
77
CVoroCell::~CVoroCell()
82
CVoroAnalysis::CVoroAnalysis()
84
m_oaVoroCells.SetName("CVoroAnalysis::m_oaVoroCells");
85
m_oaDelaunayTetrahedra.SetName("CVoroAnalysis::m_oaDelaunayTetrahedra");
86
m_oaDelaunayPoints.SetName("CVoroAnalysis::m_oaDelaunayPoints");
87
m_oaVoroPoints.SetName("CVoroAnalysis::m_oaVoroPoints");
91
CVoroAnalysis::~CVoroAnalysis()
96
void CVoroAnalysis::Build(CTimeStep *ts, bool sanity, bool verbose)
98
voronoicell_neighbor c;
99
container_periodic_poly *con;
101
int ijk, q, z, z2, z3, faces, fc, id, ti, i, cc;
106
CDelaunayTetrahedron *dt;
108
double px, py, pz, pk[4];
114
try { con = new container_periodic_poly(g_fBoxX/1000.0,0,g_fBoxY/1000.0,0,0,g_fBoxZ/1000.0,g_pVoroWrapper->m_iBlocksX,g_pVoroWrapper->m_iBlocksY,g_pVoroWrapper->m_iBlocksZ,g_iVoroMemory); } catch(...) { con = NULL; }
115
if (con == NULL) NewException((double)sizeof(container_periodic_poly),__FILE__,__LINE__,__PRETTY_FUNCTION__);
117
m_oaDelaunayPoints.SetMaxSize(g_iGesAtomCount);
118
m_oaVoroCells.SetSize(g_iGesAtomCount);
120
for (z=0;z<g_iGesAtomCount;z++)
122
try { dp = new CDelaunayPoint(); } catch(...) { dp = NULL; }
123
if (dp == NULL) NewException((double)sizeof(CDelaunayPoint),__FILE__,__LINE__,__PRETTY_FUNCTION__);
125
dp->m_vPos = ts->m_vaCoords[z];
126
m_oaDelaunayPoints.Add(dp);
127
con->put(z,ts->m_vaCoords[z][0]/1000.0,ts->m_vaCoords[z][1]/1000.0,ts->m_vaCoords[z][2]/1000.0,0.0005);
130
c_loop_all_periodic vl(*con);
134
mprintf(" Voronoi decomposition:\n");
144
if (fmod(cc,g_iGesAtomCount/60.0) < 1.0)
147
if (con->compute_cell(c,vl))
151
pp=con->p[ijk]+con->ps*q;
153
id = con->id[ijk][q];
155
try { vc = new CVoroCell(); } catch(...) { vc = NULL; }
156
if (vc == NULL) NewException((double)sizeof(CVoroCell),__FILE__,__LINE__,__PRETTY_FUNCTION__);
158
m_oaVoroCells[id] = vc;
159
vc->m_vPos[0] = ts->m_vaCoords[id][0]/1000.0;
160
vc->m_vPos[1] = ts->m_vaCoords[id][1]/1000.0;
161
vc->m_vPos[2] = ts->m_vaCoords[id][2]/1000.0;
164
faces = c.number_of_faces();
171
mprintf("### Zelle %d\n",id+1);
172
mprintf(" %d Nachbarn: ",nb.size());
175
vc->m_iaNeighborCells.SetSize(nb.size());
176
for (z=0;z<(int)nb.size();z++)
179
mprintf("%d, ",nb[z]+1);
180
vc->m_iaNeighborCells[z] = nb[z];
186
mprintf(" %d Flaechen, %d Vertices.\n",faces,fv.size());
190
for (z=0;z<faces;z++)
195
mprintf(" - Flaeche %d: %d Punkte - ",z+1,fc);
197
for (z2=0;z2<fc;z2++)
200
mprintf("%d, ",fv[ti+z2+1]+1);
212
mprintf(" %d Voronoi-Punkte.\n",i+1);
213
mprintf(" Base Point ist %.6f | %.6f | %.6f .\n",*pp,pp[1],pp[2]);
218
px = *pp+c.pts[z*3]*0.5;
219
py = pp[1]+c.pts[z*3+1]*0.5;
220
pz = pp[2]+c.pts[z*3+2]*0.5;
222
while (px < 0) px += g_fBoxX/1000.0;
223
while (px >= g_fBoxX/1000.0) px -= g_fBoxX/1000.0;
224
while (py < 0) py += g_fBoxY/1000.0;
225
while (py >= g_fBoxY/1000.0) py -= g_fBoxY/1000.0;
226
while (pz < 0) pz += g_fBoxZ/1000.0;
227
while (pz >= g_fBoxZ/1000.0) pz -= g_fBoxZ/1000.0;
229
/* while (px < -0.5) px += 1.0;
230
while (px >= 0.5) px -= 1.0;
231
while (py < -0.5) py += 1.0;
232
while (py >= 0.5) py -= 1.0;
233
while (pz < -0.5) pz += 1.0;
234
while (pz >= 0.5) pz -= 1.0;*/
237
mprintf(" %2d: %.6f | %.6f | %.6f\n",z+1,px,py,pz);
239
for (z2=0;z2<m_oaVoroPoints.GetSize();z2++)
241
vp = (CVoroPoint*)m_oaVoroPoints[z2];
242
if (fabs(vp->m_vPos[0]-px) > EPS)
244
if (fabs(vp->m_vPos[1]-py) > EPS)
246
if (fabs(vp->m_vPos[2]-pz) > EPS)
249
mprintf(" Punkt bereits vorhanden: %d.\n",z2+1);
250
vc->m_iaVoroPoints.Add(z2);
253
vc->m_iaVoroPoints.Add(m_oaVoroPoints.GetSize());
255
try { vp = new CVoroPoint(); } catch(...) { vp = NULL; }
256
if (vp == NULL) NewException((double)sizeof(CVoroPoint),__FILE__,__LINE__,__PRETTY_FUNCTION__);
261
m_oaVoroPoints.Add(vp);
263
mprintf(" * Fuege Punkt als %d hinzu.\n",m_oaVoroPoints.GetSize());
271
m_iMaxVoroPoints = m_oaVoroPoints.GetSize() * 2;
274
mprintf("Insgesamt %d verschiedene Voronoi-Punkte.\n\n",m_oaVoroPoints.GetSize());
278
mprintf(WHITE,"]\n");
279
mprintf("\n Found %d different voronoi points.\n\n",m_oaVoroPoints.GetSize());
285
mprintf(" Delaunay tetrahedron generation:\n");
289
for (z=0;z<m_oaVoroPoints.GetSize();z++)
292
if (fmod(z,m_oaVoroPoints.GetSize()/60.0) < 1.0)
295
vp = (CVoroPoint*)m_oaVoroPoints[z];
298
mprintf("### Voronoi-Punkt %d: %.6f | %.6f | %.6f\n",z+1,vp->m_vPos[0],vp->m_vPos[1],vp->m_vPos[2]);
300
try { dt = new CDelaunayTetrahedron(); } catch(...) { dt = NULL; }
301
if (dt == NULL) NewException((double)sizeof(CDelaunayTetrahedron),__FILE__,__LINE__,__PRETTY_FUNCTION__);
305
for (z2=0;z2<m_oaVoroCells.GetSize();z2++)
307
vc = (CVoroCell*)m_oaVoroCells[z2];
308
for (z3=0;z3<vc->m_iaVoroPoints.GetSize();z3++)
310
if (vc->m_iaVoroPoints[z3] == z)
314
vec = vp->m_vPos - vc->m_vPos;
316
while (vec[0] < -g_fBoxX/2000.0) vec[0] += g_fBoxX/1000.0;
317
while (vec[0] >= g_fBoxX/2000.0) vec[0] -= g_fBoxX/1000.0;
318
while (vec[1] < -g_fBoxY/2000.0) vec[1] += g_fBoxY/1000.0;
319
while (vec[1] >= g_fBoxY/2000.0) vec[1] -= g_fBoxY/1000.0;
320
while (vec[2] < -g_fBoxZ/2000.0) vec[2] += g_fBoxZ/1000.0;
321
while (vec[2] >= g_fBoxZ/2000.0) vec[2] -= g_fBoxZ/1000.0;
323
/* while (vec[0] < -0.5) vec[0] += 1.0;
324
while (vec[0] >= 0.5) vec[0] -= 1.0;
325
while (vec[1] < -0.5) vec[1] += 1.0;
326
while (vec[1] >= 0.5) vec[1] -= 1.0;
327
while (vec[2] < -0.5) vec[2] += 1.0;
328
while (vec[2] >= 0.5) vec[2] -= 1.0;*/
330
px = vec.GetLength();
332
mprintf(" - In Zelle %d als Punkt %d, Abstand %.8f. ",z2+1,z3+1,px);
338
dt->m_iPointID[ti] = z2;
348
eprintf("\nError: %d instead of 4 points in tetrahedron %d.\n",ti,z+1);
349
for (z2=0;z2<m_oaVoroCells.GetSize();z2++)
351
vc = (CVoroCell*)m_oaVoroCells[z2];
352
for (z3=0;z3<vc->m_iaVoroPoints.GetSize();z3++)
354
if (vc->m_iaVoroPoints[z3] == z)
356
vec = vp->m_vPos - vc->m_vPos;
358
while (vec[0] < -g_fBoxX/2000.0) vec[0] += g_fBoxX/1000.0;
359
while (vec[0] >= g_fBoxX/2000.0) vec[0] -= g_fBoxX/1000.0;
360
while (vec[1] < -g_fBoxY/2000.0) vec[1] += g_fBoxY/1000.0;
361
while (vec[1] >= g_fBoxY/2000.0) vec[1] -= g_fBoxY/1000.0;
362
while (vec[2] < -g_fBoxZ/2000.0) vec[2] += g_fBoxZ/1000.0;
363
while (vec[2] >= g_fBoxZ/2000.0) vec[2] -= g_fBoxZ/1000.0;
365
px = vec.GetLength();
367
mprintf(" - In cell %d as point %d, distance %.8f. ",z2+1,z3+1,px);
377
m_oaDelaunayTetrahedra.Add(dt);
379
if (verbose || sanity)
386
for (z2=0;z2<m_oaVoroCells.GetSize();z2++)
388
vc = (CVoroCell*)m_oaVoroCells[z2];
390
vec = vp->m_vPos - vc->m_vPos;
392
while (vec[0] < -g_fBoxX/2000.0) vec[0] += g_fBoxX/1000.0;
393
while (vec[0] >= g_fBoxX/2000.0) vec[0] -= g_fBoxX/1000.0;
394
while (vec[1] < -g_fBoxY/2000.0) vec[1] += g_fBoxY/1000.0;
395
while (vec[1] >= g_fBoxY/2000.0) vec[1] -= g_fBoxY/1000.0;
396
while (vec[2] < -g_fBoxZ/2000.0) vec[2] += g_fBoxZ/1000.0;
397
while (vec[2] >= g_fBoxZ/2000.0) vec[2] -= g_fBoxZ/1000.0;
399
/* while (vec[0] < -0.5) vec[0] += 1.0;
400
while (vec[0] >= 0.5) vec[0] -= 1.0;
401
while (vec[1] < -0.5) vec[1] += 1.0;
402
while (vec[1] >= 0.5) vec[1] -= 1.0;
403
while (vec[2] < -0.5) vec[2] += 1.0;
404
while (vec[2] >= 0.5) vec[2] -= 1.0;*/
406
px = vec.GetLength();
408
// px = FoldVector1(vp->m_vPos - vc->m_vPos).GetLength();
433
mprintf(" Kleinste 4 Abstaende:\n %.8f\n %.8f\n %.8f\n %.8f\n",pk[0],pk[1],pk[2],pk[3]);
435
if (sanity || verbose)
442
vc = (CVoroCell*)m_oaVoroCells[dt->m_iPointID[z2]];
443
for (z3=0;z3<vc->m_iaVoroPoints.GetSize();z3++)
445
if (vc->m_iaVoroPoints[z3] == z)
447
vec = vp->m_vPos - vc->m_vPos;
449
while (vec[0] < -g_fBoxX/2000.0) vec[0] += g_fBoxX/1000.0;
450
while (vec[0] >= g_fBoxX/2000.0) vec[0] -= g_fBoxX/1000.0;
451
while (vec[1] < -g_fBoxY/2000.0) vec[1] += g_fBoxY/1000.0;
452
while (vec[1] >= g_fBoxY/2000.0) vec[1] -= g_fBoxY/1000.0;
453
while (vec[2] < -g_fBoxZ/2000.0) vec[2] += g_fBoxZ/1000.0;
454
while (vec[2] >= g_fBoxZ/2000.0) vec[2] -= g_fBoxZ/1000.0;
456
/* while (vec[0] < -0.5) vec[0] += 1.0;
457
while (vec[0] >= 0.5) vec[0] -= 1.0;
458
while (vec[1] < -0.5) vec[1] += 1.0;
459
while (vec[1] >= 0.5) vec[1] -= 1.0;
460
while (vec[2] < -0.5) vec[2] += 1.0;
461
while (vec[2] >= 0.5) vec[2] -= 1.0;*/
463
tfa[z2+4] = vec.GetLength();
468
tf = MaxDiff_DoubleArray(tfa,8);
471
eprintf("\nSanity check failed: Largest Deviation is %.8f > EPS = %.8f.\n%.8f\n%.8f\n%.8f\n%.8f\n%.8f\n%.8f\n%.8f\n%.8f\n\n",tf,EPS,tfa[0],tfa[1],tfa[2],tfa[3],tfa[4],tfa[5],tfa[6],tfa[7]);
480
mprintf(WHITE,"]\n");
481
mprintf("\n Test passed.\n\n");
484
for (z=0;z<m_oaDelaunayTetrahedra.GetSize();z++)
486
dt = (CDelaunayTetrahedron*)m_oaDelaunayTetrahedra[z];
488
dt->m_vCenter[0] = ((CVoroPoint*)m_oaVoroPoints[z])->m_vPos[0] * 1000.0;
489
dt->m_vCenter[1] = ((CVoroPoint*)m_oaVoroPoints[z])->m_vPos[1] * 1000.0;
490
dt->m_vCenter[2] = ((CVoroPoint*)m_oaVoroPoints[z])->m_vPos[2] * 1000.0;
492
// vec = dt->m_vCenter - ((CDelaunayPoint*)m_oaDelaunayPoints[dt->m_iPointID[0]])->m_vPos;
494
dt->m_fRadius = FoldVector(dt->m_vCenter - ((CDelaunayPoint*)m_oaDelaunayPoints[dt->m_iPointID[0]])->m_vPos).GetLength();
501
void CVoroAnalysis::Parse()
508
mprintf(WHITE,">>> Void Analysis >>>\n\n");
510
mprintf(" Initializing...\n");
511
g_pVoroWrapper->Init();
514
mprintf("*** Voro: Box density is %f particles / Angstrom^3.\n",g_pVoroWrapper->m_fBoxDens);
515
mprintf("*** Voro: Using %d x %d x %d blocks.\n",g_pVoroWrapper->m_iBlocksX,g_pVoroWrapper->m_iBlocksY,g_pVoroWrapper->m_iBlocksZ);
517
try { t = new CTimeStep(); } catch(...) { t = NULL; }
518
if (t == NULL) NewException((double)sizeof(CTimeStep),__FILE__,__LINE__,__PRETTY_FUNCTION__);
520
t->CopyFrom(&g_TimeStep);
522
m = (CMolecule*)g_oaMolecules[0];
523
sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[0]];
525
t->CenterPos(t->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[sm->m_baAtomIndex.GetSize()-1])->GetAt(1)]);
526
t->CenterPos(CxVector3(-g_fBoxX/2.0,-g_fBoxY/2.0,-g_fBoxZ/2.0));
527
t->FoldAtomsPositive();
528
g_pVoroWrapper->Dump("voro.txt",t);
530
mprintf(" Voro++: Using cell memory for %d particles.\n\n",g_iVoroMemory);
532
mprintf(" Performing sanity check...\n\n");
535
// g_pVoroWrapper->WritePOV(t,"voro.pov",0,0);
538
// AskYesNo(" This is hard-coded for Ulrikes Bmim-Br ^^ [accept] ",false);
540
m_bSphereHole = AskYesNo(" Do you want to create a spherical hole distribution function (y/n)? [yes] ",true);
544
try { m_pSphereHoleDF = new CDF(); } catch(...) { m_pSphereHoleDF = NULL; }
545
if (m_pSphereHoleDF == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__);
547
m_pSphereHoleDF->m_fMinVal = 0;
548
m_pSphereHoleDF->m_fMaxVal = AskFloat(" Enter the maximal hole diameter (in pm): [1500.0] ",1500.0f);
549
m_pSphereHoleDF->m_iResolution = AskUnsignedInteger(" Enter the binning resolution: [%d] ",int(m_pSphereHoleDF->m_fMaxVal),int(m_pSphereHoleDF->m_fMaxVal));
550
m_pSphereHoleDF->Create();
551
m_pSphereHoleDF->SetLabelX("Hole diameter");
552
m_pSphereHoleDF->SetLabelY("Occurrence");
556
m_bSphereHoleRDF = AskYesNo(" Do you want to create a spherical hole RDF (y/n)? [yes] ",true);
558
if (m_bSphereHoleRDF)
560
try { m_pSphereHoleRDF = new CDF(); } catch(...) { m_pSphereHoleRDF = NULL; }
561
if (m_pSphereHoleRDF == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__);
563
m_pSphereHoleRDF->m_fMinVal = 0;
564
m_pSphereHoleRDF->m_fMaxVal = AskUnsignedInteger(" Enter the RDF range (in pm): [%d] ",HalfBox(),HalfBox());
565
m_pSphereHoleRDF->m_iResolution = AskUnsignedInteger(" Enter the RDF resolution: [300] ",300);
566
m_pSphereHoleRDF->Create();
570
m_bSphereHole2DF = AskYesNo(" Do you want to create a spherical hole 2D DF (y/n)? [no] ",false);
572
if (m_bSphereHole2DF)
574
try { m_pSphereHole2DF = new C2DF(); } catch(...) { m_pSphereHole2DF = NULL; }
575
if (m_pSphereHole2DF == NULL) NewException((double)sizeof(C2DF),__FILE__,__LINE__,__PRETTY_FUNCTION__);
577
m_pSphereHole2DF->m_fMinVal[0] = 0;
578
m_pSphereHole2DF->m_fMaxVal[0] = AskUnsignedInteger(" Enter the RDF channel range (in pm): [%d] ",HalfBox(),HalfBox());
579
m_pSphereHole2DF->m_iRes[0] = AskUnsignedInteger(" Enter the RDF channel resolution: [100] ",100);
580
m_pSphereHole2DF->m_fMinVal[1] = 0;
581
m_pSphereHole2DF->m_fMaxVal[1] = AskUnsignedInteger(" Enter the hole radius range (in pm): [300] ",300);
582
m_pSphereHole2DF->m_iRes[1] = AskUnsignedInteger(" Enter the hole radius channel resolution: [50] ",50);
583
m_pSphereHole2DF->SetLabelX("Void distance [pm]");
584
m_pSphereHole2DF->SetLabelY("Minimal void radius [pm]");
585
m_pSphereHole2DF->SetLabelZ("Occurence");
586
m_pSphereHole2DF->Create();
588
try { m_pSphereHole2DFCounter = new unsigned long[m_pSphereHole2DF->m_iRes[1]]; } catch(...) { m_pSphereHole2DFCounter = NULL; }
589
if (m_pSphereHole2DFCounter == NULL) NewException((double)m_pSphereHole2DF->m_iRes[1]*sizeof(unsigned long),__FILE__,__LINE__,__PRETTY_FUNCTION__);
591
for (z=0;z<m_pSphereHole2DF->m_iRes[1];z++)
592
m_pSphereHole2DFCounter[z] = 0;
597
m_bAllAtomRDF = AskYesNo(" Do you want to create an all-atom RDF (y/n)? [no] ",false);
601
try { m_pAllAtomRDF = new CDF(); } catch(...) { m_pAllAtomRDF = NULL; }
602
if (m_pAllAtomRDF == NULL) NewException((double)sizeof(CDF),__FILE__,__LINE__,__PRETTY_FUNCTION__);
604
m_pAllAtomRDF->m_fMinVal = 0;
605
m_pAllAtomRDF->m_fMaxVal = AskUnsignedInteger(" Enter the RDF range (in pm): [%d] ",HalfBox(),HalfBox());
606
m_pAllAtomRDF->m_iResolution = AskUnsignedInteger(" Enter the RDF resolution: [300] ",300);
607
m_pAllAtomRDF->Create();
612
m_bHoleDump = AskYesNo(" Do you want to write out a XYZ hole trajectory (y/n)? [no] ",false);
616
m_fDumpMinHole = AskFloat(" Enter the minimal hole diameter to output (in pm): [400] ",400) / 2.0;
617
m_fHoleDump = OpenFileWrite("holedump.xyz",true);
620
m_bSphereHoleSDF = AskYesNo(" Create a spherical hole SDF (y/n)? [no] ",false);
622
if (m_bSphereHoleSDF)
626
try { m_pSphereHoleSDF = new CSDF(); } catch(...) { m_pSphereHoleSDF = NULL; }
627
if (m_pSphereHoleSDF == NULL) NewException((double)sizeof(CSDF),__FILE__,__LINE__,__PRETTY_FUNCTION__);
629
m_pSphereHoleSDF->Parse(true);
631
m_pSphereHoleSDF->m_pSDF->m_fMinVal[0] = -m_pSphereHoleSDF->m_fRadius;
632
m_pSphereHoleSDF->m_pSDF->m_fMaxVal[0] = m_pSphereHoleSDF->m_fRadius;
633
m_pSphereHoleSDF->m_pSDF->m_fMinVal[1] = -m_pSphereHoleSDF->m_fRadius;
634
m_pSphereHoleSDF->m_pSDF->m_fMaxVal[1] = m_pSphereHoleSDF->m_fRadius;
635
m_pSphereHoleSDF->m_pSDF->m_fMinVal[2] = -m_pSphereHoleSDF->m_fRadius;
636
m_pSphereHoleSDF->m_pSDF->m_fMaxVal[2] = m_pSphereHoleSDF->m_fRadius;
637
m_pSphereHoleSDF->m_pSDF->m_iRes[0] = m_pSphereHoleSDF->m_iResolution;
638
m_pSphereHoleSDF->m_pSDF->m_iRes[1] = m_pSphereHoleSDF->m_iResolution;
639
m_pSphereHoleSDF->m_pSDF->m_iRes[2] = m_pSphereHoleSDF->m_iResolution;
640
m_pSphereHoleSDF->m_pSDF->m_iHistogramRes = m_pSphereHoleSDF->m_iHistogramRes;
641
m_pSphereHoleSDF->m_pSDF->Create();
644
m_bEmptySpaceSDF = AskYesNo(" Create an empty space SDF (y/n)? [no] ",false);
646
if (m_bEmptySpaceSDF)
650
m_bNewEmptyMode = AskYesNo(" Use new method (y/n)? [no] ",false);
654
m_iTempRes = AskUnsignedInteger(" Enter resoultion of the temporary SDF: [300] ",300);
656
try { m_pTempSDF = new C3DF(); } catch(...) { m_pTempSDF = NULL; }
657
if (m_pTempSDF == NULL) NewException((double)sizeof(C3DF),__FILE__,__LINE__,__PRETTY_FUNCTION__);
659
m_pTempSDF->m_fMinVal[0] = 0;
660
m_pTempSDF->m_fMaxVal[0] = g_fBoxX;
661
m_pTempSDF->m_fMinVal[1] = 0;
662
m_pTempSDF->m_fMaxVal[1] = g_fBoxY;
663
m_pTempSDF->m_fMinVal[2] = 0;
664
m_pTempSDF->m_fMaxVal[2] = g_fBoxZ;
665
m_pTempSDF->m_iRes[0] = m_iTempRes;
666
m_pTempSDF->m_iRes[1] = m_iTempRes;
667
m_pTempSDF->m_iRes[2] = m_iTempRes;
668
m_pTempSDF->m_iHistogramRes = m_pEmptySpaceSDF->m_iHistogramRes;
671
m_bEmptySpaceSDF_RefMol = AskYesNo(" Include the atoms of the reference molecule (y/n)? [yes] ",true);
672
m_iEmptySpaceBorder = AskUnsignedInteger(" Enter the size of the border in bins: [10] ",10);
674
try { m_pTempSDF = new C3DF(); } catch(...) { m_pTempSDF = NULL; }
675
if (m_pTempSDF == NULL) NewException((double)sizeof(C3DF),__FILE__,__LINE__,__PRETTY_FUNCTION__);
677
m_pTempSDF->m_fMinVal[0] = -m_pEmptySpaceSDF->m_fRadius;
678
m_pTempSDF->m_fMaxVal[0] = m_pEmptySpaceSDF->m_fRadius;
679
m_pTempSDF->m_fMinVal[1] = -m_pEmptySpaceSDF->m_fRadius;
680
m_pTempSDF->m_fMaxVal[1] = m_pEmptySpaceSDF->m_fRadius;
681
m_pTempSDF->m_fMinVal[2] = -m_pEmptySpaceSDF->m_fRadius;
682
m_pTempSDF->m_fMaxVal[2] = m_pEmptySpaceSDF->m_fRadius;
683
m_pTempSDF->m_iRes[0] = m_pEmptySpaceSDF->m_iResolution;
684
m_pTempSDF->m_iRes[1] = m_pEmptySpaceSDF->m_iResolution;
685
m_pTempSDF->m_iRes[2] = m_pEmptySpaceSDF->m_iResolution;
686
m_pTempSDF->m_iHistogramRes = m_pEmptySpaceSDF->m_iHistogramRes;
688
m_pTempSDF->Create();
690
try { m_pEmptySpaceSDF = new CSDF(); } catch(...) { m_pEmptySpaceSDF = NULL; }
691
if (m_pEmptySpaceSDF == NULL) NewException((double)sizeof(CSDF),__FILE__,__LINE__,__PRETTY_FUNCTION__);
693
m_pEmptySpaceSDF->Parse(true);
695
m_pEmptySpaceSDF->m_pSDF->m_fMinVal[0] = -m_pEmptySpaceSDF->m_fRadius;
696
m_pEmptySpaceSDF->m_pSDF->m_fMaxVal[0] = m_pEmptySpaceSDF->m_fRadius;
697
m_pEmptySpaceSDF->m_pSDF->m_fMinVal[1] = -m_pEmptySpaceSDF->m_fRadius;
698
m_pEmptySpaceSDF->m_pSDF->m_fMaxVal[1] = m_pEmptySpaceSDF->m_fRadius;
699
m_pEmptySpaceSDF->m_pSDF->m_fMinVal[2] = -m_pEmptySpaceSDF->m_fRadius;
700
m_pEmptySpaceSDF->m_pSDF->m_fMaxVal[2] = m_pEmptySpaceSDF->m_fRadius;
701
m_pEmptySpaceSDF->m_pSDF->m_iRes[0] = m_pEmptySpaceSDF->m_iResolution;
702
m_pEmptySpaceSDF->m_pSDF->m_iRes[1] = m_pEmptySpaceSDF->m_iResolution;
703
m_pEmptySpaceSDF->m_pSDF->m_iRes[2] = m_pEmptySpaceSDF->m_iResolution;
704
m_pEmptySpaceSDF->m_pSDF->m_iHistogramRes = m_pEmptySpaceSDF->m_iHistogramRes;
705
m_pEmptySpaceSDF->m_pSDF->Create();
708
mprintf(WHITE,"\n<<< End of Void Analysis <<<\n\n");
712
void CVoroAnalysis::Step(CTimeStep *ts)
714
int z, z2, z3, z4, ti;
716
CDelaunayTetrahedron *dt, *dt2;
722
if (m_bSphereHole || m_bSphereHoleRDF || m_bSphereHole2DF || m_bHoleDump || m_bSphereHoleRDF)
726
Build(ts,false,false);
731
for (z=0;z<m_oaDelaunayTetrahedra.GetSize();z++)
733
dt = (CDelaunayTetrahedron*)m_oaDelaunayTetrahedra[z];
734
m_pSphereHoleDF->AddToBin(dt->m_fRadius*2.0);
736
if (dt->m_fRadius > 250.0)
737
tva.Add(dt->m_vCenter);
741
if (m_bSphereHoleRDF)
743
for (z=0;z<m_oaDelaunayTetrahedra.GetSize();z++)
745
dt = (CDelaunayTetrahedron*)m_oaDelaunayTetrahedra[z];
747
for (z2=z+1;z2<m_oaDelaunayTetrahedra.GetSize();z2++)
749
dt2 = (CDelaunayTetrahedron*)m_oaDelaunayTetrahedra[z2];
751
tf = FoldVector(dt->m_vCenter - dt2->m_vCenter).GetLength();
753
m_pSphereHoleRDF->AddToBin(tf);
758
if (m_bSphereHole2DF)
760
tfx = 1.0 / m_pSphereHole2DF->m_iRes[1] * (m_pSphereHole2DF->m_fMaxVal[1]-m_pSphereHole2DF->m_fMinVal[1]);
762
for (z2=0;z2<m_oaDelaunayTetrahedra.GetSize();z2++)
764
dt = (CDelaunayTetrahedron*)m_oaDelaunayTetrahedra[z2];
766
for (z3=z2+1;z3<m_oaDelaunayTetrahedra.GetSize();z3++)
768
dt2 = (CDelaunayTetrahedron*)m_oaDelaunayTetrahedra[z3];
770
tf2 = FoldVector(dt->m_vCenter - dt2->m_vCenter).GetLength();
772
tf = m_pSphereHole2DF->m_fMinVal[1];
774
for (z=0;z<m_pSphereHole2DF->m_iRes[1];z++)
778
if (dt->m_fRadius < tf)
781
if (dt2->m_fRadius < tf)
784
m_pSphereHole2DFCounter[z]++;
786
m_pSphereHole2DF->AddToBin(tf2,tf);
794
for (z=0;z<g_iGesAtomCount;z++)
796
for (z2=z+1;z2<g_iGesAtomCount;z2++)
798
tf = FoldVector(ts->m_vaCoords[z] - ts->m_vaCoords[z2]).GetLength();
799
m_pAllAtomRDF->AddToBin(tf);
806
mfprintf(m_fHoleDump," %d\n",g_iGesAtomCount+m_iMaxVoroPoints);
807
mfprintf(m_fHoleDump,"\n");
809
for (z=0;z<g_oaMolecules.GetSize();z++)
811
m = (CMolecule*)g_oaMolecules[z];
814
for (z2=0;z2<m->m_laSingleMolIndex.GetSize();z2++)
816
sm = (CSingleMolecule*)g_oaSingleMolecules[m->m_laSingleMolIndex[z2]];
817
for (z3=0;z3<m->m_baAtomIndex.GetSize();z3++)
819
if ((!g_bSaveVirtAtoms) && (m->m_baAtomIndex[z3] == g_iVirtAtomType))
821
for (z4=0;z4<((CxIntArray*)sm->m_oaAtomOffset[z3])->GetSize();z4++)
822
mfprintf(m_fHoleDump," %s %8.5f %8.5f %8.5f\n",((CAtom*)g_oaAtoms[m->m_baAtomIndex[z3]])->m_sName,ts->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][0]/100.0f,ts->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][1]/100.0f,ts->m_vaCoords[((CxIntArray*)sm->m_oaAtomOffset[z3])->GetAt(z4)][2]/100.0f);
828
for (z=0;z<m_oaDelaunayTetrahedra.GetSize();z++)
830
dt = (CDelaunayTetrahedron*)m_oaDelaunayTetrahedra[z];
831
if (dt->m_fRadius > m_fDumpMinHole)
834
mfprintf(m_fHoleDump," He %8.5f %8.5f %8.5f\n",dt->m_vCenter[0]/100.0,dt->m_vCenter[1]/100.0,dt->m_vCenter[2]/100.0);
837
for (z=ti;z<m_iMaxVoroPoints;z++)
838
mfprintf(m_fHoleDump," He %8.5f %8.5f %8.5f\n",ts->m_vaCoords[0][0]/100.0f,ts->m_vaCoords[0][1]/100.0f,ts->m_vaCoords[0][2]/100.0f);
843
void CVoroAnalysis::Finish()
851
m_pSphereHoleDF->NormBinIntegral(100000.0);
852
m_pSphereHoleDF->Write("","sphere_hole_df.csv","",false);
855
if (m_bSphereHoleRDF)
857
m_pSphereHoleRDF->CorrectRadialDist();
858
m_pSphereHoleRDF->MultiplyBin(g_fBoxX*g_fBoxY*g_fBoxZ / (4.0/3.0*Pi) / (m_pSphereHoleRDF->m_fBinEntries+m_pSphereHoleRDF->m_fSkipEntries));
859
m_pSphereHoleRDF->Write("","sphere_hole_rdf.csv","",false);
862
if (m_bSphereHole2DF)
864
m_pSphereHole2DF->CorrectRadialDist(0);
865
for (z=0;z<m_pSphereHole2DF->m_iRes[1];z++)
867
if (m_pSphereHole2DFCounter[z] != 0)
869
for (z2=0;z2<m_pSphereHole2DF->m_iRes[0];z2++)
870
m_pSphereHole2DF->m_pBin[z2+m_pSphereHole2DF->m_iRes[0]*z] *= 10000.0 / m_pSphereHole2DFCounter[z];
873
m_pSphereHole2DF->Log();
874
// m_pSphereHoleRDF->MultiplyBin(g_fBoxX*g_fBoxY*g_fBoxZ / (4.0/3.0*Pi) / (m_pSphereHoleRDF->m_fBinEntries+m_pSphereHoleRDF->m_fSkipEntries));
875
m_pSphereHole2DF->WriteMathematicaNb("","sphere_hole_2df.nb","",false);
876
m_pSphereHole2DF->WriteGnuplotInput("","sphere_hole_2df","",false);
881
m_pAllAtomRDF->CorrectRadialDist();
882
m_pAllAtomRDF->MultiplyBin(g_fBoxX*g_fBoxY*g_fBoxZ / (4.0/3.0*Pi) / g_iSteps / g_iGesAtomCount / g_iGesAtomCount * 2.0 * g_iStride);
883
m_pAllAtomRDF->Write("","all_atom_rdf.csv","",false);
891
if (m_bEmptySpaceSDF)
893
mprintf(WHITE,"*** Empty Space SDF ***\n");
894
m_pEmptySpaceSDF->m_pSDF->MultiplyBin(pow(m_pEmptySpaceSDF->m_iResolution/m_pEmptySpaceSDF->m_fRadius*1000.0,3) / (double)g_iSteps / ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() * (g_bDoubleBox?g_iDoubleBoxFactor:1));
895
for (z2=0;z2<=g_iSDFSmoothGrade;z2++)
897
try { tempSDF = new C3DF(); } catch(...) { tempSDF = NULL; }
898
if (tempSDF == NULL) NewException((double)sizeof(C3DF),__FILE__,__LINE__,__PRETTY_FUNCTION__);
900
tempSDF->CopyFrom(m_pEmptySpaceSDF->m_pSDF);
904
sprintf(buf,".s%d.plt",z2);
905
} else sprintf(buf,".plt");
906
mprintf(" Saving SDF as \"sdf_emptyspace%s\"...\n",buf);
907
tempSDF->WritePLT("sdf_","emptyspace",buf,true);
910
sprintf(buf,".s%d.cube",z2);
911
else sprintf(buf,".cube");
912
mprintf(" Saving SDF as \"sdf_emptyspace%s\"...\n",buf);
913
tempSDF->WriteCube("sdf_","emptyspace",buf,true);
917
if (m_bSphereHoleSDF)
919
mprintf(WHITE,"*** Spherical Hole SDF ***\n");
920
m_pSphereHoleSDF->m_pSDF->MultiplyBin(pow(m_pSphereHoleSDF->m_iResolution/m_pSphereHoleSDF->m_fRadius*1000.0,3) / (double)g_iSteps / ((CMolecule*)g_oaMolecules[g_iFixMol])->m_laSingleMolIndex.GetSize() * (g_bDoubleBox?g_iDoubleBoxFactor:1));
921
for (z2=0;z2<=g_iSDFSmoothGrade;z2++)
923
try { tempSDF = new C3DF(); } catch(...) { tempSDF = NULL; }
924
if (tempSDF == NULL) NewException((double)sizeof(C3DF),__FILE__,__LINE__,__PRETTY_FUNCTION__);
926
tempSDF->CopyFrom(m_pSphereHoleSDF->m_pSDF);
930
sprintf(buf,".s%d.plt",z2);
931
} else sprintf(buf,".plt");
932
mprintf(" Saving SDF as \"sdf_spherehole%s\"...\n",buf);
933
tempSDF->WritePLT("sdf_","spherehole",buf,true);
936
sprintf(buf,".s%d.cube",z2);
937
else sprintf(buf,".cube");
938
mprintf(" Saving SDF as \"sdf_spherehole%s\"...\n",buf);
939
tempSDF->WriteCube("sdf_","spherehole",buf,true);
945
void CVoroAnalysis::Clean()
949
for (z=0;z<m_oaDelaunayPoints.GetSize();z++)
950
delete (CDelaunayPoint*)m_oaDelaunayPoints[z];
951
m_oaDelaunayPoints.RemoveAll_KeepSize();
953
for (z=0;z<m_oaDelaunayTetrahedra.GetSize();z++)
954
delete (CDelaunayTetrahedron*)m_oaDelaunayTetrahedra[z];
955
m_oaDelaunayTetrahedra.RemoveAll_KeepSize();
957
for (z=0;z<m_oaVoroCells.GetSize();z++)
958
delete (CVoroCell*)m_oaVoroCells[z];
959
m_oaVoroCells.RemoveAll_KeepSize();
961
for (z=0;z<m_oaVoroPoints.GetSize();z++)
962
delete (CVoroPoint*)m_oaVoroPoints[z];
963
m_oaVoroPoints.RemoveAll_KeepSize();
967
void CVoroAnalysis::BinEmptySDF()
969
int x, y, z, ti, ti2, ti3;
971
for (z=m_iEmptySpaceBorder;z<m_pTempSDF->m_iRes[2]-m_iEmptySpaceBorder;z++)
973
ti = z*m_pTempSDF->m_iResXY;
974
for (y=m_iEmptySpaceBorder;y<m_pTempSDF->m_iRes[1]-m_iEmptySpaceBorder;y++)
976
ti2 = ti + y * m_pTempSDF->m_iRes[0];
977
for (x=m_iEmptySpaceBorder;x<m_pTempSDF->m_iRes[0]-m_iEmptySpaceBorder;x++)
980
if (m_pTempSDF->m_pBin[ti3] == 0)
981
m_pEmptySpaceSDF->m_pSDF->m_pBin[ti3]++;
988
void CVoroAnalysis::BinEmptySDF_New(CxMatrix3 *m, CxVector3 *c)
990
int x, y, z, ti, ti2, ti3;
993
for (z=0;z<m_pEmptySpaceSDF->m_pSDF->m_iRes[2];z++)
995
ti = z*m_pEmptySpaceSDF->m_pSDF->m_iResXY;
996
v[2] = ((double)z)/m_pEmptySpaceSDF->m_pSDF->m_iRes[2]*(m_pEmptySpaceSDF->m_pSDF->m_fMaxVal[2]-m_pEmptySpaceSDF->m_pSDF->m_fMinVal[2])+m_pEmptySpaceSDF->m_pSDF->m_fMinVal[2] + (*c)[2];
997
for (y=0;y<m_pEmptySpaceSDF->m_pSDF->m_iRes[1];y++)
999
ti2 = ti + y * m_pEmptySpaceSDF->m_pSDF->m_iRes[0];
1000
v[1] = ((double)y)/m_pEmptySpaceSDF->m_pSDF->m_iRes[1]*(m_pEmptySpaceSDF->m_pSDF->m_fMaxVal[1]-m_pEmptySpaceSDF->m_pSDF->m_fMinVal[1])+m_pEmptySpaceSDF->m_pSDF->m_fMinVal[1] + (*c)[1];
1001
for (x=0;x<m_pEmptySpaceSDF->m_pSDF->m_iRes[0];x++)
1004
v[0] = ((double)x)/m_pEmptySpaceSDF->m_pSDF->m_iRes[0]*(m_pEmptySpaceSDF->m_pSDF->m_fMaxVal[0]-m_pEmptySpaceSDF->m_pSDF->m_fMinVal[0])+m_pEmptySpaceSDF->m_pSDF->m_fMinVal[0] + (*c)[0];
1008
// mprintf(" %f %f %f --> %f %f %f\n",v[0],v[1],v[2],v2[0],v2[1],v2[2]);
1010
while (v2[0] >= g_fBoxX)
1014
while (v2[1] >= g_fBoxY)
1018
while (v2[2] >= g_fBoxZ)
1023
// mprintf(" %f %f %f\n",v2[0],v2[1],v2[2]);
1025
if (m_pTempSDF->IsZero(v2[0],v2[1],v2[2]))
1026
m_pEmptySpaceSDF->m_pSDF->m_pBin[ti3]++;
1030
// m_pEmptySpaceSDF->m_pSDF->WritePLT("","bla2.plt","",true);
1035
void CVoroAnalysis::BinSphereHoleSDF(CxMatrix3 *m, CxVector3 *c)
1038
CDelaunayTetrahedron *dt;
1041
m_pTempVA->RemoveAll_KeepSize();
1043
for (z=0;z<m_oaDelaunayTetrahedra.GetSize();z++)
1045
dt = (CDelaunayTetrahedron*)m_oaDelaunayTetrahedra[z];
1046
vec = dt->m_vCenter - *c;
1048
while (vec[0] < -g_fBoxX/2.0) vec[0] += g_fBoxX;
1049
while (vec[0] >= g_fBoxX/2.0) vec[0] -= g_fBoxX;
1050
while (vec[1] < -g_fBoxY/2.0) vec[1] += g_fBoxY;
1051
while (vec[1] >= g_fBoxY/2.0) vec[1] -= g_fBoxY;
1052
while (vec[2] < -g_fBoxZ/2.0) vec[2] += g_fBoxZ;
1053
while (vec[2] >= g_fBoxZ/2.0) vec[2] -= g_fBoxZ;
1055
m_pTempVA->Add(vec);
1058
for (z=0;z<m_oaDelaunayTetrahedra.GetSize();z++)
1060
vec = *m * (*m_pTempVA)[z];
1062
if (m_pSphereHoleSDF->m_bVdWSpheres)
1063
m_pSphereHoleSDF->m_pSDF->AddToBin_Sphere(vec,((CDelaunayTetrahedron*)m_oaDelaunayTetrahedra[z])->m_fRadius);
1064
else m_pSphereHoleSDF->m_pSDF->AddToBin(vec);