source: trunk/anuga_work/development/2010-projects/anuga_1d/sqpipe/sqpipe.h @ 8238

Last change on this file since 8238 was 8238, checked in by paul, 12 years ago

Bulk modulus of fluid now in use for 1d domains

File size: 13.6 KB
Line 
1/**********************************************************
2Pipe params class
3**********************************************************/
4
5struct sqpipe_params {
6  struct params super;
7
8  double g;
9  double h0;
10  double bulk_modulus;
11};
12
13// Construction
14void sqpipe_params_init(struct sqpipe_params *q);
15struct sqpipe_params* sqpipe_params_new();
16
17// Destruction
18struct params* sqpipe_params_destroy(struct params *q);
19
20// Methods
21
22// Implementation
23void sqpipe_params_init(struct sqpipe_params *q) {
24  static struct params_vtable vtable = {
25    &sqpipe_params_destroy
26  };
27  q->super.vtable = &vtable;
28 
29  ((struct params *)q)->cfl = 0.0; 
30  ((struct params *)q)->epsilon = 0.0;
31  q->g = 0.0;
32  q->h0 = 0.0;
33}
34
35struct sqpipe_params* sqpipe_params_new() {
36  struct sqpipe_params *p = malloc(sizeof(struct sqpipe_params));
37
38  sqpipe_params_init(p);
39
40  return p; 
41}
42
43struct params* sqpipe_params_destroy(struct params *q) {
44  free(q);
45  q = NULL;
46 
47  return q;
48}
49/**********************************************************/
50
51
52/**********************************************************
53Pipe quantity class
54This is a virtual class and should never be created.
55The inherting class needs to implement
56    init, new, flux_formula0, flux_formula1, sound_speed,
57    get_conserved
58**********************************************************/
59
60struct sqpipe_quantity {
61  struct quantity super;
62
63  double a;
64  double d;
65  double w;
66  double h;
67  double u;
68  double z; 
69  double b;
70  double t;
71};
72
73// Construction
74void sqpipe_quantity_init(struct sqpipe_quantity *q);
75struct sqpipe_quantity* sqpipe_quantity_new();
76
77// Destruction
78struct quantity* sqpipe_quantity_destroy(struct quantity *q);
79
80// Methods
81double* sqpipe_quantity_free_surface_flux_formula (struct quantity *q, double normal, struct params *p, double *quantityflux);
82double* sqpipe_quantity_pressurised_flux_formula (struct quantity *q, double normal, struct params *p, double *quantityflux);
83double sqpipe_quantity_free_surface_sound_speed (struct quantity *q, struct params *p);
84double sqpipe_quantity_pressurised_sound_speed (struct quantity *q, struct params *p);
85
86// Implementation
87// Flux formula taking into account the normal
88// Note u, d should be normal*u, normal*d but since normal is +/- 1
89// (normal*u) * (normal*d) = u*d
90double* sqpipe_quantity_free_surface_flux_formula (struct quantity *q, double normal, struct params *p, double *quantityflux) {
91  struct sqpipe_quantity *pq = (struct sqpipe_quantity*) q;
92  struct sqpipe_params *sp = (struct sqpipe_params *) p;
93
94  quantityflux[0] = (normal * pq->u) * quantity_get_conserved(q, 0, normal);
95  quantityflux[1] = normal * (pq->u * quantity_get_conserved(q, 1, normal) + 0.5 * sp->g * pq->h *pq->h);
96
97  return quantityflux;
98}
99
100double* sqpipe_quantity_pressurised_flux_formula (struct quantity *q, double normal, struct params *p, double *quantityflux) {
101  struct sqpipe_quantity *pq = (struct sqpipe_quantity*) q;
102  struct sqpipe_params *sp = (struct sqpipe_params *) p;
103 
104  quantityflux[0] = (normal * pq->u) * pq->a; 
105  quantityflux[1] = normal * (pq->u * pq->d + sp->bulk_modulus*(pq->h - pq->t) + 0.5 * sp->g * pq->t * pq->t);
106
107  return quantityflux;
108}
109
110double sqpipe_quantity_free_surface_sound_speed (struct quantity *q, struct params *p) {
111  struct sqpipe_quantity *sq = (struct sqpipe_quantity*) q;
112  struct sqpipe_params *sp = (struct sqpipe_params*) p; 
113
114  return sqrt(sp->g * sq->h);
115}
116
117double sqpipe_quantity_pressurised_sound_speed (struct quantity *q, struct params *p) {
118  return ((struct sqpipe_params *)p)->bulk_modulus;
119}
120
121void sqpipe_quantity_init(struct sqpipe_quantity *q) {
122  static struct quantity_vtable vtable = {
123    NULL,
124    NULL,
125    NULL,
126    &sqpipe_quantity_destroy
127  };
128  q->super.vtable = &vtable;
129 
130  q->a = 0.0;
131  q->d = 0.0;
132  q->w = 0.0;
133  q->h = 0.0;
134  q->u = 0.0;
135  q->z = 0.0; 
136  q->b = 0.0;
137  q->t = 0.0;
138}
139
140struct sqpipe_quantity* sqpipe_quantity_new() {
141  struct sqpipe_quantity *p = malloc(sizeof(struct sqpipe_quantity));
142
143  return p; 
144}
145
146struct quantity* sqpipe_quantity_destroy(struct quantity *q) {
147  free(q);
148  q = NULL;
149 
150  return q;
151}
152/**********************************************************/
153
154
155/**********************************************************
156Pipe edge class
157This is a virtual class and should never be created.
158The inherting class needs to implement
159    init, new, flux_function
160**********************************************************/
161struct sqpipe_edge {
162  struct edge super;
163};
164
165// Construction
166void sqpipe_edge_init(struct sqpipe_edge *e);
167struct sqpipe_edge* sqpipe_edge_new();
168
169// Destruction
170struct edge* sqpipe_edge_destroy(struct edge *e);
171
172// Methods
173double sqpipe_edge_extreme_sound_speeds (struct edge *e, struct params *p);
174
175// Implementation
176double sqpipe_edge_extreme_sound_speeds (struct edge *e, struct params *p) {
177  double soundspeed_left, soundspeed_right, max_speed;
178  struct sqpipe_quantity *qin = (struct sqpipe_quantity*) e->qin;
179  struct sqpipe_quantity *qout = (struct sqpipe_quantity*) e->qout;
180
181  soundspeed_left = quantity_sound_speed(e->qin, p);
182  soundspeed_right = quantity_sound_speed(e->qout, p);
183
184  e->smax = max(e->normal * qin->u + soundspeed_left, e->normal * qout->u + soundspeed_right);
185  if (e->smax < 0.0) e->smax = 0.0;
186       
187  e->smin = min(e->normal * qin->u - soundspeed_left, e->normal * qout->u - soundspeed_right);
188  if (e->smin > 0.0) e->smin = 0.0;
189
190  if (e->smax - e->smin < p->epsilon) {
191    max_speed = 0.0;
192  } else {
193    max_speed = max(fabs(e->smin), fabs(e->smax));
194  }
195
196  return max_speed;
197}
198
199void sqpipe_edge_init(struct sqpipe_edge *e) {
200  static struct edge_vtable vtable = {
201    &edge_flux_function_godunov,
202    &sqpipe_edge_extreme_sound_speeds,
203    &sqpipe_edge_destroy
204  };
205  e->super.vtable = &vtable;
206
207  ((struct edge *)e)->qin = NULL;
208  ((struct edge *)e)->qout = NULL;
209  ((struct edge *)e)->normal = 0.0;
210  ((struct edge *)e)->smax = 0.0;
211  ((struct edge *)e)->smin = 0.0;
212}
213
214struct sqpipe_edge* sqpipe_edge_new() {
215  struct sqpipe_edge *p = malloc(sizeof(struct sqpipe_edge));
216
217  return p; 
218}
219
220struct edge* sqpipe_edge_destroy(struct edge *e) { 
221  e->qin = quantity_destroy(e->qin);
222  e->qout = quantity_destroy(e->qout);
223 
224  free(e);
225  e = NULL;
226 
227  return e;
228}
229/**********************************************************/
230
231/**********************************************************
232Pipe cell class
233This is a virtual class and should never be created.
234The inherting class needs to implement
235    init, new, flux_function, forcing_terms
236**********************************************************/
237struct sqpipe_cell {
238  struct cell super;
239};
240
241// Construction
242void sqpipe_cell_init(struct sqpipe_cell *e);
243struct sqpipe_cell* sqpipe_cell_new();
244
245// Destruction
246struct cell* sqpipe_cell_destroy(struct cell *c);
247
248// Methods
249double sqpipe_cell_extreme_sound_speeds (struct cell *c, struct params *p);
250double* sqpipe_cell_free_surface_forcing_terms (struct cell *c, struct params *p, double *cellforce);
251double* sqpipe_cell_pressurised_forcing_terms (struct cell *c, struct params *p, double *cellforce);
252
253// Implementation
254double sqpipe_cell_extreme_sound_speeds (struct cell *c, struct params *p) {
255  int i;
256  // The compiler doesn't know c->num_edges is positive hence whether the
257  // loop will run. This throws the warning:
258  // ‘max_speed’ may be used uninitialized in this function
259  // and the same for tmp_max_speed
260  // We initiallise them to avoid the warning since we know nothing could
261  // possibly go wrong...
262  double max_speed = 0.0, tmp_max_speed = 0.0;
263
264  for (i=0; i<c->num_edges; i++) {
265    tmp_max_speed = edge_extreme_sound_speeds(c->edges[i], p);
266    max_speed = max(max_speed, tmp_max_speed);
267  }
268
269  return max_speed;
270}
271
272double* sqpipe_cell_free_surface_forcing_terms (struct cell *c, struct params *p, double *cellforce) {
273  struct sqpipe_quantity *qin = (struct sqpipe_quantity *) c->edges[0]->qout;
274  struct sqpipe_quantity *qout = (struct sqpipe_quantity *) c->edges[1]->qin;
275  struct sqpipe_params *sp = (struct sqpipe_params *) p;
276
277  cellforce[0] = 0.0; 
278  cellforce[1] = 0.5 * sp->g * (qout->h + qin->h) * (qout->z - qin->z);
279 
280  return cellforce;
281}
282
283double* sqpipe_cell_pressurised_forcing_terms (struct cell *c, struct params *p, double *cellforce) {
284  struct sqpipe_quantity *qin = (struct sqpipe_quantity *) c->edges[0]->qout;
285  struct sqpipe_quantity *qout = (struct sqpipe_quantity *) c->edges[1]->qin;
286  struct sqpipe_params *sp = (struct sqpipe_params *) p;
287
288  cellforce[0] = 0.0;
289  cellforce[1] = sp->bulk_modulus * (sp->g * (0.5*(qout->h + qin->h) - 0.5*(qout->t + qin->t)) * (qout->b - qin->b) + sp->g * (0.5*(qout->h + qin->h) - 0.5*(qout->t + qin->t)) * 0.5*(qout->b + qin->b) * (qout->t - qin->t) * 1/(0.5*(qout->t + qin->t)));
290
291  return cellforce;
292}
293
294
295void sqpipe_cell_init(struct sqpipe_cell *c) {
296  static struct cell_vtable vtable = {
297    &cell_flux_function_generic, 
298    &sqpipe_cell_extreme_sound_speeds,
299    NULL,
300    &sqpipe_cell_destroy
301  };
302  c->super.vtable = &vtable;
303
304  // Can't set edges to NULL here since sqpipe_cell_new() has allocated memory
305  // If a cell is created without using cell_new(), then edges will be an
306  // unitialised pointer.
307  // Can't allocate memory here since init should not allocate memory
308  // The moral: Use cell_new() to create cells!
309
310  c->super.num_edges = 2;
311}
312
313struct sqpipe_cell* sqpipe_cell_new() {
314  struct sqpipe_cell *c = malloc(sizeof(struct sqpipe_cell));
315
316  // Allocate memory for a length 2 array of pointers to edges
317  ((struct cell *)c)->edges = (struct edge  **) malloc(2 * sizeof(struct sqpipe_edge *));
318 
319  return c;
320}
321
322struct cell* sqpipe_cell_destroy(struct cell *c) { 
323  int i;
324
325  for (i=0; i<c->num_edges; i++) {
326    c->edges[i] = edge_destroy(c->edges[i]);
327  } 
328
329  free(c->edges);
330  c->edges = NULL;
331  free(c);
332  c = NULL;
333 
334  return c;
335}
336/**********************************************************/
337
338
339/**********************************************************
340Pipe quantities class
341This is a virtual class and should never be created.
342The inherting class needs to implement:
343    init, new, get_quantities
344**********************************************************/
345struct sqpipe_quantities {
346  struct quantities super;
347
348  double *a;
349  double *d;
350  double *w;
351  double *h;
352  double *u;
353  double *z; 
354  double *b;
355  double *t;
356};
357
358// Construction
359void sqpipe_quantities_init(struct sqpipe_quantities *q);
360struct sqpipe_quantities* sqpipe_quantities_new();
361
362// Destruction
363struct quantities* sqpipe_quantities_destroy(struct quantities *qs);
364
365// Methods
366struct quantity* sqpipe_quantities_get_quantity(struct quantities *qs, int i, struct quantity *q);
367
368// Implementation
369struct quantity* sqpipe_quantities_get_quantity(struct quantities *qs, int i, struct quantity *q) { 
370  struct sqpipe_quantities *ps = (struct sqpipe_quantities *) qs;
371  struct sqpipe_quantity *p = (struct sqpipe_quantity *) q;
372
373  p->a = ps->a[i];
374  p->d = ps->d[i];
375  p->w = ps->w[i];
376  p->h = ps->h[i];
377  p->u = ps->u[i]; 
378  p->z = ps->z[i];
379  p->b = ps->b[i];
380  p->t = ps->t[i];
381
382  return q;
383}
384
385void sqpipe_quantities_init(struct sqpipe_quantities *q) {
386  static struct quantities_vtable vtable = {
387    &sqpipe_quantities_get_quantity,
388    NULL,
389    &sqpipe_quantities_destroy
390  };
391  q->super.vtable = &vtable;
392
393
394  q->a = NULL;
395  q->d = NULL;
396  q->w = NULL;
397  q->h = NULL;
398  q->u = NULL;
399  q->z = NULL; 
400  q->b = NULL;
401  q->t = NULL;
402}
403
404struct sqpipe_quantities* sqpipe_quantities_new() {
405  struct sqpipe_quantities *p = malloc(sizeof(struct sqpipe_quantities));
406
407  return p; 
408}
409
410
411struct quantities* sqpipe_quantities_destroy(struct quantities *qs) {
412  free(qs);
413  qs = NULL;
414 
415  return qs;
416}
417/**********************************************************/
418
419
420/**********************************************************
421Pipe domain class
422This is a virtual class and should never be created.
423The inheriting class needs to implement:
424  init, new, compute_fluxes
425**********************************************************/
426struct sqpipe_domain {
427  struct domain super;
428};
429
430// Construction
431void sqpipe_domain_init(struct sqpipe_domain *q);
432struct sqpipe_domain* sqpipe_domain_new();
433
434// Destruction
435struct domain* sqpipe_domain_destroy(struct domain *D);
436
437// Methods
438void sqpipe_domain_init(struct sqpipe_domain *D);
439
440// Implementation
441void sqpipe_domain_init(struct sqpipe_domain *d) {
442  static struct domain_vtable vtable = {
443    NULL,
444    NULL,
445    &domain_compute_fluxes_generic,
446    &domain_get_cell_generic,
447    &sqpipe_domain_destroy
448  };
449  d->super.vtable = &vtable;
450
451  ((struct domain *)d)->number_of_equations = 2;
452
453  ((struct domain *)d)->vertex_values = NULL;
454  ((struct domain *)d)->boundary_values = NULL;
455  ((struct domain *)d)->explicit_update = NULL;
456  ((struct domain *)d)->neighbours = NULL;
457  ((struct domain *)d)->neighbour_vertices = NULL;
458  ((struct domain *)d)->normals = NULL;
459  ((struct domain *)d)->areas = NULL;
460  ((struct domain *)d)->number_of_elements = 0; 
461
462  ((struct domain *)d)->timestep = 0.0;
463  ((struct domain *)d)->max_speed_array = NULL;
464
465  // Can't set params to NULL here since sqpipe_domain_new() has allocated
466  // memory
467  // If a domain is created without using domain_new(), then params will be an
468  // unitialised pointer.
469
470  // Can't allocate memory here since init should not allocate memory
471  // The moral: Use domain_new() to create domains! 
472}
473
474struct sqpipe_domain* sqpipe_domain_new() {
475  struct sqpipe_domain *p = malloc(sizeof(struct sqpipe_domain));
476
477  ((struct domain *)p)->params = (struct params *) sqpipe_params_new();
478
479  return p;
480}
481
482
483struct domain* sqpipe_domain_destroy(struct domain *D) {
484  D->vertex_values = quantities_destroy(D->vertex_values);
485  D->boundary_values = quantities_destroy(D->boundary_values);
486  D->explicit_update = quantities_destroy(D->explicit_update);
487  D->params = params_destroy(D->params);
488  free(D);
489  D = NULL;
490
491  return D;
492}
493/**********************************************************/
494
495
Note: See TracBrowser for help on using the repository browser.