├── .gitignore ├── C180 ├── C180C ├── C180N ├── C180NN ├── C180_original ├── C180_pentahexa ├── C180_pentahexa.csv ├── C180_scaled ├── C180_small ├── CellDiv.blend ├── LICENSE └── jsoncpp ├── License ├── images └── mov.gif ├── inc ├── AdaptiveTimeKernels.cuh ├── VectorFunctions.hpp └── json │ ├── json-forwards.h │ └── json.h ├── inp.dat ├── inp.json ├── makefile ├── notes ├── doc.org └── notes.org ├── readme.md ├── scripts ├── GetPacking.py ├── GetPacking3D.py ├── KinEnergy.py ├── __init__.py ├── celldiv.py ├── cellvel.py ├── center.py ├── cs.py ├── get_gr.py ├── inblender.py ├── make_video.py ├── multibar2.py ├── nn.py ├── oneCell.py ├── plot-many.py ├── plot.py ├── polyprep.py ├── pop.py ├── render.py ├── renim.sh ├── requirements.txt ├── run ├── run-many ├── shaper.py ├── sysmov.py ├── vel.py └── xyzafy.py └── src ├── AdaptiveTimeKernels.cu ├── BondKernels.cu ├── GPUbounce.cu ├── IntegrationKernels.cu ├── IntegrationKernels.h ├── PressureKernels.cu ├── RandomVector.h ├── centermass.cu ├── marsaglia.h ├── postscript.h ├── postscriptinit.cu ├── propagate.cu ├── propagatebound.cu ├── utils └── jsoncpp.cpp └── volume.cu /.gitignore: -------------------------------------------------------------------------------- 1 | *#* 2 | *.o 3 | CellDiv 4 | *~ 5 | psfil 6 | *.xyz* 7 | *.log* 8 | .directory 9 | *.png 10 | *.svg 11 | *.dat 12 | images/* 13 | graphs/* 14 | *traj* 15 | *.avi 16 | *.mp4 17 | *.jpg 18 | *.json 19 | *.gif 20 | *.bdl 21 | ./bin/* 22 | *.bak* 23 | *.gz 24 | *.csv 25 | *.h5 26 | __pycache__ 27 | -------------------------------------------------------------------------------- /C180: -------------------------------------------------------------------------------- 1 | C180_original -------------------------------------------------------------------------------- /C180C: -------------------------------------------------------------------------------- 1 | 1, 65 2 | 1, 2 3 | 1, 5 4 | 2, 71 5 | 2, 3 6 | 3, 77 7 | 3, 4 8 | 4, 83 9 | 4, 5 10 | 5, 89 11 | 6, 95 12 | 6, 10 13 | 6, 7 14 | 7, 66 15 | 7, 8 16 | 8, 88 17 | 8, 9 18 | 9, 101 19 | 9, 10 20 | 10, 107 21 | 11, 113 22 | 11, 15 23 | 11, 12 24 | 12, 70 25 | 12, 13 26 | 13, 64 27 | 13, 14 28 | 14, 94 29 | 14, 15 30 | 15, 119 31 | 16, 125 32 | 16, 20 33 | 16, 17 34 | 17, 76 35 | 17, 18 36 | 18, 72 37 | 18, 19 38 | 19, 112 39 | 19, 20 40 | 20, 131 41 | 21, 137 42 | 21, 22 43 | 21, 25 44 | 22, 82 45 | 22, 23 46 | 23, 78 47 | 23, 24 48 | 24, 124 49 | 24, 25 50 | 25, 143 51 | 26, 102 52 | 26, 30 53 | 26, 27 54 | 27, 90 55 | 27, 28 56 | 28, 84 57 | 28, 29 58 | 29, 136 59 | 29, 30 60 | 30, 149 61 | 31, 155 62 | 31, 32 63 | 31, 35 64 | 32, 161 65 | 32, 33 66 | 33, 167 67 | 33, 34 68 | 34, 173 69 | 34, 35 70 | 35, 179 71 | 36, 126 72 | 36, 37 73 | 36, 40 74 | 37, 130 75 | 37, 38 76 | 38, 160 77 | 38, 39 78 | 39, 154 79 | 39, 40 80 | 40, 142 81 | 41, 114 82 | 41, 45 83 | 41, 42 84 | 42, 118 85 | 42, 43 86 | 43, 166 87 | 43, 44 88 | 44, 162 89 | 44, 45 90 | 45, 132 91 | 46, 96 92 | 46, 47 93 | 46, 50 94 | 47, 106 95 | 47, 48 96 | 48, 172 97 | 48, 49 98 | 49, 168 99 | 49, 50 100 | 50, 120 101 | 51, 100 102 | 51, 55 103 | 51, 52 104 | 52, 148 105 | 52, 53 106 | 53, 178 107 | 53, 54 108 | 54, 174 109 | 54, 55 110 | 55, 108 111 | 56, 138 112 | 56, 57 113 | 56, 60 114 | 57, 144 115 | 57, 58 116 | 58, 156 117 | 58, 59 118 | 59, 180 119 | 59, 60 120 | 60, 150 121 | 61, 65 122 | 61, 64 123 | 61, 67 124 | 62, 66 125 | 62, 64 126 | 62, 91 127 | 63, 66 128 | 63, 65 129 | 63, 85 130 | 67, 71 131 | 67, 70 132 | 68, 70 133 | 68, 72 134 | 68, 109 135 | 69, 72 136 | 69, 71 137 | 69, 73 138 | 73, 76 139 | 73, 77 140 | 74, 78 141 | 74, 76 142 | 74, 121 143 | 75, 77 144 | 75, 78 145 | 75, 79 146 | 79, 83 147 | 79, 82 148 | 80, 82 149 | 80, 84 150 | 80, 133 151 | 81, 83 152 | 81, 84 153 | 81, 87 154 | 85, 89 155 | 85, 88 156 | 86, 90 157 | 86, 88 158 | 86, 99 159 | 87, 89 160 | 87, 90 161 | 91, 94 162 | 91, 95 163 | 92, 94 164 | 92, 96 165 | 92, 117 166 | 93, 96 167 | 93, 95 168 | 93, 103 169 | 97, 101 170 | 97, 100 171 | 97, 105 172 | 98, 100 173 | 98, 102 174 | 98, 145 175 | 99, 102 176 | 99, 101 177 | 103, 107 178 | 103, 106 179 | 104, 106 180 | 104, 108 181 | 104, 170 182 | 105, 107 183 | 105, 108 184 | 109, 112 185 | 109, 113 186 | 110, 112 187 | 110, 114 188 | 110, 129 189 | 111, 113 190 | 111, 114 191 | 111, 115 192 | 115, 119 193 | 115, 118 194 | 116, 118 195 | 116, 120 196 | 116, 164 197 | 117, 119 198 | 117, 120 199 | 121, 125 200 | 121, 124 201 | 122, 126 202 | 122, 124 203 | 122, 139 204 | 123, 126 205 | 123, 125 206 | 123, 127 207 | 127, 131 208 | 127, 130 209 | 128, 132 210 | 128, 130 211 | 128, 158 212 | 129, 131 213 | 129, 132 214 | 133, 137 215 | 133, 136 216 | 134, 138 217 | 134, 136 218 | 134, 147 219 | 135, 138 220 | 135, 137 221 | 135, 141 222 | 139, 143 223 | 139, 142 224 | 140, 144 225 | 140, 142 226 | 140, 152 227 | 141, 143 228 | 141, 144 229 | 145, 149 230 | 145, 148 231 | 146, 148 232 | 146, 150 233 | 146, 176 234 | 147, 150 235 | 147, 149 236 | 151, 154 237 | 151, 155 238 | 151, 157 239 | 152, 154 240 | 152, 156 241 | 153, 155 242 | 153, 156 243 | 153, 177 244 | 157, 160 245 | 157, 161 246 | 158, 162 247 | 158, 160 248 | 159, 161 249 | 159, 162 250 | 159, 163 251 | 163, 167 252 | 163, 166 253 | 164, 166 254 | 164, 168 255 | 165, 167 256 | 165, 168 257 | 165, 169 258 | 169, 173 259 | 169, 172 260 | 170, 172 261 | 170, 174 262 | 171, 173 263 | 171, 174 264 | 171, 175 265 | 175, 178 266 | 175, 179 267 | 176, 180 268 | 176, 178 269 | 177, 179 270 | 177, 180 271 | -------------------------------------------------------------------------------- /C180N: -------------------------------------------------------------------------------- 1 | 65, 2, 5 2 | 71, 3, 1 3 | 77, 4, 2 4 | 83, 5, 3 5 | 89, 4, 1 6 | 95, 10, 7 7 | 66, 8, 6 8 | 88, 7, 9 9 | 101, 10, 8 10 | 107, 9, 6 11 | 113, 15, 12 12 | 70, 13, 11 13 | 64, 12, 14 14 | 94, 15, 13 15 | 119, 11, 14 16 | 125, 20, 17 17 | 76, 18, 16 18 | 72, 17, 19 19 | 112, 20, 18 20 | 131, 16, 19 21 | 137, 22, 25 22 | 82, 23, 21 23 | 78, 22, 24 24 | 124, 25, 23 25 | 143, 24, 21 26 | 102, 30, 27 27 | 90, 28, 26 28 | 84, 27, 29 29 | 136, 30, 28 30 | 149, 26, 29 31 | 155, 32, 35 32 | 161, 31, 33 33 | 167, 34, 32 34 | 173, 33, 35 35 | 179, 34, 31 36 | 126, 37, 40 37 | 130, 36, 38 38 | 160, 37, 39 39 | 154, 40, 38 40 | 142, 39, 36 41 | 114, 45, 42 42 | 118, 43, 41 43 | 166, 44, 42 44 | 162, 43, 45 45 | 132, 44, 41 46 | 96, 47, 50 47 | 106, 46, 48 48 | 172, 49, 47 49 | 168, 50, 48 50 | 120, 49, 46 51 | 100, 55, 52 52 | 148, 51, 53 53 | 178, 54, 52 54 | 174, 55, 53 55 | 108, 51, 54 56 | 138, 57, 60 57 | 144, 58, 56 58 | 156, 57, 59 59 | 180, 58, 60 60 | 150, 56, 59 61 | 65, 64, 67 62 | 66, 64, 91 63 | 66, 65, 85 64 | 13, 62, 61 65 | 1, 63, 61 66 | 7, 63, 62 67 | 71, 70, 61 68 | 70, 72, 109 69 | 72, 71, 73 70 | 12, 68, 67 71 | 2, 69, 67 72 | 18, 69, 68 73 | 76, 77, 69 74 | 78, 76, 121 75 | 77, 78, 79 76 | 17, 74, 73 77 | 3, 75, 73 78 | 23, 74, 75 79 | 83, 82, 75 80 | 82, 84, 133 81 | 83, 84, 87 82 | 22, 80, 79 83 | 4, 81, 79 84 | 28, 81, 80 85 | 89, 88, 63 86 | 90, 88, 99 87 | 89, 90, 81 88 | 8, 86, 85 89 | 5, 87, 85 90 | 27, 86, 87 91 | 94, 95, 62 92 | 94, 96, 117 93 | 96, 95, 103 94 | 14, 91, 92 95 | 6, 93, 91 96 | 46, 93, 92 97 | 101, 100, 105 98 | 100, 102, 145 99 | 102, 101, 86 100 | 51, 98, 97 101 | 9, 99, 97 102 | 26, 99, 98 103 | 107, 106, 93 104 | 106, 108, 170 105 | 107, 108, 97 106 | 47, 104, 103 107 | 10, 105, 103 108 | 55, 105, 104 109 | 112, 113, 68 110 | 112, 114, 129 111 | 113, 114, 115 112 | 19, 109, 110 113 | 11, 111, 109 114 | 41, 111, 110 115 | 119, 118, 111 116 | 118, 120, 164 117 | 119, 120, 92 118 | 42, 116, 115 119 | 15, 117, 115 120 | 50, 117, 116 121 | 125, 124, 74 122 | 126, 124, 139 123 | 126, 125, 127 124 | 24, 122, 121 125 | 16, 121, 123 126 | 36, 122, 123 127 | 131, 130, 123 128 | 132, 130, 158 129 | 131, 132, 110 130 | 37, 128, 127 131 | 20, 129, 127 132 | 45, 129, 128 133 | 137, 136, 80 134 | 138, 136, 147 135 | 138, 137, 141 136 | 29, 134, 133 137 | 21, 133, 135 138 | 56, 135, 134 139 | 143, 142, 122 140 | 144, 142, 152 141 | 143, 144, 135 142 | 40, 140, 139 143 | 25, 141, 139 144 | 57, 141, 140 145 | 149, 148, 98 146 | 148, 150, 176 147 | 150, 149, 134 148 | 52, 146, 145 149 | 30, 147, 145 150 | 60, 147, 146 151 | 154, 155, 157 152 | 154, 156, 140 153 | 155, 156, 177 154 | 39, 152, 151 155 | 31, 153, 151 156 | 58, 153, 152 157 | 160, 161, 151 158 | 162, 160, 128 159 | 161, 162, 163 160 | 38, 157, 158 161 | 32, 159, 157 162 | 44, 159, 158 163 | 167, 166, 159 164 | 166, 168, 116 165 | 167, 168, 169 166 | 43, 164, 163 167 | 33, 165, 163 168 | 49, 165, 164 169 | 173, 172, 165 170 | 172, 174, 104 171 | 173, 174, 175 172 | 48, 170, 169 173 | 34, 171, 169 174 | 54, 171, 170 175 | 178, 179, 171 176 | 180, 178, 146 177 | 179, 180, 153 178 | 53, 176, 175 179 | 35, 177, 175 180 | 59, 176, 177 181 | -------------------------------------------------------------------------------- /C180NN: -------------------------------------------------------------------------------- 1 | 65, 2, 5, 1 2 | 71, 3, 1, 1 3 | 77, 4, 2, 1 4 | 83, 5, 3, 1 5 | 89, 4, 1, -1 6 | 95, 10, 7, -1 7 | 66, 8, 6, 1 8 | 88, 7, 9, -1 9 | 101, 10, 8, 1 10 | 107, 9, 6, -1 11 | 113, 15, 12, -1 12 | 70, 13, 11, 1 13 | 64, 12, 14, -1 14 | 94, 15, 13, 1 15 | 119, 11, 14, 1 16 | 125, 20, 17, -1 17 | 76, 18, 16, 1 18 | 72, 17, 19, -1 19 | 112, 20, 18, 1 20 | 131, 16, 19, 1 21 | 137, 22, 25, 1 22 | 82, 23, 21, 1 23 | 78, 22, 24, -1 24 | 124, 25, 23, 1 25 | 143, 24, 21, -1 26 | 102, 30, 27, -1 27 | 90, 28, 26, 1 28 | 84, 27, 29, -1 29 | 136, 30, 28, 1 30 | 149, 26, 29, 1 31 | 155, 32, 35, 1 32 | 161, 31, 33, -1 33 | 167, 34, 32, 1 34 | 173, 33, 35, -1 35 | 179, 34, 31, -1 36 | 126, 37, 40, 1 37 | 130, 36, 38, -1 38 | 160, 37, 39, -1 39 | 154, 40, 38, 1 40 | 142, 39, 36, -1 41 | 114, 45, 42, -1 42 | 118, 43, 41, 1 43 | 166, 44, 42, 1 44 | 162, 43, 45, -1 45 | 132, 44, 41, -1 46 | 96, 47, 50, 1 47 | 106, 46, 48, -1 48 | 172, 49, 47, 1 49 | 168, 50, 48, 1 50 | 120, 49, 46, -1 51 | 100, 55, 52, -1 52 | 148, 51, 53, -1 53 | 178, 54, 52, 1 54 | 174, 55, 53, 1 55 | 108, 51, 54, 1 56 | 138, 57, 60, 1 57 | 144, 58, 56, 1 58 | 156, 57, 59, -1 59 | 180, 58, 60, -1 60 | 150, 56, 59, 1 61 | 65, 64, 67, 1 62 | 66, 64, 91, -1 63 | 66, 65, 85, 1 64 | 13, 62, 61, -1 65 | 1, 63, 61, 1 66 | 7, 63, 62, -1 67 | 71, 70, 61, -1 68 | 70, 72, 109, -1 69 | 72, 71, 73, -1 70 | 12, 68, 67, 1 71 | 2, 69, 67, -1 72 | 18, 69, 68, 1 73 | 76, 77, 69, 1 74 | 78, 76, 121, 1 75 | 77, 78, 79, 1 76 | 17, 74, 73, 1 77 | 3, 75, 73, -1 78 | 23, 74, 75, -1 79 | 83, 82, 75, -1 80 | 82, 84, 133, -1 81 | 83, 84, 87, 1 82 | 22, 80, 79, 1 83 | 4, 81, 79, -1 84 | 28, 81, 80, 1 85 | 89, 88, 63, 1 86 | 90, 88, 99, -1 87 | 89, 90, 81, -1 88 | 8, 86, 85, -1 89 | 5, 87, 85, 1 90 | 27, 86, 87, 1 91 | 94, 95, 62, -1 92 | 94, 96, 117, 1 93 | 96, 95, 103, 1 94 | 14, 91, 92, 1 95 | 6, 93, 91, 1 96 | 46, 93, 92, -1 97 | 101, 100, 105, 1 98 | 100, 102, 145, 1 99 | 102, 101, 86, 1 100 | 51, 98, 97, -1 101 | 9, 99, 97, 1 102 | 26, 99, 98, -1 103 | 107, 106, 93, 1 104 | 106, 108, 170, 1 105 | 107, 108, 97, -1 106 | 47, 104, 103, -1 107 | 10, 105, 103, 1 108 | 55, 105, 104, -1 109 | 112, 113, 68, -1 110 | 112, 114, 129, 1 111 | 113, 114, 115, -1 112 | 19, 109, 110, 1 113 | 11, 111, 109, 1 114 | 41, 111, 110, -1 115 | 119, 118, 111, 1 116 | 118, 120, 164, 1 117 | 119, 120, 92, -1 118 | 42, 116, 115, -1 119 | 15, 117, 115, 1 120 | 50, 117, 116, -1 121 | 125, 124, 74, 1 122 | 126, 124, 139, -1 123 | 126, 125, 127, 1 124 | 24, 122, 121, -1 125 | 16, 121, 123, -1 126 | 36, 122, 123, 1 127 | 131, 130, 123, 1 128 | 132, 130, 158, -1 129 | 131, 132, 110, -1 130 | 37, 128, 127, -1 131 | 20, 129, 127, 1 132 | 45, 129, 128, -1 133 | 137, 136, 80, 1 134 | 138, 136, 147, -1 135 | 138, 137, 141, 1 136 | 29, 134, 133, -1 137 | 21, 133, 135, -1 138 | 56, 135, 134, -1 139 | 143, 142, 122, -1 140 | 144, 142, 152, 1 141 | 143, 144, 135, 1 142 | 40, 140, 139, 1 143 | 25, 141, 139, -1 144 | 57, 141, 140, 1 145 | 149, 148, 98, 1 146 | 148, 150, 176, 1 147 | 150, 149, 134, 1 148 | 52, 146, 145, -1 149 | 30, 147, 145, 1 150 | 60, 147, 146, -1 151 | 154, 155, 157, -1 152 | 154, 156, 140, 1 153 | 155, 156, 177, -1 154 | 39, 152, 151, -1 155 | 31, 153, 151, 1 156 | 58, 153, 152, -1 157 | 160, 161, 151, 1 158 | 162, 160, 128, 1 159 | 161, 162, 163, 1 160 | 38, 157, 158, -1 161 | 32, 159, 157, -1 162 | 44, 159, 158, 1 163 | 167, 166, 159, -1 164 | 166, 168, 116, -1 165 | 167, 168, 169, 1 166 | 43, 164, 163, 1 167 | 33, 165, 163, -1 168 | 49, 165, 164, 1 169 | 173, 172, 165, -1 170 | 172, 174, 104, -1 171 | 173, 174, 175, 1 172 | 48, 170, 169, 1 173 | 34, 171, 169, -1 174 | 54, 171, 170, 1 175 | 178, 179, 171, 1 176 | 180, 178, 146, 1 177 | 179, 180, 153, 1 178 | 53, 176, 175, 1 179 | 35, 177, 175, -1 180 | 59, 176, 177, -1 181 | -------------------------------------------------------------------------------- /C180_original: -------------------------------------------------------------------------------- 1 | 0.57739204 0.05633295 -0.0410812 2 | 0.57653313 -0.0733663 -0.0161388 3 | 0.55011194 -0.1362060 -0.1292346 4 | 0.53490716 -0.0454745 -0.2238444 5 | 0.55181258 0.07356430 -0.1695187 6 | 0.27670684 0.49737805 0.12046405 7 | 0.37433257 0.44206211 0.05086653 8 | 0.34874680 0.45921531 -0.0774766 9 | 0.23468291 0.52492821 -0.0871206 10 | 0.19031445 0.54880058 0.03489254 11 | 0.32798001 -0.0183981 0.48045688 12 | 0.42635071 0.00625218 0.39577812 13 | 0.42691278 0.13594058 0.37087607 14 | 0.32887339 0.19092145 0.44023913 15 | 0.26792183 0.09569949 0.50826990 16 | 0.22880853 -0.5222836 0.11380905 17 | 0.34346049 -0.4584240 0.09916477 18 | 0.36994057 -0.3956934 0.21228413 19 | 0.27158209 -0.4207549 0.29676538 20 | 0.18445558 -0.4991340 0.23596634 21 | 0.11679944 -0.3180885 -0.4732244 22 | 0.24096338 -0.3106514 -0.4288400 23 | 0.25665297 -0.4014163 -0.3343740 24 | 0.14173854 -0.4647304 -0.3199587 25 | 0.05549399 -0.4136886 -0.4057794 26 | 0.14587238 0.31204256 -0.4693995 27 | 0.25990328 0.24609321 -0.4591514 28 | 0.24344301 0.12709510 -0.5138576 29 | 0.11910468 0.11976362 -0.5575627 30 | 0.05892022 0.23399654 -0.5305523 31 | -0.5770567 -0.0561225 0.04143426 32 | -0.5515612 -0.0733926 0.16971431 33 | -0.5347779 0.04592257 0.22368060 34 | -0.5503894 0.13665568 0.12911537 35 | -0.5766050 0.07358276 0.01613119 36 | -0.1902882 -0.5481672 -0.0343309 37 | -0.2348429 -0.5248464 0.08770123 38 | -0.3486541 -0.4587868 0.07740201 39 | -0.3739593 -0.4414872 -0.0510691 40 | -0.2762848 -0.4969742 -0.1203679 41 | -0.0592086 -0.2340335 0.52983391 42 | -0.1192393 -0.1195187 0.55687350 43 | -0.2435014 -0.1275387 0.51282245 44 | -0.2599192 -0.2467806 0.45892071 45 | -0.1462074 -0.3127577 0.46943134 46 | -0.0555872 0.41356507 0.40556347 47 | -0.1417689 0.46484795 0.31976062 48 | -0.2562453 0.40065804 0.33459276 49 | -0.2404859 0.31028649 0.42941600 50 | -0.1164831 0.31819924 0.47361111 51 | -0.1843935 0.49855265 -0.2352140 52 | -0.2711941 0.42014101 -0.2964799 53 | -0.3695104 0.39553722 -0.2117023 54 | -0.3435596 0.45878580 -0.0987990 55 | -0.2290664 0.52260208 -0.1134010 56 | -0.2680223 -0.0959253 -0.5078237 57 | -0.3294682 -0.1911775 -0.4402260 58 | -0.4273427 -0.1359743 -0.3712919 59 | -0.4265951 -0.0063819 -0.3963268 60 | -0.3280867 0.01853977 -0.4807863 61 | 0.54306369 0.10340639 0.17834316 62 | 0.43288355 0.31314626 0.22837293 63 | 0.51481950 0.26995602 0.00442364 64 | 0.48158359 0.19044324 0.26428032 65 | 0.55976497 0.14926147 0.05048331 66 | 0.45461314 0.34914747 0.09819768 67 | 0.54238116 -0.0357247 0.20503033 68 | 0.43018317 -0.2109881 0.32950002 69 | 0.51178365 -0.2541381 0.10548291 70 | 0.48033586 -0.0843043 0.31701809 71 | 0.55824416 -0.1256652 0.10314869 72 | 0.45123183 -0.2926655 0.22172980 73 | 0.48354655 -0.3216862 -0.0156895 74 | 0.32400706 -0.4654699 -0.1276172 75 | 0.43660047 -0.2904266 -0.2511792 76 | 0.39516645 -0.4261995 -0.0176202 77 | 0.50270604 -0.2588601 -0.1357609 78 | 0.35055103 -0.3963192 -0.2425532 79 | 0.41994500 -0.1931775 -0.3527888 80 | 0.26146975 -0.0991541 -0.5102176 81 | 0.42145061 0.04461887 -0.3988917 82 | 0.31746211 -0.2043519 -0.4428791 83 | 0.47018775 -0.0669589 -0.3365524 84 | 0.31901109 0.02282804 -0.4869495 85 | 0.48730847 0.28808584 -0.1332540 86 | 0.32878091 0.38192120 -0.2904507 87 | 0.43934005 0.17240885 -0.3404992 88 | 0.39998280 0.38544938 -0.1736710 89 | 0.50554865 0.18525248 -0.2215782 90 | 0.35413604 0.27476486 -0.3716861 91 | 0.32800766 0.37208411 0.30294549 92 | 0.14751440 0.32674607 0.45846653 93 | 0.11914364 0.49310153 0.28442561 94 | 0.27440327 0.30731025 0.41095608 95 | 0.24732687 0.46621629 0.24494519 96 | 0.07513534 0.42277667 0.39311689 97 | 0.02692829 0.55400329 -0.1739392 98 | -0.0212260 0.43825557 -0.3815883 99 | 0.20662738 0.45246830 -0.3012294 100 | -0.0585461 0.51081746 -0.2718362 101 | 0.15901882 0.52442109 -0.1950197 102 | 0.11299938 0.41420629 -0.3930825 103 | 0.02680485 0.54818058 0.19221450 104 | -0.2011199 0.53390914 0.11158646 105 | -0.0206381 0.57959097 -0.0431050 106 | -0.1076579 0.53125924 0.21135968 107 | 0.06467390 0.57498163 0.06355069 108 | -0.1528599 0.56132769 -0.0134899 109 | 0.32476895 -0.2377611 0.42002368 110 | 0.11431169 -0.3545541 0.44743806 111 | 0.14539424 -0.1359933 0.54706376 112 | 0.24271741 -0.3456107 0.40097749 113 | 0.27236562 -0.1368078 0.49617016 114 | 0.07140064 -0.2482635 0.52219492 115 | 0.08100255 -0.0134167 0.57641536 116 | -0.1280604 0.10752348 0.55733561 117 | 0.08223656 0.22439581 0.53109258 118 | -0.0556604 -0.0064225 0.57965827 119 | 0.14515818 0.10538850 0.55459183 120 | -0.0542921 0.22086727 0.53643101 121 | 0.20113602 -0.5337637 -0.1114924 122 | -0.0268917 -0.5478717 -0.1919443 123 | 0.02054291 -0.5793841 0.04369718 124 | 0.10756016 -0.5310509 -0.2114113 125 | 0.15274821 -0.5610679 0.01352507 126 | -0.0646150 -0.5744999 -0.0632001 127 | -0.0269997 -0.5541299 0.17463564 128 | -0.2066692 -0.4527540 0.30163353 129 | 0.02128922 -0.4390040 0.38208371 130 | -0.1591048 -0.5246981 0.19534689 131 | 0.05864420 -0.5115001 0.27238172 132 | -0.1127635 -0.4148302 0.39357978 133 | 0.12819993 -0.1073960 -0.5573003 134 | -0.0809764 0.01330133 -0.5764700 135 | -0.0822903 -0.2246617 -0.5306891 136 | 0.05571488 0.00655771 -0.5798639 137 | 0.05435557 -0.2206221 -0.5361146 138 | -0.1451109 -0.1055207 -0.5542358 139 | -0.1190991 -0.4928269 -0.2842391 140 | -0.3280676 -0.3717062 -0.3031746 141 | -0.1477570 -0.3270266 -0.4582946 142 | -0.2473679 -0.4657185 -0.2449226 143 | -0.0751706 -0.4227919 -0.3932236 144 | -0.2745700 -0.3072505 -0.4112989 145 | -0.1143814 0.35410627 -0.4471372 146 | -0.3249886 0.23716098 -0.4200817 147 | -0.1453854 0.13594046 -0.5472770 148 | -0.2428437 0.34485194 -0.4007411 149 | -0.0715121 0.24823776 -0.5224354 150 | -0.2722071 0.13665244 -0.4964847 151 | -0.5145663 -0.2693261 -0.0043740 152 | -0.4329312 -0.3125352 -0.2286254 153 | -0.5434466 -0.1032149 -0.1785535 154 | -0.4543126 -0.3484846 -0.0983694 155 | -0.5597292 -0.1486870 -0.0506326 156 | -0.4820301 -0.1899937 -0.2645455 157 | -0.4869552 -0.2879562 0.13316637 158 | -0.3288410 -0.3819573 0.29059869 159 | -0.4392454 -0.1723686 0.34037220 160 | -0.3998684 -0.3852309 0.17372574 161 | -0.5053656 -0.1851198 0.22148341 162 | -0.3543347 -0.2748184 0.37168943 163 | -0.4211611 -0.0446045 0.39842158 164 | -0.2612961 0.09920091 0.51000142 165 | -0.4197726 0.19319421 0.35276466 166 | -0.3186347 -0.0227392 0.48636222 167 | -0.4699143 0.06706254 0.33631962 168 | -0.3174164 0.20446965 0.44279563 169 | -0.4363847 0.29038134 0.25113356 170 | -0.3240243 0.46543780 0.12728585 171 | -0.4838922 0.32171157 0.01548010 172 | -0.3501084 0.39619359 0.24231940 173 | -0.5028211 0.25915369 0.13563972 174 | -0.3955879 0.42607197 0.01750620 175 | -0.5118251 0.25416866 -0.1057103 176 | -0.4303677 0.21037066 -0.3295617 177 | -0.5428185 0.03570450 -0.2053688 178 | -0.4508737 0.29246243 -0.2220820 179 | -0.5584785 0.12549588 -0.1034915 180 | -0.4807933 0.08383859 -0.3173441 181 | -------------------------------------------------------------------------------- /C180_pentahexa: -------------------------------------------------------------------------------- 1 | 2 1 0 4 3 2 | 8 9 5 6 7 3 | 13 14 10 11 12 4 | 18 19 15 16 17 5 | 22 21 20 24 23 6 | 28 29 25 26 27 7 | 32 31 30 34 33 8 | 37 36 35 39 38 9 | 43 44 40 41 42 10 | 47 46 45 49 48 11 | 53 54 50 51 52 12 | 57 56 55 59 58 13 | 60 64 0 1 70 66 14 | 62 64 0 4 88 84 15 | 68 70 1 2 76 72 16 | 74 76 2 3 82 78 17 | 80 82 3 4 88 86 18 | 92 94 5 9 106 102 19 | 90 94 5 6 65 61 20 | 62 65 6 7 87 84 21 | 85 87 7 8 100 98 22 | 96 100 8 9 106 104 23 | 110 112 10 14 118 114 24 | 108 112 10 11 69 67 25 | 66 69 11 12 63 60 26 | 61 63 12 13 93 90 27 | 91 93 13 14 118 116 28 | 122 124 15 19 130 126 29 | 120 124 15 16 75 73 30 | 72 75 16 17 71 68 31 | 67 71 17 18 111 108 32 | 109 111 18 19 130 128 33 | 132 136 20 21 81 79 34 | 134 136 20 24 142 140 35 | 78 81 21 22 77 74 36 | 73 77 22 23 123 120 37 | 121 123 23 24 142 138 38 | 97 101 25 29 148 144 39 | 98 101 25 26 89 85 40 | 86 89 26 27 83 80 41 | 79 83 27 28 135 132 42 | 133 135 28 29 148 146 43 | 150 154 30 31 160 156 44 | 152 154 30 34 178 176 45 | 158 160 31 32 166 162 46 | 164 166 32 33 172 168 47 | 170 172 33 34 178 174 48 | 122 125 35 36 129 126 49 | 121 125 35 39 141 138 50 | 127 129 36 37 159 157 51 | 156 159 37 38 153 150 52 | 151 153 38 39 141 139 53 | 109 113 40 44 131 128 54 | 110 113 40 41 117 114 55 | 115 117 41 42 165 163 56 | 162 165 42 43 161 158 57 | 157 161 43 44 131 127 58 | 92 95 45 46 105 102 59 | 91 95 45 49 119 116 60 | 103 105 46 47 171 169 61 | 168 171 47 48 167 164 62 | 163 167 48 49 119 115 63 | 96 99 50 54 107 104 64 | 97 99 50 51 147 144 65 | 145 147 51 52 177 175 66 | 174 177 52 53 173 170 67 | 169 173 53 54 107 103 68 | 134 137 55 56 143 140 69 | 133 137 55 59 149 146 70 | 139 143 56 57 155 151 71 | 152 155 57 58 179 176 72 | 175 179 58 59 149 145 73 | 62 64 60 63 61 65 74 | 68 70 66 69 67 71 75 | 73 75 72 76 74 77 76 | 80 82 78 81 79 83 77 | 86 88 84 87 85 89 78 | 91 93 90 94 92 95 79 | 98 100 96 99 97 101 80 | 104 106 102 105 103 107 81 | 109 111 108 112 110 113 82 | 116 118 114 117 115 119 83 | 122 124 120 123 121 125 84 | 128 130 126 129 127 131 85 | 134 136 132 135 133 137 86 | 140 142 138 141 139 143 87 | 146 148 144 147 145 149 88 | 151 153 150 154 152 155 89 | 157 159 156 160 158 161 90 | 164 166 162 165 163 167 91 | 170 172 168 171 169 173 92 | 175 177 174 178 176 179 93 | -------------------------------------------------------------------------------- /C180_pentahexa.csv: -------------------------------------------------------------------------------- 1 | 2,1,0,4,3 2 | 8,9,5,6,7 3 | 13,14,10,11,12 4 | 18,19,15,16,17 5 | 22,21,20,24,23 6 | 28,29,25,26,27 7 | 32,31,30,34,33 8 | 37,36,35,39,38 9 | 43,44,40,41,42 10 | 47,46,45,49,48 11 | 53,54,50,51,52 12 | 57,56,55,59,58 13 | 60,64,0,1,70,66 14 | 62,64,0,4,88,84 15 | 68,70,1,2,76,72 16 | 74,76,2,3,82,78 17 | 80,82,3,4,88,86 18 | 92,94,5,9,106,102 19 | 90,94,5,6,65,61 20 | 62,65,6,7,87,84 21 | 85,87,7,8,100,98 22 | 96,100,8,9,106,104 23 | 110,112,10,14,118,114 24 | 108,112,10,11,69,67 25 | 66,69,11,12,63,60 26 | 61,63,12,13,93,90 27 | 91,93,13,14,118,116 28 | 122,124,15,19,130,126 29 | 120,124,15,16,75,73 30 | 72,75,16,17,71,68 31 | 67,71,17,18,111,108 32 | 109,111,18,19,130,128 33 | 132,136,20,21,81,79 34 | 134,136,20,24,142,140 35 | 78,81,21,22,77,74 36 | 73,77,22,23,123,120 37 | 121,123,23,24,142,138 38 | 97,101,25,29,148,144 39 | 98,101,25,26,89,85 40 | 86,89,26,27,83,80 41 | 79,83,27,28,135,132 42 | 133,135,28,29,148,146 43 | 150,154,30,31,160,156 44 | 152,154,30,34,178,176 45 | 158,160,31,32,166,162 46 | 164,166,32,33,172,168 47 | 170,172,33,34,178,174 48 | 122,125,35,36,129,126 49 | 121,125,35,39,141,138 50 | 127,129,36,37,159,157 51 | 156,159,37,38,153,150 52 | 151,153,38,39,141,139 53 | 109,113,40,44,131,128 54 | 110,113,40,41,117,114 55 | 115,117,41,42,165,163 56 | 162,165,42,43,161,158 57 | 157,161,43,44,131,127 58 | 92,95,45,46,105,102 59 | 91,95,45,49,119,116 60 | 103,105,46,47,171,169 61 | 168,171,47,48,167,164 62 | 163,167,48,49,119,115 63 | 96,99,50,54,107,104 64 | 97,99,50,51,147,144 65 | 145,147,51,52,177,175 66 | 174,177,52,53,173,170 67 | 169,173,53,54,107,103 68 | 134,137,55,56,143,140 69 | 133,137,55,59,149,146 70 | 139,143,56,57,155,151 71 | 152,155,57,58,179,176 72 | 175,179,58,59,149,145 73 | 62,64,60,63,61,65 74 | 68,70,66,69,67,71 75 | 73,75,72,76,74,77 76 | 80,82,78,81,79,83 77 | 86,88,84,87,85,89 78 | 91,93,90,94,92,95 79 | 98,100,96,99,97,101 80 | 104,106,102,105,103,107 81 | 109,111,108,112,110,113 82 | 116,118,114,117,115,119 83 | 122,124,120,123,121,125 84 | 128,130,126,129,127,131 85 | 134,136,132,135,133,137 86 | 140,142,138,141,139,143 87 | 146,148,144,147,145,149 88 | 151,153,150,154,152,155 89 | 157,159,156,160,158,161 90 | 164,166,162,165,163,167 91 | 170,172,168,171,169,173 92 | 175,177,174,178,176,179 93 | -------------------------------------------------------------------------------- /C180_scaled: -------------------------------------------------------------------------------- 1 | 0.626868 0.062944 -0.044246 2 | 0.626351 -0.077591 -0.017095 3 | 0.597923 -0.145832 -0.139585 4 | 0.581166 -0.047686 -0.242132 5 | 0.599169 0.081369 -0.183462 6 | 0.298640 0.541078 0.130268 7 | 0.404648 0.481310 0.055009 8 | 0.377022 0.499703 -0.084017 9 | 0.253170 0.570435 -0.094675 10 | 0.204936 0.596414 0.037387 11 | 0.355612 -0.018076 0.521588 12 | 0.462263 0.008843 0.430016 13 | 0.462485 0.149336 0.402896 14 | 0.355960 0.208640 0.477839 15 | 0.290209 0.105375 0.551599 16 | 0.250215 -0.565866 0.124527 17 | 0.374226 -0.496284 0.108688 18 | 0.402717 -0.428253 0.231179 19 | 0.296160 -0.455679 0.322710 20 | 0.202044 -0.540983 0.256800 21 | 0.128463 -0.345619 -0.513199 22 | 0.262899 -0.336934 -0.464838 23 | 0.280110 -0.435070 -0.362407 24 | 0.155773 -0.504029 -0.346769 25 | 0.062280 -0.449305 -0.439988 26 | 0.157778 0.338443 -0.509601 27 | 0.281524 0.267384 -0.498299 28 | 0.264176 0.138414 -0.557455 29 | 0.129476 0.129962 -0.604835 30 | 0.063894 0.253550 -0.575848 31 | -0.626351 -0.062723 0.044604 32 | -0.598831 -0.081189 0.183620 33 | -0.581040 0.048234 0.241974 34 | -0.598250 0.146360 0.139448 35 | -0.626372 0.077791 0.017063 36 | -0.204830 -0.595655 -0.036785 37 | -0.253339 -0.570551 0.095308 38 | -0.376948 -0.499450 0.083975 39 | -0.404279 -0.480888 -0.055315 40 | -0.298218 -0.540688 -0.130183 41 | -0.064189 -0.253645 0.575204 42 | -0.129687 -0.129740 0.604297 43 | -0.264187 -0.138921 0.556590 44 | -0.281524 -0.268197 0.498225 45 | -0.158115 -0.339340 0.509865 46 | -0.062385 0.449210 0.439650 47 | -0.155889 0.504483 0.346695 48 | -0.279667 0.434416 0.362618 49 | -0.262372 0.336639 0.465418 50 | -0.128147 0.345724 0.513463 51 | -0.201897 0.540298 -0.255966 52 | -0.295717 0.455056 -0.322372 53 | -0.402168 0.428085 -0.230567 54 | -0.374426 0.496875 -0.108309 55 | -0.250479 0.566372 -0.124084 56 | -0.290346 -0.105607 -0.551198 57 | -0.356614 -0.208903 -0.477923 58 | -0.463044 -0.149399 -0.403498 59 | -0.462643 -0.008948 -0.430744 60 | -0.355918 0.018277 -0.522200 61 | 0.588511 0.114334 0.193740 62 | 0.468363 0.341250 0.247641 63 | 0.557603 0.294514 0.005160 64 | 0.521018 0.208217 0.286969 65 | 0.606460 0.163497 0.054851 66 | 0.491398 0.380409 0.106399 67 | 0.588215 -0.036817 0.222896 68 | 0.467086 -0.226937 0.357838 69 | 0.555978 -0.273715 0.115305 70 | 0.520491 -0.089124 0.344352 71 | 0.605700 -0.134046 0.112181 72 | 0.489826 -0.315798 0.241077 73 | 0.525619 -0.347328 -0.016324 74 | 0.353216 -0.503586 -0.137538 75 | 0.474778 -0.313730 -0.271510 76 | 0.429773 -0.460702 -0.017918 77 | 0.546217 -0.278675 -0.146434 78 | 0.381317 -0.428549 -0.262351 79 | 0.456449 -0.208228 -0.382013 80 | 0.284553 -0.107222 -0.552770 81 | 0.457272 0.049247 -0.432105 82 | 0.345049 -0.221133 -0.479506 83 | 0.510445 -0.071207 -0.363916 84 | 0.345967 0.025600 -0.527403 85 | 0.527730 0.313951 -0.144439 86 | 0.355707 0.414884 -0.314964 87 | 0.476266 0.188231 -0.368812 88 | 0.432358 0.419210 -0.187957 89 | 0.547863 0.202002 -0.239705 90 | 0.383079 0.298566 -0.402949 91 | 0.354060 0.405028 0.328482 92 | 0.158548 0.355506 0.496822 93 | 0.127376 0.535475 0.308105 94 | 0.296202 0.334201 0.445401 95 | 0.266392 0.506604 0.264883 96 | 0.079290 0.459055 0.425710 97 | 0.027573 0.600741 -0.189339 98 | -0.024059 0.474958 -0.414166 99 | 0.222716 0.491177 -0.326920 100 | -0.065297 0.553277 -0.295200 101 | 0.171021 0.568862 -0.211489 102 | 0.121583 0.448714 -0.426554 103 | 0.026929 0.594937 0.207774 104 | -0.219941 0.578613 0.120296 105 | -0.024334 0.628451 -0.047253 106 | -0.118882 0.575732 0.228784 107 | 0.068453 0.623534 0.068220 108 | -0.167802 0.607874 -0.015649 109 | 0.352562 -0.256304 0.456122 110 | 0.124971 -0.383575 0.485732 111 | 0.157725 -0.146508 0.593386 112 | 0.264123 -0.373624 0.434975 113 | 0.295369 -0.146466 0.538124 114 | 0.077464 -0.268313 0.566351 115 | 0.087257 -0.013475 0.625053 116 | -0.139680 0.116708 0.604181 117 | 0.087848 0.244106 0.575721 118 | -0.061108 -0.006827 0.628135 119 | 0.156786 0.115357 0.600899 120 | -0.060306 0.240096 0.580934 121 | 0.219909 -0.578243 -0.120074 122 | -0.026940 -0.594483 -0.207468 123 | 0.024344 -0.628303 0.047907 124 | 0.118692 -0.575257 -0.228731 125 | 0.167728 -0.607526 0.015723 126 | -0.068326 -0.623017 -0.067862 127 | -0.027531 -0.600920 0.190078 128 | -0.222727 -0.491556 0.327353 129 | 0.024207 -0.475728 0.414704 130 | -0.171063 -0.569211 0.211847 131 | 0.065498 -0.554015 0.295780 132 | -0.121256 -0.449400 0.427124 133 | 0.139796 -0.116708 -0.604128 134 | -0.087236 0.013338 -0.625148 135 | -0.087869 -0.244464 -0.575479 136 | 0.061077 0.006943 -0.628293 137 | 0.060412 -0.239906 -0.580755 138 | -0.156743 -0.115484 -0.600667 139 | -0.127271 -0.535116 -0.307905 140 | -0.354166 -0.404764 -0.328767 141 | -0.158706 -0.355812 -0.496695 142 | -0.266445 -0.506108 -0.264883 143 | -0.079269 -0.458960 -0.425890 144 | -0.296371 -0.334180 -0.445812 145 | -0.124949 0.383058 -0.485352 146 | -0.352868 0.255745 -0.456238 147 | -0.157704 0.146444 -0.593597 148 | -0.264229 0.372854 -0.434690 149 | -0.077506 0.268228 -0.566446 150 | -0.295284 0.146339 -0.538546 151 | -0.557382 -0.294028 -0.005160 152 | -0.468510 -0.340807 -0.247968 153 | -0.588986 -0.114207 -0.194014 154 | -0.491166 -0.379924 -0.106673 155 | -0.606450 -0.162969 -0.055062 156 | -0.521652 -0.207827 -0.287338 157 | -0.527350 -0.313972 0.144334 158 | -0.355770 -0.415095 0.315186 159 | -0.476161 -0.188231 0.368739 160 | -0.432263 -0.419157 0.188020 161 | -0.547610 -0.201886 0.239621 162 | -0.383258 -0.298693 0.403033 163 | -0.457114 -0.049237 0.431841 164 | -0.284426 0.107169 0.552707 165 | -0.456301 0.208312 0.382034 166 | -0.345692 -0.025494 0.527160 167 | -0.510266 0.071439 0.363768 168 | -0.345070 0.221292 0.479421 169 | -0.474557 0.313761 0.271436 170 | -0.353322 0.503797 0.137317 171 | -0.525978 0.347328 0.016103 172 | -0.380895 0.428623 0.262140 173 | -0.546291 0.278992 0.146223 174 | -0.430269 0.460702 0.017802 175 | -0.556010 0.273736 -0.115537 176 | -0.467381 0.226378 -0.357986 177 | -0.588680 0.036806 -0.223276 178 | -0.489478 0.315618 -0.241478 179 | -0.605911 0.133845 -0.112551 180 | -0.521082 0.088692 -0.344774 181 | -------------------------------------------------------------------------------- /C180_small: -------------------------------------------------------------------------------- 1 | 0.5940600 0.0596500 -0.0419300 2 | 0.5935700 -0.0735300 -0.0162000 3 | 0.5666300 -0.1382000 -0.1322800 4 | 0.5507500 -0.0451900 -0.2294600 5 | 0.5678100 0.0771100 -0.1738600 6 | 0.2830100 0.5127600 0.1234500 7 | 0.3834700 0.4561200 0.0521300 8 | 0.3572900 0.4735500 -0.0796200 9 | 0.2399200 0.5405800 -0.0897200 10 | 0.1942100 0.5652000 0.0354300 11 | 0.3370000 -0.0171300 0.4942900 12 | 0.4380700 0.0083800 0.4075100 13 | 0.4382800 0.1415200 0.3818100 14 | 0.3373300 0.1977200 0.4528300 15 | 0.2750200 0.0998600 0.5227301 16 | 0.2371200 -0.5362501 0.1180100 17 | 0.3546400 -0.4703100 0.1030000 18 | 0.3816400 -0.4058400 0.2190800 19 | 0.2806600 -0.4318300 0.3058200 20 | 0.1914700 -0.5126700 0.2433600 21 | 0.1217400 -0.3275300 -0.4863400 22 | 0.2491400 -0.3193000 -0.4405100 23 | 0.2654500 -0.4123000 -0.3434400 24 | 0.1476200 -0.4776500 -0.3286200 25 | 0.0590200 -0.4257900 -0.4169600 26 | 0.1495200 0.3207300 -0.4829300 27 | 0.2667900 0.2533900 -0.4722200 28 | 0.2503500 0.1311700 -0.5282800 29 | 0.1227000 0.1231600 -0.5731800 30 | 0.0605500 0.2402800 -0.5457100 31 | -0.5935700 -0.0594400 0.0422700 32 | -0.5674900 -0.0769400 0.1740100 33 | -0.5506300 0.0457100 0.2293100 34 | -0.5669400 0.1387000 0.1321500 35 | -0.5935900 0.0737200 0.0161700 36 | -0.1941100 -0.5644800 -0.0348600 37 | -0.2400800 -0.5406900 0.0903200 38 | -0.3572200 -0.4733100 0.0795800 39 | -0.3831200 -0.4557200 -0.0524200 40 | -0.2826100 -0.5123900 -0.1233700 41 | -0.0608300 -0.2403700 0.5451000 42 | -0.1229000 -0.1229500 0.5726700 43 | -0.2503600 -0.1316500 0.5274600 44 | -0.2667900 -0.2541600 0.4721500 45 | -0.1498400 -0.3215800 0.4831800 46 | -0.0591200 0.4257000 0.4166400 47 | -0.1477300 0.4780800 0.3285500 48 | -0.2650300 0.4116800 0.3436400 49 | -0.2486400 0.3190200 0.4410600 50 | -0.1214400 0.3276300 0.4865900 51 | -0.1913300 0.5120201 -0.2425700 52 | -0.2802400 0.4312400 -0.3055000 53 | -0.3811200 0.4056800 -0.2185000 54 | -0.3548300 0.4708700 -0.1026400 55 | -0.2373700 0.5367300 -0.1175900 56 | -0.2751500 -0.1000800 -0.5223500 57 | -0.3379500 -0.1979700 -0.4529100 58 | -0.4388100 -0.1415800 -0.3823800 59 | -0.4384300 -0.0084800 -0.4082000 60 | -0.3372900 0.0173200 -0.4948700 61 | 0.5577100 0.1083500 0.1836000 62 | 0.4438500 0.3233900 0.2346800 63 | 0.5284200 0.2791000 0.0048900 64 | 0.4937500 0.1973200 0.2719500 65 | 0.5747200 0.1549400 0.0519800 66 | 0.4656800 0.3605000 0.1008300 67 | 0.5574300 -0.0348900 0.2112300 68 | 0.4426400 -0.2150600 0.3391100 69 | 0.5268800 -0.2593900 0.1092700 70 | 0.4932500 -0.0844600 0.3263300 71 | 0.5740000 -0.1270300 0.1063100 72 | 0.4641900 -0.2992700 0.2284600 73 | 0.4981100 -0.3291500 -0.0154700 74 | 0.3347300 -0.4772300 -0.1303400 75 | 0.4499300 -0.2973100 -0.2573000 76 | 0.4072800 -0.4365900 -0.0169800 77 | 0.5176300 -0.2640900 -0.1387700 78 | 0.3613600 -0.4061200 -0.2486200 79 | 0.4325600 -0.1973300 -0.3620200 80 | 0.2696600 -0.1016100 -0.5238400 81 | 0.4333400 0.0466700 -0.4094900 82 | 0.3269900 -0.2095600 -0.4544100 83 | 0.4837300 -0.0674800 -0.3448700 84 | 0.3278600 0.0242600 -0.4998000 85 | 0.5001100 0.2975200 -0.1368800 86 | 0.3370900 0.3931700 -0.2984800 87 | 0.4513400 0.1783800 -0.3495100 88 | 0.4097300 0.3972700 -0.1781200 89 | 0.5191900 0.1914300 -0.2271600 90 | 0.3630300 0.2829400 -0.3818600 91 | 0.3355300 0.3838300 0.3112900 92 | 0.1502500 0.3369000 0.4708200 93 | 0.1207100 0.5074500 0.2919800 94 | 0.2807000 0.3167100 0.4220900 95 | 0.2524500 0.4800900 0.2510200 96 | 0.0751400 0.4350300 0.4034300 97 | 0.0261300 0.5693000 -0.1794300 98 | -0.0228000 0.4501000 -0.3924900 99 | 0.2110600 0.4654700 -0.3098100 100 | -0.0618800 0.5243200 -0.2797500 101 | 0.1620700 0.5390900 -0.2004200 102 | 0.1152200 0.4252300 -0.4042300 103 | 0.0255200 0.5638000 0.1969000 104 | -0.2084300 0.5483300 0.1140000 105 | -0.0230600 0.5955600 -0.0447800 106 | -0.1126600 0.5456000 0.2168100 107 | 0.0648700 0.5909000 0.0646500 108 | -0.1590200 0.5760600 -0.0148300 109 | 0.3341100 -0.2428900 0.4322500 110 | 0.1184300 -0.3635000 0.4603100 111 | 0.1494700 -0.1388400 0.5623300 112 | 0.2503000 -0.3540700 0.4122100 113 | 0.2799100 -0.1388000 0.5099600 114 | 0.0734100 -0.2542700 0.5367100 115 | 0.0826900 -0.0127700 0.5923400 116 | -0.1323700 0.1106000 0.5725600 117 | 0.0832500 0.2313300 0.5455900 118 | -0.0579100 -0.0064700 0.5952600 119 | 0.1485800 0.1093200 0.5694500 120 | -0.0571500 0.2275300 0.5505300 121 | 0.2084000 -0.5479800 -0.1137900 122 | -0.0255300 -0.5633700 -0.1966100 123 | 0.0230700 -0.5954200 0.0454000 124 | 0.1124800 -0.5451500 -0.2167600 125 | 0.1589500 -0.5757300 0.0149000 126 | -0.0647500 -0.5904100 -0.0643100 127 | -0.0260900 -0.5694700 0.1801300 128 | -0.2110700 -0.4658300 0.3102200 129 | 0.0229400 -0.4508300 0.3930000 130 | -0.1621100 -0.5394200 0.2007600 131 | 0.0620700 -0.5250200 0.2803000 132 | -0.1149100 -0.4258800 0.4047700 133 | 0.1324800 -0.1106000 -0.5725100 134 | -0.0826700 0.0126400 -0.5924301 135 | -0.0832700 -0.2316700 -0.5453600 136 | 0.0578800 0.0065800 -0.5954100 137 | 0.0572500 -0.2273500 -0.5503600 138 | -0.1485400 -0.1094400 -0.5692300 139 | -0.1206100 -0.5071101 -0.2917900 140 | -0.3356300 -0.3835800 -0.3115600 141 | -0.1504000 -0.3371900 -0.4707000 142 | -0.2525000 -0.4796200 -0.2510200 143 | -0.0751200 -0.4349400 -0.4036000 144 | -0.2808600 -0.3166900 -0.4224800 145 | -0.1184100 0.3630100 -0.4599500 146 | -0.3344000 0.2423600 -0.4323600 147 | -0.1494500 0.1387800 -0.5625300 148 | -0.2504000 0.3533400 -0.4119400 149 | -0.0734500 0.2541900 -0.5368000 150 | -0.2798300 0.1386800 -0.5103600 151 | -0.5282100 -0.2786400 -0.0048900 152 | -0.4439900 -0.3229700 -0.2349900 153 | -0.5581600 -0.1082300 -0.1838600 154 | -0.4654600 -0.3600400 -0.1010900 155 | -0.5747100 -0.1544400 -0.0521800 156 | -0.4943500 -0.1969500 -0.2723000 157 | -0.4997500 -0.2975400 0.1367800 158 | -0.3371500 -0.3933700 0.2986900 159 | -0.4512400 -0.1783800 0.3494400 160 | -0.4096400 -0.3972200 0.1781800 161 | -0.5189500 -0.1913200 0.2270800 162 | -0.3632000 -0.2830600 0.3819400 163 | -0.4331900 -0.0466600 0.4092400 164 | -0.2695400 0.1015600 0.5237800 165 | -0.4324200 0.1974100 0.3620400 166 | -0.3276000 -0.0241600 0.4995700 167 | -0.4835600 0.0677000 0.3447300 168 | -0.3270100 0.2097100 0.4543300 169 | -0.4497200 0.2973400 0.2572300 170 | -0.3348300 0.4774300 0.1301300 171 | -0.4984500 0.3291500 0.0152600 172 | -0.3609600 0.4061900 0.2484200 173 | -0.5177000 0.2643900 0.1385700 174 | -0.4077500 0.4365900 0.0168700 175 | -0.5269100 0.2594100 -0.1094900 176 | -0.4429200 0.2145300 -0.3392500 177 | -0.5578700 0.0348800 -0.2115900 178 | -0.4638600 0.2991000 -0.2288400 179 | -0.5742000 0.1268400 -0.1066600 180 | -0.4938100 0.0840500 -0.3267300 181 | -------------------------------------------------------------------------------- /CellDiv.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftSimu/CellSim3D/79393c8f00479cad7bb59e6a21144e71a10cc21c/CellDiv.blend -------------------------------------------------------------------------------- /LICENSE/jsoncpp: -------------------------------------------------------------------------------- 1 | The JsonCpp library's source code, including accompanying documentation, 2 | tests and demonstration applications, are licensed under the following 3 | conditions... 4 | 5 | The author (Baptiste Lepilleur) explicitly disclaims copyright in all 6 | jurisdictions which recognize such a disclaimer. In such jurisdictions, 7 | this software is released into the Public Domain. 8 | 9 | In jurisdictions which do not recognize Public Domain property (e.g. Germany as of 10 | 2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is 11 | released under the terms of the MIT License (see below). 12 | 13 | In jurisdictions which recognize Public Domain property, the user of this 14 | software may choose to accept it either as 1) Public Domain, 2) under the 15 | conditions of the MIT License (see below), or 3) under the terms of dual 16 | Public Domain/MIT License conditions described here, as they choose. 17 | 18 | The MIT License is about as close to Public Domain as a license can get, and is 19 | described in clear, concise terms at: 20 | 21 | http://en.wikipedia.org/wiki/MIT_License 22 | 23 | The full text of the MIT License follows: 24 | 25 | ======================================================================== 26 | Copyright (c) 2007-2010 Baptiste Lepilleur 27 | 28 | Permission is hereby granted, free of charge, to any person 29 | obtaining a copy of this software and associated documentation 30 | files (the "Software"), to deal in the Software without 31 | restriction, including without limitation the rights to use, copy, 32 | modify, merge, publish, distribute, sublicense, and/or sell copies 33 | of the Software, and to permit persons to whom the Software is 34 | furnished to do so, subject to the following conditions: 35 | 36 | The above copyright notice and this permission notice shall be 37 | included in all copies or substantial portions of the Software. 38 | 39 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 40 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 41 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 42 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 43 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 44 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 45 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 46 | SOFTWARE. 47 | ======================================================================== 48 | (END LICENSE TEXT) 49 | 50 | The MIT license is compatible with both the GPL and commercial 51 | software, affording one all of the rights of Public Domain with the 52 | minor nuisance of being required to keep the above copyright notice 53 | and license text in the source code. Note also that by accepting the 54 | Public Domain "license" you can re-license your copy using whatever 55 | license you like. 56 | -------------------------------------------------------------------------------- /images/mov.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftSimu/CellSim3D/79393c8f00479cad7bb59e6a21144e71a10cc21c/images/mov.gif -------------------------------------------------------------------------------- /inc/AdaptiveTimeKernels.cuh: -------------------------------------------------------------------------------- 1 | #ifndef ADAPTIVE_TIME_KERNELS 2 | #define ADAPTIVE_TIME_KERNELS 3 | // predictor stuff 4 | inline float get_pn2(float c1, float c2){ 5 | return 2*(1-c1)/((c2-c1)*c2*(1+c2)); 6 | } 7 | 8 | inline float get_pn1(float c1, float c2){ 9 | return 2*(c2-1)/(c1*(1+c1)*(c2-c1)); 10 | } 11 | 12 | inline float get_pn0(float c1, float c2){ 13 | return -2*(c1+c2-1)/(c1*c2); 14 | } 15 | 16 | inline float get_pp1(float c1, float c2){ 17 | return 2*(c1+c2)/((1+c1)*(1+c2)); 18 | } 19 | 20 | // corrector 21 | inline float get_cn2(float c1, float c2){ 22 | return -2*(2+c1)/((c2 - c1)*c2*(1 + c2)); 23 | } 24 | 25 | inline float get_cn1(float c1, float c2){ 26 | return 2*(2+c2)/(c1*(1+c1)*(c2-c1)); 27 | } 28 | 29 | inline float get_cn0(float c1, float c2){ 30 | return -2*(2+c1+c2)/(c1*c2); 31 | } 32 | 33 | inline float get_cp1(float c1, float c2){ 34 | return 2*(3+c1+c2)/((1+c1)*(1+c2)); 35 | } 36 | 37 | inline float get_alpha(float c1, float c2){ 38 | return -(c1*c2-c1-c2)/12; 39 | } 40 | 41 | inline float get_beta(float c1, float c2){ 42 | return -(3+2*c1 + 2*c2 + c1*c2)/12; 43 | } 44 | 45 | 46 | 47 | struct adp_coeffs{ 48 | float kn1, kn2, k0, k1; 49 | }; 50 | 51 | 52 | 53 | inline adp_coeffs getAdpCoeffs(bool isPredictor, float c1, float c2){ 54 | adp_coeffs a; 55 | if (isPredictor){ 56 | a.kn1 = get_pn1(c1, c2); 57 | a.kn2 = get_pn2(c1, c2); 58 | a.k0 = get_pn0(c1, c2); 59 | a.k1 = get_pp1(c1, c2); 60 | } else { 61 | a.kn1 = get_cn1(c1, c2); 62 | a.kn2 = get_cn2(c1, c2); 63 | a.k0 = get_cn0(c1, c2); 64 | a.k1 = get_cp1(c1, c2); 65 | } 66 | 67 | return a; 68 | } 69 | 70 | 71 | __global__ void Integrate(float *d_XP, float *d_YP, float *d_ZP, 72 | float *d_X, float *d_Y, float *d_Z, 73 | float *d_XM, float *d_YM, float *d_ZM, 74 | float *d_XMM, float *d_YMM, float *d_ZMM, 75 | float *d_time, float mass, 76 | float3 *d_forceList, int numCells, adp_coeffs a); 77 | 78 | __global__ void ForwardTime(float *d_XP, float *d_YP, float *d_ZP, 79 | float *d_X, float *d_Y, float *d_Z, 80 | float *d_XM, float *d_YM, float *d_ZM, 81 | float *d_XMM, float *d_YMM, float *d_ZMM, 82 | float *d_velListX, float *d_velListY, float *d_velListZ, 83 | int numCells, float *d_time); 84 | 85 | __global__ void ComputeTimeUpdate(float *d_XP, float *d_YP, float *d_ZP, 86 | float *d_Xt, float *d_Yt, float *d_Zt, 87 | float *d_AdpErrors, float *d_time, float dt_max, 88 | float alpha, float beta, int numCells, float dt_tol); 89 | 90 | #endif // ADAPTIVE_TIME_KERNELS 91 | -------------------------------------------------------------------------------- /inc/VectorFunctions.hpp: -------------------------------------------------------------------------------- 1 | // This file contains some general purpose device only functions 2 | 3 | #ifndef VECTOR_FUNCTIONS_HPP 4 | #define VECTOR_FUNCTIONS_HPP 5 | #include 6 | #include 7 | #include 8 | #define MAX_NN 1024 9 | 10 | struct angles3{ 11 | float aij, ajk, aik; 12 | }; 13 | 14 | struct R3Nptrs{ 15 | float* x; 16 | float* y; 17 | float* z; 18 | }; 19 | 20 | typedef struct R3Nptrs R3Nptrs; 21 | 22 | __host__ __device__ inline angles3 make_angles3(float aij, float ajk, 23 | float aik){ 24 | angles3 A; 25 | A.aij = aij; 26 | A.ajk = ajk; 27 | A.aik = aik; 28 | return A; 29 | } 30 | 31 | __host__ __device__ inline float dot(float3 a, float3 b){ 32 | return a.x*b.x + a.y*b.y + a.z*b.z; 33 | } 34 | 35 | 36 | __host__ __device__ inline float3 cross(float3 a, float3 b){ 37 | float3 c; 38 | 39 | c.x = a.y*b.z - a.z*b.y; 40 | c.y = a.z*b.x - a.x*b.z; 41 | c.z = a.x*b.y - a.y*b.x; 42 | 43 | return c; 44 | } 45 | 46 | __host__ __device__ inline float mag2(float3 a){ 47 | return dot(a,a); 48 | } 49 | 50 | __host__ __device__ inline float mag(float3 a){ 51 | return sqrtf(mag2(a)); 52 | } 53 | 54 | 55 | __host__ __device__ inline float3 operator+(const float3 a, const float3 b){ 56 | float3 c; 57 | c.x = a.x + b.x; 58 | c.y = a.y + b.y; 59 | c.z = a.z + b.z; 60 | return c; 61 | } 62 | 63 | 64 | __host__ __device__ inline float3 operator-(const float3 a, const float3 b){ 65 | float3 c; 66 | c.x = a.x - b.x; 67 | c.y = a.y - b.y; 68 | c.z = a.z - b.z; 69 | return c; 70 | } 71 | 72 | __host__ __device__ inline float3 operator*(const float a, const float3 b){ 73 | float3 c; 74 | c.x = a*b.x; 75 | c.y = a*b.y; 76 | c.z = a*b.z; 77 | return c; 78 | } 79 | 80 | __host__ __device__ inline float3 operator*(const float3 b, const float a){ 81 | return a*b; 82 | } 83 | 84 | __host__ __device__ inline float3 operator/(const float3 b, const float a){ 85 | // float3 c; 86 | // c.x = b.x/a; 87 | // c.y = b.y/a; 88 | // c.z = b.z/a; 89 | // return c; 90 | 91 | return (1/a)*b; 92 | } 93 | 94 | __host__ __device__ inline bool operator==(const float3 &a, const float3 &b){ 95 | if (a.x == b.x && 96 | a.y == b.y && 97 | a.z == b.z) 98 | return true; 99 | 100 | return false; 101 | } 102 | 103 | __host__ __device__ inline bool operator!=(const float3 &a, const float3 &b){ 104 | return !(a==b); 105 | } 106 | 107 | __host__ __device__ inline float3 calcUnitVec(const float3 a){ 108 | return a/mag(a); 109 | } 110 | 111 | __host__ __device__ inline void print_float3(float3 a){ 112 | printf("(%f, %f, %f)", a.x, a.y, a.z); 113 | } 114 | 115 | __host__ __device__ inline bool good_float3(float3 a){ 116 | if ( !isfinite(a.x) || 117 | !isfinite(a.y) || 118 | !isfinite(a.z) ) 119 | return false; 120 | return true; 121 | 122 | } 123 | #endif // VECTOR_FUNCTIONS_HPP 124 | -------------------------------------------------------------------------------- /inc/json/json-forwards.h: -------------------------------------------------------------------------------- 1 | /// Json-cpp amalgated forward header (http://jsoncpp.sourceforge.net/). 2 | /// It is intented to be used with #include 3 | /// This header provides forward declaration for all JsonCpp types. 4 | 5 | // ////////////////////////////////////////////////////////////////////// 6 | // Beginning of content of file: LICENSE 7 | // ////////////////////////////////////////////////////////////////////// 8 | 9 | /* 10 | The JsonCpp library's source code, including accompanying documentation, 11 | tests and demonstration applications, are licensed under the following 12 | conditions... 13 | 14 | The author (Baptiste Lepilleur) explicitly disclaims copyright in all 15 | jurisdictions which recognize such a disclaimer. In such jurisdictions, 16 | this software is released into the Public Domain. 17 | 18 | In jurisdictions which do not recognize Public Domain property (e.g. Germany as of 19 | 2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is 20 | released under the terms of the MIT License (see below). 21 | 22 | In jurisdictions which recognize Public Domain property, the user of this 23 | software may choose to accept it either as 1) Public Domain, 2) under the 24 | conditions of the MIT License (see below), or 3) under the terms of dual 25 | Public Domain/MIT License conditions described here, as they choose. 26 | 27 | The MIT License is about as close to Public Domain as a license can get, and is 28 | described in clear, concise terms at: 29 | 30 | http://en.wikipedia.org/wiki/MIT_License 31 | 32 | The full text of the MIT License follows: 33 | 34 | ======================================================================== 35 | Copyright (c) 2007-2010 Baptiste Lepilleur 36 | 37 | Permission is hereby granted, free of charge, to any person 38 | obtaining a copy of this software and associated documentation 39 | files (the "Software"), to deal in the Software without 40 | restriction, including without limitation the rights to use, copy, 41 | modify, merge, publish, distribute, sublicense, and/or sell copies 42 | of the Software, and to permit persons to whom the Software is 43 | furnished to do so, subject to the following conditions: 44 | 45 | The above copyright notice and this permission notice shall be 46 | included in all copies or substantial portions of the Software. 47 | 48 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 49 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 50 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 51 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 52 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 53 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 54 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 55 | SOFTWARE. 56 | ======================================================================== 57 | (END LICENSE TEXT) 58 | 59 | The MIT license is compatible with both the GPL and commercial 60 | software, affording one all of the rights of Public Domain with the 61 | minor nuisance of being required to keep the above copyright notice 62 | and license text in the source code. Note also that by accepting the 63 | Public Domain "license" you can re-license your copy using whatever 64 | license you like. 65 | 66 | */ 67 | 68 | // ////////////////////////////////////////////////////////////////////// 69 | // End of content of file: LICENSE 70 | // ////////////////////////////////////////////////////////////////////// 71 | 72 | 73 | 74 | 75 | 76 | #ifndef JSON_FORWARD_AMALGATED_H_INCLUDED 77 | # define JSON_FORWARD_AMALGATED_H_INCLUDED 78 | /// If defined, indicates that the source file is amalgated 79 | /// to prevent private header inclusion. 80 | #define JSON_IS_AMALGAMATION 81 | 82 | // ////////////////////////////////////////////////////////////////////// 83 | // Beginning of content of file: include/json/config.h 84 | // ////////////////////////////////////////////////////////////////////// 85 | 86 | // Copyright 2007-2010 Baptiste Lepilleur 87 | // Distributed under MIT license, or public domain if desired and 88 | // recognized in your jurisdiction. 89 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 90 | 91 | #ifndef JSON_CONFIG_H_INCLUDED 92 | #define JSON_CONFIG_H_INCLUDED 93 | 94 | /// If defined, indicates that json library is embedded in CppTL library. 95 | //# define JSON_IN_CPPTL 1 96 | 97 | /// If defined, indicates that json may leverage CppTL library 98 | //# define JSON_USE_CPPTL 1 99 | /// If defined, indicates that cpptl vector based map should be used instead of 100 | /// std::map 101 | /// as Value container. 102 | //# define JSON_USE_CPPTL_SMALLMAP 1 103 | /// If defined, indicates that Json specific container should be used 104 | /// (hash table & simple deque container with customizable allocator). 105 | /// THIS FEATURE IS STILL EXPERIMENTAL! There is know bugs: See #3177332 106 | //# define JSON_VALUE_USE_INTERNAL_MAP 1 107 | /// Force usage of standard new/malloc based allocator instead of memory pool 108 | /// based allocator. 109 | /// The memory pools allocator used optimization (initializing Value and 110 | /// ValueInternalLink 111 | /// as if it was a POD) that may cause some validation tool to report errors. 112 | /// Only has effects if JSON_VALUE_USE_INTERNAL_MAP is defined. 113 | //# define JSON_USE_SIMPLE_INTERNAL_ALLOCATOR 1 114 | 115 | // If non-zero, the library uses exceptions to report bad input instead of C 116 | // assertion macros. The default is to use exceptions. 117 | #ifndef JSON_USE_EXCEPTION 118 | #define JSON_USE_EXCEPTION 1 119 | #endif 120 | 121 | /// If defined, indicates that the source file is amalgated 122 | /// to prevent private header inclusion. 123 | /// Remarks: it is automatically defined in the generated amalgated header. 124 | // #define JSON_IS_AMALGAMATION 125 | 126 | #ifdef JSON_IN_CPPTL 127 | #include 128 | #ifndef JSON_USE_CPPTL 129 | #define JSON_USE_CPPTL 1 130 | #endif 131 | #endif 132 | 133 | #ifdef JSON_IN_CPPTL 134 | #define JSON_API CPPTL_API 135 | #elif defined(JSON_DLL_BUILD) 136 | #if defined(_MSC_VER) 137 | #define JSON_API __declspec(dllexport) 138 | #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING 139 | #endif // if defined(_MSC_VER) 140 | #elif defined(JSON_DLL) 141 | #if defined(_MSC_VER) 142 | #define JSON_API __declspec(dllimport) 143 | #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING 144 | #endif // if defined(_MSC_VER) 145 | #endif // ifdef JSON_IN_CPPTL 146 | #if !defined(JSON_API) 147 | #define JSON_API 148 | #endif 149 | 150 | // If JSON_NO_INT64 is defined, then Json only support C++ "int" type for 151 | // integer 152 | // Storages, and 64 bits integer support is disabled. 153 | // #define JSON_NO_INT64 1 154 | 155 | #if defined(_MSC_VER) && _MSC_VER <= 1200 // MSVC 6 156 | // Microsoft Visual Studio 6 only support conversion from __int64 to double 157 | // (no conversion from unsigned __int64). 158 | #define JSON_USE_INT64_DOUBLE_CONVERSION 1 159 | // Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255' 160 | // characters in the debug information) 161 | // All projects I've ever seen with VS6 were using this globally (not bothering 162 | // with pragma push/pop). 163 | #pragma warning(disable : 4786) 164 | #endif // if defined(_MSC_VER) && _MSC_VER < 1200 // MSVC 6 165 | 166 | #if defined(_MSC_VER) && _MSC_VER >= 1500 // MSVC 2008 167 | /// Indicates that the following function is deprecated. 168 | #define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) 169 | #endif 170 | 171 | #if !defined(JSONCPP_DEPRECATED) 172 | #define JSONCPP_DEPRECATED(message) 173 | #endif // if !defined(JSONCPP_DEPRECATED) 174 | 175 | namespace Json { 176 | typedef int Int; 177 | typedef unsigned int UInt; 178 | #if defined(JSON_NO_INT64) 179 | typedef int LargestInt; 180 | typedef unsigned int LargestUInt; 181 | #undef JSON_HAS_INT64 182 | #else // if defined(JSON_NO_INT64) 183 | // For Microsoft Visual use specific types as long long is not supported 184 | #if defined(_MSC_VER) // Microsoft Visual Studio 185 | typedef __int64 Int64; 186 | typedef unsigned __int64 UInt64; 187 | #else // if defined(_MSC_VER) // Other platforms, use long long 188 | typedef long long int Int64; 189 | typedef unsigned long long int UInt64; 190 | #endif // if defined(_MSC_VER) 191 | typedef Int64 LargestInt; 192 | typedef UInt64 LargestUInt; 193 | #define JSON_HAS_INT64 194 | #endif // if defined(JSON_NO_INT64) 195 | } // end namespace Json 196 | 197 | #endif // JSON_CONFIG_H_INCLUDED 198 | 199 | // ////////////////////////////////////////////////////////////////////// 200 | // End of content of file: include/json/config.h 201 | // ////////////////////////////////////////////////////////////////////// 202 | 203 | 204 | 205 | 206 | 207 | 208 | // ////////////////////////////////////////////////////////////////////// 209 | // Beginning of content of file: include/json/forwards.h 210 | // ////////////////////////////////////////////////////////////////////// 211 | 212 | // Copyright 2007-2010 Baptiste Lepilleur 213 | // Distributed under MIT license, or public domain if desired and 214 | // recognized in your jurisdiction. 215 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 216 | 217 | #ifndef JSON_FORWARDS_H_INCLUDED 218 | #define JSON_FORWARDS_H_INCLUDED 219 | 220 | #if !defined(JSON_IS_AMALGAMATION) 221 | #include "config.h" 222 | #endif // if !defined(JSON_IS_AMALGAMATION) 223 | 224 | namespace Json { 225 | 226 | // writer.h 227 | class FastWriter; 228 | class StyledWriter; 229 | 230 | // reader.h 231 | class Reader; 232 | 233 | // features.h 234 | class Features; 235 | 236 | // value.h 237 | typedef unsigned int ArrayIndex; 238 | class StaticString; 239 | class Path; 240 | class PathArgument; 241 | class Value; 242 | class ValueIteratorBase; 243 | class ValueIterator; 244 | class ValueConstIterator; 245 | #ifdef JSON_VALUE_USE_INTERNAL_MAP 246 | class ValueMapAllocator; 247 | class ValueInternalLink; 248 | class ValueInternalArray; 249 | class ValueInternalMap; 250 | #endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP 251 | 252 | } // namespace Json 253 | 254 | #endif // JSON_FORWARDS_H_INCLUDED 255 | 256 | // ////////////////////////////////////////////////////////////////////// 257 | // End of content of file: include/json/forwards.h 258 | // ////////////////////////////////////////////////////////////////////// 259 | 260 | 261 | 262 | 263 | 264 | #endif //ifndef JSON_FORWARD_AMALGATED_H_INCLUDED 265 | -------------------------------------------------------------------------------- /inp.dat: -------------------------------------------------------------------------------- 1 | 0.04 2 | 0.2 3 | 0.3 4 | 100.0 5 | 0.50 6 | 1000.0 7 | 2.0 8 | 100.0 9 | 2.9 10 | 200000 11 | 0.0001 12 | 0 13 | 1000 14 | 0 15 | 0.6 16 | 1 17 | 1000 18 | 0 19 | traj_wallOn_longer.xyz 20 | 0 21 | 5000.0 22 | 2.0 23 | 10.0 24 | 10.0 25 | 10 26 | 20000 27 | 65.0 28 | 1 29 | z 30 | 3.0 31 | 10.0 32 | 10.0 33 | 0.01 34 | -------------------------- 35 | MASS 36 | REPULSION RANGE 37 | ATTRAnCTION RANGE 38 | REPULSION STRENGTH 39 | ATTRACTION STRENGTH 40 | YOUNGS MOD. 41 | VISCOTIC DAMPING 42 | INTERNAL DAMPING 43 | division volume 44 | TIME STEPS 45 | DT 46 | RESTART 47 | TRAJECTORY WRITE INTERVAL (Must be < Time_Steps and Time_steps%trajWriteInt == 0) 48 | countOnlyInternal (0 - no, 1 - yes) 49 | radFrac (If not between 0.4-0.8 or < 0 , countOnlyInternal = 0 always) 50 | overWriteMitIndFile 51 | New cell count interval (Must be < Time_Steps and Time_steps%newCellCountInt == 0) 52 | No of equillibration time steps 53 | Trajectory File name (extension does matter) 54 | Use population modelling (0==No and 1==Yes) 55 | Maximum Food for population modelling 56 | [NOT IMPLEMENTED] Transient food consumption 57 | Food consumed to create new cell (cells can't divide if this much extra food doesn't exist) 58 | [NOT IMPLEMENTED] Food released back into the system when a cell dies 59 | [NOT IMPLEMENTED] Hayflick limit (the max number of times a cell can divide; ignored if 0); 60 | [NOT IMPLEMENTED] Max amount of time a cell can live 61 | Maximum growth pressure (sets max growth rate) 62 | Use walls in the simulation? (0 = no, 1 = yes) 63 | Axis the walls are perpendicular to (Z for XY plane, etc) 64 | Separation between two walls 65 | length of walls in no. of cell diameters 66 | width of walls in no. of cell diameters 67 | threshold distance for repulsion 68 | -------------------------------------------------------------------------------- /inp.json: -------------------------------------------------------------------------------- 1 | { 2 | "core": { 3 | "MaxNoofC180s": 10000, 4 | "particle_mass": 0.04, 5 | "repulsion_range": 0.2, 6 | "attraction_range": 0.3, 7 | "repulsion_strength": 100.0, 8 | "attraction_strength": 0.5, 9 | "Youngs_mod": 1000, 10 | "stiffFactor1": 1.0, 11 | "viscotic_damping": 1, 12 | "internal_damping": 100.0, 13 | "gamma_visc": 1.0, 14 | "division_Vol": 2.9, 15 | //"division_Vol": 2.0, 16 | "random_z_offset?": 0, 17 | "z_offset": 0, 18 | "div_time_steps": 50000, 19 | "time_interval": 0.0001, 20 | "Restart": 0, 21 | "trajWriteInt": 1000, 22 | "non_div_time_steps": 50000, 23 | "trajFileName": "inp.xyz", 24 | "binaryOutput": 1, 25 | "maxPressure": 65.0, 26 | "minPressure": 50.0, 27 | "growth_rate": 0.002, 28 | "checkSphericity": 1, 29 | "constrainAngles": 1, 30 | "doAdaptive_dt": 0, 31 | "dt_max": 1e-4, 32 | "dt_tol": 1e-8, 33 | "phase_count": 2000000000, 34 | "write_cont_force": 1, 35 | "forces_file": "inp.csv", 36 | "correct_com" : 0 37 | }, 38 | "counting": { 39 | "countCells": 0, 40 | "mit-index_file_name": "inp.dat", 41 | "count_only_internal_cells?": 0, 42 | "radius_cutoff": 0.6, 43 | "overwrite_mit_ind_file?": 0, 44 | "cell_count_int": 1000 45 | }, 46 | 47 | "population": { 48 | "doPopModel": 0, 49 | "totalFood": 5000.0, 50 | "regular_consumption": 2.0, 51 | "division_consumption": 10.0, 52 | "death_release_food": 10.0, 53 | "haylimit": 10, 54 | "cellLifeTime": 20000 55 | }, 56 | 57 | "walls": { // deprecated, use box params 58 | "useWalls": 0, 59 | "perpAxis": "z", 60 | "dAxis": 1.1, 61 | "wallLen": 10.0, 62 | "wallWidth": 10.0, 63 | "threshDist": 0.01 64 | }, 65 | 66 | "divParams":{ 67 | "useDivPlaneBasis": 0, 68 | "divPlaneBasisX": 0, 69 | "divPlaneBasisY": 0, 70 | "divPlaneBasisZ": 1 71 | }, 72 | 73 | "stiffnessParams":{ 74 | "useDifferentStiffnesses": 0, 75 | "softStiffFactor": 0.8, 76 | "numberOfSofterCells": 0, 77 | "fractionOfSofterCells": 0.3, 78 | "duringGrowth": 1, 79 | "daughtSameStiffness": 1, 80 | "closenessToCenter": 0, 81 | "startAtPop": 2000, 82 | "chooseRandomCellIndices": 0, 83 | "recalc_r0": 0 84 | }, 85 | 86 | "boxParams":{ 87 | "useRigidSimulationBox": 1, 88 | "usePBCs": 0, // unavailable 89 | "pbcAx": "x", // unavailable 90 | "boxLength": 6.0, // deprecated 91 | "box_len_x": 500.0, 92 | "box_len_y": 500.0, 93 | "box_len_z": 2.0, 94 | "flatbox": 1, 95 | "dom_len": 1.5, 96 | "rand_pos": 0 97 | }, 98 | 99 | "rand_params":{ 100 | "add_rands": 0, 101 | "rand_seed": -1, // use time if < 0 102 | "rand_dist": 0, /* 103 | 0 - uniform (default) 104 | Others to be impimented 105 | */ 106 | "rand_scale_factor": 0.001 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | compiler = $(shell which nvcc) 2 | debug = -g -G -lineinfo 3 | arch = -arch=sm_35 4 | oflags = $(arch) -Xptxas="-v" -I inc -dc -D_FORCE_INLINES 5 | objDir = bin/ 6 | sources = $(wildcard src/*.cu) 7 | #objects = $(patsubst src%, $(objDir)%, $(patsubst %.cu, %.o, $(sources))) 8 | objects = GPUbounce.o centermass.o postscriptinit.o PressureKernels.o\ 9 | propagatebound.o propagate.o volume.o BondKernels.o 10 | linkObjects = $(patsubst %, $(objDir)%, $(objects)) 11 | 12 | eflags = $(arch) -o $(objDir)/"CellDiv" $(linkObjects) bin/jsoncpp.o -lm -lcurand 13 | opt = -O3 14 | 15 | CELLSIM3D_ROOT = $(PWD) 16 | 17 | debug: opt= -O0 18 | debug: oflags += $(debug) 19 | debug: eflags += $(debug) 20 | debug: CellDiv 21 | 22 | oflags += $(opt) 23 | eflags += $(opt) 24 | 25 | # $(objects): bin/%.o : src/%.cu 26 | # @mkdir -p $(@D) 27 | # $(compiler) $(oflags) -c $< -o $@ 28 | 29 | $(objDir)centermass.o: src/centermass.cu 30 | $(compiler) $(oflags) -c src/centermass.cu -o $(objDir)centermass.o 31 | 32 | # NeighbourSearch.o: src/NeighbourSearch.cu 33 | # $(compiler) $(oflags) -c src/NeighbourSearch.o 34 | 35 | $(objDir)postscriptinit.o: src/postscriptinit.cu 36 | $(compiler) $(oflags) -c src/postscriptinit.cu -o $(objDir)postscriptinit.o 37 | 38 | $(objDir)PressureKernels.o: src/PressureKernels.cu 39 | $(compiler) $(oflags) -c src/PressureKernels.cu -o $(objDir)PressureKernels.o 40 | 41 | $(objDir)propagatebound.o: src/propagatebound.cu 42 | $(compiler) $(oflags) -c src/propagatebound.cu -o $(objDir)propagatebound.o 43 | 44 | $(objDir)propagate.o: src/propagate.cu 45 | $(compiler) $(oflags) -c src/propagate.cu -o $(objDir)propagate.o 46 | 47 | $(objDir)volume.o : src/volume.cu 48 | $(compiler) $(oflags) -c src/volume.cu -o $(objDir)volume.o 49 | 50 | $(objDir)BondKernels.o : src/BondKernels.cu 51 | $(compiler) $(oflags) -c src/BondKernels.cu -o $(objDir)BondKernels.o 52 | 53 | $(objDir)GPUbounce.o : src/GPUbounce.cu 54 | $(compiler) $(oflags) -c src/GPUbounce.cu -o $(objDir)GPUbounce.o 55 | 56 | CellDiv: $(linkObjects) 57 | $(compiler) $(eflags) 58 | echo "export PYTHONPATH=${CELLSIM3D_ROOT}/scripts/:${PYTHONPATH}" > $(objDir)CellSim3D.rc 59 | echo "export PATH=${CELLSIM3D_ROOT}/bin:${PATH}" >> $(objDir)CellSim3D.rc 60 | echo "${CELLSIM3D_ROOT}" 61 | 62 | 63 | # Third party libraries 64 | $(objDir)jsoncpp.o: src/utils/jsoncpp.cpp inc/json/json.h 65 | $(compiler) $(oflags) -c src/utils/jsoncpp.cpp -o $(objDir)/jsoncpp.o 66 | 67 | .PHONY: clean 68 | clean: 69 | rm -f $(objDir)/CellDiv $(linkObjects) 70 | -------------------------------------------------------------------------------- /notes/doc.org: -------------------------------------------------------------------------------- 1 | * Overhaul structure 2 | As it is now (Feb 1, 2016) the code is very hard to reconfigure. I 3 | will try to rewrite it in an intelligent way to allow for easy 4 | configuration at a later time. 5 | ** CellDiv 6 | *** Input 7 | **** Force-field parameters 8 | ***** All the force field parameters 9 | **** Cell Geometry 10 | ***** Padding? 11 | ***** Number of nodes? 12 | ***** Division Algorithm Selection? 13 | **** GPU Selection? 14 | ***** Multiple GPU? 15 | ***** Which GPU? 16 | **** Simulation parameters 17 | ***** Number of Cellls 18 | ***** Boundary Conditions 19 | **** Output to disk 20 | *** Initialization 21 | *** Simulation 22 | *** Close 23 | -------------------------------------------------------------------------------- /notes/notes.org: -------------------------------------------------------------------------------- 1 | * angle force computation theory 2 | *_THIS METHOD WILL FAIL IF CELL GEOMETRY CHANGES_* 3 | 4 | Here are the details regarding the theory of calculating the force 5 | on a node $j$ due to variations of the the angle it makes with nodes 6 | $i, k$. It is based on the figure below 7 | #+CAPTION: Angles that node $j$ is a part of 8 | #+NAME: fig:angles 9 | [[./AngleForce.png]] 10 | 11 | ** First, the first neighbour contributions 12 | Derivation 13 | using a harmonic potential on the angle, we write $V(\theta_{ijk}) = 14 | \frac{1}{2} k^\theta (\theta_{ijk} - \theta_{ijk})$. 15 | for the angle $\theta_{ijk}$ between particles $i$, $j$, and 16 | $k$. assume particle $j$ is the one we are processing and the origin 17 | is the position of $j$, 18 | 19 | \begin{equation*} 20 | \begin{aligned} 21 | \mathbf{F}_{i}(\theta_{ijk}) &= -\frac{\partial}{\partial\mathbf{r}_i} 22 | (\frac{1}{2} k^\theta (\theta_{ijk} - \theta_{ijk}^o)^2)\\ 23 | &= - \frac{1}{2} k^\theta \frac{\partial \theta_{ijk}}{\partial \mathbf{r}_i} 24 | \frac{\partial}{\partial \theta_{ijk}} \left( \theta_{ijk} - \theta_{ijk}^o 25 | \right)^2\\ 26 | &= -k^\theta \left(\theta_{ijk} - \theta_{ijk}^o\right) \frac{\partial 27 | \theta_{ijk}}{\partial \mathbf{r}_i }\\ 28 | \end{aligned} 29 | \end{equation*} 30 | 31 | $\theta_{ijk} = \arccos{\left( \frac{\mathbf{r}_i \cdot \mathbf{r}_k}{r_i 32 | r_k} \right)}$ and $\frac{\partial}{\partial \mathbf{r}_i} = \left( 33 | \frac{\partial}{\partial r_{ix}} \hat{\mathbf{x}} + \frac{\partial}{\partial r_{iy}}\hat{\mathbf{y}} + 34 | \frac{\partial}{\partial r_{iz}} \hat{\mathbf{z}}\right)$, so 35 | 36 | \begin{equation*} 37 | \begin{aligned} 38 | \frac{\partial \theta_{ijk}}{\partial \mathbf{r}_i} &= \left(\frac{\partial}{\partial r_{ix}}\hat{\mathbf{x}} + 39 | \frac{\partial}{\partial r_{iy}}\hat{\mathbf{y}} + \frac{\partial}{\partial r_iz}\hat{\mathbf{z}} \right) 40 | \arccos{\left( \frac{\mathbf{r}_i \cdot \mathbf{r}_k}{r_i r_k}\right)}\\ 41 | \end{aligned} 42 | \end{equation*} 43 | 44 | \begin{equation*} 45 | \begin{aligned} 46 | \frac{\partial}{\partial r_{ix}} \arccos{\left( \frac{\mathbf{r}_i \cdot 47 | \mathbf{r}_k}{r_i r_k}\right)} &= \frac{1}{\sqrt{1 - 48 | \left( \frac{\mathbf{r}_i \cdot \mathbf{r}_k}{r_i r_k}\right)^2}} 49 | \frac{\partial}{\partial r_{ix}} \left( \frac{r_{ix} r_{kx} + r_{iy}{r_ky} 50 | + r_{iz}{r_{kz}}}{r_k \left( r_{ix}^2 + r_{iy}^2 + r_{iz}^2\right)^\frac{1}{2}} \right)\\ 51 | &= \frac{1}{r_k\sqrt{1 - 52 | \left( \frac{\mathbf{r}_i \cdot \mathbf{r}_k}{r_i r_k}\right)^2}} \left( \frac{r_{kx}}{r_i} - 53 | \frac{\mathbf{r}_i \cdot \mathbf{r}_k}{r_i^3} r_{ix}\right)\\ 54 | \end{aligned} 55 | \end{equation*} 56 | let's write a sample one for the x 57 | 58 | +*Error here. Missing minus sign, check code.*+ done, see 2424a6ca2d7 59 | 60 | Which leads to the equation for the angle force 61 | \begin{equation*} 62 | \begin{aligned} 63 | \mathbf{F}_{i}(\theta_{ijk}) = -k^\theta \left(\theta_{ijk} - \theta^o_{ijk}\right) \left[ 64 | \frac{1}{r_i r_k\sqrt{1 - \left( \frac{\mathbf{r}_i \cdot \mathbf{r}_k} {r_i r_k} \right)^2}} 65 | \left( 66 | \left(r_{kx} - \frac{\mathbf{r}_i \cdot \mathbf{r}_k}{r_i^2}r_{ix} \right)\hat{\mathbf{x}} 67 | + \left(r_{ky} - \frac{\mathbf{r}_i \cdot \mathbf{r}_k}{r_i^2}r_{iy} \right)\hat{\mathbf{y}} 68 | + \left(r_{kz} - \frac{\mathbf{r}_i \cdot \mathbf{r}_k}{r_i^2}r_{iz} \right)\hat{\mathbf{z}} 69 | \right)\right] 70 | \end{aligned} 71 | \end{equation*} 72 | 73 | let $C_1 = \frac{1}{r_i r_k \sqrt{1 - \left(\frac{\mathbf{r}_i \cdot 74 | \mathbf{r}_k}{r_i r_k}\right)^2}} = \frac{1}{\sqrt{r_i^2 r_k^2 - 75 | \left(\mathbf{r}_i \cdot \mathbf{r}_k\right)^2}}$ and $C_2 = \frac{\mathbf{r}_i 76 | \cdot \mathbf{r}_k} {r_i^2}$ then we get 77 | 78 | \begin{equation*} 79 | \mathbf{F}_i(\theta_{ijk}) = -k_\theta C_1 (\theta_{ijk} - 80 | \theta_{ijk}^o) \left[\left(r_{kx} - C_2 r_{ix} 81 | \right)\hat{\mathbf{x}} 82 | + \left(r_{ky} - C_2 r_{iy} \right)\hat{\mathbf{y}} 83 | + \left(r_{kz} - C_2 r_{iz} \right)\hat{\mathbf{z}} 84 | \right] 85 | \end{equation*} 86 | 87 | Rewrite to 88 | \begin{equation*} 89 | \mathbf{F}_i(\theta_{ijk}) = -k_\theta C_1 \left(\theta_{ijk} - \theta_{ijk}^o\right) \left( \mathbf{r}_k - 90 | C_2\mathbf{r}_i\right) 91 | \end{equation*} 92 | 93 | 94 | Which lets us calculate the force on particle $j$ 95 | \begin{equation*} 96 | \mathbf{F}_j(\theta_{ijk}) = -\mathbf{F}_i - \mathbf{F}_k 97 | \end{equation*} 98 | ** And now the second neighbour contribution 99 | $j$ participates in other angles with $i$ and $k$. E.g. $i$ will 100 | have 3 neighbours itself 101 | ** Implementation details 102 | Here are the details of how things are implemented in the code. 103 | *** 104 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ![Alt Text](https://github.com/SoftSimu/CellSim3D/raw/master/images/mov.gif) 2 | 3 | # CellSim3D 4 | Welcome to the CellSim3D repository. CellSim3D is a software package to simulate the mechanistic aspects of cell division in three dimensions. The code is written in C/C++ and CUDA. 5 | 6 | ## References: 7 | 8 | If you use the code, please cite the following papers: 9 | 10 | The 3D model is based on the 2D model introduced in 11 | 12 | A new model for cell division and migration with spontaneous topology changes, A. Mkrtchyan, J.A. Åström and M. Karttunen, Soft Matter 10, 4332-4339 (2014). [http://dx.doi.org/10.1039/C4SM00489B] 13 | 14 | 3D model: 15 | 16 | CellSim3D: GPU Accelerated Software for Simulations of Cellular Growth and Division in Three Dimensions, 17 | Pranav Madhikar, Jan Åström, Jan Westerholm, Mikko Karttunen, Computer Physics Communications 232, 206-213 (2018).[https://doi.org/10.1016/j.cpc.2018.05.024] 18 | 19 | ## Compilation 20 | CellSim3D can be compiled easily with the packaged makefile. First 21 | change the -arch variable to correspond to the compute capability of 22 | your GPU. 23 | 24 | For example: -arch=sm_52 for a GPU of compute capability of 5.2 25 | 26 | Then: 27 | 28 | 29 | ~~~bash 30 | mkdir bin 31 | make -j12 CellDiv to compile the simulator. 32 | ~~~ 33 | 34 | The simulator can be found in the bin directory 35 | 36 | 37 | ## Simulator Source Code Description (note: subject to change): 38 | 39 | ##### GPUBounce.cu 40 | 41 | This file contains the entry point for the simulator code. This is 42 | where the GPU is selected and memory is allocated. Simulation 43 | parameters are read from the input json file. 44 | 45 | All GPU functions (force calculation, integration, cell division) is 46 | controlled from here. 47 | 48 | ##### propagate.cu 49 | 50 | This file contains GPU kernel code that is used for force 51 | calculations and integration. 52 | 53 | ##### centermass.cu 54 | 55 | This file only contains a single GPU kernel that calculate the 56 | centers of mass of individual cells. This is needed for the 57 | calculation of cell volumes and the cell division algorithm 58 | 59 | ##### BondKernels.cu 60 | 61 | This file calculates the equilibrium bond lengths of bonded nodes in 62 | a cell. For now, this code is not very crucial since this bond 63 | length does not change over the course of a simulation. It will be 64 | used in later releases more extensively. 65 | 66 | ##### postscriptinit.cu 67 | 68 | This file contains some legacy code that is no longer used. It also 69 | contains the implementation of the cell division algorithm. 70 | 71 | ##### propagatebound.cu 72 | 73 | Code here is used to calculate the bounding boxes around cells, 74 | which are then used during neighbor list generation. Neighbor list 75 | generation itself is also carried out here. 76 | 77 | ##### PressureKernels.cu 78 | 79 | Cell internal pressure is managed with the code here. 80 | 81 | ##### IntegrationKernels.cu and AdaptiveTimeKernels.cu 82 | 83 | Code here is not currently used. 84 | 85 | ## Analysis Scripts (In the scripts/ directory): 86 | The scripts directory contains various analysis scripts. Their 87 | functionality can be explored by running 88 | 89 | ~~~bash 90 | python3 script.py --help 91 | ~~~ 92 | 93 | The most important ones are: 94 | 95 | ##### celldiv.py 96 | 97 | This is the interface to the binary format of the trajectory. It can 98 | be used to read the trajectory into numpy arrays. 99 | 100 | ##### render.py 101 | 102 | This is the rendering engine used to visualize the simulations. It 103 | produces images which can be made into movies. Requires Blender 2.7 or 104 | higher. Uses the scene set in CellDiv.blend 105 | 106 | Learn more by running 107 | 108 | ~~~bash 109 | blender -b CellDiv.blend -P scripts/render.py -- --help 110 | ~~~ 111 | -------------------------------------------------------------------------------- /scripts/GetPacking.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # This script uses a lot of python magic 3 | # Please ask if there are is any confusion 4 | 5 | import matplotlib 6 | matplotlib.use('Agg') 7 | import matplotlib.pyplot as plt 8 | import numpy as np 9 | from scipy.spatial import Voronoi, voronoi_plot_2d 10 | import os, sys, argparse 11 | 12 | desc=""" 13 | Anna's main analysis script. Produces many graphs 14 | """ 15 | 16 | parser = argparse.ArgumentParser(description=desc) 17 | 18 | parser.add_argument("--traj", nargs="+", 19 | help="Absolute or relative paths") 20 | parser.add_argument("--endat", type=int, 21 | help="time step to stop processing at") 22 | 23 | args = parser.parse_args() 24 | 25 | trajPaths = [os.path.abspath(p) for p in args.traj] 26 | storePaths = [ os.path.split(p)[0] for p in trajPaths] 27 | #a = [os.path.splitext(p) for p in trajPaths] 28 | #b = [list(t) for t in zip(*a)] 29 | 30 | #storePaths = b[0] 31 | 32 | print(storePaths) 33 | #sys.exit(12984) 34 | 35 | for storePath in storePaths: 36 | try: 37 | os.makedirs(storePath + '/' + 'flat') 38 | except: 39 | pass 40 | 41 | cm = plt.get_cmap('gist_rainbow') 42 | c = 0 43 | 44 | if args.endat is None: 45 | endat = 1e100 46 | else: 47 | endat = args.endat 48 | 49 | 50 | def analyze(filePath, storePath, name = None): 51 | fileName = os.path.split(storePath)[1] 52 | print(filePath) 53 | if name == None: 54 | storePath += '/' + 'flat/' 55 | else: 56 | storePath += '/' + name + '/' 57 | 58 | voro = [] 59 | #polyCountEvo = {1:[], 2:[], 3:[], 4:[], 5:[], 6:[], 7:[], 8:[], 9:[], 10:[], 11:[], 12:[], 13:[], 14:[], 15:[]} 60 | polyCountEvo = {4:[], 5:[], 6:[], 7:[], 8:[]} 61 | colorDict = {3:'k', 4:'w', 5:'g', 6:'r', 7:'c', 8:'m', 9:'y', 10:'k', 11:'k', 12:'k', 13:'k', 14:'k', 15:'k', 16:'k', 17:'k', 18:'k', 19:'k', 20:'k', 21:'k'} 62 | 63 | #ncLocDict = {0.1:[], 0.2:[], 0.3:[], 0.4:[], 0.5:[], 0.6:[], 0.7:[], 0.8:[], 0.9:[]} 64 | #rList = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9] 65 | ncLocDict = {0.1:[], 0.2:[], 0.3:[], 0.4:[], 0.5:[], 0.6:[]} 66 | rList = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6] 67 | 68 | with open(filePath, 'r') as comFile: 69 | timeStep = 0 70 | U_prev = [] 71 | 72 | while True: 73 | xLine = comFile.readline() 74 | xLine = xLine.strip() 75 | if xLine == "" or timeStep >= endat: 76 | break 77 | timeStep +=1 78 | print("Processing time step %d of %s" % (timeStep, fileName)) 79 | yLine = comFile.readline().strip() 80 | X = np.array([float(f) for f in xLine.split(' ')]) 81 | Y = np.array([float(f) for f in yLine.split(' ')]) 82 | 83 | if (X.size != Y.size): 84 | raise('X.size != Y.size') 85 | 86 | U = np.array([X, Y]).T 87 | CoM = U.mean(axis=0) 88 | 89 | # Normalize data to CoM at origin 90 | U -= CoM 91 | 92 | # Calculate distance of each cell from CoM (origin) 93 | # ie get magnitude of each position vector 94 | dists = np.linalg.norm(U, axis=1) # this needs latest numpy version 95 | 96 | # get max distance from CoM 97 | maxDist = dists.max() 98 | if (0 < maxDist < 0.001): 99 | raise("maxDist too low to continue") 100 | 101 | rel2MaxDists = dists/maxDist 102 | 103 | # Only use cells that are within some fraction of the maximum system size 104 | # This uses boollean indexing, please ask if confused 105 | 106 | U_near = U[rel2MaxDists < 0.8] 107 | nCells = U_near.shape[0] 108 | voro = Voronoi(U_near) 109 | cellList = [] 110 | for region in voro.regions: 111 | if -1 not in region and len(region) != 0: # region containing index -1 means infinite region 112 | cellList.append(region) 113 | 114 | 115 | # Count polygon types 116 | polyCount = {} 117 | polyTypes = [len(cell) for cell in cellList] 118 | nCellsCounted = len(cellList) 119 | increment = 1.0/nCellsCounted 120 | for poly in polyTypes: 121 | if not poly in polyCount: 122 | polyCount.update({poly:increment}) # test comment 123 | else: 124 | polyCount[poly]+=increment 125 | 126 | for pt in polyCountEvo: 127 | if pt not in polyCount: 128 | polyCountEvo[pt].append(0) 129 | else: 130 | polyCountEvo[pt].append(polyCount[pt]) 131 | 132 | # Get all new cells and process where they are 133 | if U_prev == [] or U_prev.size == U.size: 134 | U_prev = np.copy(U) 135 | U = [] 136 | for r in rList: 137 | ncLocDict[r].append(0) 138 | else: 139 | # get all cells not in previous 140 | newCells = U[-1*(U.shape[0] - U_prev.shape[0]) :] 141 | print(U_prev.shape, newCells.shape) 142 | inc = 1.0/newCells.shape[0] 143 | newCellDistFracs = np.linalg.norm(newCells, axis=1)/maxDist 144 | for r in rList: 145 | m1 = newCellDistFracs >= r - 0.05 146 | m2 = newCellDistFracs <= r + 0.05 147 | frac = (m1*m2).sum()*inc 148 | ncLocDict[r].append(frac) 149 | U_prev=np.copy(U) 150 | U = [] 151 | 152 | 153 | 154 | print("Plotting %s polygon count..." % fileName) 155 | 156 | timeRange=np.arange(len(polyCountEvo[6])) 157 | 158 | for pt in range(4,9): 159 | if sum(polyCountEvo[pt]) > 0: 160 | plt.plot(timeRange, [100*f for f in polyCountEvo[pt]], lw = 2, label='%s sided' % pt, alpha=0.7) 161 | 162 | plt.legend() 163 | plt.xlabel('Time') 164 | plt.ylabel('Polygon Fraction (%)') 165 | plt.savefig(storePath + '%d_polyevo.png' % timeStep) 166 | plt.close() 167 | 168 | 169 | print("Charting %s bars..." % fileName) 170 | # Generate bar charts 171 | plt.bar(np.array(list(polyCountEvo.keys())) - 0.5, 172 | [np.mean(polyCountEvo[key][-20:]) for key in polyCountEvo], 173 | yerr = [np.std(polyCountEvo[key][-20:]) for key in polyCountEvo], 174 | ecolor='k', color='grey') 175 | yerr=[np.std(polyCountEvo[key][-100:]) for key in polyCountEvo] 176 | plt.xlabel('Polygon type') 177 | plt.ylabel('fraction') 178 | plt.ylim((0,1)) 179 | plt.savefig(storePath + '%d_barcharts.png' % timeStep) 180 | plt.close() 181 | 182 | 183 | print("Voronoi-ing %s..." % fileName) 184 | # Make voronoi of last time step 185 | for region in voro.regions: 186 | if not -1 in region and len(region)!=0: 187 | polygon=[voro.vertices[i] for i in region] 188 | plt.fill(*zip(*polygon), color=colorDict[len(region)]) 189 | 190 | # plot the ridges so that we can see individual cells 191 | for simplex in voro.ridge_vertices: 192 | simplex=np.asarray(simplex) 193 | if np.all(simplex >= 0): 194 | plt.plot(voro.vertices[simplex,0], voro.vertices[simplex, 1], 'k-') 195 | 196 | 197 | # Readjust the graph to center on our cells 198 | ptp_bound = voro.points.ptp(axis=0) 199 | 200 | plt.xlim(voro.points[:, 0].min() - 0.1*ptp_bound[0], 201 | voro.points[:, 0].max() + 0.1*ptp_bound[0]) 202 | plt.ylim(voro.points[:, 1].min() - 0.1*ptp_bound[1], 203 | voro.points[:, 1].max() + 0.1*ptp_bound[1]) 204 | 205 | plt.savefig(storePath + '%d_voronoi.png' % (timeStep)) 206 | plt.close() 207 | 208 | print("Mapping %s mitotic cells..." % fileName) 209 | #Plot eh mitotic cells over time and r fraction 210 | # see http://stackoverflow.com/questions/8389636/creating-over-20-unique-legend-colors-using-matplotlib 211 | # and http://stackoverflow.com/questions/4700614/how-to-put-the-legend-out-of-the-plot 212 | fig=plt.figure() 213 | #cm = plt.get_cmap('gist_rainbow') 214 | ax =fig.add_subplot(111) 215 | #ax.set_color_cycle([cm(1.*i/10) for i in range(10)]) 216 | c = 0 217 | for r in rList: 218 | c += 1 219 | ran = np.random.uniform(0, 1, 1) 220 | line,=ax.plot(timeRange[-50:], ncLocDict[r][-50:], marker=(4, 0, 0), 221 | label="%.1f Rmax" % r) 222 | 223 | plt.ylabel("Fraction") 224 | plt.xlabel("Time") 225 | plt.legend(loc='upper center', bbox_to_anchor=(0.5, 1.15), ncol = 3, 226 | fancybox=True, shadow=True) 227 | plt.savefig(storePath + '%d_MitoticFractVSR.png' % timeStep) 228 | plt.close() 229 | 230 | for i in range(len(trajPaths)): 231 | analyze(trajPaths[i], storePaths[i]) 232 | -------------------------------------------------------------------------------- /scripts/GetPacking3D.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | #This script measures 3D packing. It is unclear how useful this measurement will 4 | #be. But I think it is worth seeing what we get. 5 | 6 | 7 | import matplotlib 8 | matplotlib.use("Agg") 9 | 10 | import matplotlib.pyplot as plt 11 | import numpy as np 12 | from scipy.spatial import Delaunay 13 | from scipy.spatial.qhull import QhullError 14 | import os, sys, argparse 15 | import csv 16 | from scipy.optimize import curve_fit 17 | from scipy.stats import lognorm 18 | 19 | sys.path.append("/home/pranav/dev/celldiv/scripts") 20 | import celldiv 21 | 22 | from scipy.spatial.qhull import QhullError 23 | 24 | desc=""" 25 | This script will measure the polygonal packing of a 3D system of cells with 26 | Voronoi Tesselation. 27 | """ 28 | 29 | parser = argparse.ArgumentParser(description=desc) 30 | 31 | parser.add_argument("--traj", nargs="+", 32 | help="One or more absolute or relative paths to trajectories") 33 | parser.add_argument("--endat", type=int, 34 | help="time step to stop processing at") 35 | parser.add_argument("-k", "--skip", type=int, required=False, 36 | help="Frame skip rate") 37 | 38 | parser.add_argument("-f", "--flat", type=bool, 39 | help="Flag that enables analysis of epithelia", 40 | default=False, required=False) 41 | args = parser.parse_args() 42 | 43 | trajPaths = [os.path.abspath(p) for p in args.traj] 44 | storePaths = [os.path.split(p)[0] for p in trajPaths] 45 | 46 | if args.endat is None: 47 | endat = 1e100 48 | else: 49 | endat = args.endat 50 | 51 | aRate = args.skip 52 | 53 | if args.skip is None: 54 | aRate = 1 55 | 56 | def measurePacking(filePath, storePath, name=None): 57 | fileName = os.path.splitext(os.path.split(filePath)[1])[0] 58 | print("Processing %s" % filePath) 59 | if name == None: 60 | storePath += '/' + fileName + '/' + '3DPacking/' 61 | else: 62 | storePath += '/' + fileName + '/' + name + '/' 63 | 64 | try: 65 | os.makedirs(storePath) 66 | except: 67 | pass 68 | 69 | dataPath = storePath + "data_best.dat" 70 | # Now read trajectory file and get the centre of masses of 71 | # all cells at every time step 72 | if os.path.isfile(dataPath): 73 | if os.path.getmtime(dataPath) > os.path.getmtime(filePath): 74 | print("{0} already processed.".format(filePath)) 75 | print("Skipping") 76 | return dataPath 77 | 78 | print("Generating cell CoMs...") 79 | 80 | with celldiv.TrajHandle(filePath) as s,\ 81 | open(storePath + "data.dat", 'w') as f: 82 | 83 | while True: 84 | try: 85 | frame = s.ReadFrame(inc = aRate) 86 | except: 87 | break 88 | step = s.step 89 | if s.fatalError: 90 | break 91 | 92 | nCells = len(frame) 93 | 94 | frame = [cell[:180] for cell in frame] 95 | 96 | if nCells > 3: 97 | CoMs = np.array([np.mean(cell, axis=0) for cell in frame]) 98 | sysCoM = np.mean(CoMs, axis=0) 99 | CoMs -= sysCoM 100 | 101 | if args.flat == True: 102 | CoMs = CoMs[:, 0:2] 103 | 104 | print("Doing Del of", CoMs.shape[0], "cells at step", step) 105 | try: 106 | d = Delaunay(CoMs) 107 | indices, indptr = d.vertex_neighbor_vertices 108 | count = [] 109 | for p in range(nCells): 110 | n = len(indptr[indices[p]:indices[p+1]]) 111 | if n > len(count): 112 | for i in range(len(count), n): 113 | count.append(0) 114 | count[n-1] += 1/nCells 115 | 116 | f.write(", ".join([str(c) for c in count])) 117 | f.write("\n") 118 | 119 | except QhullError: 120 | print("delaunay failed, skipping") 121 | pass 122 | 123 | return dataPath 124 | 125 | for i in range(len(trajPaths)): 126 | measurePacking(trajPaths[i], storePaths[i]) 127 | -------------------------------------------------------------------------------- /scripts/KinEnergy.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys 3 | import matplotlib 4 | matplotlib.use('Agg') 5 | import matplotlib.style 6 | matplotlib.style.use('ggplot') 7 | import matplotlib.pyplot as plt 8 | 9 | 10 | import numpy as np 11 | import celldiv as cd 12 | import argparse 13 | from tqdm import tqdm 14 | import pandas as pd 15 | 16 | parser = argparse.ArgumentParser() 17 | 18 | #parser.add_argument("traj", type=str) 19 | 20 | parser.add_argument("-k", "--skip", 21 | help="Trajectory frame skip rate", 22 | type = int, 23 | default = 1) 24 | 25 | parser.add_argument("-s", "--step", 26 | help="Trajectory frame skip rate", 27 | type = int, 28 | default = 1) 29 | 30 | #parser.add_argument('dt', type=float) 31 | 32 | parser.add_argument('csv') 33 | 34 | 35 | args=parser.parse_args() 36 | 37 | # t = 0 38 | # dt = args.skip*args.dt 39 | # with cd.TrajHandle(args.traj) as th: 40 | # t = dt*(int(th.maxFrames/args.skip)) 41 | # print(dt, t) 42 | # keList = [0 for i in range(int(th.maxFrames/args.skip))] 43 | # f1 = np.vstack(th.ReadFrame(inc=args.skip)) 44 | # f1 -= np.mean(f1, axis=0) 45 | # for i in tqdm(range(int(th.maxFrames/args.skip))): 46 | # frame = np.vstack(th.ReadFrame(inc=args.skip)) 47 | # frame -= np.mean(frame, axis=0) 48 | # Vs = (frame[:f1.shape[0]] - f1)/dt 49 | # keList[i] = 0.5*np.sum(np.linalg.norm(Vs, axis=1)**2) 50 | # f1 = np.copy(frame) 51 | 52 | 53 | # plt.plot(keList, lw=1.5, label="calculated") 54 | 55 | 56 | d = pd.read_csv(args.csv, usecols=["step", "F", "V"]).as_matrix() 57 | keList2 = [] 58 | FList=[] 59 | VList =[] 60 | for s in tqdm(range(0, int(d[:,0].max()), args.step*args.skip)): 61 | V = d[d[:, 0] == s, 1] 62 | F = d[d[:, 0] == s, 2] 63 | keList2.append(np.sum(0.5*V**2)) 64 | FList.append(np.sum(F)) 65 | 66 | plt.plot(keList2, '.', lw=1.5, label="velocity") 67 | plt.legend() 68 | plt.gca().set_yscale('log') 69 | plt.savefig('ke.png') 70 | plt.cla() 71 | plt.semilogy(FList, '.', label="force") 72 | plt.savefig('force.png') 73 | plt.cla() 74 | # plt.plot(VList, '.', label="volumes") 75 | # plt.savefig('vol.png') 76 | -------------------------------------------------------------------------------- /scripts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftSimu/CellSim3D/79393c8f00479cad7bb59e6a21144e71a10cc21c/scripts/__init__.py -------------------------------------------------------------------------------- /scripts/cellvel.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ipython 2 | 3 | import sys 4 | import matplotlib 5 | matplotlib.use('Agg') 6 | 7 | 8 | import matplotlib.pyplot as plt 9 | import numpy as np 10 | 11 | trajFileName = sys.argv[1] 12 | cellNo = int(sys.argv[2]) 13 | 14 | nAtoms = 0 15 | nCells = 0 16 | cmx = 0.0 17 | cmy = 0.0 18 | cmz = 0.0 19 | step = 0 20 | foundStep = 0 21 | cellX = [] 22 | cellY = [] 23 | cellZ = [] 24 | isFirst = True 25 | temp = 0 26 | dt = 0 27 | sysCMx = 0.0 28 | sysCMy = 0.0 29 | sysCMz = 0.0 30 | 31 | sysX = [] 32 | sysY = [] 33 | sysZ = [] 34 | 35 | with open(trajFileName, 'r') as trajFile: 36 | line = trajFile.readline() 37 | while (line != ""): 38 | line = line.strip() 39 | nAtoms = int(line) 40 | temp = step 41 | step = int(trajFile.readline().strip()[6:]) 42 | nCells = nAtoms/192 43 | 44 | if not foundStep: 45 | print "Processing step %d" % step 46 | 47 | if (nCells < cellNo): 48 | # skip the current time step if it does not contain 49 | # the cell of interest 50 | for i in xrange(nAtoms): 51 | trajFile.readline() 52 | else: 53 | if (isFirst): 54 | isFirst = False 55 | print "Cell was born near step %d" % step 56 | foundStep = step 57 | 58 | # only contribute to the system center of mass for all the 59 | # preceeding cells 60 | for i in xrange( (cellNo - 1) * 192): 61 | line = trajFile.readline().strip() 62 | line = line.split(", ") 63 | sysCMx += float(line[0]) 64 | sysCMy += float(line[1]) 65 | sysCMz += float(line[2]) 66 | 67 | for i in xrange(192): # read the cell of interest 68 | line = trajFile.readline().strip() 69 | line = line.split(", ") 70 | cmx += float(line[0]) 71 | cmy += float(line[1]) 72 | cmz += float(line[2]) 73 | sysCMx += float(line[0]) 74 | sysCMy += float(line[1]) 75 | sysCMz += float(line[2]) 76 | 77 | cmx /= 180.0 78 | cmy /= 180.0 79 | cmz /= 180.0 80 | 81 | 82 | 83 | cellX.append(cmx) 84 | cellY.append(cmy) 85 | cellZ.append(cmz) 86 | 87 | cmx = 0.0 88 | cmy = 0.0 89 | cmz = 0.0 90 | 91 | # Now get the contribution to system center of mass of the remaining 92 | # cells 93 | for i in xrange( (nCells - cellNo)*192 ): 94 | line = trajFile.readline().strip() 95 | line = line.split(", ") 96 | sysCMx += float(line[0]) 97 | sysCMy += float(line[1]) 98 | sysCMz += float(line[2]) 99 | 100 | sysCMx /= nCells * 180 101 | sysCMy /= nCells * 180 102 | sysCMz /= nCells * 180 103 | 104 | # print sysCMx, sysCMy, sysCMz 105 | 106 | sysX.append(sysCMx) 107 | sysY.append(sysCMy) 108 | sysZ.append(sysCMz) 109 | 110 | sysCMx = 0.0 111 | sysCMy = 0.0 112 | sysCMz = 0.0 113 | 114 | line = trajFile.readline() 115 | 116 | 117 | if (isFirst): 118 | print "The system is not that big! Only have %d cells." % nCells 119 | sys.exit() 120 | 121 | 122 | cellX = np.array(cellX) 123 | cellY = np.array(cellY) 124 | cellZ = np.array(cellZ) 125 | 126 | sysX = np.array(sysX) 127 | sysY = np.array(sysY) 128 | sysZ = np.array(sysZ) 129 | 130 | 131 | cellX = cellX - sysX 132 | cellY = cellY - sysY 133 | cellZ = cellZ - sysZ 134 | 135 | plt.subplot(2, 2, 1) 136 | plt.plot(cellX, cellY, "k.") 137 | plt.xlabel("cellX") 138 | plt.ylabel("cellY") 139 | 140 | plt.subplot(2, 2, 2) 141 | plt.plot(cellX, cellZ, "k.") 142 | plt.xlabel("cellX") 143 | plt.ylabel("cellZ") 144 | 145 | plt.subplot(2, 2, 3) 146 | plt.plot(cellY, cellZ, "k.") 147 | plt.xlabel("cellY") 148 | plt.ylabel("cellZ") 149 | 150 | 151 | plt.suptitle("Movement of cell no. %d" % cellNo) 152 | plt.tight_layout() 153 | plt.savefig("cell_%d.png" % cellNo) 154 | plt.close() 155 | 156 | # Get avg cell velocity 157 | v = [] 158 | dt = step - temp 159 | for i in xrange(len(cellX) - 1): 160 | dx = cellX[i+1] - cellX[i] 161 | dy = cellY[i+1] - cellY[i] 162 | dz = cellZ[i+1] - cellZ[i] 163 | v.append(np.sqrt(dx*dx + dy*dy + dz*dz)/dt) 164 | 165 | plt.plot(range(foundStep, step, dt), v, 'k.') 166 | plt.xlabel("t") 167 | plt.ylabel("V") 168 | plt.text(0.5, 0.5, "dt = %s steps" % dt) 169 | plt.savefig("cell_%d_vel.png" % cellNo) 170 | plt.close() 171 | 172 | 173 | -------------------------------------------------------------------------------- /scripts/center.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys, os, argparse 3 | import numpy as np 4 | 5 | desc = """ 6 | Centres a cell system to its center of mass. 7 | """ 8 | 9 | parser = argparse.ArgumentParser(description=desc) 10 | 11 | parser.add_argument("trajPaths", nargs='+', 12 | help="Path (absolute or relative) of any number of trajectory files") 13 | args = parser.parse_args() 14 | trajPaths = [os.path.abspath(p) for p in args.trajPaths] 15 | a = [os.path.splitext(p) for p in trajPaths] 16 | b = [list(t) for t in zip(*a)] 17 | 18 | storePaths = b[0] 19 | 20 | def Center(trajPath, storePath, name=None): 21 | if name == None: 22 | storePath += "_centered.xyz" 23 | else: 24 | storePath += name + ".xyz" 25 | print storePath 26 | 27 | X = [] 28 | Y = [] 29 | Z = [] 30 | 31 | CMx = 0 32 | CMy = 0 33 | CMz = 0 34 | with open(trajPath, "r") as inFileHandle: 35 | with open(storePath, "w") as outFileHandle: 36 | line = inFileHandle.readline() 37 | while (line!=""): 38 | outFileHandle.writelines(line) 39 | line = line.strip() 40 | nAtoms = int(line) 41 | step = int(inFileHandle.readline().strip()[6:]) 42 | outFileHandle.write("Step: %d\n" % step) 43 | print "Processing %d..." % step 44 | 45 | for i in xrange(nAtoms): 46 | line = inFileHandle.readline().strip().split(', ') 47 | X.append(float(line[0])) 48 | Y.append(float(line[1])) 49 | Z.append(float(line[2])) 50 | 51 | CMx = np.mean(np.array(X)) 52 | CMy = np.mean(np.array(Y)) 53 | CMz = np.mean(np.array(Z)) 54 | 55 | X = [t - CMx for t in X] 56 | Y = [t - CMy for t in Y] 57 | Z = [t - CMz for t in Z] 58 | 59 | for i in xrange(len(X)): 60 | outFileHandle.writelines("%f, %f, %f\n" % (X[i], Y[i], Z[i])) 61 | 62 | CMx, CMy, CMz = 0, 0, 0 63 | 64 | X, Y, Z = [], [], [] 65 | 66 | line = inFileHandle.readline() 67 | 68 | 69 | for i in xrange(len(trajPaths)): 70 | Center(trajPaths[i], storePaths[i] ) 71 | -------------------------------------------------------------------------------- /scripts/cs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import argparse 4 | import os 5 | import io 6 | import sys 7 | import numpy as np 8 | from tqdm import tqdm 9 | import pandas as pd 10 | 11 | import celldiv as cd 12 | 13 | import matplotlib as mpl 14 | mpl.use("Agg") 15 | 16 | import matplotlib.pyplot as plt 17 | import numpy as np 18 | from scipy.spatial import ConvexHull 19 | 20 | desc = """""" 21 | 22 | parser = argparse.ArgumentParser() 23 | 24 | parser.add_argument("traj", 25 | help="Trajectory file name", 26 | type=str) 27 | 28 | parser.add_argument("-k", "--skip", 29 | help="Trajectory frame skip rate", 30 | type=int, 31 | default=1) 32 | parser.add_argument("-t", "--threshold", 33 | help="Threshold distance from plane within which plotted", 34 | type=float, 35 | default=0.1) 36 | parser.add_argument("-l", "--set-limits", 37 | help="Set limits for the video. Must read trajectory twice. \ 38 | Must be a complete trajectory file.", 39 | type=bool, 40 | default=True) 41 | 42 | parser.add_argument("-o", "--out", 43 | help="Output file name (with format)", 44 | type=str, 45 | default="cs.png") 46 | 47 | parser.add_argument("-p", "--pixel", 48 | help="Plot pixels instead of points", 49 | action="store_true") 50 | 51 | parser.add_argument("-c", "--clear", 52 | help="Toggle clearing of storage directory", 53 | type=bool, 54 | default=True) 55 | 56 | parser.add_argument("--forces", type=str, default="", 57 | help="contact force csv file name", required=False) 58 | 59 | parser.add_argument("--colormap", type=str, default="viridis", 60 | required=False, 61 | help="Color map to use for the force heatmap.\ 62 | see: http://matplotlib.org/examples/color/colormaps_reference.html") 63 | 64 | parser.add_argument("--ref-force", type=str, default="med", required=False, 65 | help="The reference force to plot relative stress too. 'med'\ 66 | uses median, 'max' uses the maximum force") 67 | 68 | parser.add_argument("--last-frame", "-lf", type=int, default=-1, required=False, 69 | help="Only analyze upto this frame. This is useful for\ 70 | analyzing really large simulations that can also be still in\ 71 | progress") 72 | 73 | parser.add_argument("-f", "--frame", type=int, default=-1, required=False, 74 | help="Only analyze this one frame.") 75 | 76 | 77 | args = parser.parse_args() 78 | trajPath = os.path.abspath(args.traj) 79 | 80 | forcePath = [] 81 | header = [] 82 | forceFileHandle = [] 83 | header = "" 84 | if args.forces is not "": 85 | forcePath = os.path.abspath(args.forces) 86 | forceFileHandle = open(forcePath, "r") 87 | header = forceFileHandle.readline() 88 | 89 | storePath, trajFileName = os.path.split(trajPath) 90 | trajFileName = os.path.splitext(trajFileName)[0] 91 | 92 | storePath += "/" + trajFileName + "/cs/" 93 | 94 | print ("Saving to", storePath) 95 | 96 | cmap = plt.get_cmap(args.colormap) 97 | 98 | if not os.path.exists(storePath): 99 | os.makedirs(storePath) 100 | 101 | if args.clear: 102 | for f in os.listdir(storePath): 103 | os.remove(storePath + f) 104 | 105 | outName = os.path.splitext(args.out) 106 | 107 | fig, ax = plt.subplots() 108 | fig.set_size_inches(10, 10) 109 | 110 | 111 | ax.set_xlabel("$X$") 112 | ax.set_ylabel("$Y$") 113 | 114 | frames = [] 115 | 116 | 117 | maxes = [] 118 | mins = [] 119 | 120 | if args.set_limits: 121 | with cd.TrajHandle(trajPath) as th: 122 | print("Getting movie limits...") 123 | 124 | if args.last_frame > 0 and args.last_frame > th.maxFrames: 125 | print("Trajectory only has {0} frames".format(th.maxFrames)) 126 | args.last_frame = -1 127 | 128 | if args.frame > 0 and args.frame > th.maxFrames: 129 | print("Trajectory only has {0} frames".format(th.maxFrames)) 130 | args.frame = th.maxFrames 131 | 132 | if args.frame > 0: 133 | frame = np.vstack(th.ReadFrame(args.frame)) 134 | elif args.last_frame > 0: 135 | frame = np.vstack(th.ReadFrame(args.last_frame)) 136 | else: 137 | frame = np.vstack(th.ReadFrame(th.maxFrames)) 138 | 139 | frame = frame - np.mean(frame, axis=0) 140 | zs = np.abs(frame[:, 2]) 141 | m = zs <= args.threshold 142 | frame = frame[m] 143 | maxes = np.ceil(np.max(frame, axis=0)) 144 | mins = np.floor(np.min(frame, axis=0)) 145 | print("Done") 146 | 147 | 148 | ax.set_xlim([mins[0], maxes[0]]) 149 | ax.set_ylim([mins[1], maxes[1]]) 150 | 151 | cax = fig.add_axes([0.925, 0.2, 0.025, 0.6]) 152 | #norm = mpl.colors.Normalize(vmin=0.0, vmax=1.0) 153 | cbar = mpl.colorbar.ColorbarBase(cax, cmap=cmap, 154 | orientation='vertical') 155 | 156 | cbar.set_ticks([0.0, 0.5, 1.0]) 157 | 158 | cax.text(0.0125, 1.05, "$\\frac{F_i}{F_{%s}}$" % args.ref_force, fontsize=20) 159 | 160 | print("Creating frames...") 161 | 162 | 163 | def GetStepForces(step): 164 | done = False 165 | stepForces = io.StringIO() 166 | stepForces.write(header) # write header 167 | n = 0 168 | while True: 169 | x = forceFileHandle.tell() 170 | line = forceFileHandle.readline().strip().split(",") 171 | if int(line[0]) < step: 172 | for _ in range(int(line[1]) * 180): 173 | #next(forceFileHandle) 174 | forceFileHandle.readline() 175 | 176 | if int(line[0]) > step: 177 | forceFileHandle.seek(x) 178 | break 179 | 180 | if int(line[0]) == step: 181 | n = int(line[1])*180 182 | forceFileHandle.seek(x) 183 | for _ in range(n): 184 | stepForces.write(forceFileHandle.readline()) 185 | 186 | stepForces.seek(0) 187 | return stepForces 188 | 189 | 190 | with cd.TrajHandle(trajPath) as th: 191 | n = args.last_frame if args.last_frame > 0 else th.maxFrames 192 | for i in tqdm(range(int(n/args.skip))): 193 | ax.set_title("$t = {0}$".format(i+1)) 194 | try: 195 | frame = th.ReadFrame(inc=args.skip) 196 | if args.frame > 0 and th.currFrameNum < args.frame: 197 | continue 198 | 199 | if args.frame > 0 and th.currFrameNum > args.frame: 200 | break 201 | 202 | cellTypes = th.currTypes 203 | Xs0 = [] 204 | Ys0 = [] 205 | 206 | Xs1 = [] 207 | Ys1 = [] 208 | 209 | Forces = [] 210 | avgCellForces = [] 211 | datLens = [] 212 | 213 | sysCM = np.mean(np.vstack(frame), axis=0) 214 | frame = [c[:180] - sysCM for c in frame] 215 | 216 | if args.forces is not "" and th.step>0: 217 | sF = GetStepForces(th.step) 218 | Forces = pd.read_csv(sF)[["cell_ind", "FX", "FY", "FZ"]] 219 | sF.close() 220 | 221 | c = 0 222 | for cell, cellType in zip(frame, cellTypes): 223 | Zs = np.abs(cell[:, 2]) 224 | m = Zs <= args.threshold 225 | data = cell[m] 226 | datLens.append(data.shape[0]) 227 | if cellType == 0: 228 | Xs0.append(data[:, 0]) 229 | Ys0.append(data[:, 1]) 230 | else: 231 | Xs1.append(data[:, 0]) 232 | Ys1.append(data[:, 1]) 233 | 234 | if args.forces is not "" and th.step > 0: 235 | cellForces = Forces[Forces["cell_ind"] == c][["FX", "FY", "FZ"]] 236 | avgCellForces.append(np.linalg.norm(cellForces.as_matrix(), 237 | axis=1).sum()) 238 | c += 1 239 | 240 | 241 | ax.lines=[] 242 | 243 | if args.pixel: 244 | ax.plot(np.hstack(Xs0), np.hstack(Ys0), "k,", label="hard") 245 | if sum(cellTypes) > 0: 246 | ax.plot(np.hstack(Xs1), np.hstack(Ys1), "k,", label="soft") 247 | else: 248 | ax.plot(np.hstack(Xs0), np.hstack(Ys0), "k.", label="hard") 249 | if sum(cellTypes) > 0: 250 | ax.plot(np.hstack(Xs1), np.hstack(Ys1), "k.", label="soft") 251 | 252 | if args.forces is not "" and th.step>0: 253 | ax.patches=[] 254 | ref_force = np.median(avgCellForces) 255 | if args.ref_force == "max": 256 | ref_force = max(avgCellForces) 257 | 258 | for x,y,f in zip(Xs0, Ys0, avgCellForces): 259 | p = np.array([x,y]).T 260 | hull = ConvexHull(p) 261 | ax.fill(p[hull.vertices, 0], p[hull.vertices, 1], 262 | color=cmap(f/ref_force)) 263 | 264 | fig.savefig(storePath + outName[0] + "{0}".format(i+1) + outName[1]) 265 | 266 | except cd.IncompleteTrajectoryError as e: 267 | print(e.value) 268 | print("Stopping") 269 | break 270 | print("Done") 271 | 272 | if args.forces is not "": 273 | forceFileHandle.close() 274 | -------------------------------------------------------------------------------- /scripts/get_gr.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | # This script will output g(r) for aribitrary no. of timestamps. 4 | 5 | import sys 6 | import matplotlib 7 | import os 8 | matplotlib.use("agg") 9 | 10 | import matplotlib.pyplot as plt 11 | import numpy as np 12 | from math import ceil 13 | from scipy.spatial import Voronoi, voronoi_plot_2d 14 | 15 | 16 | minNumArgs = 2 17 | 18 | erorrMessage = """ 19 | Usage: shaper input.xyz t1 t2 t3 ... 20 | input.xyz: input trajectory file 21 | t1 t2 t3 ...: timestamps, use any number of them you like 22 | """ 23 | 24 | if len(sys.argv) < minNumArgs: 25 | print errorMessage 26 | sys.exit(1) 27 | 28 | 29 | trajPath = os.path.abspath(sys.argv[1]) 30 | storPath, fileName = os.path.split(trajPath) 31 | trajName = os.path.splitext(fileName)[0] 32 | 33 | storPath += "/" + fileName 34 | 35 | timeStamps = sys.argv[2:] 36 | 37 | # Make timeStamps ints 38 | 39 | timeStamps = [int(ts) for ts in timeStamps] 40 | timeStamps.sort() 41 | 42 | 43 | 44 | # seek and compute g(r) for each time stamp requested 45 | 46 | X = [] 47 | Y = [] 48 | Z = [] 49 | 50 | CMx = [] 51 | CMy = [] 52 | CMz = [] 53 | 54 | CM_x = 0 55 | CM_y = 0 56 | CM_z = 0 57 | 58 | gr = plt.figure(1) 59 | vor = plt.figure(2) 60 | 61 | 62 | def getNonNans(a): 63 | nans = np.isnan(a) 64 | notnans = np.invert(nans) 65 | return a[notnans] 66 | 67 | 68 | def ComputeGr(X, Y, Z): 69 | print "okay :(" 70 | X = np.array(X) 71 | Y = np.array(Y) 72 | Z = np.array(Z) 73 | 74 | X = getNonNans(X) 75 | Y = getNonNans(Y) 76 | Z = getNonNans(Z) 77 | 78 | vol = (X.max() - X.min()) * (Y.max() - Y.min()) * (Z.max() - Z.min()) 79 | # num density 80 | N = X.size 81 | rho = N/vol 82 | print rho 83 | 84 | dx = X - X[:, np.newaxis] 85 | dy = Y - Y[:, np.newaxis] 86 | dz = Z - Z[:, np.newaxis] 87 | 88 | r_cells = np.sqrt(dx*dx + dy*dy + dz*dz) 89 | dr = 0.01 90 | r_max = ceil(r_cells.max()) 91 | 92 | # looping through np.array is really slow 93 | # so converting to list 94 | rr = np.arange(2*dr, r_max, dr).tolist() 95 | g_r = [] 96 | for r in rr: 97 | n_over = r_cells > (r - dr/2.) 98 | n_under = r_cells < (r + dr/2.) 99 | n_mask = n_over*n_under 100 | n = n_mask.sum() 101 | s = 4*np.pi * r*r * dr 102 | n = n/s/rho 103 | n = n/N/2 104 | g_r.append(n) 105 | 106 | plt.plot(rr,g_r) 107 | plt.legend("a") 108 | 109 | g_r = [] 110 | 111 | 112 | 113 | 114 | def Voro (X, Y, ts, xstr, ystr): 115 | """Compute the voronoi diagram for a given set of points""" 116 | X = np.array(X) 117 | Y = np.array(Y) 118 | X = getNonNans(X) 119 | Y = getNonNans(Y) 120 | #print X.size==Y.size 121 | points = np.zeros([X.size, 2]) 122 | for i in xrange(X.size): 123 | points[i,0] = X[i] 124 | points[i,1] = Y[i] 125 | 126 | voronoi = Voronoi(points) 127 | #voronoi_plot_2d(voronoi) 128 | plt.title("CoM Voronoi\ntime stamp = %s" % ts) 129 | for region in voronoi.regions: 130 | if not -1 in region: 131 | polygon = [voronoi.vertices[i] for i in region] 132 | plt.fill(*zip(*polygon)) 133 | 134 | plt.xlim([np.floor(X.min()), np.ceil(X.max())]) 135 | plt.ylim([np.floor(Y.min()), np.ceil(Y.max())]) 136 | plt.xlabel(xstr) 137 | plt.ylabel(ystr) 138 | plt.savefig("vorlater.svg") 139 | 140 | 141 | with open(trajPath, "r") as trajFile: 142 | for timeStamp in timeStamps: 143 | print "Moving to time step %d ..." % timeStamp 144 | # move to time stamp, ignore everything 145 | while True: 146 | line = trajFile.readline().strip() 147 | nAtoms = int(line) 148 | line = trajFile.readline().strip() 149 | step = int(line[6:]) 150 | if (step >= timeStamp): 151 | break; 152 | print "skiping time step %d" % step 153 | 154 | for n in xrange(nAtoms): 155 | line = trajFile.readline() 156 | 157 | # we are at the timeStamp now 158 | nCells = nAtoms/192 159 | print "We have %d cells in the system" % (nCells) 160 | for n in xrange(nCells): 161 | for m in xrange(192): 162 | line = trajFile.readline().strip() 163 | line = line.split(", ") 164 | 165 | x = float(line[0]) 166 | y = float(line[1]) 167 | z = float(line[2]) 168 | 169 | X.append(x) 170 | Y.append(y) 171 | Z.append(Z) 172 | 173 | CM_x += x 174 | CM_y += y 175 | CM_z += z 176 | 177 | CMx.append(CM_x/192) 178 | CMy.append(CM_y/192) 179 | CMz.append(CM_z/192) 180 | 181 | CM_x = 0 182 | CM_y = 0 183 | CM_z = 0 184 | 185 | #Now process for g(r) 186 | 187 | Voro(CMx, CMy, timeStamp, "X", "Y") 188 | #Voro(CMx, CMz, timeStamp, "X", "Z") 189 | #Voro(CMy, CMy, timeStamp, "Y", "Z") 190 | X = [] 191 | Y = [] 192 | Z = [] 193 | CMx = [] 194 | CMy = [] 195 | CMz = [] 196 | 197 | gr.savefig("gr.png") 198 | -------------------------------------------------------------------------------- /scripts/inblender.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import bpy 3 | import csv 4 | import numpy as np 5 | import sys 6 | 7 | import celldiv 8 | 9 | class Visualizer(object): 10 | """ Class that opens and displays frames in a trajectory""" 11 | prevFrame = -1 12 | ind = 0 13 | def __init__(self, fPath): 14 | self.filePath = fPath 15 | self.th = celldiv.TrajHandle(fPath) 16 | Visualizer.ind += 1 17 | self.ind = Visualizer.ind 18 | self.pF = None 19 | 20 | bpy.data.worlds["World"].horizon_color=[0.051, 0.051, 0.051] 21 | bpy.data.scenes["Scene"].render.alpha_mode='SKY' 22 | 23 | self.firstfaces = [] 24 | 25 | with open("/home/pranav/dev/celldiv/C180_pentahexa.csv", newline='') as g: 26 | readerfaces = csv.reader(g, delimiter=",") 27 | for row in readerfaces: 28 | self.firstfaces.append([int(v) for v in row]) 29 | 30 | 31 | def DisplayFrame(self, frameNum: int = None, inc: int = None) -> None: 32 | if self.pF != frameNum: 33 | bpy.ops.object.select_pattern(pattern='cellObj%d' % self.ind) 34 | bpy.ops.object.delete() 35 | fr = self.th.ReadFrame(frameNum).tolist() 36 | f = [] 37 | for c in range(int(len(fr)/192)): 38 | for r in self.firstfaces: 39 | f.append([(v + c*192) for v in r]) 40 | 41 | 42 | mesh = bpy.data.meshes.new("cellMesh%d" % self.ind) 43 | ob = bpy.data.objects.new("cellObj%d" % self.ind, mesh) 44 | bpy.context.scene.objects.link(ob) 45 | mesh.from_pydata(fr, [], f) 46 | mesh.update() 47 | self.pF = self.th.currFrameNum 48 | 49 | def close(self): 50 | bpy.ops.object.select_pattern(pattern='cellObj%d' % self.ind) 51 | bpy.ops.object.delete() 52 | Visualizer.ind -=1 53 | self.th.close() 54 | -------------------------------------------------------------------------------- /scripts/make_video.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import bpy 3 | import csv 4 | 5 | frames = 0 6 | line = [] 7 | numVerts = 0 8 | numCells = 0 9 | vertsPerCell = 192 10 | verts = [] 11 | with open ('/home/pranav/Remotes/office/dev/CellDivision/dev/test.xyz', 'r') as trajFile: 12 | line = trajFile.readline() 13 | while (line != ""): 14 | if not "," in line and not ":" in line: 15 | frames += 1 16 | line = line.strip() 17 | numVerts = int(line) 18 | numCells = int(numVerts/vertsPerCell) 19 | 20 | line = trajFile.readline() 21 | for linNum in range(numVerts): 22 | line = trajFile.readline() 23 | line = line.strip() 24 | line = line.split(',') 25 | verts.append([float(v) for v in line]) 26 | line = trajFile.readline() 27 | 28 | firstfaces = [] 29 | faces = [] 30 | 31 | 32 | 33 | with open('/home/pranav/Remotes/office/dev/CellDivision/dev/C180_pentahexa.csv', 'r') as faceFile: 34 | faceVerts = csv.reader(faceFile, delimiter=',') 35 | for row in faceVerts: 36 | firstfaces.append([int(v) for v in row]) 37 | 38 | for cellIndex in range(numCells): 39 | for row in firstfaces: 40 | faces.append([(v+(cellIndex*192)) for v in row]) 41 | 42 | 43 | mesh = bpy.data.meshes.new('cellMesh') 44 | ob = bpy.data.objects.new('cellObject', mesh) 45 | bpy.context.scene.objects.link(ob) 46 | mesh.from_pydata(verts, [], faces) 47 | mesh.update() 48 | original_type = bpy.context.area.type 49 | bpy.context.area.type = "VIEW_3D" # switch to view3d context 50 | bpy.ops.object.select_by_type(type='MESH') 51 | bpy.context.scene.objects.active = bpy.data.objects['cellObject'] 52 | bpy.ops.object.editmode_toggle() 53 | bpy.ops.mesh.normals_make_consistent(inside=False) 54 | bpy.ops.object.editmode_toggle() 55 | bpy.ops.object.shade_smooth() 56 | bpy.context.scene.objects.active = bpy.data.objects['Cube'] 57 | bpy.ops.object.make_links_data(type='MATERIAL') # copy material from Cube 58 | bpy.context.scene.objects.active = bpy.data.objects['cellObject'] 59 | bpy.ops.object.select_all(action='TOGGLE') 60 | bpy.ops.object.modifier_add(type='SUBSURF') 61 | # bpy.ops.render.render() # ...if you want to render on screen 62 | bpy.context.area.type = original_type 63 | -------------------------------------------------------------------------------- /scripts/multibar2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # This script uses a lot of python magic 3 | # Please ask if there are is any confusion 4 | 5 | import matplotlib 6 | matplotlib.use('Agg') 7 | import matplotlib.pyplot as plt 8 | import numpy as np 9 | from scipy.spatial import Voronoi, voronoi_plot_2d 10 | import os, sys, argparse 11 | 12 | desc=""" 13 | A script to compare the hexagon percentages in a number of trajectories. 14 | """ 15 | 16 | parser = argparse.ArgumentParser(description=desc) 17 | 18 | parser.add_argument("--traj", nargs="+", 19 | help="Absolute or relative paths") 20 | parser.add_argument("--endat", type=int, 21 | help="time step to stop processing at") 22 | parser.add_argument("-o", 23 | help="Output File Name", 24 | type=str) 25 | 26 | args = parser.parse_args() 27 | 28 | if args.endat is None: 29 | endat = 1e100 30 | else: 31 | endat = args.endat 32 | 33 | if args.o is None: 34 | args.o = "multibar.png" 35 | 36 | trajList = [os.path.abspath(p) for p in args.traj] 37 | 38 | try: 39 | os.makedirs("./graphs") 40 | except: 41 | 0 42 | 43 | barFig = [] 44 | n = len(args.traj) 45 | width = 0.25 46 | 47 | gammas = ['0', '10', '20', '30', '40', '50', '100'] 48 | 49 | def analyze(filePath, cm, barAx, c, width, ind, polyTrendAx, gamma): 50 | voro = [] 51 | polyCountEvo = {1:[], 2:[], 3:[], 4:[], 5:[], 6:[], 7:[], 8:[], 9:[]} 52 | colorDict = {3:'k', 4:'w', 5:'g', 6:'r', 7:'c', 8:'m', 9:'y'} 53 | 54 | ncLocDict = {0.1:[], 0.2:[], 0.3:[], 0.4:[], 0.5:[], 0.6:[], 0.7:[], 0.8:[], 0.9:[]} 55 | rList = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9] 56 | 57 | path, fileName = os.path.split(filePath) 58 | fileName = path.split('/')[-1] 59 | with open(filePath, 'r') as comFile: 60 | timeStep = 0 61 | U_prev = [] 62 | while True: 63 | xLine = comFile.readline().strip() 64 | if xLine == "" or timeStep >= endat: 65 | break 66 | timeStep +=1 67 | #print "Processing time step %d of %s" % (timeStep, fileName) 68 | yLine = comFile.readline().strip() 69 | nCoM = 0 70 | X = np.array([float(f) for f in xLine.split(' ')]) 71 | Y = np.array([float(f) for f in yLine.split(' ')]) 72 | 73 | if (X.size != Y.size): 74 | raise('X.size != Y.size') 75 | 76 | U = np.array([X, Y]).T 77 | CoM = U.mean(axis=0) 78 | 79 | # Normalize data to CoM at origin 80 | U -= CoM 81 | 82 | # Calculate distance of each cell from CoM (origin) 83 | # ie get magnitude of each pos vector 84 | dists = np.linalg.norm(U, axis=1) # this needs latest numpy version 85 | 86 | # get max distance from CoM 87 | maxDist = dists.max() 88 | if (0 < maxDist < 0.001): 89 | raise("maxDist too low to continue") 90 | 91 | rel2MaxDists = dists/maxDist 92 | 93 | # Only use cells that are within some fraction of the maximum system size 94 | # This uses boollean indexing, please ask if confused 95 | 96 | U_near = U[rel2MaxDists < 0.8] 97 | nCells = U_near.shape[0] 98 | voro = Voronoi(U_near) 99 | cellList = [] 100 | for region in voro.regions: 101 | if -1 not in region and len(region) != 0: # region containing index -1 means infinite region 102 | cellList.append(region) 103 | 104 | 105 | # Count polygon types 106 | polyCount = {} 107 | polyTypes = [len(cell) for cell in cellList] 108 | nCellsCounted = len(cellList) 109 | increment = 1.0/nCellsCounted 110 | for poly in polyTypes: 111 | if not poly in polyCount: 112 | polyCount.update({poly:increment}) 113 | else: 114 | polyCount[poly]+=increment 115 | 116 | for pt in polyCountEvo: 117 | if pt not in polyCount: 118 | polyCountEvo[pt].append(0) 119 | else: 120 | polyCountEvo[pt].append(polyCount[pt]) 121 | 122 | # Get all new cells and process where they are 123 | if U_prev == [] or U_prev.size == U.size: 124 | U_prev = np.copy(U) 125 | for r in rList: 126 | ncLocDict[r].append(0) 127 | else: 128 | # get all cells not in previous 129 | newCells = U[-1*(U.shape[0] - U_prev.shape[0]) :] 130 | inc = 1.0/U.shape[0] 131 | newCellDistFracs = np.linalg.norm(newCells, axis=1)/maxDist 132 | for r in rList: 133 | m1 = newCellDistFracs >= r - 0.05 134 | m2 = newCellDistFracs <= r + 0.05 135 | frac = (m1*m2).sum()*inc 136 | ncLocDict[r].append(frac) 137 | 138 | 139 | 140 | #print "Plotting %s polygon count..." % fileName 141 | # 142 | #timeRange=np.arange(len(polyCountEvo[6]))*0.2 143 | # 144 | #for pt in polyCountEvo: 145 | # if sum(polyCountEvo[pt]) > 0: 146 | # plt.plot(timeRange, polyCountEvo[pt], label='%s sided' % pt) 147 | # 148 | #plt.legend(loc='upper left') 149 | #plt.xlabel('num time steps') 150 | #plt.ylabel('Cell Fraction') 151 | #plt.savefig('graphs/%s_polyevo.pdf' % fileName) 152 | #plt.close() 153 | 154 | 155 | print "Charting %s bars..." % fileName 156 | # Generate bar charts 157 | rects = [] 158 | meanFracs = [np.mean(polyCountEvo[key][:]) for key in ind] 159 | err = [np.std(polyCountEvo[key][100:]) for key in ind] 160 | cl = np.array([c*1.0/n]) 161 | pos = ind*(n+2)*width + c*width - ((n+2)/2.0 * width) 162 | 163 | barAx.bar(pos, meanFracs, width, yerr=err, 164 | label='%s%%' % gamma, ecolor='k', 165 | color=cm(cl)[0]) 166 | 167 | timeRange = xrange(len(polyCountEvo[6])) 168 | polyTrendAx.plot(timeRange, polyCountEvo[6], 169 | color=cm(cl)[0]) 170 | 171 | barFig, barAx = plt.subplots() 172 | polyTrendAx = plt.axes([0.2, 0.65, 0.4, 0.2]) 173 | cm = plt.get_cmap('rainbow') 174 | 175 | 176 | bargap = 0.05 177 | c = 0 178 | ind = np.arange(4, 9) 179 | for i in xrange(len(trajList)): 180 | analyze(trajList[i], cm , barAx, c, width, ind, polyTrendAx, gammas[i]) 181 | c +=1 182 | 183 | 184 | # plot experimental data 185 | print "Plotting experimental data..." 186 | pos = ind*(n+2)*width + c*width - ((n+2)/2.0 * width) 187 | 188 | # Reference for experimental results: 10.1038/nature05014 189 | expFracs = [0.028, 0.272, 0.458, 0.203, 0.015] 190 | expErrs = [0.016, 0.018, 0.024, 0.025, 0] 191 | #plot experimental data 192 | barAx.bar(pos, expFracs, width, yerr=expErrs, label='Drosophila', 193 | ecolor = 'k', color = 'r') 194 | 195 | pos = ind*(n+2)*width + (c+1)*width - ((n+2)/2.0 * width) 196 | 197 | #barAx.bar(pos, [0.5 for j in xrange(len(ind))], width, color='k') 198 | 199 | barAx.set_ylabel('Fraction') 200 | barAx.set_xlabel('Number of neighbours') 201 | barAx.set_title('Soft(80% Stiffness)/Normal Cell Packing') 202 | barAx.set_ylim((0,1)) 203 | 204 | 205 | barAx.set_xticks(ind*(n+2)*width - (width/2)) 206 | barAx.set_xticklabels(ind) 207 | barAx.legend(title='Percent Softer Cells') 208 | 209 | polyTrendAx.set_xlabel('Time') 210 | polyTrendAx.set_ylabel('Hexagons') 211 | -------------------------------------------------------------------------------- /scripts/nn.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | import numpy as np 4 | import celldiv as cd 5 | from tqdm import tqdm 6 | import argparse 7 | 8 | ap = argparse.ArgumentParser() 9 | 10 | ap.add_argument("--frame-num", "-fn", help="Single frame to analyze", 11 | type=int, default = 0) 12 | ap.add_argument("--flat", "-f", help="whether trajectory is flat", 13 | nargs=1, type=bool, default=False) 14 | ap.add_argument("--dom-len", "-dl", help="Domain size for neighbour list generation", 15 | type=float, default=2.9) 16 | ap.add_argument("traj", help="trajectory file name", 17 | type=str) 18 | 19 | args = ap.parse_args() 20 | trajFile = os.path.abspath(args.traj) 21 | fileName, ext = os.path.splitext(trajFile) 22 | try: 23 | os.makedirs(fileName) 24 | except: 25 | pass 26 | outputFile = fileName + "/" + fileName.split("/")[-1] + "_nn.dat" 27 | 28 | 29 | 30 | def GetNeighs(frame): 31 | frame = [c[:180] for c in frame] 32 | nCells = len(frame) 33 | def GenCellNeighs(): 34 | boxMins = np.vstack(frame).min(axis=0) 35 | boxDims = np.vstack(frame).max(axis=0) - boxMins 36 | 37 | nXDoms, nYDoms, nZDoms = [int(a)+1 for a in boxDims/2.9] 38 | 39 | 40 | doms = [[] for _ in range(nXDoms*nYDoms*nZDoms)] 41 | 42 | for cellIdx, cell in enumerate(frame): 43 | mins = cell.min(axis=0) - boxMins 44 | maxs = cell.max(axis=0) - boxMins 45 | 46 | xl, yl, zl = [int(k) for k in (mins/args.dom_len)] 47 | xu, yu, zu = [int(k) for k in (maxs/args.dom_len)] 48 | 49 | for x in range(xl, xu+1): 50 | for y in range(yl, yu+1): 51 | for z in range(zl, zu+1): 52 | doms[x + y*nXDoms + z*nXDoms*nYDoms].extend([cellIdx]) 53 | if x != 0: 54 | doms[x-1 + y*nXDoms + z*nXDoms*nYDoms].extend([cellIdx]) 55 | if x != nXDoms-1: 56 | doms[x+1 + y*nXDoms + z*nXDoms*nYDoms].extend([cellIdx]) 57 | 58 | if y != 0: 59 | doms[x + (y-1)*nXDoms + z*nXDoms*nYDoms].extend([cellIdx]) 60 | if y != nYDoms-1: 61 | doms[x + (y+1)*nXDoms + z*nXDoms*nYDoms].extend([cellIdx]) 62 | 63 | if z != 0: 64 | doms[x + y*nXDoms + (z-1)*nXDoms*nYDoms].extend([cellIdx]) 65 | if z != nZDoms-1: 66 | doms[x + y*nXDoms + (z+1)*nXDoms*nYDoms].extend([cellIdx]) 67 | 68 | cellNeighs = [[] for _ in range(nCells)] 69 | for cellIdx in range(nCells): 70 | for i, d in enumerate(doms): 71 | if cellIdx in d: 72 | if len(d) > 2: 73 | dd = d.copy() 74 | dd.remove(cellIdx) 75 | cellNeighs[cellIdx].extend(dd) 76 | 77 | cellNeighs = [list(set(n)) for n in cellNeighs] 78 | return cellNeighs 79 | 80 | 81 | neighCells = GenCellNeighs() 82 | neighs = [0 for _ in range(nCells)] 83 | #print("Doing neighbour search of {} particles in {} cells\n".format(nCells*180, nCells)) 84 | for i in range(nCells): 85 | iCell = frame[i] 86 | for j in neighCells[i]: 87 | jCell = frame[j] 88 | dr = iCell - jCell[:, np.newaxis] 89 | r = np.linalg.norm(dr, axis=2) 90 | if ((r < 0.3)).sum() > 0: 91 | neighs[i] += 1 92 | 93 | return neighs 94 | 95 | def WriteNeighs(f, step, neighs): 96 | f.write("{}\n".format(step)) 97 | f.write(",".join([str(n) for n in neighs]) + "\n") 98 | 99 | with cd.TrajHandle(trajFile) as tj, open(outputFile, "w") as f: 100 | if args.frame_num > 0: 101 | WriteNeighs(f, tj.currFrameNum, GetNeighs(tj.ReadFrame(args.frame_num))) 102 | else: 103 | for i in tqdm(range(tj.maxFrames)): 104 | WriteNeighs(f, tj.currFrameNum, GetNeighs(tj.ReadFrame())) 105 | -------------------------------------------------------------------------------- /scripts/oneCell.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ipython 2 | import matplotlib 3 | matplotlib.use('Agg') 4 | 5 | 6 | import sys 7 | 8 | import matplotlib.pyplot as plt 9 | import numpy as np 10 | 11 | trajFileName = sys.argv[1] 12 | cellNo = int(sys.argv[2]) - 1 13 | nAtoms = 0 14 | lineNo = 0 15 | 16 | CoMx = 0.0 17 | CoMy = 0.0 18 | CoMz = 0.0 19 | step = 0 20 | 21 | with open(trajFileName, "r") as trajFile: 22 | line = trajFile.readline() 23 | 24 | while (line != ""): 25 | line = line.strip 26 | nAtoms = int(line) 27 | line = trajFile.readline().strip() 28 | step = int(line[6:]) 29 | print "Processing step no.: %d" % step 30 | 31 | if nAtoms < cellNo * 192: 32 | for i in xrange(nAtoms): 33 | next(trajFile) 34 | else: 35 | for i in xrange(cellNo*192): 36 | next(trajFile) 37 | 38 | for i in xrange(192): 39 | -------------------------------------------------------------------------------- /scripts/plot-many.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | 5 | import numpy as np 6 | import sys, argparse, os 7 | 8 | import matplotlib 9 | matplotlib.use('Agg') 10 | 11 | 12 | import matplotlib.pyplot as plt 13 | from scipy.optimize import curve_fit 14 | 15 | 16 | desc="Calculates and plots average mitotic index for a number of input data files" 17 | 18 | parser=argparse.ArgumentParser(description=desc) 19 | 20 | parser.add_argument("numSims", 21 | help="Number of simulations, \ 22 | must be same for all data files") 23 | 24 | parser.add_argument("--datPaths", nargs="+", 25 | help="paths to data files") 26 | 27 | 28 | args = parser.parse_args() 29 | 30 | 31 | datPaths = [os.path.abspath(p) for p in args.datPaths] 32 | 33 | labels = ['$\gamma_{m} = 5$', '$\gamma_{m} = 10$', '$\gamma_{m} = 15$', '$\gamma_{m} = 20$', '$\gamma_{m} = 25$'] 34 | 35 | offsets = [20, 25, 32, 40, 55] 36 | 37 | fig, ax = plt.subplots() 38 | 39 | ax_inset = plt.axes([0.2, 0.585, 0.3, 0.3]) 40 | 41 | cm = plt.get_cmap('rainbow') 42 | 43 | n = [] 44 | yMax = 0 45 | 46 | def func(x, a, b, c): 47 | """ function to fit the data to. """ 48 | return a * np.exp(-b * x) + c 49 | 50 | def FitAndPlot(datPath, plotName, c, offset): 51 | data = np.loadtxt(datPath) 52 | num_sims = int(args.numSims) 53 | MI_per_sim = data.size/num_sims 54 | data_mat = np.zeros((MI_per_sim, num_sims)) 55 | err_bars = np.zeros(MI_per_sim) 56 | avg_MI = np.zeros(MI_per_sim) 57 | 58 | for i in range(num_sims): 59 | data_mat[:, i] = data[i*MI_per_sim:(i+1)*MI_per_sim] 60 | 61 | for i in range(MI_per_sim): 62 | avg_MI[i] = np.mean(data_mat[i, :]) 63 | err_bars[i] = np.std(data_mat[i, :]) 64 | 65 | allAvgMI = 100*avg_MI.copy() 66 | allErrBars = err_bars.copy() 67 | allX = np.arange(0, allAvgMI.size) 68 | 69 | #mask = avg_MI != 0 70 | #mask = mask * (avg_MI < 0.1) # Basically remove all unwanted data points 71 | #simLength = avg_MI.size 72 | #offset = simLength - mask.sum() # Mask will be 1D since avg_MI is 1D 73 | #avg_MI = avg_MI[mask] 74 | #err_bars = err_bars[mask] 75 | avg_MI = avg_MI[offset:] 76 | err_bars = err_bars[offset:] 77 | 78 | x = np.arange(0, avg_MI.size) 79 | p, pcov = curve_fit(func, x, avg_MI) 80 | fit = func (x, p[0], p[1], p[2]) 81 | x+= offset 82 | avg_MI*=100 83 | err_bars*=100 84 | fit *= 100 85 | 86 | 87 | #ax.plot(x, avg_MI, '-', color=cm(c)) 88 | ax.plot(x, fit, "-", lw=2.0, label=plotName, color=cm(c)) 89 | 90 | ax_inset.plot(allX, allAvgMI, '-', lw=0.5, color=cm(c)) 91 | 92 | for i in xrange(len(datPaths)): 93 | FitAndPlot(datPaths[i], labels[i], i*(1.0/len(datPaths)), offsets[i]) 94 | 95 | print n 96 | ax.set_xlabel('Time') 97 | ax.set_ylabel('Mitotic Index (%)') 98 | ax.set_xlim([0, 100]) 99 | ax.set_ylim([0, 10]) 100 | ax.legend() 101 | 102 | ax_inset.set_xticklabels([]) 103 | ax_inset.set_yticklabels([]) 104 | ax_inset.set_xlim([20, 100]) 105 | ax_inset.set_ylim([0, 10]) 106 | 107 | 108 | plt.savefig('MitoticIndex_many.eps') 109 | -------------------------------------------------------------------------------- /scripts/plot.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ipython3 2 | 3 | 4 | 5 | import numpy as np 6 | import sys 7 | 8 | import matplotlib 9 | matplotlib.use('Agg') 10 | import matplotlib.style 11 | matplotlib.style.use('seaborn') 12 | 13 | import matplotlib.pyplot as plt 14 | from scipy.optimize import curve_fit 15 | import warnings 16 | from scipy.optimize import OptimizeWarning 17 | 18 | if (len(sys.argv) < 2): 19 | print("Usage: plot-many.py mit-inddex.dat num_sims") 20 | sys.exit() 21 | 22 | 23 | def func(x, a, b, c): 24 | """ function to fit the data to. """ 25 | return a * np.exp(-b * x) + c 26 | 27 | 28 | data = np.loadtxt(sys.argv[1]) 29 | num_sims = int(sys.argv[2]) 30 | MI_per_sim = int(data.size/num_sims) 31 | data_mat = np.zeros((MI_per_sim, num_sims)) 32 | err_bars = np.zeros(MI_per_sim) 33 | avg_MI = np.zeros(MI_per_sim) 34 | 35 | for i in range(num_sims): 36 | data_mat[:, i] = data[i*MI_per_sim:(i+1)*MI_per_sim] 37 | 38 | for i in range(MI_per_sim): 39 | avg_MI[i] = np.mean(data_mat[i, :]) 40 | err_bars[i] = np.std(data_mat[i, :]) 41 | 42 | allAvgMI=100*avg_MI.copy() 43 | allErrBars=100*err_bars.copy() 44 | 45 | mask = avg_MI > 0 46 | mask = mask * (avg_MI < 0.2) # Basically remove all unwanted data points 47 | simLength = avg_MI.size 48 | offset = simLength - mask.sum() # Mask will be 1D since avg_MI is 1D 49 | avg_MI = avg_MI[mask] 50 | err_bars = err_bars[mask] 51 | 52 | 53 | 54 | n = 0 55 | with warnings.catch_warnings(): 56 | warnings.simplefilter("error", OptimizeWarning) 57 | warnings.simplefilter("error", RuntimeWarning) 58 | 59 | done = False 60 | 61 | while not done: 62 | print("Trying optimization after skipping ", n, " datapoints.") 63 | avg_MI_t = avg_MI[n:] 64 | err_bars_t = err_bars[n:] 65 | x = np.arange(0, avg_MI_t.size) 66 | 67 | try: 68 | p, pcov = curve_fit(func, x, avg_MI_t, sigma=err_bars_t) 69 | if p[2] > 0.03 or np.abs(p[1]) > 1 or p[0] < 0: 70 | raise OptimizeWarning 71 | except OptimizeWarning: 72 | n+=1 73 | except RuntimeWarning: 74 | n+=1 75 | else: 76 | done = True 77 | 78 | fit = 100*func (x, p[0], p[1], p[2]) 79 | avg_MI = avg_MI[n:] 80 | err_bars = err_bars[n:] 81 | 82 | print("MI = %f exp(-%f x) + %f" % (p[0], p[1], p[2])) 83 | 84 | x+= offset 85 | avg_MI*=100 86 | err_bars*=100 87 | x+= n 88 | for i in range(num_sims): 89 | plt.plot(x, 100*data_mat[:, i][mask][n:], '.', color='#B0B0B0', alpha=0.5) 90 | 91 | plt.errorbar(x, avg_MI, err_bars, ecolor='#B0B0B0', alpha=0.5) 92 | plt.plot(x, avg_MI, 'k-', label="Average of 102 simulations") 93 | 94 | plt.plot(x, fit, "-", lw=2.0, color="blue", 95 | label="MI = %f exp(-%f x) + %f" % (p[0], p[1], p[2])) 96 | plt.legend() 97 | 98 | plt.xlim(0, simLength) 99 | plt.ylim(0, 10) 100 | 101 | plt.ylabel('Mitotic Index (%)') 102 | plt.xlabel('Time') 103 | plt.title('%s' % sys.argv[1]) 104 | # a = plt.axes([0.55, 0.55, 0.3, 0.3]) 105 | # plt.plot(range(allAvgMI.size-1), allAvgMI[:-1], 'k-') 106 | # plt.tick_params(axis='both', which='major', labelsize=6) 107 | # plt.xlabel('Time') 108 | # plt.ylabel('MI (%)') 109 | # plt.xlim(0, allAvgMI.size) 110 | plt.savefig(sys.argv[1][:-3]) 111 | -------------------------------------------------------------------------------- /scripts/polyprep.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys, os, argparse 4 | import numpy as np 5 | import celldiv 6 | 7 | desc = """ 8 | Flattens the system to be analyzed by scripts that do stuff like Anna's. 9 | In the future, this will be replaced by something more powerfull and better. 10 | For now this will do. 11 | """ 12 | parser = argparse.ArgumentParser(description = desc) 13 | 14 | parser.add_argument("trajPaths", nargs="+", 15 | help = "Path (absolute or relative) of any number of trajectory files") 16 | parser.add_argument("-skip", 17 | help="If specified, then only every nth frame will be processed. Where n is the\ 18 | value specifed") 19 | 20 | parser.add_argument("-f", type=bool, required=False, 21 | help="flag for 3D (not flattening)") 22 | args = parser.parse_args() 23 | 24 | trajPaths = [os.path.abspath(p) for p in args.trajPaths] 25 | a = [os.path.splitext(p) for p in trajPaths] 26 | b = [list(t) for t in zip(*a)] 27 | 28 | storePaths = b[0] 29 | 30 | for p in storePaths: 31 | try: 32 | os.makedirs(p) 33 | except: 34 | pass 35 | 36 | 37 | 38 | def flatten(trajPath, storePath, inc, name=None, f=False): 39 | if name == None: 40 | storePath += "/flattened.xvg" 41 | else: 42 | storePath += "/" + name + ".xvg" 43 | 44 | print("writing to %s" % storePath) 45 | 46 | if os.path.isfile(storePath): 47 | 48 | print("overwriting {0}".format(storePath)) 49 | 50 | 51 | CMx = 0 52 | CMy = 0 53 | CMz = 0 54 | 55 | with open(storePath, "w") as outFileHandle: 56 | t = celldiv.TrajHandle(trajPath) 57 | try: 58 | c = 0 59 | while c < t.maxFrames: 60 | frame = t.ReadFrame(inc) 61 | c += 1 62 | nCells = len(frame) 63 | t.nCellsLastFrame 64 | print("frame ", t.currFrameNum, nCells, " cells") 65 | CM = np.vstack([np.mean(c, axis=1) for c in frame]) 66 | 67 | outFileHandle.write("%s\n" % " ".join([str(a) for a in CM[:, 0]])) 68 | outFileHandle.write("%s\n" % " ".join([str(a) for a in CM[:, 1]])) 69 | if f: 70 | outFileHandle.write("%s\n" % " ".join([str(a) for a in CM[:, 2]])) 71 | 72 | 73 | 74 | 75 | except celldiv.IncompleteTrajectoryError as e: 76 | print("broken", e) 77 | 78 | 79 | 80 | 81 | 82 | for i in range(len(trajPaths)): 83 | flatten(trajPaths[i], storePaths[i], inc = args.skip, f = args.f) 84 | -------------------------------------------------------------------------------- /scripts/pop.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import numpy as np 3 | import matplotlib 4 | matplotlib.use('Agg') 5 | import matplotlib.pyplot as plt 6 | import sys, os, argparse 7 | 8 | 9 | desc= """ 10 | Plots the population of a simulation versus time. 11 | """ 12 | 13 | parser = argparse.ArgumentParser(description=desc) 14 | 15 | parser.add_argument("trajPaths", nargs='+', help="Path to trajectory file(s)") 16 | 17 | files = sys.argv[2:] 18 | 19 | args = parser.parse_args() 20 | 21 | trajPaths = [os.path.abspath(p) for p in args.trajPaths] 22 | 23 | GetStorePath = lambda path: os.path.splitext(path)[0] 24 | 25 | def PlotPop(trajPath): 26 | pop=[] 27 | c = 0 28 | q, name = os.path.split(trajPath) 29 | print "Processing %s" % name 30 | path = GetStorePath(trajPath) 31 | 32 | try: 33 | os.makedirs(path) 34 | except: 35 | pass 36 | 37 | path += "/pop.png" 38 | 39 | with open(trajPath, 'r') as trajFile: 40 | while True: 41 | #print line 42 | line = trajFile.readline() 43 | 44 | if line == "": 45 | break 46 | 47 | nAtoms = int(line.strip()) 48 | nCells = nAtoms/192 49 | pop.append(nCells) 50 | line = trajFile.readline().strip() 51 | print "on %s" % line 52 | 53 | for n in xrange(nAtoms): # skip coords + Step line 54 | line = trajFile.readline() 55 | 56 | 57 | x=np.array(range(len(pop))) 58 | y=np.array(pop); 59 | 60 | plt.plot(x,y, '.') 61 | plt.ylabel('Population') 62 | plt.xlabel('t') 63 | plt.savefig(path) 64 | 65 | for p in trajPaths: 66 | PlotPop(p) 67 | -------------------------------------------------------------------------------- /scripts/render.py: -------------------------------------------------------------------------------- 1 | import bpy 2 | import csv 3 | import sys 4 | import os 5 | import argparse 6 | import numpy as np 7 | 8 | import celldiv 9 | 10 | argv = sys.argv 11 | 12 | if "--" not in argv: 13 | print("ERROR: No arguments provided to script") 14 | sys.exit(80) 15 | else: 16 | a = argv.index("--") 17 | argv = argv[a + 1:] 18 | 19 | helpString = """ 20 | Run as: 21 | blender --background --python %s -- 22 | [options] 23 | """ % __file__ 24 | 25 | parser = argparse.ArgumentParser(description=helpString) 26 | 27 | parser.add_argument("trajPath", type=str, 28 | help="Trajectory path. Absolute or relative.") 29 | 30 | parser.add_argument("-s", "--smooth", action='store_true', 31 | help="Do smoothing (really expensive and doesn't look as good)") 32 | 33 | parser.add_argument("-k", "--skip", type=int, required=False, 34 | help="Trajectory frame skip rate. E.g. SKIP=10 will only \ 35 | render every 10th frame.", 36 | default=1) 37 | 38 | parser.add_argument("-nc", "--noclear", type=bool, required=False, 39 | help="specifying this will not clear the destination directory\ 40 | and restart rendering.", 41 | default=False) 42 | 43 | parser.add_argument("--min-cells", type=int, required=False, 44 | help='Start rendering when system has at least this many cells', 45 | default=1) 46 | 47 | parser.add_argument("--inds", type=int, required=False, nargs='+', 48 | help="Only render cells with these indices", 49 | default=[]) 50 | 51 | parser.add_argument("-nf", "--num-frames", type=int, required=False, 52 | help="Only render this many frames.", 53 | default=sys.maxsize) 54 | 55 | parser.add_argument("-r", "--res", type=int, default=1, required=False, 56 | help='Renders images with resolution RES*1080p. RES>=1. \ 57 | Use 2 for 4k. A high number will devour your RAM.') 58 | 59 | parser.add_argument("-cc", "--cell-color", type=int, nargs=3, required=False, 60 | default=[72, 38, 153], 61 | help="RGB values of cell color. From 0 to 255") 62 | 63 | parser.add_argument("-bc", "--background-color", type=int, nargs=3, 64 | required=False, default=[255,255,255], 65 | help="RGB values of cell color. From 0 to 255") 66 | 67 | parser.add_argument("-si", "--specular-intensity", type=float, required=False, 68 | default = 0.0, 69 | help="Set specular-intensity (shininess). From 0.0 to 1.0") 70 | 71 | parser.add_argument("--only-frame", type=int, required=False, default = -1, 72 | help="Only render this frame.") 73 | 74 | args = parser.parse_args(argv) 75 | 76 | imageindex = 0 77 | firstfaces = [] 78 | bpy.data.worlds["World"].horizon_color=[ (1.0/255.0)*c for c in args.background_color] 79 | 80 | bpy.data.scenes["Scene"].render.alpha_mode='TRANSPARENT' 81 | bpy.data.scenes["Scene"].render.image_settings.color_mode="RGBA" 82 | doSmooth = args.smooth 83 | if doSmooth: 84 | print("Doing smoothing. Consider avoiding this feature...") 85 | 86 | 87 | if (args.res < 1): 88 | print("ERROR: invalid resolution factor") 89 | sys.exit() 90 | 91 | bpy.data.scenes["Scene"].render.resolution_x*=args.res 92 | bpy.data.scenes["Scene"].render.resolution_y*=args.res 93 | 94 | with open('C180_pentahexa.csv', newline='') as g: 95 | readerfaces = csv.reader(g, delimiter=',') 96 | for row in readerfaces: 97 | firstfaces.append([int(v) for v in row]) 98 | 99 | 100 | filename = os.path.realpath(args.trajPath) 101 | basename = os.path.splitext(filename)[0] + "/images/CellDiv_" 102 | 103 | nSkip = args.skip 104 | 105 | if nSkip > 1: 106 | print("Rendering every %dth" % nSkip, "frame...") 107 | 108 | 109 | noClear = args.noclear 110 | 111 | sPath = os.path.splitext(filename)[0] + "/images/" 112 | 113 | if not noClear and os.path.exists(sPath): 114 | for f in os.listdir(sPath): 115 | os.remove(sPath+f) 116 | 117 | cellInds = [] 118 | minInd = args.min_cells - 1 119 | if len(args.inds) > 0: 120 | minInd = max(minInd, min(args.inds)) 121 | 122 | stopAt = args.num_frames 123 | 124 | # Set material color 125 | #bpy.data.materials['Material'].diffuse_color = [ (1/255.0) * c for c in args.cell_color] 126 | bpy.data.materials['Material'].specular_intensity = args.specular_intensity 127 | 128 | with celldiv.TrajHandle(filename) as th: 129 | frameCount = 1 130 | try: 131 | for i in range(int(th.maxFrames/nSkip)): 132 | 133 | if frameCount > args.num_frames: 134 | break 135 | 136 | if i <= args.only_frame: 137 | print("Not there yet") 138 | continue 139 | 140 | f = th.ReadFrame(inc=nSkip) 141 | 142 | if len(f) < minInd+1: 143 | print("Only ", len(f), "cells in frame ", th.currFrameNum, 144 | " skipping...") 145 | continue 146 | 147 | if len(args.inds) > 0: 148 | f = [f[a] for a in args.inds] 149 | 150 | f = np.vstack([c[:180] for c in f]) 151 | 152 | # adjust to CoM 153 | f -= np.mean(f, axis=0) 154 | 155 | faces = [] 156 | for mi in range(int(len(f)/180)): 157 | for row in firstfaces: 158 | faces.append([(v+mi*180) for v in row]) 159 | 160 | 161 | mesh = bpy.data.meshes.new('cellMesh') 162 | ob = bpy.data.objects.new('cellObject', mesh) 163 | 164 | bpy.context.scene.objects.link(ob) 165 | mesh.from_pydata(f, [], faces) 166 | mesh.update() 167 | 168 | if doSmooth: 169 | bpy.ops.object.select_by_type(type='MESH') 170 | bpy.context.scene.objects.active = bpy.data.objects['cellObject'] 171 | bpy.ops.object.editmode_toggle() 172 | bpy.ops.mesh.normals_make_consistent(inside=False) 173 | bpy.ops.object.editmode_toggle() 174 | bpy.ops.object.shade_smooth() 175 | bpy.context.scene.objects.active = bpy.data.objects['Cube'] 176 | bpy.ops.object.make_links_data(type='Material') # copy material from Cube 177 | bpy.context.scene.objects.active = bpy.data.objects['cellObject'] 178 | bpy.ops.object.select_all(action='TOGGLE') 179 | bpy.ops.object.modifier_add(type='SUBSURF') 180 | 181 | bpy.ops.object.select_by_type(type='MESH') 182 | bpy.context.scene.objects.active = bpy.data.objects['cellObject'] 183 | bpy.context.scene.objects.active = bpy.data.objects['Cube'] 184 | bpy.ops.object.make_links_data(type='MATERIAL') 185 | bpy.ops.object.select_all(action='TOGGLE') 186 | 187 | # for p in f: 188 | # bpy.ops.mesh.primitive_uv_sphere_add(location=list(p), size=0.01) 189 | # bpy.context.scene.objects.active = bpy.data.objects['Cube'] 190 | # bpy.ops.object.make_links_data(type='MATERIAL') 191 | # bpy.ops.object.select_all(action='TOGGLE') 192 | 193 | 194 | imagename = basename + "%d.png" % frameCount 195 | bpy.context.scene.render.filepath = imagename 196 | 197 | bpy.ops.render.render(write_still=True) # render to file 198 | 199 | bpy.ops.object.select_pattern(pattern='cellObject') 200 | bpy.ops.object.delete() # delete mesh... 201 | frameCount += 1 202 | 203 | except celldiv.IncompleteTrajectoryError: 204 | print ("Stopping...") 205 | -------------------------------------------------------------------------------- /scripts/renim.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echoed='' 3 | shopt -s nullglob 4 | while [ TRUE ]; do 5 | 6 | # find unprocessed trajectory file 7 | trajFile=$(ls -tr traj*.xyz | head -n 1 ) 8 | ext="${trajFile##*.}" 9 | #echo $ext 10 | if [ "$ext" != 'xyz' ]; then 11 | if [ -z $echoed ]; then 12 | echo -e "\rNo new trajectories to render..." 13 | echoed="yes" 14 | fi 15 | #break 16 | echo -ne "\roOO " 17 | sleep 0.4 18 | echo -ne "\rOoO " 19 | sleep 0.4 20 | echo -ne "\rOOo " 21 | sleep 0.4 22 | echo -ne "\rOoO " 23 | sleep 0.4 24 | echo -ne "\roOO " 25 | sleep 0.1 26 | #sleep 3 27 | else 28 | echoed='' 29 | echo -e "\rFound $trajFile" 30 | echo "Waiting some time before rendering..." 31 | sleep 5 32 | # Create directory 33 | trajName="${trajFile%.*}" 34 | mkdir -p "$trajName/images" # 'already exists' message shouldn't happen 35 | # Start rendering with blender 36 | rm "$trajName/images"/* 2> /dev/null 37 | echo "Blender is rendering $trajName..." 38 | echo "You may monitor the $trajName/images folder to see progress" 39 | blender -b CellDiv.blend -Y -P render.py "$trajFile" "$trajName" &> /dev/null & 40 | pid=$! 41 | 42 | trap "kill $pid 2> /dev/null" EXIT 43 | 44 | tmp="unlikely string" 45 | echo -ne "oOO " 46 | while kill -0 $pid 2> /dev/null; do 47 | echo -ne "\rOoO " 48 | sleep 0.2 49 | echo -ne "\rOOo " 50 | sleep 0.2 51 | echo -ne "\rOoO " 52 | sleep 0.2 53 | echo -ne "\roOO " 54 | sleep 0.2 55 | 56 | newestFile=$(ls -At "$trajName/images/" | head -n 1) 57 | 58 | if [ "$tmp" != "$newestFile" -a -n "$newestFile" ]; then 59 | echo -e "\rCreated $trajName/images/$newestFile" 60 | echo -ne "oOO " 61 | tmp="$newestFile" 62 | fi 63 | done 64 | 65 | # Make the video 66 | imgPath="$trajName/images/CellDiv_%d.png" 67 | avconv -y -i "$imgPath" -r 60 -b 20k -vf scale=1920:1080 "$trajName/$trajName.mp4" 68 | pid=$! 69 | trap "kill $pid 2> /dev/null" EXIT 70 | echo -ne "oOO " 71 | while kill -0 $pid 2> /dev/null; do 72 | echo -ne "\rOoO " 73 | sleep 0.2 74 | echo -ne "\rOOo " 75 | sleep 0.2 76 | echo -ne "\rOoO " 77 | sleep 0.2 78 | echo -ne "\roOO " 79 | sleep 0.2 80 | done 81 | mv "$trajFile" "$trajFile~" 82 | mv "$trajName.log" "$trajName/$trajName.log" 83 | fi 84 | done 85 | shopt -u nullglob 86 | -------------------------------------------------------------------------------- /scripts/requirements.txt: -------------------------------------------------------------------------------- 1 | bokeh==0.12.9 2 | certifi==2017.7.27.1 3 | cycler==0.10.0 4 | decorator==4.1.2 5 | ibis==1.6.0 6 | ipython==6.1.0 7 | ipython-genutils==0.2.0 8 | jedi==0.10.2 9 | Jinja2>=2.10.0 10 | MarkupSafe==1.0 11 | matplotlib==2.0.2 12 | numpy==1.13.1 13 | pandas==0.20.3 14 | pexpect==4.2.1 15 | pickleshare==0.7.4 16 | prompt-toolkit==1.0.15 17 | ptyprocess==0.5.2 18 | Pygments==2.2.0 19 | pyparsing==2.2.0 20 | python-dateutil==2.6.1 21 | pytz==2017.2 22 | PyYAML==4.2b1 23 | scipy==0.19.1 24 | simplegeneric==0.8.1 25 | six==1.10.0 26 | tornado==4.5.1 27 | tqdm==4.15.0 28 | traitlets==4.3.2 29 | wcwidth==0.1.7 30 | -------------------------------------------------------------------------------- /scripts/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | n=$1 4 | 5 | m=$(echo "sqrt(""$n"")^2" | bc) 6 | 7 | if [ "$n" -ne "$m" ]; then 8 | echo "Must give me a perfect square number." 9 | else 10 | ./CellDiv $1 | tee out.log 11 | fi 12 | -------------------------------------------------------------------------------- /scripts/run-many: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Runs many simulations and puts the output log files in run-many 4 | 5 | if [ "$#" -ne 3 ]; then 6 | echo "Usage: run-many num_threads num_runs json_file" 7 | exit 1 8 | fi 9 | 10 | if ! [ -e run_logs ]; then 11 | mkdir run_logs 12 | fi 13 | 14 | 15 | numCells=$1 16 | jsonFile=$3 17 | 18 | 19 | for i in $(eval echo {1..$2}); do 20 | timeStamp=$(date +%Y-%m-%d_%H:%M) 21 | ./CellDiv $numCells $jsonFile | tee "run_logs/run"$i"_"$timeStamp"_out.log" 22 | done 23 | -------------------------------------------------------------------------------- /scripts/shaper.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | 4 | # This Script will do shape analysis on the trajectory 5 | # and produce the polygons of the different cells. 6 | import argparse 7 | import sys 8 | import matplotlib 9 | import os 10 | matplotlib.use('agg') 11 | 12 | import matplotlib.pyplot as plt 13 | import numpy as np 14 | from math import ceil 15 | from time import sleep 16 | 17 | 18 | desc =""" 19 | Creates graphs of an arbitrary number of timestamps relating to cell shape. 20 | This includes voronoi diagrams, and cross-sections. 21 | """ 22 | 23 | parser = argparse.ArgumentParser(description=desc) 24 | parser.add_argument("trajPath", nargs=1 , 25 | help="Path to the trajectory file.") 26 | parser.add_argument("timeStamps", nargs='+', type=int, 27 | help="Space separated timestamps") 28 | 29 | args = parser.parse_args() 30 | #print (args.trajPath) 31 | 32 | #minNumArgs = 2 33 | # 34 | #errorMessage = """ 35 | #Usage: shaper input timeStep1 timeStep2 ... 36 | # 37 | #input: Path to the trajectory output by the simulation. 38 | #output: Path to save a xyz file of the time step requested for viewing in vmd, 39 | # etc. 40 | #timeStep1, timeStep2, ...: list of time stemps, use any number of them you like 41 | # Unknown behaviour if greater than simulation time. 42 | #""" 43 | # 44 | #if len(sys.argv) < minNumArgs: 45 | # print errorMessage 46 | # sys.exit(1) 47 | # 48 | # 49 | trajPath = os.path.abspath(args.trajPath[0]) 50 | storPath, fileName = os.path.split(trajPath) 51 | fileName = os.path.splitext(fileName)[0] 52 | storPath += "/" + fileName + '/cross_sections/' 53 | doneSeek = False 54 | step = 0 55 | 56 | timeStamps = [int(ts) for ts in args.timeStamps] 57 | timeStamps.sort() 58 | 59 | # Make directory to store images 60 | try: 61 | os.makedirs(storPath) 62 | except: 63 | 0 64 | 65 | 66 | 67 | 68 | ax=[] 69 | 70 | 71 | 72 | def getNonNans(a): 73 | nans = np.isnan(a) 74 | notnans = np.invert(nans) 75 | return a[notnans] 76 | 77 | 78 | # First get the maxima 79 | 80 | def reverse_readline(filename, buf_size=8192): 81 | """a generator that returns the lines of a file in reverse order""" 82 | """http://stackoverflow.com/a/23646049/1186564""" 83 | with open(filename) as fh: 84 | segment = None 85 | offset = 0 86 | fh.seek(0, os.SEEK_END) 87 | total_size = remaining_size = fh.tell() 88 | while remaining_size > 0: 89 | offset = min(total_size, offset + buf_size) 90 | fh.seek(-offset, os.SEEK_END) 91 | buffer = fh.read(min(remaining_size, buf_size)) 92 | remaining_size -= buf_size 93 | lines = buffer.split('\n') 94 | # the first line of the buffer is probably not a complete line so 95 | # we'll save it and append it to the last line of the next buffer 96 | # we read 97 | if segment is not None: 98 | lines[-1] += segment 99 | segment = lines[0] 100 | for index in range(len(lines) - 1, 0, -1): 101 | yield lines[index] 102 | yield segment 103 | 104 | 105 | 106 | tX = []; tY = []; tZ = []; 107 | tCMx = 0; tCMy = 0; tCMz = 0 108 | for line in reverse_readline(trajPath): 109 | if "Step" in line: 110 | break 111 | if line == '': 112 | continue 113 | 114 | line = line.split(", ") 115 | 116 | x = float(line[0]) 117 | y = float(line[1]) 118 | z = float(line[2]) 119 | 120 | tCMx += x; tCMy += y; tCMz += z; 121 | 122 | tX.append(x) 123 | tY.append(y) 124 | tZ.append(z) 125 | 126 | 127 | tX = np.array(tX) 128 | tY = np.array(tY) 129 | tZ = np.array(tZ) 130 | num = tX.size 131 | tCMx = tCMx/num 132 | tCMy = tCMy/num 133 | tCMz = tCMz/num 134 | 135 | xMax = tX.max() - tCMx; yMax = tY.max() - tCMy; zMax = tZ.max() - tCMz; 136 | xMin = tX.min() - tCMx; yMin = tY.min() - tCMy; zMin = tZ.min() - tCMz; 137 | 138 | maxes = {"X":[xMax, xMin], "Y": [yMax, yMin], "Z":[zMax, zMin]} 139 | 140 | 141 | def Normalize (X, Y, Z, CMx, CMy, CMz): 142 | """ 143 | Get rid of all bad data, then normalize 144 | """ 145 | print "Normalizing..." 146 | 147 | # Get rid of zeros 148 | X = X[X != 0.0] 149 | Y = Y[Y != 0.0] 150 | Z = Z[Z != 0.0] 151 | 152 | X = getNonNans(X) 153 | Y = getNonNans(Y) 154 | Z = getNonNans(Z) 155 | 156 | CMx = getNonNans(CMx) 157 | CMy = getNonNans(CMy) 158 | CMz = getNonNans(CMz) 159 | 160 | # Normalize 161 | CMX = CMx.sum() / CMx.size 162 | CMY = CMy.sum() / CMy.size 163 | CMZ = CMz.sum() / CMz.size 164 | 165 | X = X - CMX 166 | Y = Y - CMY 167 | Z = Z - CMZ 168 | 169 | CMx = CMx - CMX 170 | CMy = CMy - CMY 171 | CMz = CMz - CMZ 172 | 173 | return X, Y, Z, CMx, CMy, CMz 174 | 175 | 176 | 177 | 178 | def Voro (X, Y, ts, xstr, ystr): 179 | """Compute the voronoi diagram for a given set of points""" 180 | points = np.zeros([X.size, 2]) 181 | for i in xrange(X.size): 182 | points[i,0] = X[i] 183 | points[i,1] = Y[i] 184 | 185 | voronoi = Voronoi(points) 186 | voronoi_plot_2d(voronoi) 187 | plt.title("CoM Voronoi\ntime stamp = %s" % ts) 188 | plt.xlabel(xstr) 189 | plt.ylabel(ystr) 190 | plt.savefig("%s%s_vor_%s.png" % (ts, xstr, ystr)) 191 | 192 | def CrossSections(newX, newY, newZ, Xstr, Ystr, Zstr, ts, inc=0.1, thresh=0.1): 193 | """ 194 | This function generates and saves cross section slices of the system. 195 | X, Y are the axes of the plane of intersection 196 | Z is the perpendicular to the name. 197 | Any combination of cartesian plane and normal may be given. 198 | e.g. MakeImages(X, Z, Y, "X", "Z", "Y", ts) will generate XZ planes moving 199 | along the Y axis. 200 | """ 201 | xMax, xMin = maxes[Xstr] 202 | yMax, yMin = maxes[Ystr] 203 | c = 0 204 | print "Making %s%s cross-sections at %d..." % (Xstr, Ystr, ts) 205 | for dz in np.arange(newZ.min(), newZ.max(), inc): 206 | # Get the points within a threshold distance of the plane 207 | nearMask = np.abs(newZ - dz) < thresh 208 | nearX = newX[nearMask] 209 | nearY = newY[nearMask] 210 | c += 1 211 | 212 | # Start plotting 213 | plt.plot(nearX, nearY, '.', lw=0.5, color="#AAAAAA") 214 | # The two lines below stop distortion 215 | #plt.axis('equal') 216 | plt.axis('scaled') 217 | plt.xlim(xMin, xMax) 218 | plt.ylim(yMin, yMax) 219 | #plt.axis([X.min(), X.max(), 220 | # Y.min(), Y.max()]) 221 | plt.title("%s=%f" % (Zstr, dz)) 222 | plt.xlabel("%s" % Xstr) 223 | plt.ylabel("%s" % Ystr) 224 | ax=plt.gca() 225 | ax.set_axis_bgcolor("#404040") 226 | name = "%d_shapes_%s%s_%d.jpg" % (ts, Xstr, Ystr, c) 227 | name = storPath + name 228 | #print "saving to %s ..." % name 229 | plt.gcf().set_size_inches(10, 10) 230 | plt.savefig(name) 231 | plt.close() 232 | 233 | 234 | 235 | 236 | X = [] 237 | Y = [] 238 | Z = [] 239 | 240 | CMx = [] 241 | CMy = [] 242 | CMz = [] 243 | 244 | CM_x = 0 245 | CM_y = 0 246 | CM_z = 0 247 | 248 | 249 | with open(trajPath) as trajFile: 250 | for timeStamp in timeStamps: 251 | # First seek the time step to begin processing 252 | print "Moving to time step %d..." % timeStamp 253 | while True: 254 | line = trajFile.readline().strip() 255 | # First line is always no. of atoms 256 | nAtoms = int(line) 257 | # Second line is always a comment with the time step no. 258 | line = trajFile.readline().strip() 259 | step = int(line[6:]) 260 | if (step >= timeStamp): 261 | break 262 | 263 | # Start skipping lines with coordinates 264 | for n in xrange(nAtoms): 265 | line = trajFile.readline() 266 | 267 | # Should be at the correct time step now 268 | # Begin processipng 269 | # For now only do one time step 270 | nCells = nAtoms/192 271 | print "We have %d cells at t = %d" % (nCells, timeStamp) 272 | for n in xrange(nCells): 273 | for m in xrange(192): 274 | line = trajFile.readline().strip() 275 | line = line.split(", ") 276 | 277 | x = float(line[0]) 278 | y = float(line[1]) 279 | z = float(line[2]) 280 | 281 | X.append(x) 282 | Y.append(y) 283 | Z.append(z) 284 | 285 | CM_x += x 286 | CM_y += y 287 | CM_z += z 288 | 289 | 290 | CMx.append(CM_x/192) 291 | CMy.append(CM_y/192) 292 | CMz.append(CM_z/192) 293 | 294 | CM_x = 0 295 | CM_y = 0 296 | CM_z = 0 297 | 298 | # Done getting coordinates, begin processing 299 | print "Converting to arrays..." 300 | X = np.array(X) 301 | Y = np.array(Y) 302 | Z = np.array(Z) 303 | 304 | CMx = np.array(CMx) 305 | CMy = np.array(CMy) 306 | CMz = np.array(CMz) 307 | 308 | X, Y, Z, CMx, CMy, CMz = Normalize(X, Y, Z, CMx, CMy, CMz) 309 | 310 | # do YZ plane, vary X 311 | CrossSections(Y, Z, X, "Y", "Z", "X", timeStamp) 312 | 313 | # do XZ plane, vary Y 314 | CrossSections(X, Z, Y, "X", "Z", "Y", timeStamp) 315 | 316 | # do XY plane, vary Z 317 | CrossSections(X, Y, Z, "X", "Y", "Z", timeStamp) 318 | 319 | X = [] 320 | Y = [] 321 | Z = [] 322 | CMx = [] 323 | CMy = [] 324 | CMz = [] 325 | -------------------------------------------------------------------------------- /scripts/sysmov.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import matplotlib 4 | 5 | matplotlib.use('Agg') 6 | 7 | import sys, os, argparse 8 | 9 | import matplotlib.pyplot as plt 10 | import numpy as np 11 | from mpl_toolkits.mplot3d import Axes3D 12 | from subprocess import call 13 | from moviepy.video.io.bindings import mplfig_to_npimage 14 | import moviepy.editor as mpy 15 | import matplotlib.animation 16 | 17 | import celldiv as cd 18 | 19 | from tqdm import tqdm 20 | 21 | desc=""" 22 | Creates snapshots of the movement of the center of mass of the system of cells. 23 | """ 24 | parser = argparse.ArgumentParser(description=desc, 25 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 26 | parser.add_argument("trajPath", nargs=1, help="Path to the trajectory file.") 27 | 28 | parser.add_argument("-fps", 29 | help="Optionally set the fps of the output video to this value", 30 | default=20, 31 | type=int) 32 | 33 | parser.add_argument("-s", 34 | help="Optionally set the scaling factor of the axes in the output video", 35 | default=1, 36 | type=float) 37 | 38 | parser.add_argument("-d", 39 | help="Directory relative to the root data directory to store the video.", 40 | default="", 41 | type=str) 42 | parser.add_argument("--out", 43 | help="Output file name and format", 44 | default="3d_CoM.mp4", 45 | type=str) 46 | parser.add_argument("-k", 47 | help="Skip interval", 48 | type = int, 49 | default =1); 50 | 51 | parser.add_argument("--res", 52 | help="16:9 resolution. E.g 720p for 1280x720, \ 53 | 1080p for 1920:1080", 54 | default="1080p", 55 | type=str) 56 | parser.add_argument("-m", "--movie", 57 | help="Make a movie in 3D", 58 | default=False) 59 | 60 | 61 | args = parser.parse_args() 62 | 63 | CoM = [] 64 | cellCoMs = [] 65 | trajPath = os.path.abspath(args.trajPath[0]) 66 | 67 | storPath, trajFileName = os.path.split(trajPath) 68 | trajFileName = os.path.splitext(trajFileName)[0] 69 | 70 | storPath += "/" + trajFileName + "/" + args.d 71 | outName = args.out 72 | 73 | print ("Saving to %s" % storPath) 74 | 75 | try: 76 | os.makedirs(storPath) 77 | except: 78 | pass 79 | 80 | print("Trajectory read progress:") 81 | with cd.TrajHandle(trajPath) as th: 82 | for i in tqdm(range(int(th.maxFrames/args.k))): 83 | try: 84 | frame = th.ReadFrame(inc=args.k) 85 | cc = np.array([np.mean(c, axis=0) for c in frame]) 86 | CoM.append(np.mean(cc, axis=0)) 87 | cellCoMs.append(cc) 88 | except cd.IncompleteTrajectoryError as e: 89 | print(e.value) 90 | print("Stopping") 91 | break 92 | 93 | 94 | CoM = np.array(CoM) 95 | print("Making plots") 96 | plt.subplot(2, 2, 1) 97 | plt.plot(CoM[:, 0], CoM[:, 1], '.') 98 | plt.xlabel("X") 99 | plt.ylabel("Y") 100 | 101 | plt.subplot(2, 2, 2) 102 | plt.plot(CoM[:, 0], CoM[:, 2], '.') 103 | plt.xlabel("X") 104 | plt.ylabel("Z") 105 | 106 | plt.subplot(2, 2, 3) 107 | plt.plot(CoM[:, 1], CoM[:, 2], '.') 108 | plt.xlabel("Y") 109 | plt.ylabel("Z") 110 | 111 | plt.tight_layout() 112 | plt.savefig(storPath + "COM.png") 113 | plt.clf() 114 | 115 | fig = plt.figure() 116 | fps = args.fps 117 | nFrames = CoM.shape[0] 118 | tPerFrame = 1.0/fps 119 | dur = (nFrames-1)*tPerFrame 120 | s = args.s 121 | 122 | ax = fig.add_subplot(1, 1, 1, projection='3d') 123 | 124 | maxes = np.max(np.vstack([np.max(np.vstack(f), axis=0) for f in cellCoMs]), axis=0) 125 | mins = np.min(np.vstack([np.min(np.vstack(f), axis=0) for f in cellCoMs]), axis=0) 126 | xMax = maxes[0] 127 | xMin = mins[0] 128 | 129 | yMax = maxes[1] 130 | yMin = mins[1] 131 | 132 | zMax = maxes[2] 133 | zMin = mins[2] 134 | 135 | ax.set_xlim3d([xMax, xMin]) 136 | ax.set_ylim3d([yMax, yMin]) 137 | ax.set_zlim3d([zMax, zMin]) 138 | 139 | def make3DFrame(i): 140 | i = np.floor(i/tPerFrame) 141 | 142 | ax.scatter3D(CoM[i, 0], CoM[i, 1], CoM[i, 2], '.') 143 | return mplfig_to_npimage(fig) 144 | 145 | def make3DFrameWithCells(i): 146 | i = int(np.floor(i/tPerFrame)) 147 | ax.cla() 148 | ax.scatter3D(CoM[i, 0], CoM[i, 1], CoM[i, 2], '.') 149 | ax.scatter3D(cellCoMs[i][:, 0], cellCoMs[i][:, 1], cellCoMs[i][:, 2], 150 | c='red', alpha=0.5, marker='.') 151 | 152 | ax.set_xlim3d([xMax, xMin]) 153 | ax.set_ylim3d([yMax, yMin]) 154 | ax.set_zlim3d([zMax, zMin]) 155 | return mplfig_to_npimage(fig) 156 | 157 | 158 | # This condition is false if there is more than one cell in the system 159 | if CoM.shape[0] > 1: 160 | frameFunc = make3DFrameWithCells 161 | else: 162 | frameFunc = make3DFrame 163 | 164 | if args.movie: 165 | print ("Making movie...") 166 | animation = mpy.VideoClip(frameFunc, duration=dur) 167 | animation.write_videofile(storPath + outName, fps=fps) 168 | -------------------------------------------------------------------------------- /scripts/vel.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys, os, argparse 3 | 4 | import matplotlib.pyplot as plt 5 | import numpy as np 6 | 7 | desc=""" 8 | Plots the kinetic energy of the system 9 | """ 10 | parser = argparse.ArgumentParser(description=desc) 11 | parser.add_argument("trajPath", help="Path to the trajectory file.") 12 | 13 | args = parser.parse_args() 14 | trajPath = os.path.abspath(args.trajPath) 15 | kinEnergy = [] 16 | energyStep = 0 17 | with open(trajPath, "r") as trajFile: 18 | line = trajFile.readline() 19 | while(line != ""): 20 | nAtoms=int(line) 21 | step = int(trajFile.readline().strip()[6:]) 22 | print step 23 | nCells = nAtoms/192 24 | energyStep = 0 25 | 26 | for c in xrange(nCells): 27 | for a in xrange(192): 28 | line = trajFile.readline() 29 | line = line.strip().split(', ') 30 | Vx = float(line[0]) 31 | Vy = float(line[1]) 32 | Vz = float(line[2]) 33 | energyStep += Vx**2 + Vy**2 + Vz**2 34 | 35 | kinEnergy.append([energyStep]) 36 | line = trajFile.readline() 37 | 38 | plt.plot(kinEnergy) 39 | plt.savefig('Kinetic_Energy.png') 40 | plt.close() 41 | -------------------------------------------------------------------------------- /scripts/xyzafy.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import argparse 4 | import os 5 | import sys 6 | import numpy as np 7 | from tqdm import tqdm 8 | import celldiv as cd 9 | 10 | parser = argparse.ArgumentParser() 11 | 12 | parser.add_argument("traj", type=str) 13 | parser.add_argument("-o", "--out", type=str, default="out.xyz") 14 | parser.add_argument("-k", "--skip", type=int, default=1) 15 | parser.add_argument("-m", "--max", type=int, default=float("inf")) 16 | parser.add_argument("-f", "--frame", type=int, default=-1) 17 | args = parser.parse_args() 18 | 19 | trajPath = os.path.abspath(args.traj) 20 | 21 | 22 | def GetMaxPart(): 23 | print("Scanning trajectory for parameters...") 24 | with cd.TrajHandle(trajPath) as th: 25 | n = len(th.ReadFrame(th.maxFrames)) 26 | print("Done!") 27 | print("System contains {0} particles".format(n*180)) 28 | return n*180 29 | 30 | def WriteFrame(frame, n): 31 | nP = len(frame)*180 32 | outHandle.write("%d\n" % n) 33 | outHandle.write("%d, t = %d\n" % (nP, th.currFrameNum)) 34 | CoM = np.mean(np.vstack(frame), axis=0) 35 | for c in frame: 36 | c = c[:-12] - CoM 37 | for p in c.tolist(): 38 | outHandle.write("C ") 39 | outHandle.write(" ".join([str(a) for a in p])) 40 | outHandle.write("\n") 41 | 42 | if nP < n: 43 | for _ in range(n - nP): 44 | outHandle.write(filler) 45 | 46 | n = GetMaxPart() 47 | filler = "C 0.0 0.0 0.0\n" 48 | with cd.TrajHandle(trajPath) as th, open(args.out, "w") as outHandle: 49 | if args.frame != -1: 50 | frame = th.ReadFrame(frameNum=args.frame) 51 | WriteFrame(frame, len(frame)*180) 52 | else: 53 | for i in tqdm(range(min(args.max, int(th.maxFrames/args.skip)))): 54 | frame = th.ReadFrame(inc=args.skip) 55 | WriteFrame(frame, n) 56 | -------------------------------------------------------------------------------- /src/AdaptiveTimeKernels.cu: -------------------------------------------------------------------------------- 1 | #include "VectorFunctions.hpp" 2 | #include "AdaptiveTimeKernels.cuh" 3 | #include 4 | __global__ void Integrate(float *d_XP, float *d_YP, float *d_ZP, 5 | float *d_X, float *d_Y, float *d_Z, 6 | float *d_XM, float *d_YM, float *d_ZM, 7 | float *d_XMM, float *d_YMM, float *d_ZMM, 8 | float *d_time, float mass, 9 | float3 *d_forceList, int numCells, adp_coeffs a){ 10 | 11 | const int cellInd = blockIdx.x; 12 | const int node = threadIdx.x; 13 | const float delta_t = d_time[0]; 14 | 15 | if (cellInd < numCells && node < 180){ 16 | int nodeInd = cellInd*192 + node; 17 | 18 | float3 posVecP = make_float3(d_XP[nodeInd], d_YP[nodeInd], d_ZP[nodeInd]); 19 | float3 posVec = make_float3(d_X[nodeInd], d_Y[nodeInd], d_Z[nodeInd]); 20 | float3 posVecM = make_float3(d_XM[nodeInd], d_YM[nodeInd], d_ZM[nodeInd]); 21 | float3 posVecMM = make_float3(d_XMM[nodeInd], d_YMM[nodeInd], d_ZMM[nodeInd]); 22 | 23 | posVecP = -1*(a.k0*posVec + a.kn1*posVecM + a.kn2*posVecMM)/a.k1 + 24 | ((delta_t*delta_t)/a.k1)*d_forceList[nodeInd]; 25 | 26 | d_XP[nodeInd] = posVecP.x; 27 | d_YP[nodeInd] = posVecP.y; 28 | d_ZP[nodeInd] = posVecP.z; 29 | } 30 | } 31 | 32 | __global__ void ForwardTime(float *d_XP, float *d_YP, float *d_ZP, 33 | float *d_X, float *d_Y, float *d_Z, 34 | float *d_XM, float *d_YM, float *d_ZM, 35 | float *d_XMM, float *d_YMM, float *d_ZMM, 36 | float *d_velListX, float *d_velListY, float *d_velListZ, 37 | int numCells, float *d_time){ 38 | 39 | int nodeInd = blockIdx.x*blockDim.x + threadIdx.x; 40 | float delta_t = d_time[0]; 41 | if (nodeInd < 192*numCells){ 42 | 43 | d_velListX[nodeInd] = (d_XP[nodeInd] - d_X[nodeInd])/(delta_t); 44 | d_velListY[nodeInd] = (d_YP[nodeInd] - d_Y[nodeInd])/(delta_t); 45 | d_velListZ[nodeInd] = (d_ZP[nodeInd] - d_Z[nodeInd])/(delta_t); 46 | 47 | d_XMM[nodeInd] = d_XM[nodeInd]; 48 | d_YMM[nodeInd] = d_YM[nodeInd]; 49 | d_ZMM[nodeInd] = d_ZM[nodeInd]; 50 | 51 | 52 | d_XM[nodeInd] = d_X[nodeInd]; 53 | d_YM[nodeInd] = d_Y[nodeInd]; 54 | d_ZM[nodeInd] = d_Z[nodeInd]; 55 | 56 | d_X[nodeInd] = d_XP[nodeInd]; 57 | d_Y[nodeInd] = d_YP[nodeInd]; 58 | d_Z[nodeInd] = d_ZP[nodeInd]; 59 | } 60 | } 61 | 62 | __global__ void ComputeTimeUpdate(float *d_XP, float *d_YP, float *d_ZP, 63 | float *d_Xt, float *d_Yt, float *d_Zt, 64 | float *d_AdpErrors, float *d_time, float dt_max, 65 | float alpha, float beta, int numCells, float dt_tol){ 66 | int index = blockIdx.x*blockDim.x + threadIdx.x; 67 | float delta_t = d_time[0]; 68 | 69 | if (index < 192*numCells && threadIdx.x < 180){ 70 | float3 Y1 = make_float3(d_XP[index], d_YP[index], d_ZP[index]); 71 | float3 Yt = make_float3(d_Xt[index], d_Yt[index], d_Zt[index]); 72 | 73 | // ask bart about this error computation 74 | float e = abs(alpha/(beta-alpha))*mag(Yt-Y1); 75 | 76 | d_AdpErrors[index] = e; 77 | d_time[index] = min(dt_max, 0.9*delta_t*sqrt(dt_tol/e)); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/BondKernels.cu: -------------------------------------------------------------------------------- 1 | #include "VectorFunctions.hpp" 2 | 3 | __global__ void CalculateR0(float* d_R0, float* d_X, float* d_Y, float* d_Z, 4 | int* d_C180_nn, 5 | float* d_youngsModArray, float stiffness2, int No_of_C180s){ 6 | 7 | int cellInd = blockIdx.x*blockDim.x + threadIdx.x; 8 | 9 | if (cellInd < No_of_C180s && d_youngsModArray[cellInd] == stiffness2){ 10 | float avgR0 = 0.f; 11 | 12 | for (int node = 0; node < 180; ++node){ 13 | int nodeInd = cellInd*192 + node; 14 | float3 nodePos = make_float3(d_X[nodeInd], 15 | d_Y[nodeInd], 16 | d_Z[nodeInd]); 17 | 18 | int n1 = d_C180_nn[0*192 + node]; 19 | int n2 = d_C180_nn[1*192 + node]; 20 | int n3 = d_C180_nn[2*192 + node]; 21 | 22 | float3 n1Pos = make_float3(d_X[cellInd*192 + n1], 23 | d_Y[cellInd*192 + n1], 24 | d_Z[cellInd*192 + n1]); 25 | 26 | float3 n2Pos = make_float3(d_X[cellInd*192 + n2], 27 | d_Y[cellInd*192 + n2], 28 | d_Z[cellInd*192 + n2]); 29 | 30 | float3 n3Pos = make_float3(d_X[cellInd*192 + n3], 31 | d_Y[cellInd*192 + n3], 32 | d_Z[cellInd*192 + n3]); 33 | 34 | avgR0 += 1/3.f * (mag(nodePos - n1Pos) + mag(nodePos - n2Pos) + mag(nodePos - n3Pos)); 35 | } 36 | 37 | d_R0[cellInd] = avgR0/180.f; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/IntegrationKernels.h: -------------------------------------------------------------------------------- 1 | __device__ void PositionUpdate(float Vx, float Vy, float Vz, 2 | float Ax, float Ay, float Az, 3 | float delta_t, int index, 4 | // outputs 5 | float* X, float* Y, float* Z); 6 | 7 | __device__ void VelocityUpdate(float Ax, float Ay, float Az, 8 | float dt, 9 | float VxIn, float VyIn, float VzIn, 10 | // Outputs: 11 | float* Vx, float* Vy, float* Vz); 12 | 13 | __device__ void CalculateForce(int nodeInd, int cellInd, float nodeMass, 14 | float gamma_int, float delta_t, float* pressList, 15 | float Youngs_mod, float R0, float attraction_strength, 16 | float attraction_range, float repulsion_strength, 17 | float repulsion_range, float gamma_ext, 18 | float gamma_o, float DL, 19 | float minX, float minY, float minZ, 20 | int xDiv, int yDiv, float zDiv, 21 | float* VxL, float* VyL, float* VzL, 22 | int* d_C180_nn, int* d_C180_sign, int* d_NoofNNlist, 23 | int* d_NNlist, float* d_bounding_xyz, 24 | float* d_X, float* d_Y, float* d_Z, 25 | float wall1, float wall2, bool useWalls, 26 | float threshDist, 27 | // Outputs: 28 | float* FxL, float* FyL, float* FzL); 29 | 30 | __global__ void Integrate(int No_of_C180s, int* d_C180_nn, int* d_C180_sign, 31 | float* d_X, float* d_Y, float* d_Z, 32 | float R0, float* d_pressList, float Youngs_mod, 33 | float internal_damping, float delta_t, float* d_bounding_xyz, 34 | float attraction_strength, float attraction_range, 35 | float repulsion_strength, float repulsion_range, 36 | float viscotic_damping, float m, 37 | float Minx, float Miny, float Minz, 38 | float xDiv, float yDiv, float zDiv, 39 | int* d_NoofNNlist, int* d_NNlist, float DL, float gamma_visc, 40 | float* VxL, float* VyL, float* VzL, 41 | float* FxL, float* FyL, float* FzL, 42 | float wall1, float wall2, bool useWalls, 43 | float threshDist); 44 | 45 | __global__ void FirstTimeForceCalculation(int No_of_C180s, int* d_C180_nn, int* d_C180_sign, 46 | float* d_X, float* d_Y, float* d_Z, 47 | float R0, float* d_pressList, float Youngs_mod, 48 | float internal_damping, float delta_t, float* d_bounding_xyz, 49 | float attraction_strength, float attraction_range, 50 | float repulsion_strength, float repulsion_range, 51 | float viscotic_damping, float m, 52 | float Minx, float Miny, float Minz, 53 | float xDiv, float yDiv, float zDiv, 54 | int* d_NoofNNlist, int* d_NNlist, float DL, float gamma_visc, 55 | float* VxL, float* VyL, float* VzL, 56 | float* FxL, float* FyL, float* FzL, 57 | float wall1, float wall2, bool useWalls, 58 | float threshDist); 59 | -------------------------------------------------------------------------------- /src/PressureKernels.cu: -------------------------------------------------------------------------------- 1 | #include 2 | #include "postscript.h" 3 | 4 | __global__ void PressureUpdate (float* d_pressList, float minPressure, 5 | float maxPressure, float inc, int No_of_C180s, 6 | bool useDifferentStiffnesses, 7 | float stiffness1, float* d_youngs_mod, int step, 8 | int phase_count){ 9 | 10 | int cellInd = blockIdx.x*blockDim.x + threadIdx.x; 11 | 12 | 13 | if (cellInd < No_of_C180s){ 14 | float pressure = d_pressList[cellInd]; 15 | if (useDifferentStiffnesses == true){ 16 | if (step < phase_count){ 17 | if (d_pressList[cellInd] < maxPressure){ 18 | d_pressList[cellInd] += inc; 19 | } 20 | } 21 | else{ 22 | if (d_youngs_mod[cellInd] == stiffness1){ 23 | if (d_pressList[cellInd] < maxPressure){ 24 | d_pressList[cellInd] += inc; 25 | } 26 | } 27 | else { 28 | if (d_pressList[cellInd] != 0.f){ 29 | d_pressList[cellInd] = 0.f; 30 | } 31 | } 32 | 33 | } 34 | } 35 | else { 36 | if (d_pressList[cellInd] < maxPressure){ 37 | d_pressList[cellInd] += inc; 38 | } 39 | } 40 | } 41 | } 42 | 43 | 44 | 45 | __global__ void PressureReset (int* d_resetIndices, float* d_pressList, 46 | float pressureValue, int numCells){ 47 | 48 | // This kernel has really inefficient memory access 49 | // TODO: Investigate doing this on the host. 50 | 51 | 52 | // d_resetIndices is an array of indeces to cells that have to have their 53 | // pressures reset 54 | 55 | int setInd = blockIdx.x*blockDim.x + threadIdx.x; 56 | if (setInd < numCells){ 57 | // if (!d_resetIndices[setInd]){ 58 | // printf("WARNING:Trying to set pressure of wrong cell\n"); 59 | // printf("Invalid cell index: %d setId: %d numCells: %d", d_resetIndices[setInd], setInd, numCells); 60 | // } 61 | 62 | d_pressList[d_resetIndices[setInd]] = pressureValue; 63 | d_resetIndices[setInd] = -1; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/RandomVector.h: -------------------------------------------------------------------------------- 1 | #ifndef RANDOM_VECTOR_H 2 | #define RANDOM_VECTOR_H 3 | #ifndef STD_LIB 4 | #include 5 | #include 6 | #endif 7 | #include "marsaglia.h" 8 | void GetRandomVector (float* n){ 9 | float ran2[2]; 10 | float s = 0; 11 | do { 12 | ranmar(ran2, 2); 13 | ran2[0] = 2.0f*ran2[0] - 1.0f; 14 | ran2[1] = 2.0f*ran2[1] - 1.0f; 15 | s = ran2[0]*ran2[0] + ran2[1]*ran2[1]; 16 | } while (s >= 1.0f); 17 | 18 | float x1 = ran2[0]; 19 | float x2 = ran2[1]; 20 | 21 | n[0] = 2*x1*sqrt(1 - x1*x1 - x2*x2); 22 | n[1] = 2*x2*sqrt(1 - x1*x1 - x2*x2); 23 | n[2] = 1 - 2*(x1*x1 + x2*x2); 24 | } 25 | 26 | void GetRandomVectorBasis (float* n, float* basis){ 27 | // Credit for algorithm to Arthur Vromans, Sept 10, 2015, TUE CASA 28 | float ran[1]; 29 | ranmar(ran, 1); 30 | float Nv = cos(2*3.14159*ran[0]); 31 | float Nw = sin(2*3.14159*ran[0]); 32 | float v[3], w[3]; 33 | 34 | if (basis[1] != 0){ 35 | v[0] = 0; 36 | v[1] = basis[2]; 37 | v[2] = -1*basis[1]; 38 | 39 | w[0] = basis[1]; 40 | w[1] = -1*basis[0]; 41 | w[2] = 0; 42 | }else{ // this branch is very unlikely, placed for correctness 43 | v[0] = 0; 44 | v[1] = 1; 45 | v[2] = 0; 46 | 47 | w[0] = basis[2]; 48 | w[1] = 0; 49 | w[2] = -1*basis[0]; 50 | } 51 | 52 | // Orthogonalize 53 | float f = (w[0]*v[0] + w[1]*v[1] + w[2]*w[2])/ 54 | (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); 55 | 56 | w[0] = w[0] - f*v[0]; 57 | w[1] = w[1] - f*v[1]; 58 | w[2] = w[2] - f*v[2]; 59 | 60 | // normalize 61 | f = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); 62 | 63 | v[0] = v[0]/f; 64 | v[1] = v[1]/f; 65 | v[2] = v[2]/f; 66 | 67 | f = sqrt(w[0]*w[0] + w[1]*w[1] + w[2]*w[2]); 68 | 69 | w[0] = w[0]/f; 70 | w[1] = w[1]/f; 71 | w[2] = w[2]/f; 72 | 73 | // Normal can be calculated: 74 | n[0] = Nv*v[0] + Nw*w[0]; 75 | n[1] = Nv*v[1] + Nw*w[1]; 76 | n[2] = Nv*v[2] + Nw*w[2]; 77 | 78 | } 79 | #endif // RANDOM_VECTOR_H End 80 | -------------------------------------------------------------------------------- /src/centermass.cu: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "postscript.h" 6 | 7 | 8 | __global__ void CenterOfMass( int No_of_C180s, 9 | float *d_XP, float *d_YP, float *d_ZP, 10 | float *CMx, float *CMy,float *CMz) 11 | { 12 | __shared__ float sumx[256]; 13 | __shared__ float sumy[256]; 14 | __shared__ float sumz[256]; 15 | 16 | int rank = blockIdx.x; 17 | int tid = threadIdx.x; 18 | 19 | sumx[tid] = 0.0; 20 | sumy[tid] = 0.0; 21 | sumz[tid] = 0.0; 22 | 23 | if ( tid < 180 ) 24 | { 25 | sumx[tid] = d_XP[rank*192+tid]; 26 | sumy[tid] = d_YP[rank*192+tid]; 27 | sumz[tid] = d_ZP[rank*192+tid]; 28 | } 29 | 30 | __syncthreads(); 31 | 32 | for ( int s = blockDim.x/2; s > 0; s>>=1) 33 | { 34 | if ( tid < s ) 35 | { 36 | sumx[tid] += sumx[tid+s]; 37 | sumy[tid] += sumy[tid+s]; 38 | sumz[tid] += sumz[tid+s]; 39 | } 40 | __syncthreads(); 41 | } 42 | 43 | if ( tid == 0 ) 44 | { 45 | CMx[rank] = sumx[0]/180.0f; 46 | CMy[rank] = sumy[0]/180.0f; 47 | CMz[rank] = sumz[0]/180.0f; 48 | } 49 | 50 | } 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /src/marsaglia.h: -------------------------------------------------------------------------------- 1 | #ifndef MARSAGLIA_H 2 | #define MARSAGLIA_H 3 | /* 4 | C This random number generator originally appeared in "Toward a Universal 5 | C Random Number Generator" by George Marsaglia and Arif Zaman. 6 | C Florida State University Report: FSU-SCRI-87-50 (1987) 7 | C 8 | C It was later modified by F. James and published in "A Review of Pseudo- 9 | C random Number Generators" 10 | C 11 | C THIS IS THE BEST KNOWN RANDOM NUMBER GENERATOR AVAILABLE. 12 | C (However, a newly discovered technique can yield 13 | C a period of 10^600. But that is still in the development stage.) 14 | C 15 | C It passes ALL of the tests for random number generators and has a period 16 | C of 2^144, is completely portable (gives bit identical results on all 17 | C machines with at least 24-bit mantissas in the floating point 18 | C representation). 19 | C 20 | C The algorithm is a combination of a Fibonacci sequence (with lags of 97 21 | C and 33, and operation "subtraction plus one, modulo one") and an 22 | C "arithmetic sequence" (using subtraction). 23 | C======================================================================== 24 | This C language version was written by Jim Butler, and was based on a 25 | FORTRAN program posted by David LaSalle of Florida State University. 26 | */ 27 | 28 | #ifndef STD_LIB 29 | #include 30 | #include 31 | #endif 32 | 33 | #define MARS_TRUE -1 34 | #define MARS_FALSE 0 35 | #define MARS_boolean int 36 | 37 | //void rmarin(int ij, int kl); 38 | //void ranmar(float rvec[], int len); 39 | 40 | // ij = 183; 41 | // kl = 8968; 42 | 43 | /* do the initialization */ 44 | // rmarin(ij,kl); 45 | 46 | /* generate 20,000 random numbers */ 47 | // ranmar(temp, len); 48 | 49 | 50 | static float MARS_u[98], MARS_c, MARS_cd, MARS_cm; 51 | static int MARS_i97, MARS_j97; 52 | static MARS_boolean test = MARS_FALSE; 53 | 54 | void rmarin(int ij,int kl) 55 | { 56 | /* 57 | C This is the initialization routine for the random number generator RANMAR() 58 | C NOTE: The seed variables can have values between: 0 <= IJ <= 31328 59 | C 0 <= KL <= 30081 60 | C The random number sequences created by these two seeds are of sufficient 61 | C length to complete an entire calculation with. For example, if sveral 62 | C different groups are working on different parts of the same calculation, 63 | C each group could be assigned its own IJ seed. This would leave each group 64 | C with 30000 choices for the second seed. That is to say, this random 65 | C number generator can create 900 million different subsequences -- with 66 | C each subsequence having a length of approximately 10^30. 67 | C 68 | C Use IJ = 1802 & KL = 9373 to test the random number generator. The 69 | C subroutine RANMAR should be used to generate 20000 random numbers. 70 | C Then display the next six random numbers generated multiplied by 4096*4096 71 | C If the random number generator is working properly, the random numbers 72 | C should be: 73 | C 6533892.0 14220222.0 7275067.0 74 | C 6172232.0 8354498.0 10633180.0 75 | */ 76 | int i, j, k, l, ii, jj, m; 77 | float s, t; 78 | 79 | if (ij<0 || ij>31328 || kl<0 || kl>30081) { 80 | printf("The first random number seed must have a value between 0 and 31328.\n"); 81 | printf("The second seed must have a value between 0 and 30081.\n"); 82 | exit(1); 83 | } 84 | 85 | i = (ij/177)%177 + 2; 86 | j = ij%177 + 2; 87 | k = (kl/169)%178 + 1; 88 | l = kl%169; 89 | 90 | for (ii=1; ii<=97; ii++) { 91 | s = 0.0; 92 | t = 0.5; 93 | for (jj=1; jj<=24; jj++) { 94 | m = (((i*j)%179)*k) % 179; 95 | i = j; 96 | j = k; 97 | k = m; 98 | l = (53*l + 1) % 169; 99 | if ((l*m)%64 >= 32) s += t; 100 | t *= 0.5; 101 | } 102 | MARS_u[ii] = s; 103 | } 104 | 105 | MARS_c = 362436.0 / 16777216.0; 106 | MARS_cd = 7654321.0 / 16777216.0; 107 | MARS_cm = 16777213.0 / 16777216.0; 108 | 109 | MARS_i97 = 97; 110 | MARS_j97 = 33; 111 | 112 | test = MARS_TRUE; 113 | } 114 | 115 | void ranmar(float rvec[],int len) 116 | /* 117 | C This is the random number generator proposed by George Marsaglia in 118 | C Florida State University Report: FSU-SCRI-87-50 119 | C It was slightly modified by F. James to produce an array of pseudorandom 120 | C numbers. 121 | */ 122 | { 123 | int ivec; 124 | float uni; 125 | 126 | if (test==MARS_FALSE) { 127 | printf("Call the init routine rmarin() before calling ranmar().\n"); 128 | exit(2); 129 | } 130 | for (ivec=0; ivec 2 | #include 3 | #include"VectorFunctions.hpp" 4 | #include 5 | cudaDeviceProp getDevice(void); 6 | 7 | __global__ void cell_division(int rank, 8 | float* d_XP, float* d_YP, float* d_ZP, 9 | float *d_X, float *d_Y, float *d_Z, 10 | float* d_XM, float* d_YM, float* d_ZM, 11 | float* AllCMx, float* AllCMy, float* AllCMz, 12 | float* d_velListX, float* d_velListY, float* d_velListZ, 13 | int No_of_C180s, float *d_randNorm, float repulsion_range); 14 | 15 | __global__ void minmaxpre( int No_of_C180s, float *d_bounding_xyz, 16 | float *Minx, float *Maxx, float *Miny, float *Maxy, float *Minz, float *Maxz); 17 | 18 | __global__ void minmaxpost( int No_of_C180s, 19 | float *Minx, float *Maxx, float *Miny, float *Maxy, float *Minz, float *Maxz); 20 | 21 | __global__ void makeNNlist( int No_of_C180s, float *d_bounding_xyz, 22 | float Minx, float Miny, float Minz, float attrac, int Xdiv, int Ydiv, int Zdiv, 23 | int *d_NoofNNlist, int *d_NNlist, float DL); 24 | 25 | __global__ void CenterOfMass( int No_of_C180s, 26 | float *d_XP, float *d_YP, float *d_ZP, 27 | float *CMx, float *CMy, float *CMz); 28 | 29 | __global__ void volumes( int No_of_C180s, int *C180_56, 30 | float *X, float *Y, float *Z, 31 | float *CMx , float *CMy, float *CMz, float *vol, 32 | char* cell_div, float divVol, bool checkSphericity, 33 | float* areaList, int phase_count, int step, 34 | float stiffness1, bool useDifferentStiffnesses, float* d_younds_mod, 35 | bool recalc_r0); 36 | 37 | int printboundingbox(int rank, float *bounding_xyz); 38 | int initialize_C180s(int Orig_No_of_C180s); 39 | int generate_random(int no_of_ran1_vectors); 40 | int read_fullerene_nn(void); 41 | int read_global_params(void); 42 | int read_json_params(const char* inpFile); 43 | int PSSETUP(FILE* outfile); 44 | int PSLINE(float X1, float Y1, float X2, float Y2, FILE *outfile); 45 | int PSCIRCLE(float X,float Y,FILE *outfile); 46 | int PSNET(int NN,int sl,float L1, float *X, float *Y, float *Z, int CCI[2][271]); 47 | 48 | int PSNUM(float X, float Y, int NUMBER, FILE *outfile); 49 | __global__ void CalculateConForce( int No_of_C180s, int d_C180_nn[], int d_C180_sign[], 50 | float d_X[], float d_Y[], float d_Z[], 51 | float *d_CMx, float *d_CMy, float *d_CMz, 52 | float* d_R0, float* d_pressList, float* d_Youngs_mod , float cellStiffness, 53 | float internal_damping, const float *d_time, 54 | float d_bounding_xyz[], 55 | float attraction_strength, float attraction_range, 56 | float repulsion_strength, float repulsion_range, 57 | float viscotic_damping, float mass, 58 | float Minx, float Miny, float Minz, int Xdiv, int Ydiv, int Zdiv, 59 | int *d_NoofNNlist, int *d_NNlist, float DL, float gamma_visc, 60 | float wall1, float wall2, 61 | float threshDist, bool useWalls, 62 | float* d_velListX, float* d_velListY, float* d_velListZ, 63 | bool useRigidSimulationBox, float boxLength, float* d_boxMin, float Youngs_mod, 64 | bool constrainAngles, const angles3 d_theta0[], R3Nptrs d_forceList, float r_CM_o, float3 boxMax, R3Nptrs d_contactForces, const float* d_volList, const float div_vol); 65 | 66 | __global__ void Integrate(float *d_XP, float *d_YP, float *d_ZP, 67 | float *d_X, float *d_Y, float *d_Z, 68 | float *d_XM, float *d_YM, float *d_ZM, 69 | float *d_velListX, float *d_velListY, float *d_velListZ, 70 | float *d_time, float mass, 71 | R3Nptrs d_fConList, R3Nptrs d_fDisList, R3Nptrs d_fRanList, 72 | int numCells, bool add_rands, 73 | curandState *rngStates, float rand_scale_factor); 74 | 75 | __global__ void ForwardTime(float *d_XP, float *d_YP, float *d_ZP, 76 | float *d_X, float *d_Y, float *d_Z, 77 | float *d_XM, float *d_YM, float *d_ZM, 78 | int numCells); 79 | 80 | __global__ void bounding_boxes( int No_of_C180s, 81 | float *d_XP, float *d_YP, float *d_ZP, 82 | // float *d_X, float *d_Y, float *d_Z, 83 | // float *d_XM, float *d_YM, float *d_ZM, 84 | float *bounding_xyz, 85 | float *avex, float *avey, float *avez); 86 | 87 | void rmarin(int ij, int kl); 88 | void ranmar(float rvec[], int len); 89 | 90 | 91 | 92 | // Function to write the trajectory 93 | void write_traj(int t_step, FILE* trajfile); 94 | void write_vel(int t_step, FILE* velFile); 95 | void WriteBinaryTraj(int t_step, FILE* trajfile, int frameCount); 96 | 97 | // Function to get the indeces of dividing cells 98 | inline void count_and_get_div(); 99 | 100 | 101 | inline void calc_sys_CM(); 102 | 103 | inline float getRmax2(); 104 | 105 | inline int num_cells_far(); 106 | 107 | __global__ void PressureUpdate (float* d_pressList, float minPressure, 108 | float maxPressure, float inc, int No_of_C180s, 109 | bool useDifferentStiffnesses, float stiffness1, 110 | float* d_younds_mod, int step, int phase_count); 111 | 112 | __global__ void PressureReset (int* d_resetIndices, float* d_pressList, 113 | float minPressure, int numResetCells); 114 | 115 | __global__ void CheckCellDivision(int No_of_C180s, int *C180_56, 116 | float *X, float *Y, float *Z, 117 | float *CMx , float *CMy, float *CMz, float *voll, 118 | int* d_C180_56, 119 | char* cell_div, float divVol, bool checkSpherecity); 120 | 121 | __global__ void DeviceRandInit(curandState *rngState, uint *d_seeds, unsigned long long num); 122 | 123 | __global__ void CalculateR0(float* d_R0, float* d_X, float* d_Y, float* d_Z, 124 | int* d_C180_nn, 125 | float* d_youngsModArray, float stiffness2, int No_of_C180s); 126 | 127 | void writeForces(FILE* forceFile, int t_step, int num_cells); 128 | 129 | __global__ void CorrectCoMMotion(float* d_X, float* d_Y, float* d_Z, 130 | float sysCMx, float sysCMy, float sysCMz, long int numParts); 131 | 132 | __global__ void VelocityUpdateA(float* d_VX, float* d_VY, float* d_VZ, 133 | R3Nptrs fConList, R3Nptrs fRanList, 134 | float dt, long int num_nodes, float m); 135 | 136 | __global__ void VelocityUpdateB(float* d_VX, float* d_VY, float* d_VZ, 137 | R3Nptrs fDisList, float dt, long int num_nodes, float m); 138 | 139 | __global__ void CalculateDisForce( int No_of_C180s, int d_C180_nn[], int d_C180_sign[], 140 | float d_X[], float d_Y[], float d_Z[], 141 | float gamma_int, 142 | float d_bounding_xyz[], 143 | float attraction_range, 144 | float gamma_ext, 145 | float Minx, float Miny, float Minz, int Xdiv, int Ydiv, int Zdiv, 146 | int *d_NoofNNlist, int *d_NNlist, float DL, float gamma_o, 147 | float* d_velListX, float* d_velListY, float* d_velListZ, 148 | R3Nptrs d_fDisList); 149 | 150 | __global__ void CalculateRanForce(int No_of_C180s, curandState *d_rngStates, float rand_scale_factor, 151 | R3Nptrs d_fRanList); 152 | -------------------------------------------------------------------------------- /src/postscriptinit.cu: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | int PSSETUP (FILE *outfile) 6 | { 7 | fprintf(outfile,"%%!PS-Adobe-2.0\n"); 8 | fprintf(outfile,"50 550 translate\n"); 9 | fprintf(outfile,"7.0 7.0 scale\n"); 10 | fprintf(outfile,"0.015 setlinewidth\n"); 11 | fprintf(outfile,"/circledict 8 dict def\n"); 12 | fprintf(outfile,"circledict /mtrx matrix put\n"); 13 | fprintf(outfile,"/circle { circledict begin\n"); 14 | fprintf(outfile," /rad exch def\n"); 15 | fprintf(outfile," /y exch def\n"); 16 | fprintf(outfile," /x exch def\n"); 17 | fprintf(outfile," /savematrix mtrx currentmatrix def\n"); 18 | fprintf(outfile," x y translate\n"); 19 | fprintf(outfile," rad rad scale\n"); 20 | fprintf(outfile," 0 0 1 0 360 arc\n"); 21 | fprintf(outfile," savematrix setmatrix\n"); 22 | fprintf(outfile," end } def\n"); 23 | fprintf(outfile,"/Times-Roman findfont 0.3 scalefont setfont\n"); 24 | fprintf(outfile,"/Times-Roman findfont 0.15 scalefont setfont\n"); 25 | return(0); 26 | } 27 | 28 | 29 | 30 | int PSLINE(float X1, float Y1, float X2, float Y2, FILE *outfile) 31 | { 32 | //C Prints PS-code drawing a line from (X1,Y1) to (X2,Y2) to file PSUNIT 33 | 34 | fprintf(outfile,"%7.2f %7.2f moveto\n",X1,Y1); 35 | fprintf(outfile,"%7.2f %7.2f lineto\n",X2,Y2); 36 | fprintf(outfile,"stroke\n"); 37 | 38 | return(0); 39 | } 40 | 41 | 42 | 43 | 44 | int PSCIRCLE(float X,float Y,FILE *outfile) 45 | { 46 | float RADIUS; 47 | 48 | RADIUS=0.57/2.0; 49 | 50 | fprintf(outfile,"0 0 0 setrgbcolor"); 51 | fprintf(outfile,"newpath"); 52 | fprintf(outfile,"%12.2f %12.2f %12.2f circle\n", X, Y, RADIUS); 53 | fprintf(outfile,"closepath"); 54 | fprintf(outfile,"stroke"); 55 | 56 | return(0); 57 | } 58 | 59 | 60 | 61 | 62 | int PSNUM(float X, float Y, int NUMBER, FILE *outfile) 63 | { 64 | fprintf(outfile,"%7.2f %7.2f moveto\n",X, Y ); 65 | fprintf(outfile," (%d) show\n", NUMBER); 66 | 67 | return(0); 68 | } 69 | 70 | int PSNET(int NN,int sl,float L1, float *X, float *Y, float *Z, int CCI[2][271]) 71 | { 72 | int j,rank; 73 | float X1,Y1,Z1,X2,Y2,Z2; 74 | float SX1, SX2, SZ1, SZ2; 75 | FILE *outfile; 76 | 77 | outfile = fopen("psfil","a"); 78 | if ( outfile == NULL ) {printf("Unable to open file psfil\n");return(-1);} 79 | 80 | PSSETUP(outfile); 81 | 82 | for ( rank = 0; rank < NN/270; ++rank ) 83 | for ( j = 0; j < 270; ++j ) 84 | { 85 | X1 = X[192*rank+CCI[0][j]]; 86 | X2 = X[192*rank+CCI[1][j]]; 87 | Y1 = Y[192*rank+CCI[0][j]]; 88 | Y2 = Y[192*rank+CCI[1][j]]; 89 | Z1 = Z[192*rank+CCI[0][j]]; 90 | Z2 = Z[192*rank+CCI[1][j]]; 91 | PSLINE(X1,Y1,X2,Y2,outfile); 92 | SX1=X1+40.0; 93 | SX2=X2+40.0; 94 | SZ1=Z1+10.0; 95 | SZ2=Z2+10.0; 96 | PSLINE(SX1,SZ1,SX2,SZ2,outfile); 97 | SX1=X1+40.0; 98 | SX2=X2+40.0; 99 | SZ1=Z1-10.0; 100 | SZ2=Z2-10.0; 101 | if (fabsf((Y1+Y2)/2.0-sl*L1) < 0.2) PSLINE(SX1,SZ1,SX2,SZ2,outfile); 102 | fprintf(outfile,"stroke\n"); 103 | } 104 | 105 | fprintf(outfile,"showpage\n"); 106 | 107 | fclose(outfile); 108 | return(0); 109 | } 110 | 111 | 112 | //C ***************************************************************** 113 | 114 | 115 | 116 | cudaDeviceProp getDevice(void) 117 | { 118 | 119 | int deviceCount; 120 | cudaGetDeviceCount(&deviceCount); 121 | int device; 122 | cudaDeviceProp deviceProp; 123 | for (device = 0; device < deviceCount; ++device) { 124 | cudaGetDeviceProperties(&deviceProp, device); 125 | printf(" Device %s\n", deviceProp.name); 126 | printf(" compute capability = %d.%d\n", deviceProp.major, deviceProp.minor); 127 | printf(" totalGlobalMemory = %.2lf GB\n", deviceProp.totalGlobalMem/1000000000.0); 128 | printf(" l2CacheSize = %8d\n", deviceProp.l2CacheSize); 129 | printf(" regsPerBlock = %8d\n", deviceProp.regsPerBlock); 130 | printf(" multiProcessorCount = %8d\n", deviceProp.multiProcessorCount); 131 | printf(" maxThreadsPerMultiprocessor = %8d\n", deviceProp.maxThreadsPerMultiProcessor); 132 | printf(" sharedMemPerBlock = %8d B\n", (int)deviceProp.sharedMemPerBlock); 133 | printf(" warpSize = %8d\n", deviceProp.warpSize); 134 | printf(" clockRate = %8.2lf MHz\n", deviceProp.clockRate/1000.0); 135 | printf(" maxThreadsPerBlock = %8d\n", deviceProp.maxThreadsPerBlock); 136 | printf(" asyncEngineCount = %8d\n", deviceProp.asyncEngineCount); 137 | printf(" concurrentKernels = "); 138 | if(deviceProp.concurrentKernels==1) printf(" yes\n"); else printf(" no\n"); 139 | 140 | printf(" ComputeMode = %8d\n", deviceProp.computeMode); 141 | } 142 | 143 | return deviceProp; 144 | } 145 | 146 | 147 | 148 | __device__ void CalcAndUpdateDaughtPos(int daughtInd, int partInd, float halfGap, 149 | float CMx, float CMy, float CMz, 150 | float X, float Y, float Z, 151 | float* d_XP, float* d_YP, float* d_ZP, 152 | float* d_X, float* d_Y, float* d_Z, 153 | float* d_XM, float* d_YM, float* d_ZM, 154 | float planeNx, float planeNy, float planeNz){ 155 | 156 | // redefine position of parent cell wrt to an origin that includes 157 | // 0.5 the minimum gap between daughter cells 158 | X = X - CMx - halfGap*planeNx; 159 | Y = Y - CMy - halfGap*planeNy; 160 | Z = Z - CMz - halfGap*planeNz; 161 | 162 | float posDotN = X*planeNx + Y*planeNy + Z*planeNz; 163 | 164 | // If particle is below the plane, project onto the plane 165 | if (posDotN < 0.0f || posDotN == 0){ 166 | X = X - posDotN*planeNx; 167 | Y = Y - posDotN*planeNy; 168 | Z = Z - posDotN*planeNz; 169 | } 170 | 171 | d_XP[daughtInd*192+partInd] = X + (CMx + halfGap*planeNx); 172 | d_YP[daughtInd*192+partInd] = Y + (CMy + halfGap*planeNy); 173 | d_ZP[daughtInd*192+partInd] = Z + (CMz + halfGap*planeNz); 174 | 175 | d_X[daughtInd*192+partInd] = X + (CMx + halfGap*planeNx); 176 | d_Y[daughtInd*192+partInd] = Y + (CMy + halfGap*planeNy); 177 | d_Z[daughtInd*192+partInd] = Z + (CMz + halfGap*planeNz); 178 | 179 | d_XM[daughtInd*192+partInd] = X + (CMx + halfGap*planeNx); 180 | d_YM[daughtInd*192+partInd] = Y + (CMy + halfGap*planeNy); 181 | d_ZM[daughtInd*192+partInd] = Z + (CMz + halfGap*planeNz); 182 | } 183 | 184 | 185 | __global__ void cell_division(int rank, 186 | float* d_XP, float* d_YP, float* d_ZP, 187 | float *d_X, float *d_Y, float *d_Z, 188 | float* d_XM, float* d_YM, float* d_ZM, 189 | float* AllCMx, float* AllCMy, float* AllCMz, 190 | float* d_velListX, float* d_velListY, float* d_velListZ, 191 | int No_of_C180s, float *d_randNorm, float repulsion_range){ 192 | int newrank = No_of_C180s; 193 | __shared__ float CMx, CMy, CMz; 194 | 195 | int tid = threadIdx.x; 196 | int atom = tid; 197 | 198 | if (tid == 0){ 199 | CMx = AllCMx[rank]; 200 | CMy = AllCMy[rank]; 201 | CMz = AllCMz[rank]; 202 | } 203 | 204 | __syncthreads(); 205 | 206 | 207 | if ( atom < 180 ) 208 | { 209 | 210 | // planeN is the division plane's normal vector 211 | float planeNx = d_randNorm[0]; 212 | float planeNy = d_randNorm[1]; 213 | float planeNz = d_randNorm[2]; 214 | 215 | if (abs(sqrt(planeNx*planeNx + planeNy*planeNy + planeNz*planeNz) - 1) > 1e-3){ 216 | printf("OH SHIT: normal is not normalized\n"); 217 | printf("Crash now :(\n"); 218 | asm("trap;"); 219 | } 220 | 221 | 222 | // First generate and write positions for the first daughter 223 | 224 | float X = d_X[rank*192+atom]; 225 | float Y = d_Y[rank*192+atom]; 226 | float Z = d_Z[rank*192+atom]; 227 | 228 | CalcAndUpdateDaughtPos(rank, atom, 0.5*repulsion_range, 229 | CMx, CMy, CMz, 230 | X, Y, Z, 231 | d_XP, d_YP, d_ZP, 232 | d_X, d_Y, d_Z, 233 | d_XM, d_YM, d_ZM, 234 | planeNx, planeNy, planeNz); 235 | 236 | 237 | // Invert the normal 238 | planeNx = -1*planeNx; 239 | planeNy = -1*planeNy; 240 | planeNz = -1*planeNz; 241 | 242 | // Now repeat for the second daughter 243 | CalcAndUpdateDaughtPos(newrank, atom, 0.5*repulsion_range, 244 | CMx, CMy, CMz, 245 | X, Y, Z, 246 | d_XP, d_YP, d_ZP, 247 | d_X, d_Y, d_Z, 248 | d_XM, d_YM, d_ZM, 249 | planeNx, planeNy, planeNz); 250 | 251 | // give the daughter the same velocities as the parent 252 | d_velListX[newrank*192 + atom] = d_velListX[rank*192+atom]; 253 | d_velListY[newrank*192 + atom] = d_velListY[rank*192+atom]; 254 | d_velListZ[newrank*192 + atom] = d_velListZ[rank*192+atom]; 255 | } 256 | } 257 | 258 | 259 | -------------------------------------------------------------------------------- /src/propagatebound.cu: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "postscript.h" 6 | #include "VectorFunctions.hpp" 7 | 8 | //#define PRINT_TOO_SHORT_ERROR 9 | 10 | __global__ void bounding_boxes( int No_of_C180s, 11 | float *d_XP, float *d_YP, float *d_ZP, 12 | // float *d_X, float *d_Y, float *d_Z, 13 | // float *d_XM, float *d_YM, float *d_ZM, 14 | float *d_bounding_xyz, float *CMx, 15 | float *CMy, float *CMz) 16 | { 17 | __shared__ float minx[32]; 18 | __shared__ float maxx[32]; 19 | __shared__ float miny[32]; 20 | __shared__ float maxy[32]; 21 | __shared__ float minz[32]; 22 | __shared__ float maxz[32]; 23 | 24 | int rank = blockIdx.x; 25 | int tid = threadIdx.x; 26 | int atom = tid; 27 | 28 | if ( rank < No_of_C180s ) 29 | { 30 | minx[tid] = d_XP[rank*192+atom]; 31 | maxx[tid] = d_XP[rank*192+atom]; 32 | miny[tid] = d_YP[rank*192+atom]; 33 | maxy[tid] = d_YP[rank*192+atom]; 34 | minz[tid] = d_ZP[rank*192+atom]; 35 | maxz[tid] = d_ZP[rank*192+atom]; 36 | 37 | // // move present value to past value 38 | // d_XM[rank*192+atom] = d_X[rank*192+atom]; 39 | // d_YM[rank*192+atom] = d_Y[rank*192+atom]; 40 | // d_ZM[rank*192+atom] = d_Z[rank*192+atom]; 41 | 42 | // // move future value to present value 43 | // d_X[rank*192+atom] = d_XP[rank*192+atom]; 44 | // d_Y[rank*192+atom] = d_YP[rank*192+atom]; 45 | // d_Z[rank*192+atom] = d_ZP[rank*192+atom]; 46 | 47 | 48 | while ( atom + 32 < 180 ) 49 | { 50 | atom += 32; 51 | if ( minx[tid] > d_XP[rank*192+atom] ) 52 | minx[tid] = d_XP[rank*192+atom]; 53 | if ( maxx[tid] < d_XP[rank*192+atom] ) 54 | maxx[tid] = d_XP[rank*192+atom]; 55 | if ( miny[tid] > d_YP[rank*192+atom] ) 56 | miny[tid] = d_YP[rank*192+atom]; 57 | if ( maxy[tid] < d_YP[rank*192+atom] ) 58 | maxy[tid] = d_YP[rank*192+atom]; 59 | if ( minz[tid] > d_ZP[rank*192+atom] ) 60 | minz[tid] = d_ZP[rank*192+atom]; 61 | if ( maxz[tid] < d_ZP[rank*192+atom] ) 62 | maxz[tid] = d_ZP[rank*192+atom]; 63 | 64 | // // move present value to past value 65 | // d_XM[rank*192+atom] = d_X[rank*192+atom]; 66 | // d_YM[rank*192+atom] = d_Y[rank*192+atom]; 67 | // d_ZM[rank*192+atom] = d_Z[rank*192+atom]; 68 | 69 | // // move future value to present value 70 | // d_X[rank*192+atom] = d_XP[rank*192+atom]; 71 | // d_Y[rank*192+atom] = d_YP[rank*192+atom]; 72 | // d_Z[rank*192+atom] = d_ZP[rank*192+atom]; 73 | 74 | } 75 | 76 | if ( tid < 16 ) 77 | { 78 | if ( minx[tid] > minx[tid+16] ) minx[tid] = minx[tid+16]; 79 | if ( maxx[tid] < maxx[tid+16] ) maxx[tid] = maxx[tid+16]; 80 | 81 | if ( miny[tid] > miny[tid+16] ) miny[tid] = miny[tid+16]; 82 | if ( maxy[tid] < maxy[tid+16] ) maxy[tid] = maxy[tid+16]; 83 | 84 | if ( minz[tid] > minz[tid+16] ) minz[tid] = minz[tid+16]; 85 | if ( maxz[tid] < maxz[tid+16] ) maxz[tid] = maxz[tid+16]; 86 | } 87 | 88 | if ( tid < 8 ) 89 | { 90 | if ( minx[tid] > minx[tid+8] ) minx[tid] = minx[tid+8]; 91 | if ( maxx[tid] < maxx[tid+8] ) maxx[tid] = maxx[tid+8]; 92 | if ( miny[tid] > miny[tid+8] ) miny[tid] = miny[tid+8]; 93 | if ( maxy[tid] < maxy[tid+8] ) maxy[tid] = maxy[tid+8]; 94 | if ( minz[tid] > minz[tid+8] ) minz[tid] = minz[tid+8]; 95 | if ( maxz[tid] < maxz[tid+8] ) maxz[tid] = maxz[tid+8]; 96 | } 97 | 98 | if ( tid < 4 ) 99 | { 100 | if ( minx[tid] > minx[tid+4] ) minx[tid] = minx[tid+4]; 101 | if ( maxx[tid] < maxx[tid+4] ) maxx[tid] = maxx[tid+4]; 102 | if ( miny[tid] > miny[tid+4] ) miny[tid] = miny[tid+4]; 103 | if ( maxy[tid] < maxy[tid+4] ) maxy[tid] = maxy[tid+4]; 104 | if ( minz[tid] > minz[tid+4] ) minz[tid] = minz[tid+4]; 105 | if ( maxz[tid] < maxz[tid+4] ) maxz[tid] = maxz[tid+4]; 106 | } 107 | 108 | if ( tid < 2 ) 109 | { 110 | if ( minx[tid] > minx[tid+2] ) minx[tid] = minx[tid+2]; 111 | if ( maxx[tid] < maxx[tid+2] ) maxx[tid] = maxx[tid+2]; 112 | if ( miny[tid] > miny[tid+2] ) miny[tid] = miny[tid+2]; 113 | if ( maxy[tid] < maxy[tid+2] ) maxy[tid] = maxy[tid+2]; 114 | if ( minz[tid] > minz[tid+2] ) minz[tid] = minz[tid+2]; 115 | if ( maxz[tid] < maxz[tid+2] ) maxz[tid] = maxz[tid+2]; 116 | } 117 | 118 | if ( tid == 0 ) 119 | { 120 | if ( minx[0] > minx[1] ) minx[0] = minx[1]; 121 | d_bounding_xyz[rank*6+0] = minx[0]; 122 | 123 | if ( maxx[0] < maxx[1] ) maxx[0] = maxx[1]; 124 | d_bounding_xyz[rank*6+1] = maxx[0]; 125 | 126 | if ( miny[0] > miny[1] ) miny[0] = miny[1]; 127 | d_bounding_xyz[rank*6+2] = miny[0]; 128 | 129 | if ( maxy[0] < maxy[1] ) maxy[0] = maxy[1]; 130 | d_bounding_xyz[rank*6+3] = maxy[0]; 131 | 132 | if ( minz[0] > minz[1] ) minz[0] = minz[1]; 133 | d_bounding_xyz[rank*6+4] = minz[0]; 134 | 135 | if ( maxz[0] < maxz[1] ) maxz[0] = maxz[1]; 136 | d_bounding_xyz[rank*6+5] = maxz[0]; 137 | } 138 | 139 | } 140 | 141 | } 142 | 143 | 144 | 145 | __global__ void minmaxpre( int No_of_C180s, float *d_bounding_xyz, 146 | float *Minx, float *Maxx, 147 | float *Miny, float *Maxy, 148 | float *Minz, float *Maxz) 149 | { 150 | 151 | __shared__ float minx[1024]; 152 | __shared__ float maxx[1024]; 153 | __shared__ float miny[1024]; 154 | __shared__ float maxy[1024]; 155 | __shared__ float minz[1024]; 156 | __shared__ float maxz[1024]; 157 | 158 | int fullerene = blockIdx.x*blockDim.x+threadIdx.x; 159 | int tid = threadIdx.x; 160 | 161 | minx[tid] = +1.0E8f; 162 | maxx[tid] = -1.0E8f; 163 | miny[tid] = +1.0E8f; 164 | maxy[tid] = -1.0E8f; 165 | minz[tid] = +1.0E8f; 166 | maxz[tid] = -1.0E8f; 167 | 168 | if ( fullerene < No_of_C180s ) 169 | { 170 | minx[tid] = d_bounding_xyz[6*fullerene+0]; 171 | maxx[tid] = d_bounding_xyz[6*fullerene+1]; 172 | miny[tid] = d_bounding_xyz[6*fullerene+2]; 173 | maxy[tid] = d_bounding_xyz[6*fullerene+3]; 174 | minz[tid] = d_bounding_xyz[6*fullerene+4]; 175 | maxz[tid] = d_bounding_xyz[6*fullerene+5]; 176 | } 177 | 178 | __syncthreads(); 179 | 180 | for ( int s = blockDim.x/2; s > 0; s>>=1) 181 | { 182 | if ( tid < s ) 183 | { 184 | minx[tid] = fminf(minx[tid],minx[tid+s]); 185 | maxx[tid] = fmaxf(maxx[tid],maxx[tid+s]); 186 | miny[tid] = fminf(miny[tid],miny[tid+s]); 187 | maxy[tid] = fmaxf(maxy[tid],maxy[tid+s]); 188 | minz[tid] = fminf(minz[tid],minz[tid+s]); 189 | maxz[tid] = fmaxf(maxz[tid],maxz[tid+s]); 190 | } 191 | __syncthreads(); 192 | } 193 | 194 | if ( tid == 0 ) 195 | { 196 | Minx[blockIdx.x] = minx[0]; 197 | Maxx[blockIdx.x] = maxx[0]; 198 | Miny[blockIdx.x] = miny[0]; 199 | Maxy[blockIdx.x] = maxy[0]; 200 | Minz[blockIdx.x] = minz[0]; 201 | Maxz[blockIdx.x] = maxz[0]; 202 | } 203 | 204 | } 205 | 206 | 207 | 208 | 209 | __global__ void makeNNlist(int No_of_C180s, float *d_bounding_xyz, 210 | float Minx, float Miny, float Minz, 211 | float attrac, 212 | int Xdiv, int Ydiv, int Zdiv, 213 | int *d_NoofNNlist, int *d_NNlist, float DL) 214 | { 215 | 216 | 217 | int fullerene = blockIdx.x*blockDim.x+threadIdx.x; 218 | // printf("(%d, %d, %d) %d %d\n", blockIdx.x, blockDim.x, threadIdx.x, fullerene, No_of_C180s); 219 | 220 | 221 | if ( fullerene < No_of_C180s ) 222 | { 223 | 224 | int startx = (int)((d_bounding_xyz[6*fullerene+0]-attrac 225 | - Minx)/DL); 226 | if ( startx < 0 ) startx = 0; 227 | int endx = (int)((d_bounding_xyz[6*fullerene+1]+attrac 228 | - Minx)/DL); 229 | if ( endx >= Xdiv ) endx = Xdiv-1; 230 | int starty = (int)((d_bounding_xyz[6*fullerene+2]-attrac 231 | - Miny)/DL); 232 | if ( starty < 0 ) starty = 0; 233 | int endy = (int)((d_bounding_xyz[6*fullerene+3]+attrac 234 | - Miny)/DL); 235 | if ( endy >= Ydiv ) endy = Ydiv-1; 236 | int startz = (int)((d_bounding_xyz[6*fullerene+4]-attrac 237 | - Minz)/DL); 238 | if ( startz < 0 ) startz = 0; 239 | int endz = (int)((d_bounding_xyz[6*fullerene+5]+attrac 240 | - Minz)/DL); 241 | if ( endz >= Zdiv ) endz = Zdiv-1; 242 | 243 | for ( int j1 = startx; j1 <= endx; ++j1 ) 244 | for ( int j2 = starty; j2 <= endy; ++j2 ) 245 | for ( int j3 = startz; j3 <= endz; ++j3 ) 246 | { 247 | int index = atomicAdd( &d_NoofNNlist[j3*Xdiv*Ydiv+j2*Xdiv+j1] , 1); //returns old 248 | #ifdef PRINT_TOO_SHORT_ERROR 249 | if ( index > 32 ) 250 | { 251 | printf("Fullerene %d, NN-list too short, atleast %d\n", fullerene, index); 252 | // for ( int k = 0; k < 32; ++k ) 253 | // printf("%d ",d_NNlist[ 32*(j2*Xdiv+j1) + k]); 254 | 255 | // printf("\n"); 256 | continue; 257 | } 258 | #endif 259 | d_NNlist[ 32*(j3*Xdiv*Ydiv+j2*Xdiv+j1)+index] = fullerene; 260 | } 261 | } 262 | 263 | } 264 | 265 | 266 | __global__ void minmaxpost( int No_of_C180s, 267 | float *Minx, float *Maxx, float *Miny, float *Maxy, float *Minz, float *Maxz) 268 | { 269 | 270 | __shared__ float minx[1024]; 271 | __shared__ float maxx[1024]; 272 | __shared__ float miny[1024]; 273 | __shared__ float maxy[1024]; 274 | __shared__ float minz[1024]; 275 | __shared__ float maxz[1024]; 276 | 277 | int fullerene = blockIdx.x*blockDim.x+threadIdx.x; 278 | int tid = threadIdx.x; 279 | 280 | minx[tid] = +1.0E8f; 281 | maxx[tid] = -1.0E8f; 282 | miny[tid] = +1.0E8f; 283 | maxy[tid] = -1.0E8f; 284 | minz[tid] = +1.0E8f; 285 | maxz[tid] = -1.0E8f; 286 | 287 | if ( fullerene < No_of_C180s ) 288 | { 289 | minx[tid] = Minx[fullerene]; 290 | maxx[tid] = Maxx[fullerene]; 291 | miny[tid] = Miny[fullerene]; 292 | maxy[tid] = Maxy[fullerene]; 293 | minz[tid] = Minz[fullerene]; 294 | maxz[tid] = Maxz[fullerene]; 295 | } 296 | 297 | __syncthreads(); 298 | 299 | for ( int s = blockDim.x/2; s > 0; s>>=1) 300 | { 301 | if ( tid < s ) 302 | { 303 | minx[tid] = fminf(minx[tid],minx[tid+s]); 304 | maxx[tid] = fmaxf(maxx[tid],maxx[tid+s]); 305 | miny[tid] = fminf(miny[tid],miny[tid+s]); 306 | maxy[tid] = fmaxf(maxy[tid],maxy[tid+s]); 307 | minz[tid] = fminf(minz[tid],minz[tid+s]); 308 | maxz[tid] = fmaxf(maxz[tid],maxz[tid+s]); 309 | } 310 | __syncthreads(); 311 | } 312 | 313 | if ( tid == 0 ) 314 | { 315 | Minx[blockIdx.x+0] = minx[0]; 316 | Minx[blockIdx.x+1] = maxx[0]; 317 | Minx[blockIdx.x+2] = miny[0]; 318 | Minx[blockIdx.x+3] = maxy[0]; 319 | Minx[blockIdx.x+4] = minz[0]; 320 | Minx[blockIdx.x+5] = maxz[0]; 321 | } 322 | 323 | } 324 | -------------------------------------------------------------------------------- /src/volume.cu: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "VectorFunctions.hpp" 4 | 5 | __global__ void volumes( int No_of_C180s, int *C180_56, 6 | float *X, float *Y, float *Z, 7 | float *CMx , float *CMy, float *CMz, float *vol, 8 | char* cell_div, float divVol, bool checkSphericity, 9 | float* areaList, int phase_count, int step, 10 | float stiffness1, bool useDifferentStiffnesses, float* d_younds_mod, 11 | bool recalc_r0){ 12 | __shared__ float locX[192]; 13 | __shared__ float locY[192]; 14 | __shared__ float locZ[192]; 15 | __shared__ float volume; 16 | __shared__ float volume2; 17 | __shared__ float area; 18 | 19 | int fullerene = blockIdx.x; 20 | int tid = threadIdx.x; 21 | 22 | if ( tid < 180 ){ 23 | locX[tid] = X[192*fullerene+tid] -CMx[fullerene]; 24 | locY[tid] = Y[192*fullerene+tid] -CMy[fullerene]; 25 | locZ[tid] = Z[192*fullerene+tid] -CMz[fullerene]; 26 | } 27 | 28 | 29 | if ( tid == 0){ 30 | volume = 0.0f; 31 | volume2 = 0.0f; 32 | area = 0.0f; 33 | } 34 | 35 | __syncthreads(); 36 | 37 | if ( tid < 92 ){ 38 | 39 | float avX = 0.0f; 40 | float avY = 0.0f; 41 | float avZ = 0.0f; 42 | 43 | for ( int i = 0; i < 5; ++i ){ 44 | avX += locX[C180_56[7*tid+i]]; 45 | avY += locY[C180_56[7*tid+i]]; 46 | avZ += locZ[C180_56[7*tid+i]]; 47 | } 48 | 49 | float avefactor = 0.166666667f; 50 | if ( tid < 12 ) 51 | { 52 | avefactor = 0.2f; 53 | } 54 | else 55 | { 56 | avX += locX[C180_56[7*tid+5]]; 57 | avY += locY[C180_56[7*tid+5]]; 58 | avZ += locZ[C180_56[7*tid+5]]; 59 | } 60 | 61 | avX *= avefactor; 62 | avY *= avefactor; 63 | avZ *= avefactor; 64 | 65 | float totvol = 0.0f; 66 | float totvol2 = 0.0f; 67 | float n1 = 0.0f; 68 | float n2 = 0.0f; 69 | float n3 = 0.0f; 70 | float faceArea = 0.0f; 71 | 72 | float3 p0 = make_float3(avX, avY, avZ); 73 | float3 p1, p2; 74 | 75 | for ( int i = 0; i < 6; ++i ){ 76 | n1 = (locY[C180_56[7*tid+i+1]]*avZ-avY*locZ[C180_56[7*tid+i+1]])*locX[C180_56[7*tid+i]]; 77 | n2 = (locZ[C180_56[7*tid+i+1]]*avX-avZ*locX[C180_56[7*tid+i+1]])*locY[C180_56[7*tid+i]]; 78 | n3 = (locX[C180_56[7*tid+i+1]]*avY-avX*locY[C180_56[7*tid+i+1]])*locZ[C180_56[7*tid+i]]; 79 | totvol += fabsf(n1+n2+n3); 80 | 81 | 82 | p1.x = locX[C180_56[7*tid+i]]; 83 | p1.y = locY[C180_56[7*tid+i]]; 84 | p1.z = locZ[C180_56[7*tid+i]]; 85 | 86 | p2.x = locX[C180_56[7*tid+i+1]]; 87 | p2.y = locY[C180_56[7*tid+i+1]]; 88 | p2.z = locZ[C180_56[7*tid+i+1]]; 89 | 90 | totvol2 += dot(p0, cross(p1, p2)); 91 | 92 | if (checkSphericity){ 93 | 94 | // Get vectors that define a triangle 1, 2 95 | float x1 = locX[C180_56[7*tid+i]] - avX; 96 | float y1 = locY[C180_56[7*tid+i]] - avY; 97 | float z1 = locZ[C180_56[7*tid+i]] - avZ; 98 | 99 | float x2 = locX[C180_56[7*tid+i+1]] - avX; 100 | float y2 = locY[C180_56[7*tid+i+1]] - avY; 101 | float z2 = locZ[C180_56[7*tid+i+1]] - avZ; 102 | 103 | p1.x = p1.x - p0.x; 104 | p1.y = p1.y - p0.y; 105 | p1.z = p1.z - p0.z; 106 | 107 | p2.x = p2.x - p0.x; 108 | p2.y = p2.y - p0.y; 109 | p2.z = p2.z - p0.z; 110 | 111 | // now 1 will hold 1X2 112 | float xx = y1*z2 - z1*y2; 113 | float yy = z1*x2 - x1*z2; 114 | float zz = x1*y2 - y1*x2; 115 | 116 | // area of triangle is then 0.5*|1| 117 | faceArea += 0.5 * sqrt(xx*xx + yy*yy + zz*zz); 118 | } 119 | } 120 | atomicAdd(&volume, totvol); 121 | atomicAdd(&volume2, totvol2); 122 | 123 | if (checkSphericity) 124 | atomicAdd(&area, faceArea); 125 | } 126 | 127 | __syncthreads(); 128 | 129 | if ( tid == 0){ 130 | volume = volume/6.0; 131 | volume2 = volume2/6.0; 132 | vol[fullerene] = volume; 133 | 134 | if (!isfinite(volume)){ 135 | printf("OH SHIT: non-finite volume %f, cell %d\nvol2 %f\n", volume, fullerene, volume2); 136 | printf("Crash now :(\n"); 137 | asm("trap;"); 138 | volume = 1.f; 139 | } 140 | 141 | if (volume > divVol){ 142 | cell_div[fullerene] = 1; 143 | } 144 | 145 | if (checkSphericity){ 146 | areaList[fullerene] = area; 147 | float c = cbrtf(volume); 148 | float psi = 4.835975862049408 * c * c/area; 149 | if (abs(1.0f - psi) > 0.05){ // why 0.05? 150 | cell_div[fullerene] = 0; 151 | //printf("cell %d division rejected\n", fullerene); 152 | } 153 | } 154 | 155 | if (useDifferentStiffnesses){ 156 | if (recalc_r0){ 157 | if (d_younds_mod[fullerene] != stiffness1){ 158 | cell_div[fullerene] = 0; 159 | } 160 | } 161 | } 162 | } 163 | } 164 | --------------------------------------------------------------------------------