Trisurf Monte Carlo simulator
Samo Penic
2016-12-06 c2c6364dc7d23f21dabd2179e775e93ba4eeb252
src/cluster.c
New file
@@ -0,0 +1,166 @@
/* vim: set ts=4 sts=4 sw=4 noet : */
#include<stdlib.h>
#include "general.h"
#include "cluster.h"
#include <math.h>
ts_cluster_list *init_cluster_list(){
   ts_cluster_list *cstlist=(ts_cluster_list *)malloc(sizeof(ts_cluster_list));
   cstlist->n=0;
   cstlist->cluster=NULL;
   return cstlist;
}
ts_cluster *new_cluster(ts_cluster_list *cstlist){
   cstlist->n++;
   cstlist->cluster=(ts_cluster **)realloc(cstlist->cluster,cstlist->n*sizeof(ts_cluster *));
   if(cstlist->cluster==NULL) fatal("Cannot reallocate memory for additional **ts_cluster.",100);
   cstlist->cluster[cstlist->n-1]=(ts_cluster *)calloc(1,sizeof(ts_cluster));
   if(cstlist->cluster[cstlist->n-1]==NULL) fatal("Cannot allocate memory for additional *ts_cluster.",100);
   return cstlist->cluster[cstlist->n-1];
}
ts_bool cluster_add_vertex(ts_cluster *cluster, ts_vertex *vtx){
   cluster->nvtx++;
   cluster->vtx=(ts_vertex **)realloc(cluster->vtx, cluster->nvtx*sizeof(ts_vertex *));
   cluster->vtx[cluster->nvtx-1]=vtx;
   vtx->cluster=cluster;
   return TS_SUCCESS;
}
ts_bool cluster_list_compact(ts_cluster_list *cstlist){
   ts_uint i,n=cstlist->n;
   for(i=0;i<cstlist->n;i++){
      if(cstlist->cluster[i]==NULL){
         if(i>=n) break;
         //printf("Have to do compacting n=%d\n ",n);
         do{
            n--;
         } while(cstlist->cluster[n]==NULL && n>i);
         cstlist->cluster[i]=cstlist->cluster[n];
         cstlist->cluster[n]=NULL;
         //printf("After compacting n=%d\n",n);
      }
   }
   cstlist->cluster=(ts_cluster **)realloc(cstlist->cluster,n*sizeof(ts_cluster *));
   cstlist->n=n;
   return TS_SUCCESS;
}
ts_bool cluster_join(ts_cluster_list *cstlist, ts_cluster *cluster1, ts_cluster *cluster2){
   ts_cluster *master_cluster,*slave_cluster;
   ts_uint i;
   if(cluster1->idx<cluster2->idx){
      master_cluster=cluster1;
      slave_cluster=cluster2;
   } else {
      master_cluster=cluster2;
      slave_cluster=cluster1;
   }
   for(i=0;i<slave_cluster->nvtx;i++){
      cluster_add_vertex(master_cluster,slave_cluster->vtx[i]);
   }
   //find cluster in the list and free the location of the cluster
   for(i=0;i<cstlist->n;i++){
      if(cstlist->cluster[i]==slave_cluster){
         cluster_free(slave_cluster);
         cstlist->cluster[i]=NULL;
      }
   }
   return TS_SUCCESS;
}
ts_bool cluster_free(ts_cluster *cluster){
   if(cluster!=NULL){
      if(cluster->vtx!=NULL)
         free(cluster->vtx);
      free(cluster);
   }
   return TS_SUCCESS;
}
ts_bool cluster_list_free(ts_cluster_list *cstlist){
   ts_uint i;
   if(cstlist!=NULL){
      for(i=0;i<cstlist->n;i++){
         cluster_free(cstlist->cluster[i]);
      }
      free(cstlist->cluster);
      free(cstlist);
   }
   return TS_SUCCESS;
}
/* This is a stub function. User should check whether the vertex is clustering or not. */
ts_bool is_clusterable(ts_vertex *vtx){
   if(fabs(vtx->c)>1e-6){
      return 1;
   }
   else {
      return 0;
   }
}
ts_cluster *cluster_vertex_neighbor(ts_vertex *vtx){
   int j;
   for(j=0;j<vtx->neigh_no;j++){
      if(vtx->neigh[j]->cluster!=NULL)
         return vtx->neigh[j]->cluster;
   }
   return NULL;
}
ts_bool cluster_vertex_neighbor_check(ts_cluster_list *cstlist, ts_vertex *vtx){
   int j;
   for(j=0;j<vtx->neigh_no;j++){
      if(vtx->neigh[j]->cluster!=NULL){
         if(vtx->neigh[j]->cluster!=vtx->cluster){
            cluster_join(cstlist, vtx->cluster, vtx->neigh[j]->cluster);
         }
      }
   }
   return TS_SUCCESS;
}
ts_bool clusterize_vesicle(ts_vesicle *vesicle, ts_cluster_list *cstlist){
   int i;
   ts_vertex *vtx;
   ts_cluster *cst;
   for(i=0;i<vesicle->vlist->n;i++){
   //for each vertex
      vtx=vesicle->vlist->vtx[i];
      if(is_clusterable(vtx)){
         if(vtx->cluster==NULL){
            //find first neigbor with cluster index
            cst=cluster_vertex_neighbor(vtx);
            if(cst==NULL){
               //no clusters are around us, vo we are probably lonely vertex or no surronding vertex has been mapped yet.
               cst=new_cluster(cstlist);
               cluster_add_vertex(cst,vtx);
            } else {
               //we are added to the first cluster found
               cluster_add_vertex(cst,vtx);
               cluster_vertex_neighbor_check(cstlist, vtx);
               cluster_list_compact(cstlist);
            }
         }
      }
   }
   return TS_SUCCESS;
}