| commit | author | age | ||
| 7f6076 | 1 | /* vim: set ts=4 sts=4 sw=4 noet : */ |
| 7958e9 | 2 | #include<stdlib.h> |
| SP | 3 | #include<math.h> |
| 4 | #include<stdio.h> | |
| 5 | #include "general.h" | |
| 6 | #include "vertex.h" | |
| 7 | #include "bond.h" | |
| 8 | #include "vesicle.h" | |
| 9 | #include "vertex.h" | |
| 10 | #include "triangle.h" | |
| 11 | #include "initial_distribution.h" | |
| f74313 | 12 | #include "energy.h" |
| 1ab449 | 13 | #include "poly.h" |
| 8a6614 | 14 | #include "io.h" |
| dc77e8 | 15 | #include "sh.h" |
| 459ff9 | 16 | #include "shcomplex.h" |
| 7958e9 | 17 | |
| SP | 18 | ts_vesicle *initial_distribution_dipyramid(ts_uint nshell, ts_uint ncmax1, ts_uint ncmax2, ts_uint ncmax3, ts_double stepsize){ |
| 1ab449 | 19 | ts_fprintf(stdout,"Starting initial_distribution on vesicle with %u shells!...\n",nshell); |
| 7958e9 | 20 | ts_bool retval; |
| 1ab449 | 21 | ts_uint no_vertices=5*nshell*nshell+2; |
| SP | 22 | ts_vesicle *vesicle=init_vesicle(no_vertices,ncmax1,ncmax2,ncmax3,stepsize); |
| 23 | vesicle->nshell=nshell; | |
| 24 | //retval = vtx_set_global_values(vesicle); | |
| 25 | retval = pentagonal_dipyramid_vertex_distribution(vesicle->vlist); | |
| 26 | retval = init_vertex_neighbours(vesicle->vlist); | |
| 27 | vesicle->vlist = init_sort_neighbours(vesicle->blist,vesicle->vlist); | |
| b01cc1 | 28 | // retval = init_vesicle_bonds(vesicle); // bonds are created in sort_neigh |
| 1ab449 | 29 | retval = init_triangles(vesicle); |
| SP | 30 | retval = init_triangle_neighbours(vesicle); |
| 31 | retval = init_common_vertex_triangle_neighbours(vesicle); | |
| 32 | retval = init_normal_vectors(vesicle->tlist); | |
| 33 | retval = mean_curvature_and_energy(vesicle); | |
| 34 | ts_fprintf(stdout,"initial_distribution finished!\n"); | |
| 41a035 | 35 | if(retval); |
| 7958e9 | 36 | return vesicle; |
| SP | 37 | } |
| 38 | ||
| 39 | ||
| 1ab449 | 40 | |
| SP | 41 | ts_vesicle *create_vesicle_from_tape(ts_tape *tape){ |
| 42 | ts_vesicle *vesicle; | |
| bcf455 | 43 | |
| 1ab449 | 44 | vesicle=initial_distribution_dipyramid(tape->nshell,tape->ncxmax,tape->ncymax,tape->nczmax,tape->stepsize); |
| 698ae1 | 45 | vesicle->tape=tape; |
| d43116 | 46 | vesicle->clist->dmin_interspecies = tape->dmin_interspecies*tape->dmin_interspecies; |
| SP | 47 | vesicle->poly_list=init_poly_list(tape->npoly,tape->nmono, vesicle->vlist, vesicle); |
| 698ae1 | 48 | set_vesicle_values_from_tape(vesicle); |
| def8b5 | 49 | initial_population_with_c0(vesicle,tape); |
| 698ae1 | 50 | return vesicle; |
| SP | 51 | } |
| 52 | ||
| 53 | ts_bool set_vesicle_values_from_tape(ts_vesicle *vesicle){ | |
| 58230a | 54 | // Nucleus: |
| 698ae1 | 55 | ts_vertex *vtx; |
| SP | 56 | ts_tape *tape=vesicle->tape; |
| fe24d2 | 57 | vesicle->R_nucleus=tape->R_nucleus*tape->R_nucleus; |
| 37791b | 58 | vesicle->R_nucleusX=tape->R_nucleusX*tape->R_nucleusX; |
| SP | 59 | vesicle->R_nucleusY=tape->R_nucleusY*tape->R_nucleusY; |
| 60 | vesicle->R_nucleusZ=tape->R_nucleusZ*tape->R_nucleusZ; | |
| fe24d2 | 61 | vesicle->clist->dmin_interspecies = tape->dmin_interspecies*tape->dmin_interspecies; |
| bcf455 | 62 | |
| 58230a | 63 | //Initialize grafted polymers (brush): |
| d43116 | 64 | //vesicle->poly_list=init_poly_list(tape->npoly,tape->nmono, vesicle->vlist, vesicle); |
| 1ab449 | 65 | vesicle->spring_constant=tape->kspring; |
| SP | 66 | poly_assign_spring_const(vesicle); |
| bcf455 | 67 | |
| 58230a | 68 | //Initialize filaments (polymers inside the vesicle): |
| M | 69 | vesicle->filament_list=init_poly_list(tape->nfil,tape->nfono, NULL, vesicle); |
| bcf455 | 70 | poly_assign_filament_xi(vesicle,tape); |
| 58230a | 71 | |
| bcf455 | 72 | ts_uint i,j; |
| M | 73 | for(i=0;i<vesicle->filament_list->n;i++){ |
| 74 | for(j=0;j<vesicle->filament_list->poly[i]->blist->n;j++){ | |
| 75 | bond_vector(vesicle->filament_list->poly[i]->blist->bond[j]); | |
| 76 | vesicle->filament_list->poly[i]->blist->bond[j]->bond_length = sqrt(vtx_distance_sq(vesicle->filament_list->poly[i]->blist->bond[j]->vtx1,vesicle->filament_list->poly[i]->blist->bond[j]->vtx2)); | |
| 77 | } | |
| 58230a | 78 | } |
| bcf455 | 79 | |
| M | 80 | for(i=0;i<vesicle->filament_list->n;i++){ |
| 81 | for(j=0;j<vesicle->filament_list->poly[i]->vlist->n;j++){ | |
| 82 | vtx = vesicle->filament_list->poly[i]->vlist->vtx[j]; | |
| 83 | if(vtx->bond_no == 2){ | |
| 84 | vtx->energy = -(vtx->bond[0]->x*vtx->bond[1]->x + vtx->bond[0]->y*vtx->bond[1]->y + vtx->bond[0]->z*vtx->bond[1]->z)/vtx->bond[0]->bond_length/vtx->bond[1]->bond_length; | |
| 85 | } | |
| 86 | } | |
| 58230a | 87 | } |
| bcf455 | 88 | |
| ea1cce | 89 | for(i=0;i<vesicle->filament_list->n;i++){ |
| M | 90 | vertex_list_assign_id(vesicle->filament_list->poly[i]->vlist,TS_ID_FILAMENT); |
| 91 | } | |
| bcf455 | 92 | |
| 58230a | 93 | // vesicle->spring_constant=tape->kspring; |
| M | 94 | // poly_assign_spring_const(vesicle); |
| 95 | ||
| 1ab449 | 96 | |
| SP | 97 | vesicle->nshell=tape->nshell; |
| 98 | vesicle->dmax=tape->dmax*tape->dmax; /* dmax^2 in the vesicle dmax variable */ | |
| 99 | vesicle->bending_rigidity=tape->xk0; | |
| 100 | vtx_set_global_values(vesicle); /* make xk0 default value for every vertex */ | |
| f4d6ca | 101 | // ts_fprintf(stdout, "Tape setting: xk0=%e\n",tape->xk0); |
| 1ab449 | 102 | vesicle->stepsize=tape->stepsize; |
| SP | 103 | vesicle->clist->ncmax[0]=tape->ncxmax; |
| 104 | vesicle->clist->ncmax[1]=tape->ncymax; | |
| 105 | vesicle->clist->ncmax[2]=tape->nczmax; | |
| 2a1e3d | 106 | //THIS IS NOW HARDCODED IN CELL.C |
| SP | 107 | // vesicle->clist->max_occupancy=16; /* hard coded max occupancy? */ |
| 1ab449 | 108 | |
| SP | 109 | vesicle->pressure= tape->pressure; |
| 110 | vesicle->pswitch=tape->pswitch; | |
| 632960 | 111 | if(tape->shc>0){ |
| 459ff9 | 112 | vesicle->sphHarmonics=complex_sph_init(vesicle->vlist,tape->shc); |
| 632960 | 113 | } |
| SP | 114 | else { |
| 115 | vesicle->sphHarmonics=NULL; | |
| 116 | } | |
| e5858f | 117 | |
| 699ac4 | 118 | vesicle->tlist->a0=sqrt(3)/4*pow((vesicle->tape->dmax+1.0)/2.0,2); |
| 698ae1 | 119 | return TS_SUCCESS; |
| 1ab449 | 120 | |
| SP | 121 | } |
| 122 | ||
| 123 | ||
| def8b5 | 124 | ts_bool initial_population_with_c0(ts_vesicle *vesicle, ts_tape *tape){ |
| SP | 125 | int rndvtx,i,j; |
| e5858f | 126 | if(tape->number_of_vertices_with_c0>0){ |
| 073d28 | 127 | // ts_fprintf(stderr,"Setting values for spontaneous curvature as defined in tape\n"); |
| eb9583 | 128 | j=0; |
| e5858f | 129 | for(i=0;i<tape->number_of_vertices_with_c0;i++){ |
| SP | 130 | rndvtx=rand() % vesicle->vlist->n; |
| eb9583 | 131 | if(fabs(vesicle->vlist->vtx[rndvtx]->c-tape->c0)<1e-15){ |
| SP | 132 | j++; |
| 133 | i--; | |
| 134 | if(j>10*vesicle->vlist->n){ | |
| 135 | fatal("cannot populate vesicle with vertices with spontaneous curvature. Too many spontaneous curvature vertices?",100); | |
| 136 | } | |
| 137 | continue; | |
| 138 | } | |
| e5858f | 139 | vesicle->vlist->vtx[rndvtx]->c=tape->c0; |
| SP | 140 | } |
| 141 | mean_curvature_and_energy(vesicle); | |
| 142 | if(fabs(tape->w)>1e-16){ //if nonzero energy | |
| 073d28 | 143 | // ts_fprintf(stderr,"Setting attraction between vertices with spontaneous curvature\n"); |
| e5858f | 144 | sweep_attraction_bond_energy(vesicle); |
| SP | 145 | } |
| 146 | } | |
| def8b5 | 147 | return TS_SUCCESS; |
| 1ab449 | 148 | } |
| SP | 149 | |
| 150 | ||
| 7958e9 | 151 | ts_bool pentagonal_dipyramid_vertex_distribution(ts_vertex_list *vlist){ |
| SP | 152 | /* Some often used relations */ |
| 153 | const ts_double s1= sin(2.0*M_PI/5.0); | |
| 154 | const ts_double s2= sin(4.0*M_PI/5.0); | |
| 155 | const ts_double c1= cos(2.0*M_PI/5.0); | |
| 156 | const ts_double c2= cos(4.0*M_PI/5.0); | |
| 157 | ||
| 158 | /* Calculates projection lenght of an edge bond to pentagram plane */ | |
| fab2ad | 159 | const ts_double xl0=DEF_A0/(2.0*sin(M_PI/5.0)); |
| 7958e9 | 160 | #ifdef TS_DOUBLE_DOUBLE |
| fab2ad | 161 | const ts_double z0=sqrt(pow(DEF_A0,2)-pow(xl0,2)); |
| 7958e9 | 162 | #endif |
| SP | 163 | #ifdef TS_DOUBLE_FLOAT |
| fab2ad | 164 | const ts_double z0=sqrtf(powf(DEF_A0,2)-powf(xl0,2)); |
| 7958e9 | 165 | #endif |
| SP | 166 | #ifdef TS_DOUBLE_LONGDOUBLE |
| fab2ad | 167 | const ts_double z0=sqrtl(powl(DEF_A0,2)-powl(xl0,2)); |
| 7958e9 | 168 | #endif |
| SP | 169 | // const z0=sqrt(A0*A0 -xl0*xl0); /* I could use pow function but if pow is used make a check on the float type. If float then powf, if long double use powl */ |
| 170 | ||
| 171 | /*placeholder for the pointer to vertex datastructure list... DIRTY: actual pointer points towards invalid address, one position before actual beginning of the list... This is to solve the difference between 1 based indexing in original program in fortran and 0 based indexing in C. All algorithms remain unchanged because of this!*/ | |
| 172 | ts_vertex **vtx=vlist->vtx -1 ; | |
| 173 | ||
| 174 | ||
| 175 | ts_uint nshell=(ts_uint)( sqrt((ts_double)(vlist->n-2)/5)); | |
| 176 | // printf("nshell=%u\n",nshell); | |
| 177 | ts_uint i,n0; // some for loop prereq | |
| 178 | ts_int j,k; | |
| 179 | ts_double dx,dy; // end loop prereq | |
| 180 | ||
| 181 | /* topmost vertex */ | |
| 8f6a69 | 182 | vtx[1]->x=0.0; |
| SP | 183 | vtx[1]->y=0.0; |
| 184 | vtx[1]->z=z0*(ts_double)nshell; | |
| 7958e9 | 185 | |
| SP | 186 | /* starting from to in circular order on pentagrams */ |
| 187 | for(i=1;i<=nshell;i++){ | |
| 188 | n0=2+5*i*(i-1)/2; //-1 would be for the reason that C index starts from 0 | |
| 8f6a69 | 189 | vtx[n0]->x=0.0; |
| SP | 190 | vtx[n0]->y=(ts_double)i*xl0; |
| 191 | vtx[n0+i]->x=vtx[n0]->y*s1; | |
| 192 | vtx[n0+i]->y=vtx[n0]->y*c1; | |
| 193 | vtx[n0+2*i]->x=vtx[n0]->y*s2; | |
| 194 | vtx[n0+2*i]->y=vtx[n0]->y*c2; | |
| 195 | vtx[n0+3*i]->x=-vtx[n0+2*i]->x; | |
| 196 | vtx[n0+3*i]->y=vtx[n0+2*i]->y; | |
| 197 | vtx[n0+4*i]->x=-vtx[n0+i]->x; | |
| 198 | vtx[n0+4*i]->y=vtx[n0+i]->y; | |
| 7958e9 | 199 | } |
| SP | 200 | |
| 201 | /* vertexes on the faces of the dipyramid */ | |
| 202 | for(i=1;i<=nshell;i++){ | |
| 203 | n0=2+5*i*(i-1)/2; // -1 would be because of C! | |
| 204 | for(j=1;j<=i-1;j++){ | |
| 8f6a69 | 205 | dx=(vtx[n0]->x-vtx[n0+4*i]->x)/(ts_double)i; |
| SP | 206 | dy=(vtx[n0]->y-vtx[n0+4*i]->y)/(ts_double)i; |
| 207 | vtx[n0+4*i+j]->x=(ts_double)j*dx+vtx[n0+4*i]->x; | |
| 208 | vtx[n0+4*i+j]->y=(ts_double)j*dy+vtx[n0+4*i]->y; | |
| 7958e9 | 209 | } |
| SP | 210 | for(k=0;k<=3;k++){ // I would be worried about zero starting of for |
| 8f6a69 | 211 | dx=(vtx[n0+(k+1)*i]->x - vtx[n0+k*i]->x)/(ts_double) i; |
| SP | 212 | dy=(vtx[n0+(k+1)*i]->y - vtx[n0+k*i]->y)/(ts_double) i; |
| 7958e9 | 213 | for(j=1; j<=i-1;j++){ |
| 8f6a69 | 214 | vtx[n0+k*i+j]->x= (ts_double)j*dx+vtx[n0+k*i]->x; |
| SP | 215 | vtx[n0+k*i+j]->y= (ts_double)j*dy+vtx[n0+k*i]->y; |
| 7958e9 | 216 | } |
| SP | 217 | } |
| 218 | } | |
| 219 | ||
| 220 | for(i=1;i<=nshell;i++){ | |
| 221 | n0= 2+ 5*i*(i-1)/2; | |
| 222 | for(j=0;j<=5*i-1;j++){ | |
| 8f6a69 | 223 | vtx[n0+j]->z= z0*(ts_double)(nshell-i); // I would be worried about zero starting of for |
| 7958e9 | 224 | } |
| SP | 225 | } |
| 226 | ||
| 227 | /* for botom part of dipyramide we calculate the positions of vertices */ | |
| 228 | for(i=2+5*nshell*(nshell+1)/2;i<=vlist->n;i++){ | |
| 8f6a69 | 229 | vtx[i]->x=vtx[vlist->n - i +1]->x; |
| SP | 230 | vtx[i]->y=vtx[vlist->n - i +1]->y; |
| 231 | vtx[i]->z=-vtx[vlist->n - i +1]->z; | |
| 7958e9 | 232 | } |
| SP | 233 | |
| 234 | for(i=1;i<=vlist->n;i++){ | |
| 235 | for(j=1;j<=vlist->n;j++){ | |
| 236 | if(i!=j && vtx_distance_sq(vtx[i],vtx[j])<0.001){ | |
| 237 | printf("Vertices %u and %u are the same!\n",i,j); | |
| 238 | } | |
| 239 | } | |
| 240 | } | |
| 241 | return TS_SUCCESS; | |
| 242 | } | |
| 243 | ||
| 244 | ||
| 245 | ||
| 246 | ts_bool init_vertex_neighbours(ts_vertex_list *vlist){ | |
| 247 | ts_vertex **vtx=vlist->vtx -1; // take a look at dipyramid function for comment. | |
| 248 | const ts_double eps=0.001; //TODO: find out if you can use EPS from math.h | |
| 249 | ts_uint i,j; | |
| 250 | ts_double dist2; // Square of distance of neighbours | |
| 251 | /*this is not required if we zero all data in vertex structure at initialization */ | |
| 252 | /*if we force zeroing at initialization this for loop can safely be deleted */ | |
| 253 | //for(i=1;i<=vlist->n;i++){ | |
| 254 | // vtx[i].neigh_no=0; | |
| 255 | //} | |
| 256 | for(i=1;i<=vlist->n;i++){ | |
| 257 | for(j=1;j<=vlist->n;j++){ | |
| 258 | dist2=vtx_distance_sq(vtx[i],vtx[j]); | |
| fab2ad | 259 | if( (dist2>eps) && (dist2<(DEF_A0*DEF_A0+eps))){ |
| 7958e9 | 260 | //if it is close enough, but not too much close (solves problem of comparing when i==j) |
| SP | 261 | vtx_add_neighbour(vtx[i],vtx[j]); |
| 262 | } | |
| 263 | } | |
| 264 | // printf ("vertex %u ima %u sosedov!\n",i,vtx[i]->data->neigh_no); | |
| 265 | } | |
| 266 | ||
| 267 | return TS_SUCCESS; | |
| 268 | } | |
| 269 | ||
| b01cc1 | 270 | // TODO: with new datastructure can be rewritten. Partially it is done, but it is complicated. |
| SP | 271 | ts_vertex_list *init_sort_neighbours(ts_bond_list *blist,ts_vertex_list *vlist){ |
| 7958e9 | 272 | ts_vertex **vtx=vlist->vtx -1; // take a look at dipyramid function for comment. |
| SP | 273 | ts_uint i,l,j,jj,jjj,k=0; |
| 274 | ts_double eps=0.001; // Take a look if EPS from math.h can be used | |
| 275 | ||
| 276 | /*lets initialize memory for temporary vertex_list. Should we write a function instead */ | |
| b01cc1 | 277 | ts_vertex_list *tvlist=vertex_list_copy(vlist); |
| 7958e9 | 278 | ts_vertex **tvtx=tvlist->vtx -1; /* again to compensate for 0-indexing */ |
| SP | 279 | |
| 280 | ts_double dist2; // Square of distance of neighbours | |
| 281 | ts_double direct; // Something, dont know what, but could be normal of some kind | |
| 282 | for(i=1;i<=vlist->n;i++){ | |
| 283 | k++; // WHY i IS NOT GOOD?? | |
| 8f6a69 | 284 | vtx_add_cneighbour(blist,tvtx[k], tvtx[vtx[i]->neigh[0]->idx+1]); //always add 1st |
| 7958e9 | 285 | jjj=1; |
| SP | 286 | jj=1; |
| 8f6a69 | 287 | for(l=2;l<=vtx[i]->neigh_no;l++){ |
| SP | 288 | for(j=2;j<=vtx[i]->neigh_no;j++){ |
| 289 | dist2=vtx_distance_sq(vtx[i]->neigh[j-1],vtx[i]->neigh[jj-1]); | |
| 290 | direct=vtx_direct(vtx[i],vtx[i]->neigh[j-1],vtx[i]->neigh[jj-1]); | |
| 291 | // TODO: check if fabs can be used with all floating point types!! | |
| fab2ad | 292 | if( (fabs(dist2-DEF_A0*DEF_A0)<=eps) && (direct>0.0) && (j!=jjj) ){ |
| 8f6a69 | 293 | vtx_add_cneighbour(blist,tvtx[k],tvtx[vtx[i]->neigh[j-1]->idx+1]); |
| 7958e9 | 294 | jjj=jj; |
| SP | 295 | jj=j; |
| 296 | break; | |
| 297 | } | |
| 298 | } | |
| 299 | } | |
| 300 | } | |
| b01cc1 | 301 | /* We use the temporary vertex for our main vertices and we abandon main |
| SP | 302 | * vertices, because their neighbours are not correctly ordered */ |
| 303 | // tvtx=vlist->vtx; | |
| 304 | // vlist->vtx=tvtx; | |
| 305 | // tvlist->vtx=vtx; | |
| 306 | vtx_list_free(vlist); | |
| 307 | /* Let's make a check if the number of bonds is correct */ | |
| 308 | if((blist->n)!=3*(tvlist->n-2)){ | |
| 309 | ts_fprintf(stderr,"Number of bonds is %u should be %u!\n", blist->n, 3*(tvlist->n-2)); | |
| 310 | fatal("Number of bonds is not 3*(no_vertex-2).",4); | |
| 7958e9 | 311 | } |
| SP | 312 | |
| b01cc1 | 313 | return tvlist; |
| 7958e9 | 314 | } |
| SP | 315 | |
| 316 | ||
| 317 | ts_bool init_vesicle_bonds(ts_vesicle *vesicle){ | |
| 318 | ts_vertex_list *vlist=vesicle->vlist; | |
| 319 | ts_bond_list *blist=vesicle->blist; | |
| 320 | ts_vertex **vtx=vesicle->vlist->vtx - 1; // Because of 0 indexing | |
| 321 | /* lets make correct clockwise ordering of in nearest neighbour list */ | |
| 322 | ts_uint i,j,k; | |
| 323 | for(i=1;i<=vlist->n;i++){ | |
| 324 | for(j=i+1;j<=vlist->n;j++){ | |
| 8f6a69 | 325 | for(k=0;k<vtx[i]->neigh_no;k++){ // has changed 0 to < instead of 1 and <= |
| SP | 326 | if(vtx[i]->neigh[k]==vtx[j]){ //if addresses matches it is the same |
| 7958e9 | 327 | bond_add(blist,vtx[i],vtx[j]); |
| SP | 328 | break; |
| 329 | } | |
| 330 | } | |
| 331 | } | |
| 332 | } | |
| 333 | /* Let's make a check if the number of bonds is correct */ | |
| 334 | if((blist->n)!=3*(vlist->n-2)){ | |
| 335 | ts_fprintf(stderr,"Number of bonds is %u should be %u!\n", blist->n, 3*(vlist->n-2)); | |
| 336 | fatal("Number of bonds is not 3*(no_vertex-2).",4); | |
| 337 | } | |
| 338 | return TS_SUCCESS; | |
| 339 | } | |
| 340 | ||
| 341 | ||
| 342 | ||
| 343 | ts_bool init_triangles(ts_vesicle *vesicle){ | |
| 344 | ts_uint i,j,jj,k; | |
| 345 | ts_vertex **vtx=vesicle->vlist->vtx -1; // difference between 0 indexing and 1 indexing | |
| 346 | ts_triangle_list *tlist=vesicle->tlist; | |
| 347 | ts_double dist, direct; | |
| 348 | ts_double eps=0.001; // can we use EPS from math.h? | |
| 349 | k=0; | |
| 350 | for(i=1;i<=vesicle->vlist->n;i++){ | |
| 8f6a69 | 351 | for(j=1;j<=vtx[i]->neigh_no;j++){ |
| SP | 352 | for(jj=1;jj<=vtx[i]->neigh_no;jj++){ |
| 7958e9 | 353 | // ts_fprintf(stderr,"%u: (%u,%u) neigh_no=%u ",i,j,jj,vtx[i].neigh_no); |
| SP | 354 | // ts_fprintf(stderr,"%e, %e",vtx[i].neigh[j-1]->x,vtx[i].neigh[jj-1]->x); |
| 8f6a69 | 355 | dist=vtx_distance_sq(vtx[i]->neigh[j-1],vtx[i]->neigh[jj-1]); |
| SP | 356 | direct=vtx_direct(vtx[i],vtx[i]->neigh[j-1],vtx[i]->neigh[jj-1]); |
| 357 | // TODO: same as above | |
| fab2ad | 358 | if(fabs(dist-DEF_A0*DEF_A0)<=eps && direct < 0.0 && vtx[i]->neigh[j-1]->idx+1 > i && vtx[i]->neigh[jj-1]->idx+1 >i){ |
| 8f6a69 | 359 | triangle_add(tlist,vtx[i],vtx[i]->neigh[j-1],vtx[i]->neigh[jj-1]); |
| 7958e9 | 360 | } |
| SP | 361 | } |
| 362 | } | |
| 363 | } | |
| 364 | /* We check if all triangles have 3 vertices and if the number of triangles | |
| 365 | * matches the theoretical value. | |
| 366 | */ | |
| 367 | for(i=0;i<tlist->n;i++){ | |
| 368 | k=0; | |
| 369 | for(j=0;j<3;j++){ | |
| 41a035 | 370 | if(tlist->tria[i]->vertex[j]!=NULL) |
| 7958e9 | 371 | k++; |
| SP | 372 | } |
| 373 | if(k!=3){ | |
| 8f6a69 | 374 | fatal("Some triangles have less than 3 vertices..",4); |
| 7958e9 | 375 | } |
| SP | 376 | } |
| 377 | if(tlist->n!=2*(vesicle->vlist->n -2)){ | |
| 378 | ts_fprintf(stderr,"The number of triangles is %u but should be %u!\n",tlist->n,2*(vesicle->vlist->n -2)); | |
| 379 | fatal("The number of triangles doesn't match 2*(no_vertex -2).",4); | |
| 380 | } | |
| 381 | return TS_SUCCESS; | |
| 382 | } | |
| 383 | ||
| 384 | ||
| 385 | ||
| 386 | ts_bool init_triangle_neighbours(ts_vesicle *vesicle){ | |
| 387 | ts_uint i,j,nobo; | |
| 388 | ts_vertex *i1,*i2,*i3,*j1,*j2,*j3; | |
| 389 | // ts_vertex **vtx=vesicle->vlist->vtx -1; // difference between 0 indexing and 1 indexing | |
| 390 | ts_triangle_list *tlist=vesicle->tlist; | |
| 391 | ts_triangle **tria=tlist->tria -1; | |
| 392 | nobo=0; | |
| 393 | for(i=1;i<=tlist->n;i++){ | |
| 41a035 | 394 | i1=tria[i]->vertex[0]; |
| SP | 395 | i2=tria[i]->vertex[1]; |
| 396 | i3=tria[i]->vertex[2]; | |
| 7958e9 | 397 | for(j=1;j<=tlist->n;j++){ |
| SP | 398 | if(j==i) continue; |
| 41a035 | 399 | j1=tria[j]->vertex[0]; |
| SP | 400 | j2=tria[j]->vertex[1]; |
| 401 | j3=tria[j]->vertex[2]; | |
| 7958e9 | 402 | if((i1==j1 && i3==j2) || (i1==j2 && i3==j3) || (i1==j3 && i3==j1)){ |
| SP | 403 | triangle_add_neighbour(tria[i],tria[j]); |
| 404 | nobo++; | |
| 405 | } | |
| 406 | } | |
| 407 | } | |
| 408 | for(i=1;i<=tlist->n;i++){ | |
| 41a035 | 409 | i1=tria[i]->vertex[0]; |
| SP | 410 | i2=tria[i]->vertex[1]; |
| 411 | i3=tria[i]->vertex[2]; | |
| 7958e9 | 412 | for(j=1;j<=tlist->n;j++){ |
| SP | 413 | if(j==i) continue; |
| 41a035 | 414 | j1=tria[j]->vertex[0]; |
| SP | 415 | j2=tria[j]->vertex[1]; |
| 416 | j3=tria[j]->vertex[2]; | |
| 7958e9 | 417 | if((i1==j1 && i2==j3) || (i1==j3 && i2==j2) || (i1==j2 && i2==j1)){ |
| SP | 418 | triangle_add_neighbour(tria[i],tria[j]); |
| 419 | nobo++; | |
| 420 | } | |
| 421 | } | |
| 422 | } | |
| 423 | for(i=1;i<=tlist->n;i++){ | |
| 41a035 | 424 | i1=tria[i]->vertex[0]; |
| SP | 425 | i2=tria[i]->vertex[1]; |
| 426 | i3=tria[i]->vertex[2]; | |
| 7958e9 | 427 | for(j=1;j<=tlist->n;j++){ |
| SP | 428 | if(j==i) continue; |
| 41a035 | 429 | j1=tria[j]->vertex[0]; |
| SP | 430 | j2=tria[j]->vertex[1]; |
| 431 | j3=tria[j]->vertex[2]; | |
| 7958e9 | 432 | if((i2==j1 && i3==j3) || (i2==j3 && i3==j2) || (i2==j2 && i3==j1)){ |
| SP | 433 | triangle_add_neighbour(tria[i],tria[j]); |
| 434 | nobo++; | |
| 435 | } | |
| 436 | } | |
| 437 | } | |
| 438 | if(nobo != vesicle->blist->n*2) { | |
| 439 | ts_fprintf(stderr,"Number of triangles= %u, number of bonds= %u\n",nobo/2, vesicle->blist->n); | |
| 440 | fatal("Number of triangle neighbour pairs differs from double the number of bonds!",4); | |
| 441 | } | |
| 442 | return TS_SUCCESS; | |
| 443 | } | |
| 444 | ||
| 445 | ||
| 446 | ts_bool init_common_vertex_triangle_neighbours(ts_vesicle *vesicle){ | |
| 447 | ts_uint i,j,jp,k; | |
| 448 | ts_vertex *k1,*k2,*k3,*k4,*k5; | |
| 449 | ts_vertex **vtx=vesicle->vlist->vtx -1; // difference between 0 indexing and 1 indexing | |
| 450 | ts_triangle_list *tlist=vesicle->tlist; | |
| 451 | ts_triangle **tria=tlist->tria -1; | |
| 452 | ||
| 453 | for(i=1;i<=vesicle->vlist->n;i++){ | |
| 8f6a69 | 454 | for(j=1;j<=vtx[i]->neigh_no;j++){ |
| SP | 455 | k1=vtx[i]->neigh[j-1]; |
| 7958e9 | 456 | jp=j+1; |
| 8f6a69 | 457 | if(j == vtx[i]->neigh_no) jp=1; |
| SP | 458 | k2=vtx[i]->neigh[jp-1]; |
| 7958e9 | 459 | for(k=1;k<=tlist->n;k++){ // VERY NON-OPTIMAL!!! too many loops (vlist.n * vtx.neigh * tlist.n )! |
| 41a035 | 460 | k3=tria[k]->vertex[0]; |
| SP | 461 | k4=tria[k]->vertex[1]; |
| 462 | k5=tria[k]->vertex[2]; | |
| 7958e9 | 463 | // ts_fprintf(stderr,"%u %u: k=(%u %u %u)\n",k1,k2,k3,k4,k5); |
| SP | 464 | if((vtx[i]==k3 && k1==k4 && k2==k5) || |
| 465 | (vtx[i]==k4 && k1==k5 && k2==k3) || | |
| 466 | (vtx[i]==k5 && k1==k3 && k2==k4)){ | |
| b01cc1 | 467 | |
| SP | 468 | //TODO: probably something wrong with neighbour distribution. |
| 469 | // if(vtx[i]==k3 || vtx[i]==k4 || vtx[i]==k5){ | |
| dac2e5 | 470 | // if(i==6) ts_fprintf(stdout, "Vtx[%u] > Added to tristar!\n",i); |
| 7958e9 | 471 | vertex_add_tristar(vtx[i],tria[k]); |
| SP | 472 | } |
| 473 | } | |
| 474 | } | |
| 475 | /* ts_fprintf(stderr,"TRISTAR for %u (%u):",i-1,vtx[i].tristar_no); | |
| 476 | for(j=0;j<vtx[i].tristar_no;j++){ | |
| 477 | ts_fprintf(stderr," %u,",vtx[i].tristar[j]->idx); | |
| 478 | } | |
| 479 | ts_fprintf(stderr,"\n"); */ | |
| 480 | } | |
| 481 | return TS_SUCCESS; | |
| 482 | } | |
| 483 | ||
| 484 | ||
| 485 | ts_bool init_normal_vectors(ts_triangle_list *tlist){ | |
| 486 | /* Normals point INSIDE vesicle */ | |
| 487 | ts_uint k; | |
| 488 | ts_triangle **tria=tlist->tria -1; //for 0 indexing | |
| 489 | for(k=1;k<=tlist->n;k++){ | |
| 490 | triangle_normal_vector(tria[k]); | |
| 491 | } | |
| 492 | return TS_SUCCESS; | |
| 493 | } | |