Trisurf Monte Carlo simulator
Samo Penic
2014-04-29 fbcbdf4093644e43688d9a44d6553d7153d8a2eb
Constant volume in bondflip need lots of debugging
5 files modified
149 ■■■■ changed files
src/bondflip.c 59 ●●●● patch | view | raw | blame | history
src/constvol.c 44 ●●●●● patch | view | raw | blame | history
src/constvol.h 4 ●●●● patch | view | raw | blame | history
src/tape 4 ●●●● patch | view | raw | blame | history
src/vertexmove.c 38 ●●●●● patch | view | raw | blame | history
src/bondflip.c
@@ -12,6 +12,7 @@
//#include "io.h"
#include<stdio.h>
#include<string.h>
#include "constvol.h"
ts_bool single_bondflip_timestep(ts_vesicle *vesicle, ts_bond *bond, ts_double *rn){
/*c  Vertex and triangle (lm and lp) indexing for bond flip:
@@ -34,6 +35,10 @@
    ts_triangle *lm=NULL,*lp=NULL, *lp1=NULL, *lm2=NULL;
    ts_vertex *kp,*km;
    ts_double delta_energy_cv;
    ts_vertex *constvol_vtx_moved, *constvol_vtx_backup;
    ts_bool retval;
    if(it->neigh_no< 3) return TS_FAIL;
    if(k->neigh_no< 3) return TS_FAIL;
@@ -164,7 +169,7 @@
  oldenergy+=it->xk* it->energy;
  //Neigbours of k, it, km, kp don't change its energy.
    if(vesicle->pswitch == 1){dvol = -lm->volume - lp->volume;}
    if(vesicle->pswitch == 1 || vesicle->tape->constvolswitch==1){dvol = -lm->volume - lp->volume;}
/* fix data structure for flipped bond */
    ts_flip_bond(k,it,km,kp, bond,lm, lp, lm2, lp1);
@@ -178,16 +183,51 @@
  delta_energy+=it->xk* it->energy;
  //Neigbours of k, it, km, kp don't change its energy.
  delta_energy-=oldenergy;
    if(vesicle->pswitch == 1){
    delta_energy-=oldenergy;
    if(vesicle->pswitch == 1 || vesicle->tape->constvolswitch==1){
        dvol = dvol + lm->volume + lp->volume;
        delta_energy-= vesicle->pressure*dvol;
        if(vesicle->pswitch==1) delta_energy-= vesicle->pressure*dvol;
    }
    retval=TS_SUCCESS;
    if(vesicle->tape->constvolswitch == 1){
        retval=constvolume(vesicle, it, -dvol, &delta_energy_cv, &constvol_vtx_moved,&constvol_vtx_backup);
        if(retval==TS_FAIL){
/* restoration procedure copied from few lines below */
        for(i=0;i<4;i++){
//            fprintf(stderr,"Restoring vtx neigh[%d] with neighbours %d\n",i, orig_vtx[i]->neigh_no );
            free(orig_vtx[i]->neigh);
            free(orig_vtx[i]->tristar);
            free(orig_vtx[i]->bond);
            free(orig_tria[i]->neigh);
            memcpy((void *)orig_vtx[i],(void *)bck_vtx[i],sizeof(ts_vertex));
            memcpy((void *)orig_tria[i],(void *)bck_tria[i],sizeof(ts_triangle));
//            fprintf(stderr,"Restored vtx neigh[%d] with neighbours %d\n",i, orig_vtx[i]->neigh_no );
            /* level 2 pointers are redirected*/
        }
        memcpy(bond,bck_bond,sizeof(ts_bond));
        for(i=0;i<4;i++){
            free(bck_vtx[i]);
            free(bck_tria[i]);
/*            fprintf(stderr,"Restoring vtx neigh[%d] with neighbours %d =",i, orig_vtx[i]->neigh_no );
            for(j=0;j<orig_vtx[i]->neigh_no;j++) fprintf(stderr," %d", orig_vtx[i]->neigh[j]->idx);
            fprintf(stderr,"\n"); */
        }
        free(bck_bond);
        return TS_FAIL;
        }
    delta_energy+=delta_energy_cv;
    }
/* MONTE CARLO */
    if(delta_energy>=0){
#ifdef TS_DOUBLE_DOUBLE
        if(exp(-delta_energy)< drand48() )
        if(exp(-delta_energy)< drand48())
#endif
#ifdef TS_DOUBLE_FLOAT
        if(expf(-delta_energy)< (ts_float)drand48())
@@ -222,13 +262,17 @@
        }
        free(bck_bond);
        if(vesicle->tape->constvolswitch == 1){
            constvolumerestore(constvol_vtx_moved,constvol_vtx_backup);
        }
//        fprintf(stderr,"Restoration complete!!!\n");
        return TS_FAIL;
        }
    }
     /* IF BONDFLIP ACCEPTED, THEN RETURN SUCCESS! */
  //          fprintf(stderr,"SUCCESS!!!\n");
