dfnTrans
Code for Particle Tracking simulations in 3D DFN
InitialPartPositions.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <search.h>
3 #include <stdlib.h>
4 #include <math.h>
5 #include <string.h>
6 #include "FuncDef.h"
7 #include <unistd.h>
8 #include <time.h>
9 
10 struct inpfile {
11  char filename[120];
12  long int flag;
13  double param;
14 };
15 
16 struct posit3d {
17  double cord3[3];
18 };
19 
20 
21 int InitPos()
23 {
24  int i, k_current, k_new = 0, numbf = 1, frc, firstn, lastn, flag_in = 0, parts_fracture;
25  struct inpfile initfile;
26  double parts_dist = 0;
27  int zonenumb_in = 0, first_ind = 0, last_ind = 0;
28  double ixmin = 0, ixmax = 0, iymin = 0, iymax = 0, izmin = 0, izmax = 0;
29  double px[4] = {0.0, 0.0, 0.0, 0.0}, py[4] = {0.0, 0.0, 0.0, 0.0};
30  double weight_p = 0.0;
31 
32  /* calculating number of fractures in in-flow boundary face of the domain ****/
33 
34  for (i = 0; i < nzone_in; i++) {
35  if ((i > 0) && (node[nodezonein[i] - 1].fracture[0] != node[nodezonein[i - 1] - 1].fracture[0])) {
36  if (node[nodezonein[i] - 1].fracture[1] != node[nodezonein[i - 1] - 1].fracture[0])
37  // printf("fract %d ", node[nodezonein[i]-1].fracture[0]);
38  {
39  numbf++;
40  }
41  }
42  }
43 
44  if ((numbf == 0) && (nzone_in != 0)) {
45  numbf = 1;
46  }
47 
48  printf(" %d fracture(s) in in-flow boundary zone \n", numbf);
49  // define first and last node and their ID for each boundary fracture edge
50  unsigned int firstind[numbf], lastind[numbf], firstnode[numbf], lastnode[numbf], numberf = 1, curfr = 0;
51  firstnode[0] = nodezonein[0];
52  lastnode[0] = nodezonein[0];
53  firstind[0] = 0;
54  lastind[0] = 0;
55  curfr = node[nodezonein[0] - 1].fracture[0];
56 
57  for (i = 1; i < nzone_in; i++) {
58  if ((node[nodezonein[i] - 1].fracture[0] != curfr) && (node[nodezonein[i] - 1].fracture[1] != curfr)) {
59  lastnode[numberf - 1] = nodezonein[i - 1];
60  lastind[numberf - 1] = i - 1;
61 
62  if (i < nzone_in - 1) {
63  numberf++;
64  firstnode[numberf - 1] = nodezonein[i];
65  firstind[numberf - 1] = i;
66  curfr = node[nodezonein[i] - 1].fracture[0];
67  }
68  }
69  }
70 
71  lastnode[numberf - 1] = nodezonein[nzone_in - 1];
72  lastind[numberf - 1] = nzone_in - 1;
73 
74  if (numberf > numbf) {
75  printf("check the boundary zone file\n");
76  }
77 
78  // check the input options of particles positions
79  double inter_p[numbf][4];
80  int inter_fr[numbf];
81  int res;
82  initfile = Control_File("init_nf:", 8);
83  res = strncmp(initfile.filename, "yes", 3);
84 
86  if (res == 0) {
87  flag_in = 1;
88  flag_w = 1;
89  initfile = Control_Data("init_partn:", 11 );
90  parts_fracture = initfile.flag;
91  printf("\n %d particles per boundary fracture edge \n", parts_fracture);
92  npart = (numbf + 1) * parts_fracture;
93  /* memory allocatation for particle */
94  particle = (struct contam*) malloc (npart * sizeof(struct contam));
95  } else {
96  initfile = Control_File("init_eqd:", 9);
97  res = strncmp(initfile.filename, "yes", 3);
98 
99  if (res == 0) {
100  flag_in = 2;
101  flag_w = 1;
105  initfile = Control_Data("init_npart:", 11 );
106  parts_fracture = initfile.flag;
107  npart = (numbf) * parts_fracture * 2;
108  /* memory allocatation for particle structures */
109  particle = (struct contam*) malloc ((npart) * sizeof(struct contam));
110  // define a distance between particles
111  double length2 = 0.0, t_length = 0.0;
112 
113  for (i = 0; i < numbf; i++) {
114  length2 = pow((node[firstnode[i] - 1].coord[0] - node[lastnode[i] - 1].coord[0]), 2) + pow((node[firstnode[i] - 1].coord[1] - node[lastnode[i] - 1].coord[1]), 2) + pow((node[firstnode[i] - 1].coord[2] - node[lastnode[i] - 1].coord[2]), 2);
115  t_length = t_length + sqrt(length2);
116  }
117 
118  parts_dist = t_length / (parts_fracture * numbf);
119  printf("\n Particles placed on %f [m] from each other. Total length %lf \n", parts_dist, t_length);
120  } else {
121  initfile = Control_File("init_oneregion:", 15);
122  res = strncmp(initfile.filename, "yes", 3);
123 
124  if (res == 0) {
125  flag_in = 3;
126  flag_w = 1;
129  initfile = Control_Data("in_partn:", 9 );
130  npart = initfile.flag;
131  /* memory allocatation for particle structures */
132  particle = (struct contam*) malloc ((npart * 2) * sizeof(struct contam));
133  printf("\n Initially particles have the same starting region \n");
134  initfile = Control_Param("in_xmin:", 8 );
135  ixmin = initfile.param;
136  initfile = Control_Param("in_xmax:", 8 );
137  ixmax = initfile.param;
138  initfile = Control_Param("in_ymin:", 8 );
139  iymin = initfile.param;
140  initfile = Control_Param("in_ymax:", 8 );
141  iymax = initfile.param;
142  initfile = Control_Param("in_zmin:", 8 );
143  izmin = initfile.param;
144  initfile = Control_Param("in_zmax:", 8 );
145  izmax = initfile.param;
146  initfile = Control_Data("in-flow-boundary:", 17 );
147  zonenumb_in = initfile.flag;
148 
149  /* define coordinations of region according to in-flow zone */
150  if ((zonenumb_in == 1) || (zonenumb_in == 2)) {
151  px[0] = ixmin;
152  py[0] = iymin;
153  px[1] = ixmin;
154  py[1] = iymax;
155  px[2] = ixmax;
156  py[2] = iymax;
157  px[3] = ixmax;
158  py[3] = iymin;
159  }
160 
161  if ((zonenumb_in == 3) || (zonenumb_in == 5)) {
162  px[0] = izmin;
163  py[0] = iymin;
164  px[1] = izmin;
165  py[1] = iymax;
166  px[2] = izmax;
167  py[2] = iymax;
168  px[3] = izmax;
169  py[3] = iymin;
170  }
171 
172  if ((zonenumb_in == 4) || (zonenumb_in == 6)) {
173  px[0] = ixmin;
174  py[0] = izmin;
175  px[1] = ixmin;
176  py[1] = izmax;
177  px[2] = ixmax;
178  py[2] = izmax;
179  px[3] = ixmax;
180  py[3] = izmin;
181  }
182  } else {
184  initfile = Control_File("init_random:", 12);
185  res = strncmp(initfile.filename, "yes", 3);
186 
187  if (res == 0) {
188  flag_in = 4;
189  initfile = Control_Data("in_randpart:", 12 );
190  npart = initfile.flag;
191  /* memory allocatation for particle structures */
192  particle = (struct contam*) malloc ((npart + 1) * sizeof(struct contam));
193  printf("\n Initially particles will be distributed randomly over all fracture surfaces \n");
194  double random_number = 0, sum_aperture = 0.0;
195  unsigned int currentcell, k_curr = 0;
196 
197  do {
198  random_number = drand48();
199  currentcell = random_number * ncells;
200 
201  if ((currentcell != 0) && (((node[cell[currentcell - 1].node_ind[0] - 1].typeN < 200) || (node[cell[currentcell - 1].node_ind[0] - 1].typeN > 250)) && ((node[cell[currentcell - 1].node_ind[1] - 1].typeN < 200) || (node[cell[currentcell - 1].node_ind[1] - 1].typeN > 250)) && ((node[cell[currentcell - 1].node_ind[2] - 1].typeN < 200) || (node[cell[currentcell - 1].node_ind[2] - 1].typeN > 250)))) {
202  particle[k_curr].velocity[0] = 0.;
203  particle[k_curr].velocity[1] = 0.;
204  particle[k_curr].fracture = cell[currentcell - 1].fracture;
205  particle[k_curr].cell = currentcell;
206  particle[k_curr].time = 0.0;
207  particle[k_curr].pressure = 0.0;
208  Moving2Center (k_curr, currentcell);
209  int insc;
210  insc = InsideCell (currentcell);
211  sum_aperture = sum_aperture + node[cell[currentcell - 1].node_ind[0] - 1].aperture;
212  k_curr++;
213  }
214  } while(k_curr != npart);
215 
216  k_new = k_curr;
217 
218  for (i = 0; i < npart; i++) {
219  particle[i].fl_weight = node[cell[particle[i].cell - 1].node_ind[0] - 1].aperture / sum_aperture;
220  }
221  } //end if flag_in=4
222  else {
224  initfile = Control_File_Optional("init_matrix:", 12);
225 
226  if (initfile.flag > 0) {
227  res = strncmp(initfile.filename, "yes", 3);
228 
229  if (res == 0) {
230  printf(" Initially particles are placed in rock matrix randomly. ");
231  printf(" The closest cells to initial particles positions ");
232  printf(" will be set as starting point in DFN. ");
233  flag_in = 5;
234  InitInMatrix();
235  k_new = npart;
236  } // end if flag_in=5
237  else {
238  initfile = Control_File("init_fluxw:", 11);
239  res = strncmp(initfile.filename, "yes", 3);
240 
241  if (res == 0) {
243  flag_in = 6;
244  flag_w = 0;
245  initfile = Control_Data("init_totalnumber:", 17 );
246  npart = initfile.flag;
247 
248  if (npart < nzone_in) {
249  printf("\n The requested number of particles (%d) is less than number of nodes in in-flow boundary (\%d). The initial number of particles is changed to number of nodes in in-flow boundary. \n", npart, nzone_in);
250  npart = nzone_in;
251  }
252 
253  weight_p = (totalFluxIn / (float)npart);
254  printf("\n Requested number of particles %d with flux weight %5.12e (Total Flux %5.12e) \n", npart, weight_p, totalFluxIn);
255  int npart_alloc = 0;
256  npart_alloc = npart * 3;
257  /* memory allocatation for particle structures */
258  particle = (struct contam*) malloc (npart_alloc * sizeof(struct contam));
259  } // end if flag_in=6
260  else {
261  initfile = Control_File("init_well:", 10);
262  res = strncmp(initfile.filename, "yes", 3);
263 
264  if (res == 0) {
265  /* Option 7: init_well. Particles are seeded at the in-flow zone nodes*/
266  flag_in = 7;
267  flag_w = 0;
268  int nodepart = 0, npartalloc = 0;
269  initfile = Control_Data("init_nodepart:", 14 );
270  nodepart = initfile.flag;
271  npartalloc = (nzone_in + 1 ) * nodepart;
272  /* memory allocatation for particle structures */
273  particle = (struct contam*) malloc (npartalloc * sizeof(struct contam));
274  k_new = InitInWell (nodepart);
275  } // end if flag_in=7
276  }// end if/else flag_in=7
277  }//end if/else flag_in=6
278  } //end if/else flag_in=5
279  } //end if flag_in=4
280  } //end if/else flag_in=3
281  } //end if /else flag_in=2
282  } //end if/else flag_in=1
283 
284  /* loop on fractures and initial setting of particles */
285  k_current = 0;
286 
287  if ((flag_in <= 2) || (flag_in == 6)) {
288  for (i = 0; i < numberf; i++) {
289  if (lastnode[i] != firstnode[i]) {
290  if (flag_in == 6) { //initial set according to in flow flux
291  k_new = InitParticles_flux(k_current, firstind[i], lastind[i], weight_p);
292  // printf ("IPF %d %d %d %d %12.5e %d %d %d\n",i+1, k_current, firstind[i], lastind[i], weight_p, firstnode[i], lastnode[i], node[lastnode[i]-1].fracture[0]);
293  k_current = k_new;
294  }
295 
296  if (flag_in == 2) { //equidistant placing of particles on the entire in-flow boundary
297  k_new = InitParticles_eq (k_current, firstnode[i], lastnode[i], parts_dist, firstind[i], lastind[i]);
298  // printf("IPE fract first %d fract last %d number parts %d\n", node[firstn-1].fracture[0], node[lastn-1].fracture[0], k_new);
299  }
300 
301  if (flag_in == 1) { //equidistant placing of particles on each fracture
302  k_new = InitParticles_np (k_current, firstnode[i], lastnode[i], parts_fracture, firstind[i], lastind[i]);
303  }
304 
305  k_current = k_new;
306  }
307  }// end of loop on fractures
308  }
309 
310  frc = node[nodezonein[0] - 1].fracture[0];
311  firstn = nodezonein[0];
312  lastn = nodezonein[0];
313  double thirdcoor = 0.0;
314  int firstcoor = 0, secondcoor = 0, frc_count = 0;
315 
316  if (node[nodezonein[1] - 1].fracture[0] == frc) {
317  if (fabs(node[nodezonein[0] - 1].coord[0]) - fabs(node[nodezonein[1] - 1].coord[0]) < 1e-10) {
318  firstcoor = 1;
319  secondcoor = 2;
320  } else {
321  firstcoor = 0;
322 
323  if (fabs(node[nodezonein[0] - 1].coord[1]) - fabs(node[nodezonein[1] - 1].coord[1]) < 1e-10) {
324  secondcoor = 2;
325  } else {
326  secondcoor = 1;
327  }
328  }
329  }
330 
331  /*** loop on all nodes in zone: define the boundary nodes for each fracture ****/
332  // k_current=0;
333 
334  // fprintf(inp,"%d\n", nzone_in);
335  for (i = 0; i < nzone_in - 1; i++) {
336  // printf(" %d %d %d %d %d %d\n", i,nodezonein[i], node[nodezonein[i]-1].fracture[0], node[nodezonein[i]-1].fracture[1], firstn, lastn);
337  if (node[nodezonein[i] - 1].fracture[0] == frc) {
338  if (node[nodezonein[i] - 1].coord[firstcoor] != node[firstn - 1].coord[firstcoor]) {
339  if (node[nodezonein[i] - 1].coord[firstcoor] < node[firstn - 1].coord[firstcoor]) {
340  firstn = nodezonein[i];
341  first_ind = i;
342  }
343 
344  if (node[nodezonein[i] - 1].coord[firstcoor] > node[lastn - 1].coord[firstcoor]) {
345  lastn = nodezonein[i];
346  last_ind = i;
347  }
348 
349  // fprintf(inp,"first coord, %d %d\n",firstn, lastn);
350  } else {
351  if (node[nodezonein[i] - 1].coord[secondcoor] < node[firstn - 1].coord[secondcoor]) {
352  firstn = nodezonein[i];
353  first_ind = i;
354  }
355 
356  if (node[nodezonein[i] - 1].coord[secondcoor] > node[lastn - 1].coord[secondcoor]) {
357  lastn = nodezonein[i];
358  last_ind = i;
359  }
360 
361  // fprintf(inp,"second coord, %d %d\n",firstn, lastn);
362  }
363  }
364 
365  // printf("fracture in flow-in zone %d first node %d last node %d \n", frc, firstn, lastn);
366  if ((node[nodezonein[i] - 1].fracture[0] != frc) || ((i == nzone_in - 2))) {
367  // printf("fracture in flow-in zone %d first node %d last node %d \n", frc, firstn, lastn);
368  if ((i == nzone_in - 2) && (node[firstn - 1].fracture[0] == node[nodezonein[nzone_in - 1] - 1].fracture[0])) {
369  lastn = nodezonein[nzone_in - 1];
370  last_ind = nzone_in - 1;
371  }
372 
373  if (firstn == lastn) {
374  //printf("firstn %d lastn %d fracture %d %d \n", firstn, lastn, node[nodezonein[i]-1].fracture[0],node[nodezonein[i]-1].fracture[1] );
375  }
376 
377  if (firstn != lastn) {
378  if (flag_in == 3) {
379  double cx1 = 0, cx2 = 0, cy1 = 0, cy2 = 0;
380  /* define ends points of fracture edge, then calculate an intersection with starting region */
381  inter_p[frc_count][0] = 1e-10;
382  inter_p[frc_count][1] = 1e-10;
383  inter_p[frc_count][2] = 1e-10;
384  inter_p[frc_count][3] = 1e-10;
385 
386  if ((zonenumb_in == 1) || (zonenumb_in == 2)) {
387  cx1 = node[firstn - 1].coord[0];
388  cy1 = node[firstn - 1].coord[1];
389 
390  if ((cx1 > ixmin) && (cx1 < ixmax) && (cy1 > iymin) && (cy1 < iymax)) {
391  inter_p[frc_count][0] = cx1;
392  inter_p[frc_count][1] = cy1;
393  }
394 
395  cx2 = node[lastn - 1].coord[0];
396  cy2 = node[lastn - 1].coord[1];
397 
398  if ((cx2 > ixmin) && (cx2 < ixmax) && (cy2 > iymin) && (cy2 < iymax)) {
399  inter_p[frc_count][0] = cx2;
400  inter_p[frc_count][1] = cy2;
401  }
402 
403  thirdcoor = node[firstn - 1].coord[2];
404  }
405 
406  if ((zonenumb_in == 3) || (zonenumb_in == 5)) {
407  cx1 = node[firstn - 1].coord[2];
408  cy1 = node[firstn - 1].coord[1];
409 
410  if ((cx1 > izmin) && (cx1 < izmax) && (cy1 > iymin) && (cy1 < iymax)) {
411  inter_p[frc_count][0] = cx1;
412  inter_p[frc_count][1] = cy1;
413  }
414 
415  cx2 = node[lastn - 1].coord[2];
416  cy2 = node[lastn - 1].coord[1];
417 
418  if ((cx2 > izmin) && (cx2 < izmax) && (cy2 > iymin) && (cy2 < iymax)) {
419  inter_p[frc_count][0] = cx2;
420  inter_p[frc_count][1] = cy2;
421  }
422 
423  thirdcoor = node[firstn - 1].coord[0];
424  }
425 
426  if ((zonenumb_in == 4) || (zonenumb_in == 6)) {
427  cx1 = node[firstn - 1].coord[0];
428  cy1 = node[firstn - 1].coord[2];
429 
430  if ((cx1 > ixmin) && (cx1 < ixmax) && (cy1 > izmin) && (cy1 < izmax)) {
431  inter_p[frc_count][0] = cx1;
432  inter_p[frc_count][1] = cy1;
433  }
434 
435  cx2 = node[lastn - 1].coord[0];
436  cy2 = node[lastn - 1].coord[2];
437 
438  if ((cx2 > ixmin) && (cx2 < ixmax) && (cy2 > izmin) && (cy2 < izmax)) {
439  inter_p[frc_count][0] = cx2;
440  inter_p[frc_count][1] = cy2;
441  }
442 
443  thirdcoor = node[firstn - 1].coord[1];
444  }
445 
446  double pr1, pr2, pr3, pr4, p_x, p_y;
447  int ii;
448 
449  /* define intersection points of boundary fracture edges and starting region sides*/
450  for (ii = 0; ii < 4; ii++) {
451  int kk;
452  kk = ii + 1;
453 
454  if (ii == 3) {
455  kk = 0;
456  }
457 
458  pr1 = (px[ii] - cx1) * (py[kk] - cy1) - (py[ii] - cy1) * (px[kk] - cx1);
459  pr2 = (cx1 - px[ii]) * (cy2 - py[ii]) - (cy1 - py[ii]) * (cx2 - px[ii]);
460  pr3 = (px[ii] - cx2) * (py[kk] - cy2) - (py[ii] - cy2) * (px[kk] - cx2);
461  pr4 = (cx1 - px[kk]) * (cy2 - py[kk]) - (cy1 - py[kk]) * (cx2 - px[kk]);
462 
463  if ((pr1 * pr3 < 0) && (pr2 * pr4 < 0)) {
464  pr1 = cx1 * cy2 - cy1 * cx2;
465  pr2 = px[ii] * py[kk] - py[ii] * px[kk];
466  pr3 = (cx1 - cx2) * (py[ii] - py[kk]) - (cy1 - cy2) * (px[ii] - px[kk]);
467  p_x = ((px[ii] - px[kk]) * pr1 - (cx1 - cx2) * pr2) / pr3;
468  p_y = ((py[ii] - py[kk]) * pr1 - (cy1 - cy2) * pr2) / pr3;
469 
470  if (inter_p[frc_count][0] == 1e-10) {
471  inter_p[frc_count][0] = p_x;
472  inter_p[frc_count][1] = p_y;
473  } else {
474  inter_fr[frc_count] = frc;
475  inter_p[frc_count][2] = p_x;
476  inter_p[frc_count][3] = p_y;
477  frc_count++;
478  break;
479  }
480  }
481  }
482  } //end of flag
483  }
484 
485  if (i < nzone_in - 2) {
486  frc = node[nodezonein[i] - 1].fracture[0];
487  firstn = nodezonein[i];
488  first_ind = i;
489  lastn = nodezonein[i];
490  last_ind = i;
491 
492  // fprintf(inp,"p %d %d %d %d\n", i, frc, firstn, lastn);
493  if (node[nodezonein[i + 1] - 1].fracture[0] == frc) {
494  if (abs(node[nodezonein[i] - 1].coord[0]) - abs(node[nodezonein[i + 1] - 1].coord[0]) < 1e-10) {
495  firstcoor = 1;
496  secondcoor = 2;
497  } else {
498  firstcoor = 0;
499 
500  if (abs(node[nodezonein[i] - 1].coord[1]) - abs(node[nodezonein[i + 1] - 1].coord[1]) < 1e-10) {
501  secondcoor = 2;
502  } else {
503  secondcoor = 1;
504  }
505  }
506  }
507  }
508  }
509  }
510 
511  // printf("fracture in flow-in zone %d first node %d last node %d \n", frc, firstn, lastn);
512  if ((flag_in == 3) && (frc_count == 0)) {
513  printf("\n There is no fracture crosses the given range. Try to increase the range. \n");
514  printf("\n Program is terminated. \n");
515  exit(1);
516  }
517 
518  /* place particles in starting region: every fracture (or part of fracture
519  edge will have the same amount of particles */
520  if (flag_in == 3) {
521  for (i = 0; i < frc_count; i++) {
522  parts_fracture = (int) npart / frc_count;
523  k_new = InitParticles_ones (k_current, inter_p, inter_fr[i], parts_fracture, i, thirdcoor, zonenumb_in, first_ind, last_ind);
524  k_current = k_new;
525  // printf(" %d intersects at %f %f %f %f\n",i, inter_p[i][0], inter_p[i][1], inter_p[i][2], inter_p[i][3]);
526  }
527  }
528 
529  // fclose(inp);
530  if (flag_in == 0) {
531  printf("\n There is no option specified for particles initial positions! \n");
532  printf("\n Program is terminated. \n");
533  exit(1);
534  }
535 
536  return k_new;
537 }
538 
539 
541 
542 int InitCell ()
544 {
545  int i, j, k, curcel, insc = 0;
546 
547  for (i = 0; i < nzone_in; i++) {
548  for (j = 0; j < node[nodezonein[i] - 1].numneighb; j++) {
549  for (k = 0; k < 4; k++)
550  if (node[nodezonein[i] - 1].cells[j][k] != 0) {
551  curcel = node[nodezonein[i] - 1].cells[j][k];
552  insc = InsideCell (curcel);
553 
554  if (insc == 1) {
555  break;
556  }
557  }
558 
559  if (insc == 1) {
560  break;
561  }
562  }
563 
564  if (insc == 1) {
565  break;
566  }
567  }
568 
569  // if (insc==0)
570  // {
571  // printf("Init Cell: NOT FOUND \n");
572  // printf("%d find cell: particle cell %d \n", np, particle[np].cell);
573  // }
574  return insc;
575 }
577 
578 int InitParticles_np (int k_current, int firstnd, int lastnd, int parts_fracture, int first_ind, int last_ind)
580 {
581  double deltax, deltay;
582  int j, pf;
583  pf = parts_fracture;
584  int ii, jj, k, curcel, insc = 0;
585  deltax = fabs(node[nodezonein[last_ind] - 1].coord_xy[0] - node[nodezonein[first_ind] - 1].coord_xy[0]);
586  deltay = fabs(node[nodezonein[last_ind] - 1].coord_xy[1] - node[nodezonein[first_ind] - 1].coord_xy[1]);
587 
588 // printf ("%d %d %d %d %f %f\n", first_ind, last_ind, firstnd, lastnd, deltax, deltay);
589 
590  for (j = 0; j < pf; j++) {
591  if (node[firstnd - 1].coord_xy[0] < node[lastnd - 1].coord_xy[0]) {
592  particle[k_current].position[0] = node[firstnd - 1].coord_xy[0] + (deltax / pf) * (j) + deltax / (2.0 * pf);
593  } else {
594  particle[k_current].position[0] = node[firstnd - 1].coord_xy[0] - (deltax / pf) * (j) - deltax / (2.0 * pf);
595  }
596 
597  if (node[firstnd - 1].coord_xy[1] < node[lastnd - 1].coord_xy[1]) {
598  particle[k_current].position[1] = node[firstnd - 1].coord_xy[1] + (deltay / pf) * (j) + deltay / (2.0 * pf);
599  } else {
600  particle[k_current].position[1] = node[firstnd - 1].coord_xy[1] - (deltay / pf) * (j) - deltay / (2.0 * pf);
601  }
602 
603  particle[k_current].velocity[0] = 0.;
604  particle[k_current].velocity[1] = 0.;
605  particle[k_current].fracture = node[firstnd - 1].fracture[0];
606  particle[k_current].intcell = 0;
607  particle[k_current].time = 0.0;
608  particle[k_current].fl_weight = 0.0;
609  particle[k_current].pressure = 0.0;
610  k_current++;
611 
612  if (k_current > npart) {
613  printf(" \n Number of particles with allocated memory is less than number of particles set up initially. \n");
614  printf(" Increase the number of particles. Program is terminated. \n");
615  exit(1);
616  }
617  }
618 
619  return k_current;
620 }
622 
623 int InitParticles_eq (int k_current, int firstn, int lastn, double parts_dist, int first_ind, int last_ind)
625 {
626  double deltax, deltay, edgelength, eqdist_x, eqdist_y;
627  unsigned int j, pf;
628  deltax = (node[lastn - 1].coord_xy[0] - node[firstn - 1].coord_xy[0]);
629  deltay = (node[lastn - 1].coord_xy[1] - node[firstn - 1].coord_xy[1]);
630  edgelength = sqrt(deltax * deltax + deltay * deltay);
631  pf = (int)(edgelength / parts_dist);
632 
633  if (pf < 2) {
634  pf = 1;
635  eqdist_x = deltax / 2.0;
636  eqdist_y = deltay / 2.0;
637  } else {
638  eqdist_x = deltax / pf;
639  eqdist_y = deltay / pf;
640  }
641 
642  for (j = 0; j < pf; j++) {
643  particle[k_current].position[0] = node[firstn - 1].coord_xy[0] + eqdist_x * (j) + eqdist_x / 2.0;
644  particle[k_current].position[1] = node[firstn - 1].coord_xy[1] + eqdist_y * (j) + eqdist_y / 2.0;
645  particle[k_current].velocity[0] = 0.;
646  particle[k_current].velocity[1] = 0.;
647  particle[k_current].fracture = node[firstn - 1].fracture[0];
648  particle[k_current].intcell = 0;
649  particle[k_current].time = 0.0;
650  particle[k_current].fl_weight = 0.0;
651  particle[k_current].pressure = 0.0;
652  // if (particle[k_current].fracture == 13) {
653  // printf("os %lf %lf \n", particle[k_current].position[0], particle[k_current].position[1]);
654  }
655 
656  k_current++;
657 
658  if (k_current > npart) {
659  printf("\n Number of particles with allocated memory is less than number of particles set up initially. \n");
660  printf(" Increase the number of particles. Program is terminated. \n");
661  exit(1);
662  }
663 
664  return k_current;
665 }
667 
668 int InitParticles_ones (int k_current, double inter_p[][4], int fracture_n, int parts_fracture, int ii, double thirdcoor, int zonenumb_in, int first_ind, int last_ind)
670 {
671  int j = fracture_n - 1;
672  double x_1 = 0, y_1 = 0, z_1 = 0, x_2 = 0, z_2 = 0, y_2 = 0;
673  double x1cor = 0.0, y1cor = 0.0, z1cor = 0, x2cor = 0.0, y2cor = 0.0, z2cor = 0;
674 
675  if ((zonenumb_in == 1) || (zonenumb_in == 2)) {
676  x1cor = inter_p[ii][0];
677  y1cor = inter_p[ii][1];
678  z1cor = thirdcoor;
679  x2cor = inter_p[ii][2];
680  y2cor = inter_p[ii][3];
681  z2cor = thirdcoor;
682  }
683 
684  if ((zonenumb_in == 3) || (zonenumb_in == 5)) {
685  x1cor = thirdcoor;
686  x2cor = thirdcoor;
687  z1cor = inter_p[ii][0];
688  z2cor = inter_p[ii][2];
689  y1cor = inter_p[ii][1];
690  y2cor = inter_p[ii][3];
691  }
692 
693  if ((zonenumb_in == 4) || (zonenumb_in == 6)) {
694  y1cor = thirdcoor;
695  y2cor = thirdcoor;
696  x1cor = inter_p[ii][0];
697  x2cor = inter_p[ii][2];
698  z1cor = inter_p[ii][1];
699  z2cor = inter_p[ii][3];
700  }
701 
702  if (fracture[j].theta != 0.0) {
703  x_1 = fracture[j].rot2mat[0][0] * x1cor + fracture[j].rot2mat[0][1] * y1cor + fracture[j].rot2mat[0][2] * z1cor;
704  y_1 = fracture[j].rot2mat[1][0] * x1cor + fracture[j].rot2mat[1][1] * y1cor + fracture[j].rot2mat[1][2] * z1cor;
705  z_1 = fracture[j].rot2mat[2][0] * x1cor + fracture[j].rot2mat[2][1] * y1cor + fracture[j].rot2mat[2][2] * z1cor;
706  x_2 = fracture[j].rot2mat[0][0] * x2cor + fracture[j].rot2mat[0][1] * y2cor + fracture[j].rot2mat[0][2] * z2cor;
707  y_2 = fracture[j].rot2mat[1][0] * x2cor + fracture[j].rot2mat[1][1] * y2cor + fracture[j].rot2mat[1][2] * z2cor;
708  z_2 = fracture[j].rot2mat[2][0] * x2cor + fracture[j].rot2mat[2][1] * y2cor + fracture[j].rot2mat[2][2] * z2cor;
709  } else {
710  /* if angle =0 and fracture is parallel to xy plane, we use the same x and y coordinates */
711  x_1 = x1cor;
712  y_1 = y1cor;
713  z_1 = z1cor;
714  x_2 = x2cor;
715  y_2 = y2cor;
716  z_2 = z2cor;
717  }
718 
719  double deltax, deltay;
720  unsigned int pf;
721  pf = parts_fracture;
722  deltax = (x_2 - x_1);
723  deltay = (y_2 - y_1);
724 
725  for (j = 0; j < pf; j++) {
726  particle[k_current].position[0] = x_1 + (deltax / pf) * (j) + deltax / (2.0 * pf);
727  particle[k_current].position[1] = y_1 + (deltay / pf) * (j) + deltay / (2.0 * pf);
728  particle[k_current].velocity[0] = 0.;
729  particle[k_current].velocity[1] = 0.;
730  particle[k_current].fracture = fracture_n;
731  particle[k_current].intcell = 0;
732  particle[k_current].time = 0.0;
733  particle[k_current].fl_weight = 0.0;
734  particle[k_current].pressure = 0.0;
735  k_current++;
736 
737  if (k_current > npart) {
738  printf(" \n Number of particles with allocated memory is less than number of particles set up initially. \n");
739  printf(" Increase the number of particles. Program is terminated. \n");
740  exit(1);
741  }
742  }
743 
744  return k_current;
745 }
747 void FlowInWeight(int numberpart)
749 {
750  int ind1 = 0, ind2 = 0, ver1 = 0, ver2 = 0, ver3 = 0, incell = 0, n1in = 0, n2in = 0, jj;
751  int ins;
752  double sumflux1 = 0, sumflux2 = 0, particleflux[numberpart], totalflux = 0;
753 
754  for (np = 0; np < numberpart; np++) {
755  ins = 0;
756  ins = InitCell();
757  incell = particle[np].cell;
758 
759  if (incell != 0) {
760  incell = particle[np].cell;
761  ver1 = cell[incell - 1].node_ind[0];
762  ver2 = cell[incell - 1].node_ind[1];
763  ver3 = cell[incell - 1].node_ind[2];
764  n1in = 0;
765  n2in = 0;
766 
767  if (node[ver1 - 1].typeN >= 300) {
768  n1in = ver1;
769  ind1 = 0;
770  }
771 
772  if (node[ver2 - 1].typeN >= 300) {
773  if (n1in == 0) {
774  n1in = ver2;
775  ind1 = 1;
776  } else {
777  n2in = ver2;
778  ind2 = 1;
779  }
780  }
781 
782  if (node[ver3 - 1].typeN >= 300) {
783  if (n1in == 0) {
784  n1in = ver3;
785  ind1 = 2;
786  } else {
787  n2in = ver3;
788  ind2 = 2;
789  }
790  }
791 
792  if ((n1in != 0) && (n2in != 0)) {
793  sumflux1 = 0;
794  sumflux2 = 0;
795 
796  for (jj = 0; jj < node[n1in - 1].numneighb; jj++) {
797  sumflux1 = sumflux1 + fabs(node[n1in - 1].flux[jj]);
798  }
799 
800  for (jj = 0; jj < node[n2in - 1].numneighb; jj++) {
801  sumflux2 = sumflux2 + fabs(node[n2in - 1].flux[jj]);
802  }
803 
804  particleflux[np] = particle[np].weight[ind1] * sumflux1 + particle[np].weight[ind2] * sumflux2;
805  totalflux = totalflux + particleflux[np];
806  } else {
807  int ncent = 0;
808  ncent = n1in + n2in;
809 
810  if (ncent != 0) {
811  sumflux1 = 0;
812 
813  for (jj = 0; jj < node[ncent - 1].numneighb; jj++) {
814  sumflux1 = sumflux1 + fabs(node[ncent - 1].flux[jj]);
815  }
816 
817  particleflux[np] = sumflux1;
818  totalflux = totalflux + particleflux[np];
819  }
820  }
821  }
822  }
823 
824  for (np = 0; np < numberpart; np++) {
825  particle[np].fl_weight = particleflux[np] / totalflux;
826  // printf("%d %5.12e %5.12e %5.12e \n", np+1,particleflux[np], totalflux, particle[np].fl_weight);
827  }
828 
829  return;
830 }
836 {
837  struct inpfile inputfile;
838  inputfile = Control_File("inm_coord:", 10 );
839  FILE *mc = OpenFile (inputfile.filename, "r");
840  printf("\n OPEN AND READ FILE: %s \n \n", inputfile.filename);
841  inputfile = Control_File("inm_nodeID:", 10 );
842  FILE *mn = OpenFile (inputfile.filename, "r");
843  printf("\n OPEN AND READ FILE: %s \n \n", inputfile.filename);
844  //FILE *mdf=OpenFile("distance_time.dat","w");
845  int i, ii;
846  unsigned int number, no;
847  char cs;
848 
849  if (fscanf(mn, "%d %d %d %d %d \n", &no, &no, &number, &no, &no) != 5) {
850  printf("error");
851  }
852 
853  for (i = 0; i < (number + 1); i++) {
854  do {
855  cs = fgetc(mn);
856  } while (cs != '\n');
857  }
858 
859  if (fscanf(mc, " %d \n", &npart) != 1) {
860  printf("error");
861  }
862 
863  /* memory allocatation for particle structures */
864  particle = (struct contam*) malloc ((npart + 1) * sizeof(struct contam));
865  double* distance = malloc ((npart + 1) * sizeof(double));
866  double xp, yp, zp, sum_distance = 0.0, xp2, yp2, zp2;
867 
868  for (ii = 0; ii < npart; ii++) {
869  if (fscanf(mn, " %d %d %d %d %d %d \n", &no, &no, &no, &no, &no, &number) != 6) {
870  printf("error");
871  }
872 
873  if (fscanf(mc, " %lf %lf %lf \n ", &xp, &yp, &zp) != 1) {
874  printf ("error");
875  }
876 
877  xp2 = (node[number - 1].coord[0] - xp) * (node[number - 1].coord[0] - xp);
878  yp2 = (node[number - 1].coord[1] - yp) * (node[number - 1].coord[1] - yp);
879  zp2 = (node[number - 1].coord[2] - zp) * (node[number - 1].coord[2] - zp);
880  distance[ii] = sqrt(xp2 + yp2 + zp2);
881  particle[ii].velocity[0] = 0.;
882  particle[ii].velocity[1] = 0.;
883  particle[ii].fracture = node[number - 1].fracture[0];
884  particle[ii].cell = 0;
885  particle[ii].position[0] = node[number - 1].coord_xy[0];
886  particle[ii].position[1] = node[number - 1].coord_xy[1];
887  particle[ii].time = 0.0;
888  particle[ii].weight[0] = 0.0;
889  particle[ii].weight[1] = 0.0;
890  particle[ii].weight[2] = 0.0;
891  particle[ii].prev_pos[0] = 0.0;
892  particle[ii].prev_pos[1] = 0.0;
893  particle[ii].intcell = 0;
894  particle[ii].fl_weight = 0.0;
895  particle[ii].pressure = 0.0;
896  // define a time that took for particle to reach fracture from a rock matrix
897  particle[ii].time = TimeFromMatrix(distance[ii]);
898  sum_distance = sum_distance + distance[ii];
899  }
900 
901  fclose(mc);
902  fclose(mn);
903 
904  //define weights according to distance from fracture
905  for (i = 0; i < npart; i++) {
906  particle[i].fl_weight = distance[i] / sum_distance;
907  }
908 
909  free(distance);
910  return;
911 }
913 double TimeFromMatrix(double pdist)
915 {
916  struct inpfile inputfile;
917  double ptime = 0.0, ptime1 = 0.0, ptime2 = 0.0;
918  double randomnumber = 0.0;
919  randomnumber = drand48();
920  double mporosity = 0.0;
921  double mdiffcoeff = 0.0;
922  inputfile = Control_Param("inm_porosity:", 13);
923  mporosity = inputfile.param;
924  inputfile = Control_Param("inm_diffcoeff:", 14);
925  mdiffcoeff = inputfile.param;
926  // printf("diff coeff %5.9e porosity %lf \n",mdiffcoeff, mporosity);
927  double retardation_factor = 1.0;
928  double inverse_erfc = 0.0;
929  double z;
930  z = 1 - randomnumber;
931  inverse_erfc = 0.5 * sqrt(pi) * (z + (pi / 12) * pow(z, 3) + ((7 * pow(pi, 2)) / 480) * pow(z, 5) + ((127 * pow(pi, 3)) / 40320) * pow(z, 7) + ((4369 * pow(pi, 4)) / 5806080) * pow(z, 9) + ((34807 * pow(pi, 5)) / 182476800) * pow(z, 11));
932  ptime2 = (1.0 / inverse_erfc) * (1.0 / inverse_erfc);
933  ptime1 = (pdist * pdist) / (4.0 * (mporosity * mdiffcoeff / retardation_factor));
934  ptime = (ptime1 * ptime2) / timeunit;
935  return ptime;
936 }
938 
939 int InitParticles_flux (int k_current, int first_ind, int last_ind, double weight_p)
942 {
943  double deltax, deltay, edgelength, eqdist_x, eqdist_y, sumflux = 0, startpos_x, startpos_y, sumdelta = 0.0;
944  double sumfluxfract = 0.0;
945  unsigned int i, k, j, jj, pf, curcel = 0, insc = 0, np, np_init;
946  struct posit3d particle3dposition;
947  np_init = k_current;
948  deltax = (node[nodezonein[last_ind] - 1].coord_xy[0] - node[nodezonein[first_ind] - 1].coord_xy[0]);
949  deltay = (node[nodezonein[last_ind] - 1].coord_xy[1] - node[nodezonein[first_ind] - 1].coord_xy[1]);
950 
951 // printf("firstn %d lastn %d %f %f \n", first_ind, last_ind, deltax, deltay);
952  for (j = first_ind; j <= last_ind; j++) {
953  sumflux = 0.0;
954 
955  // calculate the flux of the current cell
956  for (jj = 0; jj < node[nodezonein[j] - 1].numneighb; jj++) {
957  sumflux = sumflux + (node[nodezonein[j] - 1].flux[jj]);
958  }
959 
960  sumflux = sumflux / density;
961  sumfluxfract = sumfluxfract + sumflux;
962  // ceiling number of particles in cell nodezonein[j]
963  pf = ceilf(fabs(sumflux) / weight_p);
964 
965  // printf("%5.12e %d %5.12e %5.12e\n", sumflux, pf, fabs(sumflux)/weight_p, density);
966 
967  if ((j > first_ind) && (j < last_ind)) {
968  //calculate distance between nodes
969  deltax = (node[nodezonein[j + 1] - 1].coord_xy[0] - node[nodezonein[j - 1] - 1].coord_xy[0]) / 2.0;
970  deltay = (node[nodezonein[j + 1] - 1].coord_xy[1] - node[nodezonein[j - 1] - 1].coord_xy[1]) / 2.0;
971  //define starting position of first particle
972  startpos_x = ((node[nodezonein[j] - 1].coord_xy[0]) - (node[nodezonein[j - 1] - 1].coord_xy[0])) / 2.0 + node[nodezonein[j - 1] - 1].coord_xy[0];
973  startpos_y = ((node[nodezonein[j] - 1].coord_xy[1]) - (node[nodezonein[j - 1] - 1].coord_xy[1])) / 2.0 + node[nodezonein[j - 1] - 1].coord_xy[1];
974  }
975 
976  if (j == first_ind) {
977  //calculate distance between nodes
978  deltax = (node[nodezonein[j + 1] - 1].coord_xy[0] - node[nodezonein[j] - 1].coord_xy[0]) / 2.0;
979  deltay = (node[nodezonein[j + 1] - 1].coord_xy[1] - node[nodezonein[j] - 1].coord_xy[1]) / 2.0;
980  //define starting position of first particle
981  startpos_x = node[nodezonein[j] - 1].coord_xy[0];
982  startpos_y = node[nodezonein[j] - 1].coord_xy[1];
983  }
984 
985  if (j == last_ind) {
986  //calculate distance between nodes
987  deltax = (node[nodezonein[j] - 1].coord_xy[0] - node[nodezonein[j - 1] - 1].coord_xy[0]) / 2.0;
988  deltay = (node[nodezonein[j] - 1].coord_xy[1] - node[nodezonein[j - 1] - 1].coord_xy[1]) / 2.0;
989  //define starting position of first particle
990  startpos_x = node[nodezonein[j - 1] - 1].coord_xy[0];
991  startpos_y = node[nodezonein[j - 1] - 1].coord_xy[1];
992  }
993 
994  if (pf < 2) {
995  pf = 1;
996  eqdist_x = deltax / 2.0;
997  eqdist_y = deltay / 2.0;
998  } else {
999  eqdist_x = deltax / pf;
1000  eqdist_y = deltay / pf;
1001  }
1002 
1003  for (jj = 0; jj < pf; jj++) {
1004  particle[k_current].position[0] = startpos_x + eqdist_x * (jj);
1005  particle[k_current].position[1] = startpos_y + eqdist_y * (jj);
1006  particle[k_current].velocity[0] = 0.;
1007  particle[k_current].velocity[1] = 0.;
1008  particle[k_current].fracture = node[nodezonein[first_ind] - 1].fracture[0];
1009  particle[k_current].intcell = 0;
1010  particle[k_current].time = 0.0;
1011  particle[k_current].fl_weight = weight_p;
1012  particle[k_current].cell = 0;
1013  particle[k_current].pressure = 0.0;
1014  np = k_current;
1015  k_current++;
1016 
1017  if (k_current > npart * 3) {
1018 // printf("\n Number of particles with allocated memory (%d) is less than number of particles set up initially (%d). \n", k_current, npart);
1019  printf(" Increase the number of particles. Program is terminated. \n");
1020  exit(1);
1021  }
1022  }
1023  }
1024 
1025  return k_current;
1026 }
1028 int InitInWell(int node_part) {
1029 // Function defines initial parameters for the particles in Option #7, where certain number of particles are seeded at nodes in in-flow zone.
1030  int i = 0, j = 0, k_current = 0;
1031  float sum_aperture = 0.0;
1032 
1033  for (i = 0; i < nzone_in; i++) {
1034  for (j = 0; j < node_part; j++) {
1035  particle[k_current].position[0] = node[nodezonein[i] - 1].coord_xy[0];
1036  particle[k_current].position[1] = node[nodezonein[i] - 1].coord_xy[1];
1037  particle[k_current].velocity[0] = 0.;
1038  particle[k_current].velocity[1] = 0.;
1039  particle[k_current].fracture = node[nodezonein[i] - 1].fracture[0];
1040  particle[k_current].cell = 0;
1041  particle[k_current].time = 0.0;
1042  particle[k_current].fl_weight = node[nodezonein[i] - 1].aperture;
1043  particle[k_current].pressure = 0.0;
1044  k_current++;
1045  sum_aperture = sum_aperture + node[nodezonein[i] - 1].aperture;
1046  }
1047  }
1048 
1049  for (i = 0; i < k_current; i++) {
1050  particle[i].fl_weight = particle[i].fl_weight / sum_aperture;
1051  }
1052 
1053  return k_current;
1054 }
#define pi
Definition: FuncDef.h:2
FILE * OpenFile(char filen[120], char fileopt[2])
Definition: ReadGridInit.c:664
struct element * cell
Definition: main.c:42
struct inpfile Control_File(char fileobject[], int ctr)
Definition: ReadGridInit.c:998
struct inpfile Control_File_Optional(char fileobject[], int ctr)
unsigned int ncells
Definition: main.c:30
double timeunit
Definition: main.c:51
int InsideCell(unsigned int numc)
unsigned int np
Definition: main.c:34
void Moving2Center(int nnp, int cellnumber)
unsigned int nzone_in
Definition: main.c:35
double density
Definition: main.c:47
struct contam * particle
Definition: main.c:41
struct inpfile Control_Param(char fileobject[], int ctr)
struct inpfile Control_Data(char fileobject[], int ctr)
unsigned int npart
Definition: main.c:33
struct vertex * node
Definition: main.c:40
double totalFluxIn
Definition: main.c:52
struct material * fracture
Definition: main.c:39
unsigned int flag_w
Definition: main.c:38
unsigned int * nodezonein
Definition: main.c:36
int InitParticles_eq(int k_current, int firstn, int lastn, double parts_dist, int first_ind, int last_ind)
void InitInMatrix()
double TimeFromMatrix(double pdist)
int InitParticles_ones(int k_current, double inter_p[][4], int fracture_n, int parts_fracture, int ii, double thirdcoor, int zonenumb_in, int first_ind, int last_ind)
int InitParticles_np(int k_current, int firstnd, int lastnd, int parts_fracture, int first_ind, int last_ind)
int InitCell()
void FlowInWeight(int numberpart)
int InitParticles_flux(int k_current, int first_ind, int last_ind, double weight_p)
int InitInWell(int node_part)
int InitPos()
unsigned int fracture
Definition: FuncDef.h:189
double time
Definition: FuncDef.h:201
unsigned int intcell
Definition: FuncDef.h:195
double pressure
Definition: FuncDef.h:207
double weight[3]
Definition: FuncDef.h:198
double velocity[2]
Definition: FuncDef.h:180
unsigned int cell
Definition: FuncDef.h:192
double prev_pos[2]
Definition: FuncDef.h:186
double fl_weight
Definition: FuncDef.h:204
double position[2]
Definition: FuncDef.h:183
unsigned int node_ind[3]
Definition: FuncDef.h:167
unsigned int fracture
Definition: FuncDef.h:164
char filename[120]
double rot2mat[3][3]
Definition: FuncDef.h:98
double cord3[3]
double coord[3]
Definition: FuncDef.h:115
double coord_xy[6]
Definition: FuncDef.h:118
unsigned int ** cells
Definition: FuncDef.h:139
double aperture
Definition: FuncDef.h:157
double * flux
Definition: FuncDef.h:148
unsigned int fracture[2]
Definition: FuncDef.h:112
unsigned int numneighb
Definition: FuncDef.h:127