Trisurf Monte Carlo simulator
Samo Penic
2010-12-04 bb77ca8f6e18e5a3ee2996095db5394dcd49197a
Datastructure & basic functions rewritten. It seems there is no memory leaks in
simple operations.
11 files modified
361 ■■■■ changed files
src/Makefile.am 2 ●●● patch | view | raw | blame | history
src/cell.c 104 ●●●●● patch | view | raw | blame | history
src/cell.h 10 ●●●● patch | view | raw | blame | history
src/general.h 28 ●●●●● patch | view | raw | blame | history
src/main.c 13 ●●●●● patch | view | raw | blame | history
src/triangle.c 147 ●●●●● patch | view | raw | blame | history
src/triangle.h 6 ●●●●● patch | view | raw | blame | history
src/vertex.c 14 ●●●●● patch | view | raw | blame | history
src/vertex.h 1 ●●●● patch | view | raw | blame | history
src/vesicle.c 34 ●●●● patch | view | raw | blame | history
src/vesicle.h 2 ●●● patch | view | raw | blame | history
src/Makefile.am
@@ -1,5 +1,5 @@
trisurfdir=../
trisurf_PROGRAMS=trisurf
trisurf_SOURCES=general.c vertex.c bond.c triangle.c main.c
trisurf_SOURCES=general.c vertex.c bond.c triangle.c cell.c main.c
trisurf_LDFLAGS = -lm -lconfuse
trisurf_CFLAGS = -Wall -Werror
src/cell.c
@@ -1,87 +1,107 @@
#include<stdlib.h>
#include "general.h"
#include "vertex.h"
#include <stdio.h>
ts_bool init_cell_list(ts_cell_list *clist, ts_double stepsize){
ts_cell_list  *init_cell_list(ts_uint ncmax1, ts_uint ncmax2, ts_uint ncmax3, ts_double stepsize){
    ts_uint i;
    ts_uint nocells=clist->ncmax[0]*clist->ncmax[1]*clist->ncmax[2];
    clist->cell=malloc(nocells*sizeof(ts_cell));
    ts_uint nocells=ncmax1*ncmax2*ncmax3;
    ts_cell_list *clist=(ts_cell_list *)malloc(sizeof(ts_cell_list));
    if(clist==NULL) fatal("Error while allocating memory for cell list!",100);
    clist->ncmax[0]=ncmax1;
    clist->ncmax[1]=ncmax2;
    clist->ncmax[2]=ncmax3;
    clist->cellno=nocells;
    clist->dcell=1.0/(1.0 + stepsize);
    clist->shift=(ts_double) clist->ncmax[0]/2;
    clist->cellno=nocells;
    clist->cell=(ts_cell **)malloc(nocells*sizeof(ts_cell *));
    if(clist->cell==NULL) fatal("Error while allocating memory for cell list! ncmax too large?",101);
    for(i=0;i<nocells;i++){
        clist->cell[i].idx=i+1; // We enumerate cells! Probably never required!
        clist->cell[i].nvertex=0;
        clist->cell[i].vertex=NULL;
        clist->cell[i]=(ts_cell *)malloc(sizeof(ts_cell));
        if(clist->cell[i]==NULL) fatal("Error while allocating memory for cell list! ncmax too large?",102);
        clist->cell[i]->idx=i+1; // We enumerate cells! Probably never required!
        clist->cell[i]->data=(ts_cell_data *)calloc(1,sizeof(ts_cell_data));
    }
    return clist;
}
ts_bool cell_free(ts_cell* cell){
    if(cell->data!=NULL){
        if(cell->data->vertex!=NULL) free(cell->data->vertex);
        free(cell->data);
    }
    free(cell);
    return TS_SUCCESS;
}
ts_bool cell_list_free(ts_cell_list *clist){
    ts_uint i;
     ts_uint nocells=clist->ncmax[0]*clist->ncmax[1]*clist->ncmax[2];
    if(clist==NULL) return TS_FAIL;
    ts_uint nocells=clist->cellno;
    for(i=0;i<nocells;i++)
         if(clist->cell->vertex != NULL) free(clist->cell->vertex);
         if(clist->cell[i] != NULL) cell_free(clist->cell[i]);
    free(clist->cell);
    free(clist);
    return TS_SUCCESS;
}
inline ts_uint vertex_self_avoidance(ts_vesicle *vesicle, ts_vertex *vtx){
    ts_uint i,cellidx;
    ts_uint ncx, ncy,ncz;
    ncx=(ts_uint)((vtx->x-vesicle->cm[0])*vesicle->clist.dcell+vesicle->clist.shift);
    ncy=(ts_uint)((vtx->y-vesicle->cm[1])*vesicle->clist.dcell+vesicle->clist.shift);
    ncz=(ts_uint)((vtx->z-vesicle->cm[2])*vesicle->clist.dcell+vesicle->clist.shift);
//    fprintf(stderr,"(ncx,ncy,ncz)=(%i %i %i)\t",ncx,ncy,ncz);
//    fprintf(stderr,"(ncxmax,ncymax,nczmax)=(%i %i %i)\n",vesicle->clist.ncmax[0], vesicle->clist.ncmax[1], vesicle->clist.ncmax[2]);
    if(ncx == vesicle->clist.ncmax[0]-1 || ncx == 2){
//TODO: not debugged at all!
inline ts_uint vertex_self_avoidance(ts_vesicle *vesicle, ts_vertex *vtx){
    ts_uint cellidx;
    ts_uint ncx, ncy,ncz;
    ts_cell_list *clist=vesicle->clist;
    ncx=(ts_uint)((vtx->data->x-vesicle->cm[0])*clist->dcell+clist->shift);
    ncy=(ts_uint)((vtx->data->y-vesicle->cm[1])*clist->dcell+clist->shift);
    ncz=(ts_uint)((vtx->data->z-vesicle->cm[2])*clist->dcell+clist->shift);
    if(ncx == clist->ncmax[0]-1 || ncx == 2){
        fatal("Vesicle is positioned outside the cell covered area. Coordinate x is the problem.",1500);
    }
    if(ncy == vesicle->clist.ncmax[1]-1 || ncy == 2){
    if(ncy == clist->ncmax[1]-1 || ncy == 2){
        fatal("Vesicle is positioned outside the cell covered area. Coordinate y is the problem.",1500);
    }
    if(ncz == vesicle->clist.ncmax[2]-1 || ncz == 2){
    if(ncz == clist->ncmax[2]-1 || ncz == 2){
        fatal("Vesicle is positioned outside the cell covered area. Coordinate z is the problem.",1500);
    }
    cellidx=ncz+(ncy-1)*vesicle->clist.ncmax[2] +
(ncx-1)*vesicle->clist.ncmax[2]* vesicle->clist.ncmax[1] - 1; // -1 is because of 0 based indexing
    cellidx=ncz+(ncy-1)*clist->ncmax[2] + (ncx-1)*clist->ncmax[2]*
                                    clist->ncmax[1] - 1; // -1 is because of 0 based indexing
    return cellidx;
}
//TODO: looks ok, but debug anyway in the future
ts_bool cell_add_vertex(ts_cell *cell, ts_vertex *vtx){
    cell->nvertex++;
    cell->vertex=realloc(cell->vertex,cell->nvertex*sizeof(ts_vertex *));
        if(vtx->neigh == NULL){
    cell->data->nvertex++;
    cell->data->vertex=(ts_vertex **)realloc(cell->data->vertex,cell->data->nvertex*sizeof(ts_vertex *));
        if(vtx->data->neigh == NULL){
            fatal("Reallocation of memory failed during insertion of vertex neighbour in vertex_add_neighbour",3);
        }
    cell->vertex[cell->nvertex-1]=vtx;
    cell->data->vertex[cell->data->nvertex-1]=vtx;
    return TS_SUCCESS;
}
ts_bool cell_list_cell_ocupation_clear(ts_cell_list *clist){
ts_bool cell_list_cell_occupation_clear(ts_cell_list *clist){
    ts_uint i;
    for(i=0;i<clist->cellno;i++){
        if(clist->cell[i].vertex != NULL){
            free(clist->cell[i].vertex);
            clist->cell[i].vertex=NULL;
        if(clist->cell[i]->data->vertex != NULL){
            free(clist->cell[i]->data->vertex);
            clist->cell[i]->data->vertex=NULL;
        }
        clist->cell[i].nvertex=0;
        clist->cell[i]->data->nvertex=0;
    }
    return TS_SUCCESS;
}
// TODO: compiles ok, but it is completely untested and undebugged. It was debugged before rewrite, but this was long time ago.
ts_bool cell_occupation_number_and_internal_proximity(ts_cell_list *clist, ts_uint cellidx, ts_vertex *vtx, ts_vertex *tvtx){
    ts_uint ncx,ncy,ncz,remainder,cell_occupation;
    ts_uint i,j,k,l,neigh_cidx,mcell;
    ts_uint i,j,k,l,neigh_cidx;
    ts_double dist;
    ncx=(cellidx+1)/(clist->ncmax[2]*clist->ncmax[1])+1;
    ncx=(cellidx+1)/(clist->ncmax[2]*clist->ncmax[1])+1; //+1 because of zero indexing.
    remainder=(cellidx+1)%(clist->ncmax[2]*clist->ncmax[1]);
    ncy=remainder/clist->ncmax[2]+1;
    ncz=remainder%clist->ncmax[2];
@@ -92,7 +112,7 @@
            for(k=ncz-1;k<=ncz+1;k++){
                neigh_cidx=k+(j-1)*clist->ncmax[2]+(i-1)*clist->ncmax[2]*clist->ncmax[1] -1;
          //      fprintf(stderr,"neigh_cell_index=%i\n",neigh_cidx);
                cell_occupation=clist->cell[neigh_cidx].nvertex;
                cell_occupation=clist->cell[neigh_cidx]->data->nvertex;
          //      fprintf(stderr, "cell_occupation=%i\n",cell_occupation);
                if(cell_occupation>clist->max_occupancy){
                    fatal("Neighbouring cell occupation more than set max_occupancy value.",2000);
@@ -101,9 +121,9 @@
// cell!
                if(cell_occupation>1){
                    for(l=0;l<cell_occupation;l++){
                        if(clist->cell[neigh_cidx].vertex[l]!=vtx){
                        if(clist->cell[neigh_cidx]->data->vertex[l]!=vtx){
                    //        fprintf(stderr,"calling dist on vertex %i\n",l);
                           dist=vertex_distance_sq(clist->cell[neigh_cidx].vertex[l],tvtx);
                           dist=vtx_distance_sq(clist->cell[neigh_cidx]->data->vertex[l],tvtx);
                    //        fprintf(stderr,"dist was %f\n",dist);
                            if(dist<1) return TS_FAIL;
                        }
src/cell.h
@@ -1,6 +1,12 @@
#ifndef _H_CELL
#define _H_CELL
ts_cell_list  *init_cell_list(ts_uint ncmax1, ts_uint ncmax2, ts_uint ncmax3, ts_double stepsize);
ts_bool cell_free(ts_cell* cell);
ts_bool cell_list_free(ts_cell_list *clist);
inline ts_uint vertex_self_avoidance(ts_vesicle *vesicle, ts_vertex *vtx);
ts_bool cell_occupation_number_and_internal_proximity(ts_cell_list *clist,
ts_uint cellidx, ts_vertex *vtx, ts_vertex *tvtx);
ts_bool cell_add_vertex(ts_cell *cell, ts_vertex *vtx);
ts_bool cell_list_cell_occupation_clear(ts_cell_list *clist);
//ts_bool cell_occupation_number_and_internal_proximity(ts_cell_list *clist,
//ts_uint cellidx, ts_vertex *vtx, ts_vertex *tvtx);
#endif
src/general.h
@@ -194,22 +194,32 @@
};
typedef struct ts_triangle_list ts_triangle_list;
typedef struct ts_cell {
    ts_uint idx;
typedef struct ts_cell_data {
    ts_vertex **vertex;
    ts_uint nvertex;
} ts_cell_data;
typedef struct ts_cell {
    ts_uint idx;
    ts_cell_data *data;
} ts_cell;
typedef struct {
    ts_vertex *vlist;
    ts_bond *blist;
    ts_triangle *tlist;
    ts_cell *clist;
    ts_uint nshell;
typedef struct ts_cell_list{
    ts_uint ncmax[3];
    ts_uint cellno;
    ts_cell **cell;
    ts_double dcell;
    ts_double shift;
    ts_double max_occupancy;
    ts_uint ncmax[3];
} ts_cell_list;
typedef struct {
    ts_vertex_list *vlist;
    ts_bond_list *blist;
    ts_triangle_list *tlist;
    ts_cell_list *clist;
    ts_uint nshell;
    ts_double bending_rigidity;
    ts_double dmax;
    ts_double stepsize;
src/main.c
@@ -4,6 +4,7 @@
#include "vertex.h"
#include "bond.h"
#include "triangle.h"
#include "cell.h"
//#include "io.h"
//#include "initial_timestep.h"
@@ -18,7 +19,7 @@
ts_vertex_list *vlist=init_vertex_list(5);
ts_bond_list *blist=init_bond_list();
ts_triangle_list *tlist=init_triangle_list();
ts_cell_list *clist=init_cell_list(3,3,3,0.3);
retval=vtx_add_cneighbour(blist,vlist->vtx[1],vlist->vtx[0]);
@@ -38,9 +39,19 @@
triangle_add(tlist,vlist->vtx[1],vlist->vtx[2],vlist->vtx[3]);
printf("Cell idx=1 has vertices=%u\n",clist->cell[0]->data->nvertex);
cell_add_vertex(clist->cell[0], vlist->vtx[0]);
printf("Cell idx=1 has vertices=%u\n",clist->cell[0]->data->nvertex);
printf("Cell idx=1 has vertex[0] has x coordinate=%e\n",clist->cell[0]->data->vertex[0]->data->x);
cell_list_cell_occupation_clear(clist);
printf("Cell idx=1 has vertices=%u\n",clist->cell[0]->data->nvertex);
cell_add_vertex(clist->cell[0], vlist->vtx[0]);
triangle_list_free(tlist);
bond_list_free(blist);
vtx_list_free(vlist);
cell_list_free(clist);
printf("Done.\n");
return 0; //program finished perfectly ok. We return 0.
src/triangle.c
@@ -4,6 +4,21 @@
#include "triangle.h"
#include<math.h>
/** @brief Prepares the list for triangles.
  *
  * Create empty list for holding the information on triangles. Triangles are
  * added later on with triangle_add().
  * Returns pointer to the tlist datastructure it has created. This pointer must
  * be assigned to some variable or it will be lost.
  *
  *
  * Example of usage:
  *     ts_triangle_list *tlist;
  *        tlist=triangle_data_free();
  *
  *        Initalized data structure for holding the information on triangles.
  *
  */
ts_triangle_list *init_triangle_list(){
    ts_triangle_list *tlist=(ts_triangle_list *)malloc(sizeof(ts_triangle_list));
    tlist->n = 0;
@@ -11,7 +26,27 @@
    return tlist;
}
/** @brief Add the triangle to the triangle list and create necessary data
 * structures.
  *
  * Add the triangle ts_triangle with ts_triangle_data to the ts_triangle_list.
  * The triangle list is resized, the ts_triangle is allocated and
  * ts_triangle_data is allocated and zeroed. The function receives 4 arguments:
  * ts_triangle_list *tlist as list of triangles and 3 ts_vertex *vtx as
  * vertices that are used to form a triangle. Returns a pointer to newly
  * created triangle. This pointer doesn't need assigning, since it is
  * referenced by triangle list.
  *
  * WARNING: Function can be accelerated a bit by removing the NULL checks.
  * However the time gained by removal doesn't justify the time spent by
  * debugging stupid NULL pointers.
  *
  * Example of usage:
  *        triangle_add(tlist, vlist->vtx[1], vlist->vtx[2], vlist->vtx[3]);
  *
  *        Creates a triangle with given vertices and puts it into the list.
  *
  */
ts_triangle *triangle_add(ts_triangle_list *tlist, ts_vertex *vtx1, ts_vertex *vtx2, ts_vertex *vtx3){
        if(vtx1==NULL || vtx2==NULL || vtx3==NULL){
            return NULL;
@@ -32,6 +67,27 @@
        return tlist->tria[tlist->n-1];
}
/** @brief Add the neigbour to triangles.
  *
  * Add the neigbour to the list of neighbouring triangles. The
  * neighbouring triangles are those, who share two vertices. Function resizes
  * the list and adds the pointer to neighbour. It receives two arguments of
  * ts_triangle type. It then adds eachother to eachother's list. Upon
  * success it returns TS_SUCCESS, upon detecting NULL pointers
  * returns TS_FAIL and it FATALY ends when the data structure
  * cannot be resized.
  *
  *
  * WARNING: Function can be accelerated a bit by removing the NULL checks.
  * However the time gained by removal doesn't justify the time spent by
  * debugging stupid NULL pointers.
  *
  * Example of usage:
  *        triangle_remove_neighbour(tlist->tria[3], tlist->tria[4]);
  *
  *        Triangles 3 and 4 are not neighbours anymore.
  *
  */
ts_bool triangle_add_neighbour(ts_triangle *tria, ts_triangle *ntria){
    if(tria==NULL || ntria==NULL) return TS_FAIL;
@@ -52,7 +108,27 @@
    return TS_SUCCESS;
}
/** @brief Remove the neigbours from triangle.
  *
  * Removes the neigbour from the list of neighbouring triangles. The
  * neighbouring triangles are those, who share two vertices. Function resizes
  * the list and deletes the pointer to neighbour. It receives two arguments of
  * ts_triangle type. It then removes eachother form eachother's list. Upon
  * success it returns TS_SUCCESS, upon failure to find the triangle in the
  * neighbour list returns TS_FAIL and it FATALY ends when the datastructure
  * cannot be resized.
  *
  * WARNING: The function doesn't check whether the pointer is NULL or invalid. It is the
  * job of programmer to make sure the pointer is valid.
  *
  * WARNING: Function is slow. Do not use it often!
  *
  * Example of usage:
  *        triangle_remove_neighbour(tlist->tria[3], tlist->tria[4]);
  *
  *        Triangles 3 and 4 are not neighbours anymore.
  *
  */
ts_bool triangle_remove_neighbour(ts_triangle *tria, ts_triangle *ntria){
    ts_uint i,j=0; 
    if(tria==NULL || ntria==NULL) return TS_FAIL;
@@ -91,6 +167,28 @@
    return TS_SUCCESS;
}
/** @brief Calculates normal vector of the triangle.
  *
  * Calculate normal vector of the triangle (xnorm, ynorm and znorm) and stores
  * information in underlying ts_triangle_data data_structure.
  *
  * Function receives one argument of type ts_triangle. It should be corectly
  * initialized with underlying data structure of type ts_triangle_data. the
  * result is stored in triangle->data->xnorm, triangle->data->ynorm,
  * triangle->data->znorm. Returns TS_SUCCESS on completion.
  *
  * NOTE: Function uses math.h library. pow function implementation is selected
  * accordind to the setting in genreal.h
  *
  * Example of usage:
  *        triangle_normal_vector(tlist->tria[3]);
  *
  *        Computes normals and stores information into tlist->tria[3]->xnorm,
  *        tlist->tria[3]->ynorm, tlist->tria[3]->znorm.
  *
  */
ts_bool triangle_normal_vector(ts_triangle *tria){
    ts_double x21,x31,y21,y31,z21,z31,xden;
    x21=tria->data->vertex[1]->data->x - tria->data->vertex[0]->data->x;
@@ -122,12 +220,57 @@
}
/** @brief Frees the memory allocated for data structure of triangle data
 * (ts_triangle_data)
  *
  * Function frees the memory of ts_triangle_data previously allocated. It
  * accepts one argument, the address of data structure. It destroys all
  * pointers the structure might have (currently only neigh -- the pointer to
  * list of neighbouring triangles) and data structure itself. The return value
  * is always TS_SUCCESS.
  *
  * WARNING: The function doesn't check whether the pointer is NULL or invalid. It is the
  * job of programmer to make sure the pointer is valid.
  *
  * Example of usage:
  *        triangle_data_free(tlist->tria[3]->data);
  *
  *        Clears the data structure with all pointers.
  *
  */
ts_bool triangle_data_free(ts_triangle_data *data){
    if(data->neigh!=NULL) free(data->neigh);
    free(data);
    return TS_SUCCESS;
}
/** @brief Frees the memory allocated for data structure of triangle list
 * (ts_triangle_list)
  *
  * Function frees the memory of ts_triangle_list previously allocated. It
  * accepts one argument, the address of data structure. It destroys all
  * ts_triangle's in the list with underlying data (by calling
  * triangle_data_free()), and the list itself.
  *
  * Should be used eveytime the deletion of triangle list (created by
  * init_triangle_list() and altered by add_triangle() or remove_triangle()) is desired.
  *
  * WARNING: The function doesn't check whether the pointer is NULL or invalid. It is the
  * job of programmer to make sure the pointer is valid.
  *
  * WARNING: Careful when destroying triangle lists. There could be pointers to
  * that information remaining in structures like vertex_data. This pointers
  * will be rendered invalid by this operation and should not be used anymore.
  *
  * Example of usage:
  *        triangle_list_free(tlist);
  *
  *        Clears all the information on triangles.
  *
  */
ts_bool triangle_list_free(ts_triangle_list *tlist){
    ts_uint i;
    for(i=0;i<tlist->n;i++){
src/triangle.h
@@ -3,12 +3,6 @@
ts_triangle_list *init_triangle_list(void);
ts_triangle *triangle_add(ts_triangle_list *tlist, ts_vertex *vtx1, ts_vertex *vtx2, ts_vertex *vtx3);
/** Adds a neighbouring triangle in a list
 *    @param *tria is a pointer to the triangle, to which additional member want to be added
 *    @param *ntria is a pointer to neighbouring triangle
 *    @returns TS_SUCCESS on success, TS_FAIL otherwise. If memory cannot be alloccated, this is considered as serious error and the execution is immediately terminated with error code returned to the underlying operating system
 */
ts_bool triangle_add_neighbour(ts_triangle *tria, ts_triangle *ntria);
ts_bool triangle_normal_vector(ts_triangle *tria);
ts_bool triangle_data_free(ts_triangle_data *triang);
src/vertex.c
@@ -175,20 +175,18 @@
    return TS_SUCCESS;
}
/* rewrite for additional structure in chain */
/*inline ts_double vtx_distance_sq(ts_vertex *vtx1, ts_vertex *vtx2){
inline ts_double vtx_distance_sq(ts_vertex *vtx1, ts_vertex *vtx2){
    ts_double dist;
    ts_vertex_data *vd1=vtx1->data, *vd2=vtx2->data;
#ifdef TS_DOUBLE_DOUBLE
    dist=pow((*vtx1)->x-(*vtx2)->x,2) + pow((*vtx1)->y-(*vtx2)->y,2) + pow((*vtx1)->z-(*vtx2)->z,2);
    dist=pow(vd1->x-vd2->x,2) + pow(vd1->y-vd2->y,2) + pow(vd1->z-vd2->z,2);
#endif
#ifdef TS_DOUBLE_LONGDOUBLE
    dist=powl((*vtx1)->x-(*vtx2)->x,2) + powl((*vtx1)->y-(*vtx2)->y,2) + powl((*vtx1)->z-(*vtx2)->z,2);
    dist=powl(vd1->x-vd2->x,2) + powl(vd1->y-vd2->y,2) + powl(vd1->z-vd2->z,2);
#endif
#ifdef TS_DOUBLE_FLOAT
    dist=powf((*vtx1)->x-(*vtx2)->x,2) + powf((*vtx1)->y-(*vtx2)->y,2) + powf((*vtx1)->z-(*vtx2)->z,2);
    dist=powf(vd1->x-vd2->x,2) + powf(vd1->y-vd2->y,2) + powf(vd1->z-vd2->z,2);
#endif
    return(dist);
}
*/
src/vertex.h
@@ -22,4 +22,5 @@
ts_bool vtx_data_free(ts_vertex_data *data);
ts_bool vtx_free(ts_vertex *vtx);
ts_bool vtx_list_free(ts_vertex_list *vlist);
inline ts_double vtx_distance_sq(ts_vertex *vtx1, ts_vertex *vtx2);
#endif
src/vesicle.c
@@ -1,21 +1,37 @@
#include<general.h>
#include "vesicle.h"
#include "vertex.h"
#include "triangle.h"
#include "bond.h"
#include "cell.h"
ts_vesicle *init_vesicle(ts_uint N, ts_uint ncmax1, ts_uint ncmax2, ts_uint
ncmax3, ts_double stepsize){
    ts_vesicle *vesicle;
    vesicle->vlist=init_vertex_list(N);
    vesicle->blist=init_bond_list();
    vesicle->tlist=init_triangle_list();
    vesicle->clist=init_cell_list(ncmax1, ncmax2, ncmax3, stepsize);
    return TS_SUCCESS;
}
ts_bool vesicle_translate(ts_vesicle *vesicle,ts_double x, ts_double y, ts_double z){
    ts_uint i;
    ts_vertex *vtx=vesicle->vlist.vertex;
    ts_uint nn=vesicle->vlist.n;
    ts_vertex *vtx=vesicle->vlist->vertex;
    ts_uint nn=vesicle->vlist->n;
    for(i=0;i<nn;i++){
        vtx[i].x+=x;
        vtx[i].y+=y;
        vtx[i].z+=z;
        vtx[i]->data->x+=x;
        vtx[i]->data->y+=y;
        vtx[i]->data->z+=z;
    }
    return TS_SUCCESS;
}
ts_bool vesicle_free(ts_vesicle *vesicle){
    vertex_list_free(&vesicle->vlist);
    bond_list_free(&vesicle->blist);
    triangle_list_free(&vesicle->tlist);
    cell_list_free(&vesicle->clist);
    vertex_list_free(vesicle->vlist);
    bond_list_free(vesicle->blist);
    triangle_list_free(vesicle->tlist);
    cell_list_free(vesicle->clist);
    return TS_SUCCESS;
}
src/vesicle.h
@@ -1,7 +1,7 @@
#ifndef _VESICLE_H
#define _VESICLE_H
ts_vesicle *init_vesicle(ts_uint N, ts_uint ncmax1, ts_uint ncmax2, ts_uint ncmax3, ts_double stepsize);
ts_bool vesicle_translate(ts_vesicle *vesicle,ts_double x, ts_double y, ts_double z);
ts_bool vesicle_free(ts_vesicle *vesicle);