//            fprintf(stderr,"SUCCESS!!!\n");
    // delete all backups
    for(i=0;i<4;i++){
@@ -244,6 +288,9 @@
*/    
    }
    free(bck_bond);
    if(vesicle->tape->constvolswitch == 1){
        constvolumeaccept(vesicle,constvol_vtx_moved,constvol_vtx_backup);
    }
    return TS_SUCCESS;
}
src/constvol.c
@@ -9,15 +9,15 @@
#include "vertex.h"
#include "cell.h"
ts_bool constvolume(ts_vesicle *vesicle, ts_vertex *vtx_avoid, ts_double Vol, ts_double *retEnergy, ts_vertex *vtx_moved, ts_vertex *vtx_backup){
ts_bool constvolume(ts_vesicle *vesicle, ts_vertex *vtx_avoid, ts_double Vol, ts_double *retEnergy, ts_vertex **vtx_moved_retval, ts_vertex **vtx_backup){
    ts_vertex *vtx_moved;
    ts_uint vtxind,i,j;
    ts_uint Ntries=20;
    ts_vertex *backupvtx;
    ts_double Rv, dh, dvol, voldiff, oenergy,delta_energy;
    backupvtx=(ts_vertex *)calloc(sizeof(ts_vertex),10);
    ts_double l0 = (1.0 + sqrt(vesicle->dmax))/2.0; //make this a global constant if necessary
    for(i=0;i<Ntries;i++){
        vtxind=rand() % vesicle->vlist->n;
        vtx_moved=vesicle->vlist->vtx[vtxind];
@@ -26,21 +26,24 @@
        for(j=0;j<vtx_moved->neigh_no;j++){
            if(vtx_moved->neigh[j]==vtx_avoid) continue;
        }
        memcpy((void *)&backupvtx[0],(void *)vtx_moved,sizeof(ts_vertex));
        //move vertex in specified direction. first try, test move!
        Rv=sqrt(pow(vtx_moved->x,2)+pow(vtx_moved->y,2)+pow(vtx_moved->z,2));
        dh=2*Rv*vesicle->dmax/sqrt(3);
        vtx_moved->x=vtx_moved->x*(1-dh/Rv);
        vtx_moved->y=vtx_moved->y*(1-dh/Rv);
        vtx_moved->z=vtx_moved->z*(1-dh/Rv);
        dh=2.0*Vol/(sqrt(3.0)*l0*l0);
//        fprintf(stderr,"Prej (x,y,z)=(%e,%e,%e).\n",vtx_moved->x,vtx_moved->y,vtx_moved->z);
        vtx_moved->x=vtx_moved->x*(1.0-dh/Rv);
        vtx_moved->y=vtx_moved->y*(1.0-dh/Rv);
        vtx_moved->z=vtx_moved->z*(1.0-dh/Rv);
//        fprintf(stderr,"Potem (x,y,z)=(%e,%e,%e). Vol=%e\n",vtx_moved->x,vtx_moved->y,vtx_moved->z,Vol);
        //check for constraints
          if(constvolConstraintCheck(vesicle, vtx_moved)==TS_FAIL){
            vtx_moved=memcpy((void *)vtx_moved,(void *)&backupvtx[0],sizeof(ts_vertex));
            continue;
        }
//        fprintf(stderr,"Sprejet.\n");
        // All checks OK!
@@ -69,7 +72,8 @@
                delta_energy+=vtx_moved->neigh[i]->xk*(vtx_moved->neigh[i]->energy-oenergy);
            }
            *retEnergy=delta_energy;
            vtx_backup=backupvtx;
            *vtx_backup=backupvtx;
            *vtx_moved_retval=vtx_moved;
            return TS_SUCCESS;
        }        
        //do it again ;)
@@ -100,7 +104,8 @@
                delta_energy+=vtx_moved->neigh[i]->xk*(vtx_moved->neigh[i]->energy-oenergy);
            }
            *retEnergy=delta_energy;
            vtx_backup=backupvtx;
            *vtx_backup=backupvtx;
            *vtx_moved_retval=vtx_moved;
            return TS_SUCCESS;
        }        
