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