sandbox/Emily/writenetcdf.h
Basilisk programme to write outputs as netcdf files. Written by Cyprien Bosserelle cyprien.bosserelle@niwa.co.nz 2018-2019 Usage: //Save this file in $BASILISK. In the modelling programme include this file with other includes at the top of the file: #include “writenetcdf.h” // First create a netcdf file - define name char ncfile[]=“TPacGebco-out.nc”; // In an initialisation event create file printf(“Create netcdf file for output ”); //Prepare netcdf file for output int nx=(int) 1 << MAXLEVEL; scalar * outvars = {eta,h,hmax,l,u.x,u.y}; create2dnc(ncfile,nx, L0, 0.0, outvars); // Output at designated timesteps (i.e. in ongoing event) printf(“Saving step: t=%f”,t); int nx=1<<MAXLEVEL; scalar * outvars = {eta,h,hmax,l,u.x,u.y}; write2varnc(ncfile,nx, t, outvars);
Still to do (useful but works without): Set attributes for _FillValue, missing_value
#include <netcdf.h>
double BiInterp(double q11, double q12, double q21, double q22, double x1, double x2, double y1, double y2, double x, double y)
{
double x2x1, y2y1, x2x, y2y, yy1, xx1;
= x2 - x1;
x2x1 = y2 - y1;
y2y1 = x2 - x;
x2x = y2 - y;
y2y = y - y1;
yy1 = x - x1;
xx1 return 1.0 / (x2x1 * y2y1) * (
* x2x * y2y +
q11 * xx1 * y2y +
q21 * x2x * yy1 +
q12 * xx1 * yy1
q22 );
}
void create2dnc(char * ncfilename,int n, double len, double totaltime, scalar * outvars)
{
int status;
int ncid, xx_dim, yy_dim, time_dim, p_dim;
int * tvar_id;
int nvars = list_len(outvars);
=(int*)malloc(nvars*sizeof(int));
tvar_id
double *xx,*yy, *var;
double dx=len/n;
= (double *)malloc(n*sizeof(double));
xx = (double *)malloc(n*sizeof(double));
yy = (double *)malloc(n*n*sizeof(double));
var
for (int ix=0; ix<n; ix++)
{
[ix]=ix*dx+ X0 + dx/2.;
xx[ix]=ix*dx+ Y0 + dx/2.;
yy}
size_t nxx, nyy, ntt;
size_t start[] = { 0, 0, 0 }; // start at first value
size_t count[] = { 1, 1, 1 };
[1]=n;
count[2]=n;
count
int time_id, xx_id, yy_id, tt_id; //
= n;
nxx = n;
nyy
//create the netcdf dataset
= nc_create(ncfilename, NC_NOCLOBBER, &ncid);
status
//Define dimensions: Name and length
= nc_def_dim(ncid, "xx", nxx, &xx_dim);
status = nc_def_dim(ncid, "yy", nyy, &yy_dim);
status
= nc_def_dim(ncid, "time", NC_UNLIMITED, &time_dim);
status int tdim[] = { time_dim };
int xdim[] = { xx_dim };
int ydim[] = { yy_dim };
//define variables: Name, Type,...
int var_dimids[3];
[0] = time_dim;
var_dimids
[1] = yy_dim;
var_dimids[2] = xx_dim;
var_dimids
= nc_def_var(ncid, "time", NC_DOUBLE, 1, tdim, &time_id);
status = nc_def_var(ncid, "xx", NC_DOUBLE, 1, xdim, &xx_id);
status = nc_def_var(ncid, "yy", NC_DOUBLE, 1, ydim, &yy_id);
status
int kk=0;
for (scalar s in outvars)
{
= nc_def_var(ncid, s.name, NC_DOUBLE, 3, var_dimids, &tvar_id[kk++]);
status }
= nc_enddef(ncid);
status
size_t tst[] = { 0 };
size_t xstart[] = { 0 }; // start at first value
size_t xcount[] = { 1 };
[0]=n;
xcount
size_t ystart[] = { 0 }; // start at first value
size_t ycount[] = { 1 };
[0]=n;
ycount
//Provide values for variables
= nc_put_var1_double(ncid, time_id, tst, &totaltime);
status = nc_put_vara_double(ncid, xx_id, xstart, xcount, xx);
status = nc_put_vara_double(ncid, yy_id, ystart, ycount, yy);
status =0;
kkfor (scalar s in outvars)
{
for (int ii=0; ii<nxx; ii++)
{
for (int jj=0;jj<nyy;jj++)
{
[ii+jj*nxx]=interpolate(s,ii*dx+ X0 + dx/2.,jj*dx+Y0+dx/2.);
var}
}
= nc_put_vara_double(ncid, tvar_id[kk++], start, count, var);
status }
= nc_close(ncid);
status
free(xx);
free(yy);
free(var);
}
void write2varnc(char * ncfilename,int n, double totaltime, scalar * outvars)
{
int status;
int ncid, time_dim, recid;
size_t nxx, nyy;
size_t start[] = { 0, 0, 0 }; // start at first value should be static?
size_t count[] = { 1, n, n };
// Is this absurd?
[1]=n;
count[2]=n;
count
static size_t tst[] = { 0 };
int time_id, *var_id;
int nvars = list_len(outvars);
double * var;
=(int*)malloc(nvars*sizeof(int));
var_id
= (double *)malloc(n*n*sizeof(double));
var
= n;
nxx = n;
nyy
double dx= L0/n;
static size_t nrec;
= nc_open(ncfilename, NC_WRITE, &ncid);
status
//read id from time dimension
= nc_inq_unlimdim(ncid, &recid);
status = nc_inq_dimlen(ncid, recid, &nrec);// What is the point of static definition if it is redefined here!
status //printf("nrec=%d\n",nrec);
//read file for variable ids
= nc_inq_varid(ncid, "time", &time_id);
status int kk=0;
for (scalar s in outvars)
{
= nc_inq_varid(ncid, s.name, &var_id[kk++]);
status }
[0] = nrec;//
start[0] = nrec;
tst
//Provide values for variables
= nc_put_var1_double(ncid, time_id, tst, &totaltime);
status //status = nc_put_vara_double(ncid, var_id, start, count, var);
=0;
kkfor (scalar s in outvars)
{
for (int ii=0; ii<nxx; ii++)
{
for (int jj=0;jj<nyy;jj++)
{
[ii+jj*nxx]=interpolate(s,ii*dx+ X0 + dx/2.,jj*dx+Y0+dx/2.);
var}
}
= nc_put_vara_double(ncid, var_id[kk++], start, count, var);
status }
= nc_close(ncid);
status
free(var);
}