/* nag_pde_parab_1d_fd (d03pcc) Example Program.
*
* Copyright 2014 Numerical Algorithms Group.
*
* Mark 7, 2001.
* Mark 7b revised, 2004.
* Mark 23 revised, 2011.
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <nag.h>
#include <nag_stdlib.h>
#include <nagd03.h>
#include <nagx01.h>
#ifdef __cplusplus
extern "C" {
#endif
static void NAG_CALL pdedef(Integer, double, double, const double[],
const double[], double[], double[], double[],
Integer *, Nag_Comm *);
static void NAG_CALL bndary(Integer, double, const double[], const double[],
Integer, double[], double[], Integer *, Nag_Comm *);
static int NAG_CALL uinit(double *, double *, Integer, Integer, double);
#ifdef __cplusplus
}
#endif
int main(void)
{
const Integer npts = 20, npde = 2, neqn = npts*npde, intpts = 6, itype = 1;
const Integer nwk = (10+6*npde)*neqn, lisave = neqn+24;
const Integer lrsave = nwk+(21+3*npde)*npde+7*npts+54;
static double ruser[2] = {-1.0, -1.0};
Integer exit_status = 0, i, ind, it, itask, itrace, m;
double acc, alpha, hx, piby2, tout, ts;
double xout[6] = { 0., .4, .6, .8, .9, 1. };
double *rsave = 0, *u = 0, *uout = 0, *x = 0;
Integer *isave = 0;
NagError fail;
Nag_Comm comm;
Nag_D03_Save saved;
INIT_FAIL(fail);
printf("nag_pde_parab_1d_fd (d03pcc) Example Program Results\n\n");
/* For communication with user-supplied functions: */
comm.user = ruser;
/* Allocate memory */
if (!(rsave = NAG_ALLOC(lrsave, double)) ||
!(u = NAG_ALLOC(npde*npts, double)) ||
!(uout = NAG_ALLOC(npde*intpts*itype, double)) ||
!(x = NAG_ALLOC(npts, double)) ||
!(isave = NAG_ALLOC(lisave, Integer)))
{
printf("Allocation failure\n");
exit_status = 1;
goto END;
}
acc = 0.001;
m = 1;
itrace = 0;
alpha = 1.0;
comm.p = (Pointer)α
ind = 0;
itask = 1;
/* Set spatial mesh points */
piby2 = 0.5*nag_pi;
hx = piby2/((double)(npts-1));
x[0] = 0.0;
x[npts-1] = 1.0;
for (i = 1; i < npts-1; ++i) x[i] = sin(hx*i);
/* Set initial conditions */
ts = 0.0;
tout = 1e-5;
printf("Accuracy requirement = %12.5f\n", acc);
printf("Parameter alpha = %10.3f\n\n", alpha);
printf(" t / x ");
for (i = 0; i < intpts; ++i) printf("%8.4f", xout[i]);
printf("\n");
/* Set the initial values */
uinit(u, x, npde, npts, alpha);
for (it = 0; it < 5; ++it)
{
tout *= 10.0;
/* Solve for next iteration step using
* nag_pde_parab_1d_fd (d03pcc).
* General system of parabolic PDEs, method of lines, finite
* differences, one space variable
*/
nag_pde_parab_1d_fd(npde, m, &ts, tout, pdedef, bndary, u, npts, x, acc,
rsave, lrsave, isave, lisave, itask, itrace, 0, &ind,
&comm, &saved, &fail);
if (fail.code != NE_NOERROR)
{
printf("Error from nag_pde_parab_1d_fd (d03pcc).\n%s\n",
fail.message);
exit_status = 1;
goto END;
}
/* Interpolate at required spatial points using
* nag_pde_interp_1d_fd (d03pzc).
* PDEs, spatial interpolation fo use with the suite of routines
* nag_pde_parab_1d (d03p).
*/
nag_pde_interp_1d_fd(npde, m, u, npts, x, xout, intpts, 1, uout, &fail);
if (fail.code != NE_NOERROR)
{
printf("Error from nag_pde_interp_1d_fd (d03pzc).\n%s\n",
fail.message);
exit_status = 1;
goto END;
}
printf("\n %6.4f u(1)", tout);
for (i = 0; i < intpts; ++i) printf("%8.4f", uout[npde*i]);
printf("\n %6s u(2)","");
for (i = 0; i < intpts; ++i) printf("%8.4f", uout[npde*i+1]);
printf("\n");
}
/* Print integration statistics */
printf("\n %-55s%4ld\n", "Number of integration steps in time",
isave[0]);
printf(" %-55s%4ld\n", "Number of residual evaluations of"
" resulting ODE system", isave[1]);
printf(" %-55s%4ld\n", "Number of Jacobian evaluations", isave[2]);
printf(" %-55s%4ld\n", "Number of iterations of nonlinear solver",
isave[4]);
END:
NAG_FREE(rsave);
NAG_FREE(u);
NAG_FREE(uout);
NAG_FREE(x);
NAG_FREE(isave);
return exit_status;
}
static int NAG_CALL uinit(double *u, double *x, Integer npde, Integer npts,
double alpha)
{
Integer i;
/* Intial conditions for u1 */
for (i = 0; i < npts; ++i) u[i*npde] = alpha*2.0*x[i];
/* Intial conditions for u2 */
for (i = 0; i < npts; ++i) u[i*npde+1] = 1.0;
return 0;
}
static void NAG_CALL pdedef(Integer npde, double t, double x, const double u[],
const double ux[], double p[], double q[],
double r[], Integer *ires, Nag_Comm *comm)
{
/* PDE coefficients */
double *alpha = (double *) comm->p;
if (comm->user[0] == -1.0)
{
printf("(User-supplied callback pdedef, first invocation.)\n");
comm->user[0] = 0.0;
}
/* Coefficients on first PDE */
q[0] = *alpha*4.0*(u[1]+x*ux[1]);
r[0] = x*ux[0];
p[0] = 0.0;
p[npde] = 0.0;
/* Coefficients on first PDE */
q[1] = 0.0;
r[1] = ux[1] - u[0] * u[1];
p[1] = 0.0;
p[1+npde] = 1.0-x*x;
return;
}
static void NAG_CALL bndary(Integer npde, double t, const double u[],
const double ux[], Integer ibnd, double beta[],
double gamma[], Integer *ires, Nag_Comm *comm)
{
/* Boundary conditions */
if (comm->user[1] == -1.0)
{
printf("(User-supplied callback bndary, first invocation.)\n");
comm->user[1] = 0.0;
}
if (ibnd == 0)
{
/* u[0] = 0 */
beta[0] = 0.0;
gamma[0] = u[0];
/* ux[1] = 0 ==> 1.0*r[1] = ux[1] - u[0]*u[1] = -u[0]*u[1] */
beta[1] = 1.0;
gamma[1] = -u[0]*u[1];
}
else
{
/* d(x*u[0])/dx = x*ux[0] + u[0] = 0 */
beta[0] = 1.0;
gamma[0] = -u[0];
/* u[1] = 0 */
beta[1] = 0.0;
gamma[1] = u[1];
}
return;
}