-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbackboneOneFrame.py
More file actions
186 lines (124 loc) · 5.62 KB
/
Copy pathbackboneOneFrame.py
File metadata and controls
186 lines (124 loc) · 5.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# -*- coding: utf-8 -*-
"""
Created on Mon May 6 14:20:01 2022
@author: Laura Stricker, laura.stricker@mat.ethz.ch
Routines to calculate elastic backbone for a single particle configuration
by implementing the burning algorithm described in
H J Herrmann et al, J. Phys. A: Math. Gen., 17 L261, 1984
"""
import numpy as np
from importlib import reload
from burningAlgorithm import forwardBurning
from burningAlgorithm import backwardBurning
import Backbone
reload(Backbone)
from Backbone import Backbone
import SimulationBox
reload(SimulationBox)
from SimulationBox import SimulationBox
import Particle
reload(Particle)
from Particle import Particle
import Point
reload(Point)
from Point import Point
import DataManager
reload(DataManager)
from DataManager import DataManager
from myEnum import enum
CLUSTER_ID = enum(LARGEST_CLUSTER = 1)
def findClosestParticleToPoint(particles,pointP):
'''Function that finds the minimum distance between pointP and all
particles contained in a list'''
particleDistancesToPoint = np.asarray([p.distanceToPoint(pointP) for p in particles])
# Get the index (not the ID) of particle with smallest distance to pointP
indexClosestParticleToPoint= np.argmin(particleDistancesToPoint)
closestParticleToPoint = particles[indexClosestParticleToPoint]
return closestParticleToPoint
def findBurningAlgorithmExtremes(box,particles,parameters,backbone):
'''
Find the particles P1,P2 to use as initial and final point for the
burning algorithm
Parameters
----------
box : OBJECT(SimulationBox)
particles : ARRAY of OBJECTS(Particle) = particles of the largest cluster
parameters: OBJECT(Parameters)
Returns
-------
backboneExtremeParticles : array(2,OBJECT(Particle))
'''
box.findNodes()
if parameters.useConstantBoxNodesForBackboneExtremes():
#Box can change size but the box node pair reamins constant
box.defineFixedNodesToSetBackboneExtremes(parameters)
fixedBoxNodes = box.fixedNodePair
#Find the closest particles to the two fixed box vertices
backboneExtremes = np.asarray([findClosestParticleToPoint(particles,node) for node in fixedBoxNodes])
else:
#Find closer particles to box nodes (one per node)
closestParticlesToNodes = [findClosestParticleToPoint(particles,node) for node in box.nodes]
#Find particle pair further apart
particleDistanceMax = 0.
for index1, particle1 in enumerate(closestParticlesToNodes):
for particle2 in closestParticlesToNodes[index1+1:]:
particleDistance = particle1.distanceToParticle(particle2)
if particleDistance > particleDistanceMax:
particleDistanceMax = particleDistance
backboneExtremes = np.asarray([particle1,particle2])
backbone.extremes = backboneExtremes
backbone.calculateLinearDistanceBetweenExtremes()
def calculateBackboneOneFrame(fileNamesIO,time,timeIndex,parameters):
'''
It calculates the elastic backbone for a single particle configuration,
corresponding to a single time instant, provided by a .dat file.
Parameters
----------
nameFilesIO : OBJECT(NameFilesIO)
it contains names of input/output files and the bare name.
parameters : OBJECT(Parameter)
time : FLOAT
timeIndex : INT
Returns
-------
backbone = OBJECT(Backbone)
summary of general info on backbone for one time instant
Input file
----------
File with an instantaneous particle configuration, with the data structure:
Number of particles
[empty line]
particleID particleType positionX positionY positionZ particleVoronoiVolume clusterID numberOfNeighbours listOfNeighbourIDs(variable length)
particleID particleType positionX positionY positionZ particleVoronoiVolume clusterID numberOfNeighbours listOfNeighbourIDs(variable length)
...
Output file
-----------
.xyz file that can be used as input in the Ovito visualization tool
and has the following structure:
numberOfParticle
[empty line]
positionX positionY positionZ chemicalType radius particleForwardBurningTime particleBackwardBurningTime particleID
positionX positionY positionZ chemicalType radius particleForwardBurningTime particleBackwardBurningTime particleID
...
'''
DM = DataManager()
DM.loadDataFromFile(fileNamesIO.input)
#Retain only particles belonging to largest cluster
DM.filterParticlesByClusterID(CLUSTER_ID.LARGEST_CLUSTER)
DM.setParticleRadii(parameters)
#Conversion table: particle ID --> index
DM.buildParticleIndexFromIDlookup()
DM.setParticleIndexes()
#Shift box so that origin coincides with min(x,y,z) of particles
DM.shiftOriginOfAxes()
# CALCULATE ELASTIC BACKBONE
#---------------------------
backbone = Backbone(timeIndex,time,DM.particles)
findBurningAlgorithmExtremes(DM.box,DM.particles,parameters,backbone)
#Find backbone length = min # connected particles and min path between extremes
forwardBurning(DM,backbone)
#Find whole backbone = all equivalent paths between extremes
backwardBurning(DM,backbone)
backbone.checkForErrors()
DM.printXYZFile(DM.particles,fileNamesIO.output)
return backbone