@@ -145,16 +150,23 @@
ts_bool constvolumerestore(ts_vertex *vtx_moved,ts_vertex *vtx_backup){
    ts_uint j;
    for(j=0;j<vtx_moved->neigh_no;j++){
     memcpy((void *)vtx_moved,(void *)&vtx_backup[0],sizeof(ts_vertex));
     for(j=0;j<vtx_moved->neigh_no;j++){
                memcpy((void *)vtx_moved->neigh[j],(void *)&vtx_backup[j+1],sizeof(ts_vertex));
            }
            vtx_moved=memcpy((void *)vtx_moved,(void *)&vtx_backup[0],sizeof(ts_vertex));
    }
    free(vtx_backup);
    return TS_SUCCESS;
}
ts_bool constvolumeaccept(ts_vertex *vtx_moved, ts_vertex *vtx_backup){
ts_bool constvolumeaccept(ts_vesicle *vesicle,ts_vertex *vtx_moved, ts_vertex *vtx_backup){
    ts_bool retval;
    ts_uint cellidx=vertex_self_avoidance(vesicle, vtx_moved);
    if(vtx_moved->cell!=vesicle->clist->cell[cellidx]){
        retval=cell_add_vertex(vesicle->clist->cell[cellidx],vtx_moved);
        if(retval==TS_SUCCESS) cell_remove_vertex(vtx_backup[0].cell,vtx_moved);
    }
    free(vtx_backup);
    return TS_SUCCESS;
}
src/constvol.h
@@ -1,8 +1,8 @@
#ifndef _H_CONSTVOL
#define _H_CONSTVOL
ts_bool constvolume(ts_vesicle *vesicle, ts_vertex *vtx_avoid, ts_double Vol, ts_double *retEnergy, ts_vertex *vtx_moved, ts_vertex *vtx_backup);
ts_bool constvolume(ts_vesicle *vesicle, ts_vertex *vtx_avoid, ts_double Vol, ts_double *retEnergy, ts_vertex **vtx_moved_retval, ts_vertex **vtx_backup);
ts_bool constvolConstraintCheck(ts_vesicle *vesicle, ts_vertex *vtx);
ts_bool constvolumerestore(ts_vertex *vtx_moved, ts_vertex *vtx_backup);
ts_bool constvolumeaccept(ts_vertex *vtx_moved, ts_vertex *vtx_backup);
ts_bool constvolumeaccept(ts_vesicle *vesicle, ts_vertex *vtx_moved, ts_vertex *vtx_backup);
#endif
src/tape
@@ -49,11 +49,11 @@
####### Program Control ############
#how many MC sweeps between subsequent records of states to disk
mcsweeps=2500
mcsweeps=250
#how many initial mcsweeps*inititer MC sweeps before recording to disk?
inititer=0
#how many records do you want on the disk iteration are there in a run?
iterations=15000
iterations=100
###### Spherical harmonics ###########
src/vertexmove.c
@@ -20,7 +20,7 @@
    ts_double dist;
    ts_bool retval; 
    ts_uint cellidx; 
    ts_double delta_energy,oenergy,dvol=0.0;
    ts_double delta_energy, delta_energy_cv,oenergy,dvol=0.0;
    ts_double costheta,sintheta,phi,r;
    //This will hold all the information of vtx and its neighbours
    ts_vertex backupvtx[20], *constvol_vtx_moved=NULL, *constvol_vtx_backup=NULL;
@@ -92,22 +92,14 @@
    memcpy((void *)&backupvtx[i+1],(void *)vtx->neigh[i],sizeof(ts_vertex));
    }
    if(vesicle->pswitch == 1){
    if(vesicle->pswitch == 1 || vesicle->tape->constvolswitch==1){
        for(i=0;i<vtx->tristar_no;i++) dvol-=vtx->tristar[i]->volume;
    };
    delta_energy=0;
    if(vesicle->tape->constvolswitch == 1){
        retval=constvolume(vesicle, vtx, dvol, &delta_energy, constvol_vtx_moved,constvol_vtx_backup);
        if(retval==TS_FAIL){ // if we couldn't move the vertex to assure constant volume
            vtx=memcpy((void *)vtx,(void *)&backupvtx[0],sizeof(ts_vertex));
            for(i=0;i<vtx->neigh_no;i++){
                vtx->neigh[i]=memcpy((void *)vtx->neigh[i],(void *)&backupvtx[i+1],sizeof(ts_vertex));
            }
            return TS_FAIL;
        }
    }
//    fprintf(stderr,"Success for now.\n");
    //update the normals of triangles that share bead i.
    for(i=0;i<vtx->tristar_no;i++) triangle_normal_vector(vtx->tristar[i]);
@@ -121,12 +113,23 @@
        delta_energy+=vtx->neigh[i]->xk*(vtx->neigh[i]->energy-oenergy);
    }
    if(vesicle->pswitch == 1){
    if(vesicle->pswitch == 1 || vesicle->tape->constvolswitch == 1){
        for(i=0;i<vtx->tristar_no;i++) dvol+=vtx->tristar[i]->volume;
        delta_energy-=vesicle->pressure*dvol;
        if(vesicle->pswitch==1) delta_energy-=vesicle->pressure*dvol;
    };
   if(vesicle->tape->constvolswitch == 1){
        retval=constvolume(vesicle, vtx, -dvol, &delta_energy_cv, &constvol_vtx_moved,&constvol_vtx_backup);
        if(retval==TS_FAIL){ // if we couldn't move the vertex to assure constant volume
            vtx=memcpy((void *)vtx,(void *)&backupvtx[0],sizeof(ts_vertex));
            for(i=0;i<vtx->neigh_no;i++){
                vtx->neigh[i]=memcpy((void *)vtx->neigh[i],(void *)&backupvtx[i+1],sizeof(ts_vertex));
            }
            for(i=0;i<vtx->tristar_no;i++) triangle_normal_vector(vtx->tristar[i]);
            return TS_FAIL;
        }
    delta_energy+=delta_energy_cv;
    }
/* No poly-bond energy for now!
    if(vtx->grafted_poly!=NULL){
        delta_energy+=
@@ -148,6 +151,7 @@
#endif
    {
    //not accepted, reverting changes
  //  fprintf(stderr,"MC failed\n");
    vtx=memcpy((void *)vtx,(void *)&backupvtx[0],sizeof(ts_vertex));
    for(i=0;i<vtx->neigh_no;i++){
        vtx->neigh[i]=memcpy((void *)vtx->neigh[i],(void *)&backupvtx[i+1],sizeof(ts_vertex));
@@ -159,11 +163,11 @@
    if(vesicle->tape->constvolswitch == 1){
        constvolumerestore(constvol_vtx_moved,constvol_vtx_backup);
    }
    return TS_FAIL; 
    }
}
    //accepted    
 //   fprintf(stderr,"MC accepted\n");
//    oldcellidx=vertex_self_avoidance(vesicle, &backupvtx[0]);
    if(vtx->cell!=vesicle->clist->cell[cellidx]){
        retval=cell_add_vertex(vesicle->clist->cell[cellidx],vtx);
@@ -173,7 +177,7 @@
    }
    if(vesicle->tape->constvolswitch == 1){
        constvolumeaccept(constvol_vtx_moved,constvol_vtx_backup);
        constvolumeaccept(vesicle,constvol_vtx_moved,constvol_vtx_backup);
    }
//    if(oldcellidx);
    //END MONTE CARLOOOOOOO