HyPar  1.0
Finite-Difference Hyperbolic-Parabolic PDE Solver on Cartesian Grids
ComputeRHSOperators.c
Go to the documentation of this file.
1 
5 #ifdef compute_rhs_operators
6 
7 #include <basic.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <arrayfunctions.h>
12 #include <mathfunctions.h>
13 #include <mpivars.h>
14 #include <hypar.h>
15 
51  void *s,
52  void *m,
53  double t
54  )
55 {
56  HyPar *solver = (HyPar*) s;
57  MPIVariables *mpi = (MPIVariables*) m;
58  int i, j, size, ndof;
59  double *f, *f0, *u, *u0, *rhs, *drhs;
60  FILE *fout;
61  char filename[_MAX_STRING_SIZE_];
62 
63  if (mpi->nproc > 1) return(0);
64 
65  int ndims = solver->ndims;
66  int nvars = solver->nvars;
67  int ghosts = solver->ghosts;
68  int *dim = solver->dim_local;
69  int index[ndims];
70 
71  double epsilon = 1e-6;
72  double tolerance = 1e-15;
73 
74  /* allocate arrays */
75  size = solver->npoints_local_wghosts * nvars;
76  u = (double*) calloc (size,sizeof(double));
77  u0 = (double*) calloc (size,sizeof(double));
78  rhs = (double*) calloc (size,sizeof(double));
79  drhs = (double*) calloc (size,sizeof(double));
80  ndof = solver->npoints_local * nvars;
81  f = (double*) calloc (ndof,sizeof(double));
82  f0 = (double*) calloc (ndof,sizeof(double));
83 
84  /* copy the current solution to u0 */
85  _ArrayCopy1D_(solver->u,u0,size);
86  /* apply boundary conditions to the solution u0 */
87  IERR solver->ApplyBoundaryConditions(solver,mpi,u0,NULL,t);CHECKERR(ierr);
88  IERR solver->ApplyIBConditions(solver,mpi,u0,t);CHECKERR(ierr);
89  IERR MPIExchangeBoundariesnD(ndims,nvars,dim,ghosts,mpi,u0); CHECKERR(ierr);
90 
91  /* compute linearized matrix for the hyperbolic FFunction */
92  if (solver->FFunction) {
93  strcpy(filename,"Mat_FFunction_");
94  strcat(filename,solver->filename_index);
95  strcat(filename,".dat");
96  printf("ComputeRHSOperators(): Computing linearized matrix operator for FFunction. ndof=%d.\n",ndof);
97  printf("ComputeRHSOperators(): Writing to sparse matrix file %s.\n",filename);
98  fout = fopen(filename,"w");
99  fprintf(fout,"%d\n",ndof);
100  /* compute the FFunction of u0 */
101  _ArraySetValue_(f0,ndof,0.0);
102  IERR solver->HyperbolicFunction(rhs,u0,solver,mpi,t,1,solver->FFunction,
103  solver->Upwind); CHECKERR(ierr);
104  _ArrayScale1D_(rhs,-1.0,size);
105  /* transfer to an array f0 which as no ghost points */
106  IERR ArrayCopynD(ndims,rhs,f0,dim,ghosts,0,index,nvars); CHECKERR(ierr);
107  for (i=0; i<ndof; i++) {
108  /* copy the solution u0 to u */
109  _ArrayCopy1D_(u0,u,size);
110  /* find the 1D index p in an array with ghosts points (u),
111  * corresponding to index i which assumes no ghost points */
112  int ii, p, v;
113  ii = i / nvars;
114  v = i - ii*nvars;
115  _ArrayIndexnD_(ndims,ii,dim,index,0);
116  _ArrayIndex1D_(ndims,dim,index,ghosts,p);
117  /* add a perturbation */
118  u[nvars*p+v] += epsilon;
119  /* apply boundary conditions to the perturbed solution u */
120  IERR solver->ApplyBoundaryConditions(solver,mpi,u,NULL,t);CHECKERR(ierr);
121  IERR solver->ApplyIBConditions(solver,mpi,u,t);CHECKERR(ierr);
122  IERR MPIExchangeBoundariesnD(ndims,nvars,dim,ghosts,mpi,u); CHECKERR(ierr);
123  /* compute the FFunction of u */
124  IERR solver->HyperbolicFunction(rhs,u,solver,mpi,t,1,solver->FFunction,
125  solver->Upwind); CHECKERR(ierr);
126  _ArrayScale1D_(rhs,-1.0,size);
127  /* transfer to an array f which as no ghost points */
128  _ArraySetValue_(f,ndof,0.0);
129  IERR ArrayCopynD(ndims,rhs,f,dim,ghosts,0,index,nvars); CHECKERR(ierr);
130  /* subtract f0 from f */
131  _ArrayAXPY_(f0,-1.0,f,ndof);
132  /* f is now espilon*column of the matrix */
133  for (j=0; j<ndof; j++) {
134  double mat_elem = f[j] / epsilon;
135  /* write to file if element is non-zero */
136  if (absolute(mat_elem) > tolerance) fprintf(fout,"%5d %5d %+1.16e\n",j+1,i+1,mat_elem);
137  }
138  }
139  fclose(fout);
140  }
141  /* compute linearized matrix for the split hyperbolic (FFunction-dFFunction) and dFFunction
142  functions, if dFFunction is available */
143  if (solver->dFFunction) {
144  strcpy(filename,"Mat_FdFFunction_");
145  strcat(filename,solver->filename_index);
146  strcat(filename,".dat");
147  printf("ComputeRHSOperators(): Computing linearized matrix operator for (FFunction-dFFunction). ndof=%d.\n",ndof);
148  printf("ComputeRHSOperators(): Writing to sparse matrix file %s.\n",filename);
149  fout = fopen(filename,"w");
150  fprintf(fout,"%d\n",ndof);
151  /* compute the FFunction of u0 */
152  _ArraySetValue_(f0,ndof,0.0);
153  if (solver->flag_fdf_specified) {
154  IERR solver->HyperbolicFunction(rhs,u0,solver,mpi,t,1,solver->FdFFunction,
155  solver->UpwindFdF); CHECKERR(ierr);
156  _ArrayScale1D_(rhs,-1.0,size);
157  } else {
158  IERR solver->HyperbolicFunction(rhs,u0,solver,mpi,t,1,solver->FFunction,
159  solver->Upwind); CHECKERR(ierr);
160  IERR solver->HyperbolicFunction(drhs,u0,solver,mpi,t,0,solver->dFFunction,
161  solver->UpwinddF); CHECKERR(ierr);
162  _ArrayScale1D_(rhs,-1.0,size);
163  _ArrayAXPY_(drhs,1.0,rhs,size);
164  }
165  /* transfer to an array f0 which as no ghost points */
166  IERR ArrayCopynD(ndims,rhs,f0,dim,ghosts,0,index,nvars); CHECKERR(ierr);
167  for (i=0; i<ndof; i++) {
168  /* copy the solution u0 to u */
169  _ArrayCopy1D_(u0,u,size);
170  /* find the 1D index p in an array with ghosts points (u),
171  * corresponding to index i which assumes no ghost points */
172  int ii, p, v;
173  ii = i / nvars;
174  v = i - ii*nvars;
175  _ArrayIndexnD_(ndims,ii,dim,index,0);
176  _ArrayIndex1D_(ndims,dim,index,ghosts,p);
177  /* add a perturbation */
178  u[nvars*p+v] += epsilon;
179  /* apply boundary conditions to the perturbed solution u */
180  IERR solver->ApplyBoundaryConditions(solver,mpi,u,NULL,t);CHECKERR(ierr);
181  IERR solver->ApplyIBConditions(solver,mpi,u,t);CHECKERR(ierr);
182  IERR MPIExchangeBoundariesnD(ndims,nvars,dim,ghosts,mpi,u); CHECKERR(ierr);
183  /* compute the FFunction of u */
184  if (solver->flag_fdf_specified) {
185  IERR solver->HyperbolicFunction(rhs,u,solver,mpi,t,1,solver->FdFFunction,
186  solver->UpwindFdF); CHECKERR(ierr);
187  _ArrayScale1D_(rhs,-1.0,size);
188  } else {
189  IERR solver->HyperbolicFunction(rhs,u,solver,mpi,t,1,solver->FFunction,
190  solver->Upwind); CHECKERR(ierr);
191  IERR solver->HyperbolicFunction(drhs,u,solver,mpi,t,0,solver->dFFunction,
192  solver->UpwinddF); CHECKERR(ierr);
193  _ArrayScale1D_(rhs,-1.0,size);
194  _ArrayAXPY_(drhs,1.0,rhs,size);
195  }
196  /* transfer to an array f which as no ghost points */
197  _ArraySetValue_(f,ndof,0.0);
198  IERR ArrayCopynD(ndims,rhs,f,dim,ghosts,0,index,nvars); CHECKERR(ierr);
199  /* subtract f0 from f */
200  _ArrayAXPY_(f0,-1.0,f,ndof);
201  /* f is now espilon*column of the matrix */
202  for (j=0; j<ndof; j++) {
203  double mat_elem = f[j] / epsilon;
204  /* write to file if element is non-zero */
205  if (absolute(mat_elem) > tolerance) fprintf(fout,"%5d %5d %+1.16e\n",j+1,i+1,mat_elem);
206  }
207  }
208  fclose(fout);
209 
210  strcpy(filename,"Mat_dFFunction_");
211  strcat(filename,solver->filename_index);
212  strcat(filename,".dat");
213  printf("ComputeRHSOperators(): Computing linearized matrix operator for dFFunction. ndof=%d.\n",ndof);
214  printf("ComputeRHSOperators(): Writing to sparse matrix file %s.\n",filename);
215  fout = fopen(filename,"w");
216  fprintf(fout,"%d\n",ndof);
217  /* compute the FFunction of u0 */
218  _ArraySetValue_(f0,ndof,0.0);
219  IERR solver->HyperbolicFunction(rhs,u0,solver,mpi,t,0,solver->dFFunction,
220  solver->UpwinddF); CHECKERR(ierr);
221  _ArrayScale1D_(rhs,-1.0,size);
222  /* transfer to an array f0 which as no ghost points */
223  IERR ArrayCopynD(ndims,rhs,f0,dim,ghosts,0,index,nvars); CHECKERR(ierr);
224  for (i=0; i<ndof; i++) {
225  /* copy the solution u0 to u */
226  _ArrayCopy1D_(u0,u,size);
227  /* find the 1D index p in an array with ghosts points (u),
228  * corresponding to index i which assumes no ghost points */
229  int ii, p, v;
230  ii = i / nvars;
231  v = i - ii*nvars;
232  _ArrayIndexnD_(ndims,ii,dim,index,0);
233  _ArrayIndex1D_(ndims,dim,index,ghosts,p);
234  /* add a perturbation */
235  u[nvars*p+v] += epsilon;
236  /* apply boundary conditions to the perturbed solution u */
237  IERR solver->ApplyBoundaryConditions(solver,mpi,u,NULL,t);CHECKERR(ierr);
238  IERR solver->ApplyIBConditions(solver,mpi,u,t);CHECKERR(ierr);
239  IERR MPIExchangeBoundariesnD(ndims,nvars,dim,ghosts,mpi,u); CHECKERR(ierr);
240  /* compute the FFunction of u */
241  IERR solver->HyperbolicFunction(rhs,u,solver,mpi,t,0,solver->dFFunction,
242  solver->UpwinddF); CHECKERR(ierr);
243  _ArrayScale1D_(rhs,-1.0,size);
244  /* transfer to an array f which as no ghost points */
245  _ArraySetValue_(f,ndof,0.0);
246  IERR ArrayCopynD(ndims,rhs,f,dim,ghosts,0,index,nvars); CHECKERR(ierr);
247  /* subtract f0 from f */
248  _ArrayAXPY_(f0,-1.0,f,ndof);
249  /* f is now espilon*column of the matrix */
250  for (j=0; j<ndof; j++) {
251  double mat_elem = f[j] / epsilon;
252  /* write to file if element is non-zero */
253  if (absolute(mat_elem) > tolerance) fprintf(fout,"%5d %5d %+1.16e\n",j+1,i+1,mat_elem);
254  }
255  }
256  fclose(fout);
257  }
258 
259  /* compute linearized matrix for the source SFunction */
260  if (solver->SFunction) {
261  strcpy(filename,"Mat_SFunction_");
262  strcat(filename,solver->filename_index);
263  strcat(filename,".dat");
264  printf("ComputeRHSOperators(): Computing linearized matrix operator for SFunction. ndof=%d.\n",ndof);
265  printf("ComputeRHSOperators(): Writing to sparse matrix file %s.\n",filename);
266  fout = fopen(filename,"w");
267  fprintf(fout,"%d\n",ndof);
268  /* compute the FFunction of u0 */
269  _ArraySetValue_(f0,ndof,0.0);
270  IERR solver->SourceFunction(rhs,u0,solver,mpi,t); CHECKERR(ierr);
271  /* transfer to an array f0 which as no ghost points */
272  IERR ArrayCopynD(ndims,rhs,f0,dim,ghosts,0,index,nvars); CHECKERR(ierr);
273  for (i=0; i<ndof; i++) {
274  /* copy the solution u0 to u */
275  _ArrayCopy1D_(u0,u,size);
276  /* find the 1D index p in an array with ghosts points (u),
277  * corresponding to index i which assumes no ghost points */
278  int ii, p, v;
279  ii = i / nvars;
280  v = i - ii*nvars;
281  _ArrayIndexnD_(ndims,ii,dim,index,0);
282  _ArrayIndex1D_(ndims,dim,index,ghosts,p);
283  /* add a perturbation */
284  u[nvars*p+v] += epsilon;
285  /* apply boundary conditions to the perturbed solution u */
286  IERR solver->ApplyBoundaryConditions(solver,mpi,u,NULL,t);CHECKERR(ierr);
287  IERR solver->ApplyIBConditions(solver,mpi,u,t);CHECKERR(ierr);
288  IERR MPIExchangeBoundariesnD(ndims,nvars,dim,ghosts,mpi,u); CHECKERR(ierr);
289  /* compute the SFunction of u */
290  IERR solver->SourceFunction(rhs,u,solver,mpi,t); CHECKERR(ierr);
291  /* transfer to an array f which as no ghost points */
292  _ArraySetValue_(f,ndof,0.0);
293  IERR ArrayCopynD(ndims,rhs,f,dim,ghosts,0,index,nvars); CHECKERR(ierr);
294  /* subtract f0 from f */
295  _ArrayAXPY_(f0,-1.0,f,ndof);
296  /* f is now espilon*column of the matrix */
297  for (j=0; j<ndof; j++) {
298  double mat_elem = f[j] / epsilon;
299  /* write to file if element is non-zero */
300  if (absolute(mat_elem) > tolerance) fprintf(fout,"%5d %5d %+1.16e\n",j+1,i+1,mat_elem);
301  }
302  }
303  fclose(fout);
304  }
305 
306  /* clean up */
307  free(u);
308  free(u0);
309  free(rhs);
310  free(drhs);
311  free(f);
312  free(f0);
313  return(0);
314 }
315 
316 #endif
#define absolute(a)
Definition: math_ops.h:32
int nvars
Definition: hypar.h:29
#define IERR
Definition: basic.h:16
MPI related function definitions.
char * filename_index
Definition: hypar.h:197
#define CHECKERR(ierr)
Definition: basic.h:18
Contains function definitions for common mathematical functions.
int MPIExchangeBoundariesnD(int, int, int *, int, void *, double *)
int(* ApplyBoundaryConditions)(void *, void *, double *, double *, double)
Definition: hypar.h:214
double * u
Definition: hypar.h:116
Some basic definitions and macros.
int npoints_local
Definition: hypar.h:42
int(* FdFFunction)(double *, double *, int, void *, double)
Definition: hypar.h:286
int(* ApplyIBConditions)(void *, void *, double *, double)
Definition: hypar.h:217
int(* SFunction)(double *, double *, void *, void *, double)
Definition: hypar.h:317
#define _ArrayIndexnD_(N, index, imax, i, ghost)
int(* Upwind)(double *, double *, double *, double *, double *, double *, int, void *, double)
Definition: hypar.h:295
int(* SourceFunction)(double *, double *, void *, void *, double)
Definition: hypar.h:259
int ndims
Definition: hypar.h:26
int(* HyperbolicFunction)(double *, double *, void *, void *, double, int, int(*)(double *, double *, int, void *, double), int(*)(double *, double *, double *, double *, double *, double *, int, void *, double))
Definition: hypar.h:250
int(* FFunction)(double *, double *, int, void *, double)
Definition: hypar.h:276
Structure containing all solver-specific variables and functions.
Definition: hypar.h:23
#define _MAX_STRING_SIZE_
Definition: basic.h:14
#define _ArrayAXPY_(x, a, y, size)
Contains structure definition for hypar.
#define _ArrayIndex1D_(N, imax, i, ghost, index)
INLINE int ArrayCopynD(int, const double *, double *, int *, int, int, int *, int)
int(* UpwindFdF)(double *, double *, double *, double *, double *, double *, int, void *, double)
Definition: hypar.h:307
int flag_fdf_specified
Definition: hypar.h:290
#define _ArraySetValue_(x, size, value)
int * dim_local
Definition: hypar.h:37
int(* dFFunction)(double *, double *, int, void *, double)
Definition: hypar.h:280
int(* UpwinddF)(double *, double *, double *, double *, double *, double *, int, void *, double)
Definition: hypar.h:300
int ghosts
Definition: hypar.h:52
Structure of MPI-related variables.
#define _ArrayScale1D_(x, a, size)
int npoints_local_wghosts
Definition: hypar.h:42
int ComputeRHSOperators(void *s, void *m, double t)
#define _ArrayCopy1D_(x, y, size)
Contains macros and function definitions for common array operations.