Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
uvahotspot
GitHub Repository: uvahotspot/HotSpot
Path: blob/master/microchannel.c
612 views
1
#include <string.h>
2
#include <math.h>
3
#include <stdlib.h>
4
#include "microchannel.h"
5
6
#if SUPERLU > 0
7
#include "slu_ddefs.h"
8
#endif
9
10
#define MAX_LINE_SIZE 4096
11
#define DEBUG 0
12
13
// How many extra nodes we need to include in the pressure circuit
14
int extra_pressure_nodes;
15
16
// default microchannel configuration parameters
17
microchannel_config_t default_microchannel_config(void)
18
{
19
microchannel_config_t config;
20
21
config.cell_width = 100e-6;
22
config.cell_height = 100e-6;
23
config.cell_thickness = 100e-6;
24
config.pumping_pressure = 5000;
25
config.pump_internal_res = 0; // ideal pump
26
config.inlet_temperature = 300;
27
config.coolant_capac = 4172638; // water
28
config.coolant_res = 1.647717911; // water
29
config.coolant_visc = 0.000889; // water
30
config.wall_capac = 1635660; // silicon
31
config.wall_res = 0.0076923077; // silicon
32
config.htc = 27132;
33
config.num_rows = -1;
34
config.num_columns = -1;
35
config.n_fluid_cells = -1;
36
config.cell_types = NULL;
37
config.mapping = NULL;
38
config.A = NULL;
39
config.b = NULL;
40
config.nnz = 0;
41
42
return config;
43
}
44
45
/*
46
* parse a table of name-value string pairs and add the configuration
47
* parameters to 'config'
48
*/
49
void microchannel_config_add_from_strs(microchannel_config_t *config, materials_list_t *materials_list, str_pair *table, int size)
50
{
51
int idx;
52
53
if ((idx = get_str_index(table, size, "pumping_pressure")) >= 0)
54
if(sscanf(table[idx].value, "%lf", &config->pumping_pressure) != 1)
55
fatal("invalid format for configuration parameter pumping_pressure\n");
56
if ((idx = get_str_index(table, size, "pump_internal_res")) >= 0)
57
if(sscanf(table[idx].value, "%lf", &config->pump_internal_res) != 1)
58
fatal("invalid format for configuration parameter pumping internal resistance\n");
59
if ((idx = get_str_index(table, size, "inlet_temperature")) >= 0)
60
if(sscanf(table[idx].value, "%lf", &config->inlet_temperature) != 1)
61
fatal("invalid format for configuration parameter inlet_temperature\n");
62
if ((idx = get_str_index(table, size, "coolant_capac")) >= 0)
63
if(sscanf(table[idx].value, "%lf", &config->coolant_capac) != 1)
64
fatal("invalid format for configuration parameter coolant_capacity\n");
65
if ((idx = get_str_index(table, size, "coolant_res")) >= 0)
66
if(sscanf(table[idx].value, "%lf", &config->coolant_res) != 1)
67
fatal("invalid format for configuration parameter coolant resistivity\n");
68
if ((idx = get_str_index(table, size, "coolant_visc")) >= 0)
69
if(sscanf(table[idx].value, "%lf", &config->coolant_visc) != 1)
70
fatal("invalid format for configuration parameter coolant dynamic viscosity\n");
71
if ((idx = get_str_index(table, size, "wall_capac")) >= 0)
72
if(sscanf(table[idx].value, "%lf", &config->wall_capac) != 1)
73
fatal("invalid format for configuration parameter wall_capacity\n");
74
if ((idx = get_str_index(table, size, "wall_res")) >= 0)
75
if(sscanf(table[idx].value, "%lf", &config->wall_res) != 1)
76
fatal("invalid format for configuration parameter wall_resistivity\n");
77
if ((idx = get_str_index(table, size, "htc")) >= 0)
78
if(sscanf(table[idx].value, "%lf", &config->htc) != 1)
79
fatal("invalid format for configuration parameter heat transfer coefficient\n");
80
if ((idx = get_str_index(table, size, "network_file")) >= 0)
81
if(sscanf(table[idx].value, "%s", config->network_file) != 1)
82
fatal("invalid format for configuration parameter network_file\n");
83
84
if ((idx = get_str_index(table, size, "wall_material")) >= 0) {
85
char material_name[STR_SIZE];
86
if(sscanf(table[idx].value, "%s", material_name) != 1)
87
fatal("invalid format for configuration parameter wall_material\n");
88
89
config->wall_res = 1.0 / get_material_thermal_conductivity(materials_list, material_name);
90
config->wall_capac = get_material_volumetric_heat_capacity(materials_list, material_name);
91
92
if(config->wall_res < 0 || config->wall_capac < 0)
93
fatal("material name specified in configuration parameter wall_material not found\n");
94
}
95
96
if ((idx = get_str_index(table, size, "coolant_material")) >= 0) {
97
char material_name[STR_SIZE];
98
if(sscanf(table[idx].value, "%s", material_name) != 1)
99
fatal("invalid format for configuration parameter coolant_material\n");
100
101
config->coolant_res = 1.0 / get_material_thermal_conductivity(materials_list, material_name);
102
config->coolant_capac = get_material_volumetric_heat_capacity(materials_list, material_name);
103
config->coolant_visc = get_material_dynamic_viscosity(materials_list, material_name);
104
105
if(config->coolant_res < 0 || config->coolant_capac < 0 || config->coolant_visc < 0)
106
fatal("material name specified in configuration parameter coolant_material not found\n");
107
}
108
}
109
110
/*
111
* convert config into a table of name-value pairs. returns the no.
112
* of parameters converted
113
*/
114
int microchannel_config_to_strs(microchannel_config_t *config, str_pair *table, int max_entries)
115
{
116
if (max_entries < 17)
117
fatal("not enough entries in table\n");
118
119
sprintf(table[0].name, "cell_width");
120
sprintf(table[1].name, "cell_height");
121
sprintf(table[2].name, "cell_thickness");
122
sprintf(table[3].name, "pumping_pressure");
123
sprintf(table[4].name, "pump_internal_res");
124
sprintf(table[5].name, "inlet_temperature");
125
sprintf(table[6].name, "coolant_capac");
126
sprintf(table[7].name, "coolant_res");
127
sprintf(table[8].name, "coolant_visc");
128
sprintf(table[9].name, "wall_capac");
129
sprintf(table[10].name, "wall_res");
130
sprintf(table[11].name, "htc");
131
sprintf(table[12].name, "network_file");
132
sprintf(table[13].name, "floorplan_file");
133
sprintf(table[14].name, "num_rows");
134
sprintf(table[15].name, "num_columns");
135
sprintf(table[16].name, "n_fluid_cells");
136
137
sprintf(table[0].value, "%e", config->cell_width);
138
sprintf(table[1].value, "%e", config->cell_height);
139
sprintf(table[2].value, "%e", config->cell_thickness);
140
sprintf(table[3].value, "%e", config->pumping_pressure);
141
sprintf(table[4].value, "%e", config->pump_internal_res);
142
sprintf(table[5].value, "%e", config->inlet_temperature);
143
sprintf(table[6].value, "%e", config->coolant_capac);
144
sprintf(table[7].value, "%e", config->coolant_res);
145
sprintf(table[8].value, "%e", config->coolant_visc);
146
sprintf(table[9].value, "%e", config->wall_capac);
147
sprintf(table[10].value, "%e", config->wall_res);
148
sprintf(table[11].value, "%e", config->htc);
149
sprintf(table[12].value, "%s", config->network_file);
150
sprintf(table[13].value, "%s", config->floorplan_file);
151
sprintf(table[14].value, "%d", config->num_rows);
152
sprintf(table[15].value, "%d", config->num_columns);
153
sprintf(table[16].value, "%d", config->n_fluid_cells);
154
155
return 16;
156
}
157
158
void solve_pressure_circuit(microchannel_config_t *config) {
159
#if SUPERLU > 0
160
SuperMatrix A, L, U, B;
161
double *a, *rhs;
162
int *asub, *xa;
163
int *perm_r;
164
int *perm_c;
165
int nnz, nrhs, info, i, m, n, perc_spec;
166
int j;
167
superlu_options_t options;
168
SuperLUStat_t stat;
169
170
m = n = config->n_fluid_cells + extra_pressure_nodes;
171
nnz = config->nnz;
172
if( !(a = doubleMalloc(nnz)) ) ABORT("malloc failed");
173
if( !(asub = intMalloc(nnz)) ) ABORT("malloc failed");
174
if( !(xa = intMalloc(n + 1)) ) ABORT("malloc failed");
175
176
int v = 0;
177
int x = 1;
178
xa[0] = 0;
179
for(i = 0; i < m; i++) {
180
for(j = 0; j < n; j++) {
181
if(config->A[i][j] != 0) {
182
a[v] = config->A[i][j];
183
asub[v++] = j;
184
}
185
}
186
xa[x++] = v;
187
}
188
189
if(DEBUG) {
190
fprintf(stderr, "\n");
191
for(i = 0; i < nnz; i++)
192
fprintf(stderr, "a[%d] = %.15lf\n", i, a[i]);
193
194
for(i = 0; i < nnz; i++)
195
fprintf(stderr, "asub[%d] = %d\n", i, asub[i]);
196
197
for(i = 0; i < n+1; i++)
198
fprintf(stderr, "xa[%d] = %d\n", i, xa[i]);
199
}
200
201
dCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NR, SLU_D, SLU_GE);
202
203
nrhs = 1;
204
if( !(rhs = doubleMalloc(m * nrhs)) ) ABORT("malloc failed");
205
206
for(i = 0; i < m; i++) {
207
rhs[i] = config->b[i];
208
}
209
210
dCreate_Dense_Matrix(&B, m, nrhs, rhs, m, SLU_DN, SLU_D, SLU_GE);
211
212
if( !(perm_r = intMalloc(m)) ) ABORT("malloc failed");
213
if( !(perm_c = intMalloc(n)) ) ABORT("malloc failed");
214
215
set_default_options(&options);
216
options.ColPerm = NATURAL;
217
218
StatInit(&stat);
219
220
dgssv(&options, &A, perm_c, perm_r, &L, &U, &B, &stat, &info);
221
222
if(DEBUG) {
223
//dPrint_CompCol_Matrix("A", &A);
224
//dPrint_Dense_Matrix("B", &B);
225
}
226
227
DNformat *Astore = (DNformat *) B.Store;
228
double *dp = (double *) Astore->nzval;
229
230
for(i = 0; i < n; i++) {
231
config->b[i] = dp[i];
232
if(DEBUG)
233
fprintf(stderr, "config->b[%d] = %e\n", i, config->b[i]);
234
}
235
236
SUPERLU_FREE(rhs);
237
SUPERLU_FREE(perm_r);
238
SUPERLU_FREE(perm_c);
239
Destroy_CompCol_Matrix(&A);
240
Destroy_SuperMatrix_Store(&B);
241
Destroy_SuperNode_Matrix(&L);
242
Destroy_CompCol_Matrix(&U);
243
StatFree(&stat);
244
#else
245
246
gaussj(config->A, config->n_fluid_cells + extra_pressure_nodes, config->b);
247
248
if(DEBUG) {
249
int i;
250
for(i = 0; i < config->n_fluid_cells + extra_pressure_nodes; i++)
251
fprintf(stderr, "config->b[%d] = %e\n", i, config->b[i]);
252
}
253
254
#endif
255
}
256
257
// Parse config's CSV file to build internal array of microchannel network
258
void microchannel_build_network(microchannel_config_t *config) {
259
char line[MAX_LINE_SIZE], str[STR_SIZE];
260
char *cell;
261
int cell_type, i = 0, j = 0;
262
FILE *fp = fopen(config->network_file, "r");
263
264
if(DEBUG)
265
fprintf(stderr, "network_file = %s\n", config->network_file);
266
267
if(!fp) {
268
strncpy(str, "Unable to open ", STR_SIZE);
269
strncat(str, config->network_file, STR_SIZE - strlen(str));
270
strncat(str, "\n", STR_SIZE - strlen(str));
271
fatal(str);
272
}
273
274
int nr = config->num_rows;
275
int nc = config->num_columns;
276
277
if(DEBUG)
278
fprintf(stderr, "num_rows: %d, num_cols: %d\n", nr, nc);
279
280
config->cell_types = calloc(nr, sizeof(int *));
281
282
if (config->cell_types == NULL) {
283
fprintf(stderr, "ERROR: Couldn't allocate space for cell_types array");
284
}
285
286
for(i = 0; i < nr; i++) {
287
config->cell_types[i] = calloc(nc, sizeof(int));
288
289
if (config->cell_types[i] == NULL) {
290
fprintf(stderr, "ERROR: Couldn't allocate space for cell_types[%d] array", i);
291
}
292
}
293
294
// parse network file to build cell_types array
295
i = j = 0;
296
fgets(line, MAX_LINE_SIZE, fp);
297
while(!feof(fp)) {
298
cell = strtok(line, " ,\n");
299
while(cell != NULL) {
300
cell_type = atoi(cell);
301
config->cell_types[i][j] = cell_type;
302
if(DEBUG)
303
fprintf(stderr, "Adding cell %d, %d; type = %d\n", i, j, config->cell_types[i][j]);
304
j++;
305
306
307
if(j > nc) {
308
fclose(fp);
309
sprintf(str, "Microchannel row %d has more cells than num_columns(%d)\n", i, nc);
310
fatal(str);
311
}
312
313
cell = strtok(NULL, " ,\n");
314
}
315
316
i++; j = 0;
317
318
if(i > nr) {
319
fclose(fp);
320
sprintf(str, "Microchannel has more rows than num_rows(%d)\n", nr);
321
fatal(str);
322
}
323
324
fgets(line, MAX_LINE_SIZE, fp);
325
}
326
327
fclose(fp);
328
329
// Create floorplan file for microchannel
330
strcpy(config->floorplan_file, config->network_file);
331
char *ext = strstr(config->floorplan_file, NETWORK_EXTENSION);
332
strcpy(ext, FLOORPLAN_EXTENSION);
333
fp = fopen(config->floorplan_file, "w");
334
335
fprintf(fp, "# Name\tw\th\tx\ty\tc_v\tp\n");
336
for(i = 0; i < nr; i++) {
337
for(j = 0; j < nc; j++) {
338
if(IS_FLUID_CELL(config, i, j)) {
339
// For floorplan files, x = y = 0 is the bottom left corner, but for our parsing i = j = 0 is
340
// the top left cell, so we have to account for that
341
fprintf(fp, "Cell_%d_%d\t%e\t%e\t%e\t%e\t%e\t%e\n", i, j, config->cell_width, config->cell_height,
342
j*config->cell_width, (config->num_rows - i - 1)*config->cell_height, config->coolant_capac,
343
config->coolant_res);
344
}
345
else {
346
fprintf(fp, "Cell_%d_%d\t%e\t%e\t%e\t%e\t%e\t%e\n", i, j, config->cell_width, config->cell_height,
347
j*config->cell_width, (config->num_rows - i - 1)*config->cell_height, config->wall_capac,
348
config->wall_res);
349
}
350
}
351
}
352
353
fclose(fp);
354
355
printf("Creating pressure circuit...\n");
356
build_pressure_matrix(config);
357
printf("Solving pressure circuit...\n");
358
solve_pressure_circuit(config);
359
}
360
361
double hydroC(microchannel_config_t *config) {
362
double h = config->cell_thickness;
363
double w = config->cell_width;
364
double L = config->cell_height;
365
double viscosity = config->coolant_visc;
366
double ret_val;
367
368
if(h == w)
369
ret_val = (0.42229 * pow(h, 4)) / (12 * viscosity * L);
370
else if(h > w)
371
ret_val = ((1 - 0.63*(w / h)) * (pow(w, 3)) * (h)) / (12 * viscosity * L);
372
else
373
ret_val = ((1 - 0.63*(h / w)) * (pow(h, 3)) * (w)) / (12 * viscosity * L);
374
375
return ret_val;
376
}
377
378
void build_pressure_matrix(microchannel_config_t *config) {
379
int i, j;
380
int nr = config->num_rows;
381
int nc = config->num_columns;
382
int **mapping;
383
int n = 0;
384
config->nnz = 0;
385
386
mapping = calloc(nr, sizeof(int *));
387
388
if(mapping == NULL)
389
fatal("Unable to allocate pressure circuit mapping\n");
390
391
for(i = 0; i < nr; i++) {
392
mapping[i] = calloc(nc, sizeof(int));
393
394
if(mapping[i] == NULL) {
395
fatal("Unable to allocate pressure circuit mapping\n");
396
}
397
}
398
399
// Assign unique number to each fluid cell
400
for(i = 0; i < nr; i++) {
401
for(j = 0; j < nc; j++) {
402
if(IS_FLUID_CELL(config, i, j)) {
403
mapping[i][j] = n++;
404
}
405
else
406
mapping[i][j] = -1;
407
}
408
}
409
config->n_fluid_cells = n;
410
config->mapping = mapping;
411
412
// If we're modeling a non-ideal pump, we include one extra node for the pump
413
if(config->pump_internal_res == 0) {
414
extra_pressure_nodes = 0;
415
}
416
else {
417
extra_pressure_nodes = 1;
418
}
419
420
config->A = calloc(config->n_fluid_cells + extra_pressure_nodes, sizeof(double *));
421
422
if(!config->A)
423
fatal("Unable to allocate matrix A for pressure circuit\n");
424
for(i = 0; i < config->n_fluid_cells + extra_pressure_nodes; i++) {
425
config->A[i] = calloc(config->n_fluid_cells, sizeof(double));
426
427
if(!config->A[i])
428
fatal("Unable to allocate matrix A for pressure circuit\n");
429
}
430
431
config->b = calloc(config->n_fluid_cells + extra_pressure_nodes, sizeof(double));
432
433
if(!config->b)
434
fatal("Unable to allocate matrix b for pressure circuit\n");
435
436
437
if(DEBUG) {
438
fprintf(stderr, "Mapping number: %d\n", n);
439
for(i = 0; i < nr; i++) {
440
for(j = 0; j < nc; j++) {
441
fprintf(stderr, "mapping[%d][%d] = %d\n", i, j, mapping[i][j]);
442
}
443
}
444
}
445
446
// Iterate through all cells
447
double diagonal_val = 0;
448
double hydro_conductance = -hydroC(config);
449
for(i = 0; i < nr; i++) {
450
for(j = 0; j < nc; j++) {
451
if(config->cell_types[i][j] == FLUID ||
452
(config->cell_types[i][j] == INLET && config->pump_internal_res != 0)) {
453
// northern cell
454
if(i > 0 && IS_FLUID_CELL(config, i-1, j)) {
455
if(DEBUG)
456
fprintf(stderr, "[%d, %d]: Northern cell. Setting A[%d][%d] = %.15lf\n", i, j, mapping[i][j], mapping[i-1][j], hydro_conductance);
457
458
config->A[mapping[i][j]][mapping[i-1][j]] = hydro_conductance;
459
diagonal_val += hydro_conductance;
460
config->nnz++;
461
}
462
463
// southern cell
464
if(i < nr - 1 && IS_FLUID_CELL(config, i+1, j)) {
465
if(DEBUG)
466
fprintf(stderr, "[%d, %d]: Southern cell. Setting A[%d][%d] = %.15lf\n", i, j, mapping[i][j], mapping[i+1][j], hydro_conductance);
467
468
config->A[mapping[i][j]][mapping[i+1][j]] = hydro_conductance;
469
diagonal_val += hydro_conductance;
470
config->nnz++;
471
}
472
473
// western cell
474
if(j > 0 && IS_FLUID_CELL(config, i, j-1)) {
475
if(DEBUG)
476
fprintf(stderr, "[%d, %d]: Western Cell. Setting A[%d][%d] = %.15lf\n", i, j, mapping[i][j], mapping[i][j-1], hydro_conductance);
477
478
config->A[mapping[i][j]][mapping[i][j-1]] = hydro_conductance;
479
diagonal_val += hydro_conductance;
480
config->nnz++;
481
}
482
483
// eastern cell
484
if(j < nc - 1 && IS_FLUID_CELL(config, i, j+1)) {
485
if(DEBUG)
486
fprintf(stderr, "[%d, %d]: Eastern Cell. Setting A[%d][%d] = %.15lf\n", i, j, mapping[i][j], mapping[i][j+1], hydro_conductance);
487
488
config->A[mapping[i][j]][mapping[i][j+1]] = hydro_conductance;
489
diagonal_val += hydro_conductance;
490
config->nnz++;
491
}
492
493
// diagonal
494
if(DEBUG)
495
fprintf(stderr, "[%d, %d]: Diagonal. Setting A[%d][%d] = %.15lf\n", i, j, mapping[i][j], mapping[i][j], -diagonal_val);
496
497
config->A[mapping[i][j]][mapping[i][j]] = -diagonal_val;
498
config->nnz++;
499
diagonal_val = 0;
500
}
501
502
if(IS_INLET_CELL(config, i, j)) {
503
// Non-ideal pump
504
if(config->pump_internal_res != 0) {
505
if(DEBUG) {
506
fprintf(stderr, "[%d, %d]: Inlet. Setting A[%d][%d] = %e\n", i, j, mapping[i][j], config->n_fluid_cells, -1.0 / config->pump_internal_res);
507
fprintf(stderr, "[%d, %d]: Inlet. Setting A[%d][%d] = %e\n", i, j, mapping[i][j], mapping[i][j], 1.0 / config->pump_internal_res);
508
}
509
510
// Inlet cells are connected to the pump through the pump's internal
511
// resistance
512
config->A[mapping[i][j]][config->n_fluid_cells] = -1.0 / config->pump_internal_res;
513
config->A[mapping[i][j]][mapping[i][j]] += 1.0 / config->pump_internal_res;
514
config->nnz++; // diagonal val already exists, so we're only adding one nonzero value
515
}
516
517
// Ideal pump
518
else {
519
if(DEBUG) {
520
fprintf(stderr, "[%d, %d]: Inlet. Setting A[%d][%d] = %e\n", i, j, mapping[i][j], mapping[i][j], 1.0);
521
fprintf(stderr, "[%d, %d]: Inlet. Setting b[%d] = %e\n", i, j, mapping[i][j], config->pumping_pressure);
522
}
523
config->A[mapping[i][j]][mapping[i][j]] = 1.0;
524
config->b[mapping[i][j]] = config->pumping_pressure;
525
config->nnz++;
526
}
527
}
528
529
else if(IS_OUTLET_CELL(config, i, j)) {
530
if(DEBUG)
531
fprintf(stderr, "[%d, %d]: OUTLET. Setting A[%d][%d] = 1\n", i, j, mapping[i][j], mapping[i][j]);
532
533
config->A[mapping[i][j]][mapping[i][j]] = 1;
534
config->nnz++;
535
}
536
}
537
}
538
539
if(config->pump_internal_res != 0) {
540
if(DEBUG) {
541
fprintf(stderr, "Pump Node. Setting A[%d][%d] = %e\n", config->n_fluid_cells, config->n_fluid_cells, 1.0);
542
fprintf(stderr, "Pump Node. Setting b[%d] = %e\n", config->n_fluid_cells, config->pumping_pressure);
543
}
544
545
// Handle extra node representing pump
546
config->A[config->n_fluid_cells][config->n_fluid_cells] = 1;
547
config->b[config->n_fluid_cells] = config->pumping_pressure;
548
config->nnz++;
549
}
550
551
if(DEBUG) {
552
fprintf(stderr, "Nonzero values (%d total):\n", config->nnz);
553
for(i = 0; i < config->n_fluid_cells + extra_pressure_nodes; i++) {
554
for(j = 0; j < config->n_fluid_cells + extra_pressure_nodes; j++) {
555
if(config->A[i][j] != 0)
556
fprintf(stderr, "A[%d][%d] = %e\n", i, j, config->A[i][j]);
557
}
558
}
559
560
if(DEBUG)
561
for(i = 0; i < config->n_fluid_cells + extra_pressure_nodes; i++)
562
fprintf(stderr, "b[%d] = %e\n", i, config->b[i]);
563
564
}
565
}
566
567
double flow_rate(microchannel_config_t * config, int cell1_i, int cell1_j, int cell2_i, int cell2_j) {
568
double *pressure = config->b;
569
int **mapping = config->mapping;
570
return (pressure[mapping[cell1_i][cell1_j]] - pressure[mapping[cell2_i][cell2_j]]) * hydroC(config);
571
}
572
573
// Copy user-defined parameters from one microchannel config to another
574
void copy_microchannel(microchannel_config_t *dst, microchannel_config_t *src) {
575
dst->pumping_pressure = src->pumping_pressure;
576
dst->pump_internal_res = src->pump_internal_res;
577
dst->inlet_temperature = src->inlet_temperature;
578
dst->coolant_capac = src->coolant_capac;
579
dst->coolant_res = src->coolant_res;
580
dst->coolant_visc = src->coolant_visc;
581
dst->wall_capac = src->wall_capac;
582
dst->wall_res = src->wall_res;
583
dst->htc = src->htc;
584
}
585
586
void free_microchannel(microchannel_config_t *config) {
587
int i;
588
if(config) {
589
if(config->cell_types) {
590
for(i = 0; i < config->num_rows; i++) {
591
free(config->cell_types[i]);
592
}
593
free(config->cell_types);
594
}
595
596
if(config->A) {
597
for(i = 0; i < config->n_fluid_cells; i++) {
598
free(config->A[i]);
599
}
600
free(config->A);
601
}
602
603
if(config->b) {
604
free(config->b);
605
}
606
607
if(config->mapping) {
608
for(i = 0; i < config->num_rows; i++) {
609
free(config->mapping[i]);
610
}
611
free(config->mapping);
612
}
613
614
free(config);
615
}
616
}
617
618