Timothy  0.9
Tissue Modelling Framework
 All Data Structures Files Functions Variables Typedefs Macros
tempf.c
Go to the documentation of this file.
1 /* **************************************************************************
2  * This file is part of Timothy
3  *
4  * Copyright (c) 2014/15 Maciej Cytowski
5  * Copyright (c) 2014/15 ICM, University of Warsaw, Poland
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20  *
21  * *************************************************************************/
22 
23 #include "_hypre_utilities.h"
24 #include "HYPRE_sstruct_ls.h"
25 #include "HYPRE_parcsr_ls.h"
26 #include "HYPRE_krylov.h"
27 
28 #include "global.h"
29 #include "fields.h"
30 
35 HYPRE_SStructGrid tempGrid;
36 HYPRE_SStructGraph tempGraph;
37 HYPRE_SStructStencil tempStencil;
38 
39 HYPRE_SStructMatrix A;
40 HYPRE_SStructVector b;
41 HYPRE_SStructVector x;
42 
43 HYPRE_ParCSRMatrix parA;
44 HYPRE_ParVector parb;
45 HYPRE_ParVector parx;
46 
47 HYPRE_Solver tempSolver;
48 HYPRE_Solver tempPrecond;
49 
51 
52 long long tempLower[3], tempUpper[3];
53 long long bcLower[3];
54 long long bcUpper[3];
55 
56 double dt;
57 double tempLambda = 0.25;
58 
59 char tfname[256];
60 
63 
65 
66 HYPRE_SStructVariable tempVartypes[1] = { HYPRE_SSTRUCT_VARIABLE_NODE };
67 
71 void tempSetBoundary(int coord, int boundary)
72 {
73  if (coord == 0 && boundary == -1) {
74  bcLower[0] = tempLower[0];
75  bcUpper[0] = tempLower[0];
76  bcLower[1] = tempLower[1];
77  bcUpper[1] = tempUpper[1];
78  bcLower[2] = tempLower[2];
79  bcUpper[2] = tempUpper[2];
80  }
81  if (coord == 0 && boundary == 1) {
82  bcLower[0] = tempUpper[0];
83  bcUpper[0] = tempUpper[0];
84  bcLower[1] = tempLower[1];
85  bcUpper[1] = tempUpper[1];
86  bcLower[2] = tempLower[2];
87  bcUpper[2] = tempUpper[2];
88  }
89  if (coord == 1 && boundary == -1) {
90  bcLower[0] = tempLower[0];
91  bcUpper[0] = tempUpper[0];
92  bcLower[1] = tempLower[1];
93  bcUpper[1] = tempLower[1];
94  bcLower[2] = tempLower[2];
95  bcUpper[2] = tempUpper[2];
96  }
97  if (coord == 1 && boundary == 1) {
98  bcLower[0] = tempLower[0];
99  bcUpper[0] = tempUpper[0];
100  bcLower[1] = tempUpper[1];
101  bcUpper[1] = tempUpper[1];
102  bcLower[2] = tempLower[2];
103  bcUpper[2] = tempUpper[2];
104  }
105  if (coord == 2 && boundary == -1) {
106  bcLower[0] = tempLower[0];
107  bcUpper[0] = tempUpper[0];
108  bcLower[1] = tempLower[1];
109  bcUpper[1] = tempUpper[1];
110  bcLower[2] = tempLower[2];
111  bcUpper[2] = tempLower[2];
112  }
113  if (coord == 2 && boundary == 1) {
114  bcLower[0] = tempLower[0];
115  bcUpper[0] = tempUpper[0];
116  bcLower[1] = tempLower[1];
117  bcUpper[1] = tempUpper[1];
118  bcLower[2] = tempUpper[2];
119  bcUpper[2] = tempUpper[2];
120  }
121 }
122 
127 {
128  int i, j, k;
129  double z;
130  int entry;
131  long long offsets[7][3] =
132  { {0, 0, 0}, {-1, 0, 0}, {1, 0, 0}, {0, -1, 0}, {0, 1, 0}, {0, 0,
133  -1}, {0,
134  0,
135  1}
136  };
137 
138  dt = 0.1;
139  tempIter = 0;
140  tempNVars = 1;
141  tempNParts = 1;
142 
143  sprintf(tfname, "%s/tempSolver.log", logdir);
144  /* stdout redirected to file */
146 
147  /* 1. INIT GRID */
148 
149  /* create an empty 3D grid object */
150  HYPRE_SStructGridCreate(MPI_CART_COMM, 3, tempNParts, &tempGrid);
151 
152  /* set this process box */
156 
160 
161  /* add a new box to the grid */
162  HYPRE_SStructGridSetExtents(tempGrid, 0, tempLower, tempUpper);
163 
164  HYPRE_SStructGridSetVariables(tempGrid, 0, tempNVars, tempVartypes);
165  HYPRE_SStructGridAssemble(tempGrid);
166 
167  /* 2. INIT STENCIL */
168  HYPRE_SStructStencilCreate(3, 7, &tempStencil);
169  for (entry = 0; entry < 7; entry++)
170  HYPRE_SStructStencilSetEntry(tempStencil, entry, offsets[entry], 0);
171 
172  /* 3. SET UP THE GRAPH */
173  tempObjectType = HYPRE_PARCSR;
174  HYPRE_SStructGraphCreate(MPI_CART_COMM, tempGrid, &tempGraph);
175  HYPRE_SStructGraphSetObjectType(tempGraph, tempObjectType);
176  HYPRE_SStructGraphSetStencil(tempGraph, 0, 0, tempStencil);
177  HYPRE_SStructGraphAssemble(tempGraph);
178 
179  /* 4. SET UP MATRIX */
180  long long nentries = 7;
181  long long nvalues;
182  double *values;
183  long long stencil_indices[7];
184 
185  nvalues = nentries * gridSize.x * gridSize.y * gridSize.z;
186  /* create an empty matrix object */
187  HYPRE_SStructMatrixCreate(MPI_CART_COMM, tempGraph, &A);
188  HYPRE_SStructMatrixSetObjectType(A, tempObjectType);
189  /* indicate that the matrix coefficients are ready to be set */
190  HYPRE_SStructMatrixInitialize(A);
191 
192  values = calloc(nvalues, sizeof(double));
193 
194  for (j = 0; j < nentries; j++)
195  stencil_indices[j] = j;
196 
197  z = dt / (gridResolution * gridResolution);
198 
199  /* set the standard stencil at each grid point,
200  * we will fix the boundaries later */
201  for (i = 0; i < nvalues; i += nentries) {
202  values[i] = 1 + 6.0 * z;
203  for (j = 1; j < nentries; j++)
204  values[i + j] = -z;
205  }
206 
207  HYPRE_SStructMatrixSetBoxValues(A, 0, tempLower, tempUpper, 0, nentries,
208  stencil_indices, values);
209 
210  free(values);
211  /* stdout brought back */
212  revertStdOut();
213 }
214 
220 {
221  int i, j, k;
222  int m;
223  int nvalues;
224  int nentries;
225  double *values, *bvalues;
226  double z;
227  z = dt / (gridResolution * gridResolution);
228  /* stdout redirected to file */
230 
231  /* 5. SETUP STRUCT VECTORS FOR B AND X */
232  nvalues = gridSize.x * gridSize.y * gridSize.z;
233 
234  values = calloc(nvalues, sizeof(double));
235 
236  /* create an empty vector object */
237  HYPRE_SStructVectorCreate(MPI_CART_COMM, tempGrid, &b);
238  HYPRE_SStructVectorCreate(MPI_CART_COMM, tempGrid, &x);
239 
240  /* as with the matrix, set the appropriate object type for the vectors */
241  HYPRE_SStructVectorSetObjectType(b, tempObjectType);
242  HYPRE_SStructVectorSetObjectType(x, tempObjectType);
243 
244  /* indicate that the vector coefficients are ready to be set */
245  HYPRE_SStructVectorInitialize(b);
246  HYPRE_SStructVectorInitialize(x);
247 
248  /* set the values */
249  m = 0;
250  for (k = tempLower[2]; k <= tempUpper[2]; k++)
251  for (j = tempLower[1]; j <= tempUpper[1]; j++)
252  for (i = tempLower[0]; i <= tempUpper[0]; i++) {
253  values[m] = fieldICMean[TEMP];
254  m++;
255  }
256 
257  HYPRE_SStructVectorSetBoxValues(b, 0, tempLower, tempUpper, 0, values);
258 
259  m = 0;
260  for (k = tempLower[2]; k <= tempUpper[2]; k++)
261  for (j = tempLower[1]; j <= tempUpper[1]; j++)
262  for (i = tempLower[0]; i <= tempUpper[0]; i++) {
263  values[m] = fieldICMean[TEMP];
264  m++;
265  }
266 
267  HYPRE_SStructVectorSetBoxValues(x, 0, tempLower, tempUpper, 0, values);
268 
269  free(values);
270 
271  /* incorporate boundary conditions; Dirichlet on 1 face; Robin on 7 other faces (low X) */
272 
273  /* Robin conditions */
274  nentries = 3;
275  long long stencilRindices[3];
276  int Nmax;
277  Nmax = 0;
278  Nmax = (Nmax < gridSize.x ? gridSize.x : Nmax);
279  Nmax = (Nmax < gridSize.y ? gridSize.y : Nmax);
280  Nmax = (Nmax < gridSize.z ? gridSize.z : Nmax);
281  values = calloc(nentries * Nmax * Nmax, sizeof(double));
282  bvalues = calloc(Nmax * Nmax, sizeof(double));
283 
284  for (i = 0; i < Nmax * Nmax; i++)
285  bvalues[i] = 2.0 * z * gridResolution * tempLambda * fieldICMean[TEMP];
286 
287  if (MPIcoords[MPIrank][0] == MPIdim[0] - 1) {
288  nvalues = nentries * gridSize.y * gridSize.z;
289  for (i = 0; i < nvalues; i += nentries) {
290  values[i] = 2.0 * z * gridResolution * tempLambda;
291  values[i + 1] = z;
292  values[i + 2] = -z;
293  }
294 
295  tempSetBoundary(0, 1);
296 
297  stencilRindices[0] = 0;
298  stencilRindices[1] = 2;
299  stencilRindices[2] = 1;
300 
301  HYPRE_SStructMatrixAddToBoxValues(A, 0, bcLower, bcUpper, 0, nentries,
302  stencilRindices, values);
303 
304  HYPRE_SStructVectorAddToBoxValues(b, 0, bcLower, bcUpper, 0, bvalues);
305 
306  }
307 
308  if (MPIcoords[MPIrank][1] == 0) {
309  nvalues = nentries * gridSize.x * gridSize.z;
310  for (i = 0; i < nvalues; i += nentries) {
311  values[i] = 2.0 * z * gridResolution * tempLambda;
312  values[i + 1] = z;
313  values[i + 2] = -z;
314  }
315 
316  tempSetBoundary(1, -1);
317 
318  stencilRindices[0] = 0;
319  stencilRindices[1] = 3;
320  stencilRindices[2] = 4;
321 
322  HYPRE_SStructMatrixAddToBoxValues(A, 0, bcLower, bcUpper, 0, nentries,
323  stencilRindices, values);
324 
325  HYPRE_SStructVectorAddToBoxValues(b, 0, bcLower, bcUpper, 0, bvalues);
326 
327  }
328 
329  if (MPIcoords[MPIrank][1] == MPIdim[1] - 1) {
330  nvalues = nentries * gridSize.x * gridSize.z;
331  for (i = 0; i < nvalues; i += nentries) {
332  values[i] = 2.0 * z * gridResolution * tempLambda;
333  values[i + 1] = z;
334  values[i + 2] = -z;
335  }
336 
337  tempSetBoundary(1, 1);
338 
339  stencilRindices[0] = 0;
340  stencilRindices[1] = 4;
341  stencilRindices[2] = 3;
342 
343  HYPRE_SStructMatrixAddToBoxValues(A, 0, bcLower, bcUpper, 0, nentries,
344  stencilRindices, values);
345 
346  HYPRE_SStructVectorAddToBoxValues(b, 0, bcLower, bcUpper, 0, bvalues);
347 
348  }
349 
350  if (MPIcoords[MPIrank][2] == 0) {
351  nvalues = nentries * gridSize.x * gridSize.y;
352  for (i = 0; i < nvalues; i += nentries) {
353  values[i] = 2.0 * z * gridResolution * tempLambda;
354  values[i + 1] = z;
355  values[i + 2] = -z;
356  }
357 
358  tempSetBoundary(2, -1);
359 
360  stencilRindices[0] = 0;
361  stencilRindices[1] = 5;
362  stencilRindices[2] = 6;
363 
364  HYPRE_SStructMatrixAddToBoxValues(A, 0, bcLower, bcUpper, 0, nentries,
365  stencilRindices, values);
366 
367  HYPRE_SStructVectorAddToBoxValues(b, 0, bcLower, bcUpper, 0, bvalues);
368 
369  }
370 
371  if (MPIcoords[MPIrank][2] == MPIdim[2] - 1) {
372  nvalues = nentries * gridSize.x * gridSize.y;
373  for (i = 0; i < nvalues; i += nentries) {
374  values[i] = 2.0 * z * gridResolution * tempLambda;
375  values[i + 1] = z;
376  values[i + 2] = -z;
377  }
378 
379  tempSetBoundary(2, 1);
380 
381  stencilRindices[0] = 0;
382  stencilRindices[1] = 6;
383  stencilRindices[2] = 5;
384 
385  HYPRE_SStructMatrixAddToBoxValues(A, 0, bcLower, bcUpper, 0, nentries,
386  stencilRindices, values);
387 
388  HYPRE_SStructVectorAddToBoxValues(b, 0, bcLower, bcUpper, 0, bvalues);
389 
390  }
391 
392  free(values);
393  free(bvalues);
394 
395  /* Dirichlet conditions */
396  if (MPIcoords[MPIrank][0] == 0) {
397 
398  int nentries = 1;
399  long long stencilDindices[1];
400  nvalues = nentries * gridSize.y * gridSize.z;
401  values = calloc(nvalues, sizeof(double));
402  bvalues = calloc(nvalues, sizeof(double));
403  for (i = 0; i < nvalues; i++)
404  values[i] = z;
405 
406  tempSetBoundary(0, -1);
407 
408  stencilDindices[0] = 1;
409 
410  HYPRE_SStructMatrixAddToBoxValues(A, 0, bcLower, bcUpper, 0, nentries,
411  stencilDindices, values);
412 
413  for (i = 0; i < nvalues; i++)
414  bvalues[i] = z * fieldBC[TEMP];
415 
416  HYPRE_SStructVectorAddToBoxValues(b, 0, bcLower, bcUpper, 0, bvalues);
417 
418  free(values);
419  free(bvalues);
420  }
421  /* stdout brought back */
422  revertStdOut();
423 }
424 
429 {
430  /* stdout redirected to file */
432 
433  HYPRE_SStructMatrixAssemble(A);
434  /* This is a collective call finalizing the vector assembly.
435  The vector is now ``ready to be used'' */
436  HYPRE_SStructVectorAssemble(b);
437  HYPRE_SStructVectorAssemble(x);
438 
439  HYPRE_SStructMatrixGetObject(A, (void **) &parA);
440  HYPRE_SStructVectorGetObject(b, (void **) &parb);
441  HYPRE_SStructVectorGetObject(x, (void **) &parx);
442 
443  HYPRE_ParCSRPCGCreate(MPI_CART_COMM, &tempSolver);
444  HYPRE_ParCSRPCGSetTol(tempSolver, 1.0e-12);
445  HYPRE_ParCSRPCGSetPrintLevel(tempSolver, 2);
446  HYPRE_ParCSRPCGSetMaxIter(tempSolver, 50);
447 
448  HYPRE_BoomerAMGCreate(&tempPrecond);
449  HYPRE_BoomerAMGSetMaxIter(tempPrecond, 1);
450  HYPRE_BoomerAMGSetTol(tempPrecond, 0.0);
451  HYPRE_BoomerAMGSetPrintLevel(tempPrecond, 2);
452  HYPRE_BoomerAMGSetCoarsenType(tempPrecond, 6);
453  HYPRE_BoomerAMGSetRelaxType(tempPrecond, 6);
454  HYPRE_BoomerAMGSetNumSweeps(tempPrecond, 1);
455 
456  HYPRE_ParCSRPCGSetPrecond(tempSolver, HYPRE_BoomerAMGSolve,
457  HYPRE_BoomerAMGSetup, tempPrecond);
458  HYPRE_ParCSRPCGSetup(tempSolver, parA, parb, parx);
459  /* stdout brought back */
460  revertStdOut();
461 }
462 
468 {
469 
470  int i, j, k;
471  int idx;
472  double z;
473  double *values;
474  long long nvalues = gridSize.x * gridSize.y * gridSize.z;
475  z = dt / (gridResolution * gridResolution);
476  /* stdout redirected to file */
478 
479  if (tempIter > 0) {
480 
481  /* update right hand side */
482 
483  values = calloc(nvalues, sizeof(double));
484 
485  HYPRE_SStructVectorGetBoxValues(x, 0, tempLower, tempUpper, 0, values);
486  HYPRE_SStructVectorSetBoxValues(b, 0, tempLower, tempUpper, 0, values);
487 
488  for (i = 0; i < nvalues; i++)
489  values[i] =
490  2.0 * z * gridResolution * tempLambda * fieldICMean[TEMP];
491 
492  if (MPIcoords[MPIrank][0] == MPIdim[0] - 1) {
493  tempSetBoundary(0, 1);
494  HYPRE_SStructVectorAddToBoxValues(b, 0, bcLower, bcUpper, 0, values);
495  }
496  if (MPIcoords[MPIrank][1] == 0) {
497  tempSetBoundary(1, -1);
498  HYPRE_SStructVectorAddToBoxValues(b, 0, bcLower, bcUpper, 0, values);
499  }
500  if (MPIcoords[MPIrank][1] == MPIdim[1] - 1) {
501  tempSetBoundary(1, 1);
502  HYPRE_SStructVectorAddToBoxValues(b, 0, bcLower, bcUpper, 0, values);
503  }
504  if (MPIcoords[MPIrank][2] == 0) {
505  tempSetBoundary(2, -1);
506  HYPRE_SStructVectorAddToBoxValues(b, 0, bcLower, bcUpper, 0, values);
507  }
508  if (MPIcoords[MPIrank][2] == MPIdim[2] - 1) {
509  tempSetBoundary(2, 1);
510  HYPRE_SStructVectorAddToBoxValues(b, 0, bcLower, bcUpper, 0, values);
511  }
512 
513  if (MPIcoords[MPIrank][0] == 0) {
514  int nentries = 1;
515  long long nvalues;
516  nvalues = gridSize.x * gridSize.y * gridSize.z;
517  for (i = 0; i < nvalues; i++)
518  values[i] = z * fieldBC[TEMP];
519 
520  tempSetBoundary(0, -1);
521 
522  HYPRE_SStructVectorAddToBoxValues(b, 0, bcLower, bcUpper, 0, values);
523  }
524  free(values);
525 
526  HYPRE_SStructVectorAssemble(b);
527  HYPRE_SStructVectorAssemble(x);
528 
529  }
530 
531  HYPRE_ParCSRPCGSolve(tempSolver, parA, parb, parx);
532 
533  /* copy solution to field buffer */
534  HYPRE_SStructVectorGather(x);
535  values = calloc(nvalues, sizeof(double));
536  HYPRE_SStructVectorGetBoxValues(x, 0, tempLower, tempUpper, 0, values);
537  idx = 0;
538  for (k = 0; k < gridSize.z; k++)
539  for (j = 0; j < gridSize.y; j++)
540  for (i = 0; i < gridSize.x; i++, idx++)
541  tempField[gridSize.y * gridSize.z * i + gridSize.z * j + k] =
542  values[idx];
543  free(values);
544 
545  tempIter++;
546  /* stdout brought back */
547  revertStdOut();
548 }
int64_t x
Definition: global.h:229
int MPIdim[3]
Definition: global.h:136
int MPIrank
Definition: global.h:134
double * tempField
Definition: fields.h:76
HYPRE_SStructVector x
Definition: tempf.c:41
HYPRE_SStructGraph tempGraph
Definition: tempf.c:36
int tempIter
Definition: tempf.c:64
struct int64Vector3d * gridEndIdx
Definition: fields.h:42
HYPRE_SStructStencil tempStencil
Definition: tempf.c:37
long long tempUpper[3]
Definition: tempf.c:52
HYPRE_Solver tempSolver
Definition: tempf.c:47
void tempEnvInitSystem()
Definition: tempf.c:126
int tempNParts
Definition: tempf.c:62
HYPRE_SStructVector b
Definition: tempf.c:40
int64_t z
Definition: global.h:231
contains the most important global variables, arrays and defines
float m
Definition: global.h:188
int tempObjectType
Definition: tempf.c:50
double tempLambda
Definition: tempf.c:57
void switchStdOut(const char *newStream)
Definition: io.c:1790
long long bcUpper[3]
Definition: tempf.c:54
HYPRE_SStructGrid tempGrid
Definition: tempf.c:35
long long tempLower[3]
Definition: tempf.c:52
HYPRE_SStructMatrix A
Definition: tempf.c:39
struct int64Vector3d gridSize
Definition: fields.h:41
char logdir[128]
Definition: global.h:167
HYPRE_ParVector parb
Definition: tempf.c:44
double fieldBC[NFIELDS]
Definition: fields.h:57
int tempNVars
Definition: tempf.c:61
HYPRE_Solver tempPrecond
Definition: tempf.c:48
double dt
Definition: tempf.c:56
long long bcLower[3]
Definition: tempf.c:53
void tempSetBoundary(int coord, int boundary)
Definition: tempf.c:71
HYPRE_ParCSRMatrix parA
Definition: tempf.c:43
HYPRE_SStructVariable tempVartypes[1]
Definition: tempf.c:66
struct int64Vector3d * gridStartIdx
Definition: fields.h:42
double gridResolution
Definition: fields.h:45
void revertStdOut()
Definition: io.c:1803
double fieldICMean[NFIELDS]
Definition: fields.h:58
void tempEnvSolve()
Definition: tempf.c:467
void tempEnvInitSolver()
Definition: tempf.c:428
int64_t y
Definition: global.h:230
contains variables and arrays for global fields
void tempEnvInitBC()
Definition: tempf.c:219
int ** MPIcoords
Definition: global.h:144
#define TEMP
Definition: fields.h:82
HYPRE_ParVector parx
Definition: tempf.c:45
char tfname[256]
Definition: tempf.c:59
MPI_Comm MPI_CART_COMM
Definition: global.h:143