Trisurf Monte Carlo simulator
Samo Penic
2022-05-04 06afc729f9061c1cfa14c78728d61d518324c2f0
commit | author | age
7f6076 1 /* vim: set ts=4 sts=4 sw=4 noet : */
SP 2 /* vim: set ts=4 sts=4 sw=4 noet : */    
854cb6 3 #include<stdio.h>
SP 4 #include<general.h>
5 #include<snapshot.h>
22721d 6 #include<stdlib.h>
SP 7 #include<stdarg.h>
8 #include <zlib.h>
f0bcea 9 #include<inttypes.h>
11fef8 10 #include<config.h>
2e8c7f 11 #include <time.h>
698ae1 12 #include "io.h"
06afc7 13 #include "globals.h"
SP 14
a3dbf0 15 /* a helper function that utilizes ts_string data structure and performs same as sprintf */
22721d 16 ts_uint ts_sprintf(ts_string *str, char *fmt, ...){
SP 17     va_list ap;
18     va_start(ap,fmt);
19     ts_uint n=vsprintf(&(str->string[str->beg]),fmt,ap);
20     va_end(ap);
21     str->beg+=n;
22     return n;
23 }
24
a3dbf0 25 /* outputs additional data into paraview xml file */
854cb6 26 ts_bool xml_trisurf_data(FILE *fh, ts_vesicle *vesicle){
22721d 27
2a1e3d 28     ts_string *data=(ts_string *)malloc(sizeof(ts_string));
02d65c 29     data->string=(char *)malloc(5120000*sizeof(char)); /*TODO: warning, can break if the string is to long */
22721d 30     data->beg=0;
SP 31     
854cb6 32     xml_trisurf_header(fh, vesicle);
22721d 33     xml_trisurf_tria(data,vesicle->tlist);
SP 34     xml_trisurf_tria_neigh(data,vesicle->tlist);
35     xml_trisurf_vtx_neigh(data,vesicle->vlist);    
36     xml_trisurf_vtx_tristar(data,vesicle->vlist);
4891eb 37     xml_trisurf_nucleus(data,vesicle);
49981c 38     xml_trisurf_constvolarea(data,V0,A0);
22721d 39 #ifdef COMPRESSION
f0bcea 40     char *compressed;
588bbb 41     ts_uint nbytes=ts_compress_string64(data->string, data->beg-1, &compressed); //suppress null character at the end with by substracting 1
f0bcea 42     fwrite(compressed, sizeof(unsigned char), nbytes, fh);
SP 43     free (compressed);
22721d 44 #else
SP 45     fprintf(fh,"%s", data->string);
46 #endif
a3dbf0 47     free(data->string);  /* TODO: valgrind is not ok with this! */
22721d 48     free(data);
854cb6 49     xml_trisurf_footer(fh);
SP 50     return TS_SUCCESS;
51 }
52
53 ts_bool xml_trisurf_header(FILE *fh, ts_vesicle *vesicle){
2e8c7f 54 /* format current time */
SP 55     time_t current_time;
56         char *c_time_string;
57     current_time = time(NULL);
58     c_time_string = ctime(&current_time);
a3dbf0 59     int npoly, nfono;    
SP 60
e29756 61     fprintf(fh, "<trisurfversion>Trisurf (commit %s), compiled on %s %s</trisurfversion>\n",TS_VERSION, __DATE__,  __TIME__);
2e8c7f 62     fprintf(fh, "<dumpdate>%s</dumpdate>\n", c_time_string);
SP 63
cc95bd 64     fprintf(fh, "<tape>");
698ae1 65         fprintf(fh,"%s",tapetxt);    
f0bcea 66     fprintf(fh, "</tape>\n");
a3dbf0 67     if(vesicle->poly_list!=NULL){
SP 68         npoly=vesicle->poly_list->n;
69         if(npoly!=0){
70             nfono=vesicle->poly_list->poly[0]->vlist->n;
71         } else {
72             nfono=0;
73         }
74     } else {
75         npoly=0;
76         nfono=0;
77     }
86b69b 78     fprintf(fh, "<trisurf nvtx=\"%u\" npoly=\"%u\" nmono=\"%u\" compressed=\"false\">\n", vesicle->vlist->n, npoly, nfono);
854cb6 79     return TS_SUCCESS;
SP 80 }
81
82 ts_bool xml_trisurf_footer(FILE *fh){
83     fprintf(fh, "</trisurf>\n");
84     return TS_SUCCESS;
85 }
86
22721d 87 ts_bool xml_trisurf_tria(ts_string *data, ts_triangle_list *tlist){
854cb6 88     ts_uint i;
588bbb 89     ts_sprintf(data,"<tria>");
854cb6 90     for(i=0; i<tlist->n;i++){
e87e4e 91         ts_sprintf(data,"%u %u %u ",tlist->tria[i]->vertex[0]->idx, tlist->tria[i]->vertex[1]->idx, tlist->tria[i]->vertex[2]->idx);
854cb6 92     }
588bbb 93     ts_sprintf(data,"</tria>");
854cb6 94     return TS_SUCCESS;
SP 95 }
96
22721d 97 ts_bool xml_trisurf_tria_neigh(ts_string *data, ts_triangle_list *tlist){
854cb6 98     ts_uint i;
22721d 99     ts_sprintf(data,"<trianeigh>\n");
854cb6 100     for(i=0; i<tlist->n;i++){
e87e4e 101         ts_sprintf(data,"%u %u %u ",tlist->tria[i]->neigh[0]->idx, tlist->tria[i]->neigh[1]->idx, tlist->tria[i]->neigh[2]->idx);
854cb6 102     }
22721d 103     ts_sprintf(data,"</trianeigh>\n");
854cb6 104     return TS_SUCCESS;
SP 105 }
106
22721d 107 ts_bool xml_trisurf_vtx_neigh(ts_string *data, ts_vertex_list *vlist){
854cb6 108     ts_uint i,j;
SP 109     for(i=0;i<vlist->n;i++){
22721d 110         ts_sprintf(data,"<vtxn idx=\"%u\">",vlist->vtx[i]->idx);
854cb6 111         for(j=0;j<vlist->vtx[i]->neigh_no;j++){
22721d 112             ts_sprintf(data,"%u ",vlist->vtx[i]->neigh[j]->idx);
854cb6 113         }
588bbb 114         ts_sprintf(data, "</vtxn>");
854cb6 115     }
SP 116     return TS_SUCCESS;
117 }
118
22721d 119 ts_bool xml_trisurf_vtx_tristar(ts_string *data, ts_vertex_list *vlist){
854cb6 120     ts_uint i,j;
SP 121     for(i=0;i<vlist->n;i++){
22721d 122         ts_sprintf(data,"<tristar idx=\"%u\">",vlist->vtx[i]->idx);
854cb6 123         for(j=0;j<vlist->vtx[i]->tristar_no;j++){
22721d 124             ts_sprintf(data,"%u ",vlist->vtx[i]->tristar[j]->idx);
854cb6 125         }
588bbb 126         ts_sprintf(data, "</tristar>");
854cb6 127     }
SP 128     return TS_SUCCESS;
129 }
130
4891eb 131 ts_bool xml_trisurf_nucleus(ts_string *data, ts_vesicle* vesicle){
SP 132     if(vesicle->R_nucleus>0.0 || (vesicle->R_nucleusX>0.0 && vesicle->R_nucleusY>0.0 && vesicle->R_nucleusZ>0.0)){
49981c 133         ts_sprintf(data,"<nucleus>%.17e %.17e %.17e</nucleus>",vesicle->nucleus_center[0], vesicle->nucleus_center[1], vesicle->nucleus_center[2]);
4891eb 134     }
SP 135     return TS_SUCCESS;
136 }
49981c 137 ts_bool xml_trisurf_constvolarea(ts_string *data, ts_double volume, ts_double area){
SP 138     ts_sprintf(data,"<constant_volume>%.17e</constant_volume>",volume);
139     ts_sprintf(data,"<constant_area>%.17e</constant_area>",area);
140
141     return TS_SUCCESS;
142 }
f0bcea 143
SP 144
145 /* UTILITIES */
146
147 /* zlib compression base64 encoded */
148 /* compressed must not be pre-malloced */
8c1bb1 149 /* taken from https://gist.github.com/arq5x/5315739 */
f0bcea 150 ts_uint ts_compress_string64(char *data, ts_uint data_len, char **compressed){
SP 151     z_stream defstream;
152     defstream.zalloc = Z_NULL;
153     defstream.zfree = Z_NULL;
154     defstream.opaque = Z_NULL;
155     defstream.avail_in = data_len+1;
156     defstream.next_in = (unsigned char *)data;    
157     char *compr=(char *)malloc(data_len*sizeof(char *));
158     defstream.avail_out = data_len+1;
159     defstream.next_out = (unsigned char *)compr;
160     deflateInit(&defstream, Z_BEST_COMPRESSION);
161         deflate(&defstream, Z_FINISH);
162         deflateEnd(&defstream);
163     /*base64 encode*/
164     size_t nbase;
165     *compressed=base64_encode((unsigned char *)compr,(size_t)defstream.total_out,&nbase);
166     //fwrite(base64, sizeof(unsigned char), nbase, fh);
167     free(compr);
168     return nbase;
169 }
170
8c1bb1 171 ts_uint ts_decompress_string64(char *b64, ts_uint data_len, char **decompressed){
SP 172 return TS_SUCCESS;
173
174 }
f0bcea 175
SP 176 /* base64 encoding, taken from http://stackoverflow.com/questions/342409/how-do-i-base64-encode-decode-in-c */
177 static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
178                                 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
179                                 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
180                                 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
181                                 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
182                                 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
183                                 'w', 'x', 'y', 'z', '0', '1', '2', '3',
184                                 '4', '5', '6', '7', '8', '9', '+', '/'};
185 static char *decoding_table = NULL;
186 static int mod_table[] = {0, 2, 1};
187
188
7f6076 189 char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length) {
f0bcea 190     *output_length = 4 * ((input_length + 2) / 3);
SP 191     int i,j;
192     char *encoded_data = malloc(*output_length);
193     if (encoded_data == NULL) return NULL;
194     
195     for (i = 0, j = 0; i < input_length;) {
196
7f6076 197            uint32_t octet_a = i < input_length ? (unsigned char)data[i++] : 0;
SP 198         uint32_t octet_b = i < input_length ? (unsigned char)data[i++] : 0;
199            uint32_t octet_c = i < input_length ? (unsigned char)data[i++] : 0;
200         uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
f0bcea 201
7f6076 202            encoded_data[j++] = encoding_table[(triple >> 3 * 6) & 0x3F];
SP 203            encoded_data[j++] = encoding_table[(triple >> 2 * 6) & 0x3F];
204            encoded_data[j++] = encoding_table[(triple >> 1 * 6) & 0x3F];
205            encoded_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F];
f0bcea 206     }
SP 207
208     for (i = 0; i < mod_table[input_length % 3]; i++)
7f6076 209            encoded_data[*output_length - 1 - i] = '=';
f0bcea 210
SP 211     return encoded_data;
212 }
213
214
7f6076 215 unsigned char *base64_decode(const char *data, size_t input_length, size_t *output_length) {
f0bcea 216     int i,j;
SP 217     if (decoding_table == NULL) build_decoding_table();
218
219     if (input_length % 4 != 0) return NULL;
220
221     *output_length = input_length / 4 * 3;
222     if (data[input_length - 1] == '=') (*output_length)--;
223     if (data[input_length - 2] == '=') (*output_length)--;
224
225     unsigned char *decoded_data = malloc(*output_length);
226     if (decoded_data == NULL) return NULL;
227
228     for (i = 0, j = 0; i < input_length;) {
7f6076 229            uint32_t sextet_a = data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]];
SP 230            uint32_t sextet_b = data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]];
231            uint32_t sextet_c = data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]];
232            uint32_t sextet_d = data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]];
f0bcea 233
7f6076 234            uint32_t triple = (sextet_a << 3 * 6)
f0bcea 235             + (sextet_b << 2 * 6)
SP 236             + (sextet_c << 1 * 6)
237             + (sextet_d << 0 * 6);
238
7f6076 239            if (j < *output_length) decoded_data[j++] = (triple >> 2 * 8) & 0xFF;
SP 240            if (j < *output_length) decoded_data[j++] = (triple >> 1 * 8) & 0xFF;
241            if (j < *output_length) decoded_data[j++] = (triple >> 0 * 8) & 0xFF;
f0bcea 242     }
8c1bb1 243     if(decoding_table !=NULL) free(decoding_table);
f0bcea 244     return decoded_data;
SP 245 }
246
247
248 void build_decoding_table() {
249
250     decoding_table = malloc(256);
251     int i;
252     for (i = 0; i < 64; i++)
7f6076 253         decoding_table[(unsigned char) encoding_table[i]] = i;
f0bcea 254 }
SP 255
256
257 void base64_cleanup() {
258     free(decoding_table);
259 }
260
261
262
263
264
265
266