int main()
{
/*
  dimension statements (note that tri-dimensional arrays
  r and p must be dimensioned exactly as [N-1][17-1+2][21-1+2] (N>=9)
  for this particular case or else they will be written to 
  the CGNS file incorrectly!  Other options are to use 1-D 
  arrays, use dynamic memory, or pass index values to a 
  subroutine and dimension exactly there):
  Rind cells are stored in array locations [k][0][i], [k][17][i], [k][j][0], [k][j][21]
*/
    double r[8][18][22],p[8][18][22];
    int ni,nj,nk,i,j,k,kk,index_file,index_base,index_zone,index_flow,index_field;
    int irinddata[6];
    char solname[33];

/* create fake flow solution AT CELL CENTERS for simple example: */
    ni=20;
    nj=16;
    nk=8;
    for (k=0; k < nk; k++)
    {
      for (j=0; j < nj; j++)
      {
        for (i=0; i < ni; i++)
        {
          r[k][j+1][i+1]=(float)i;
          p[k][j+1][i+1]=(float)j;
        }
      }
    }
/* create rind cell data: */
    for (k=0; k < nk; k++)
    {
      kk=k+1;
      for (j=0; j <= nj+1; j++)
      {
        r[k][j][0]=999.+(float)j+(5.*(float)kk);
        p[k][j][0]=999.+(float)j+(5.*(float)kk)+1.;
        r[k][j][ni+1]=-999.-(float)j-(5.*(float)kk);
        p[k][j][ni+1]=-999.-(float)j-(5.*(float)kk)-1.;
      }
    }
    for (k=0; k < nk; k++)
    {
      kk=k+1;
      for (i=0; i <= ni+1; i++)
      {
        r[k][0][i]=888.+(float)i+(5.*(float)kk);
        p[k][0][i]=888.+(float)i+(5.*(float)kk)+1.;
        r[k][nj+1][i]=-888.-(float)i-(5.*(float)kk);
        p[k][nj+1][i]=-888.-(float)i-(5.*(float)kk)-1.;
      }
    }
    printf("\ncreated simple 3-D rho and p flow solution with rind data\n");

/* WRITE FLOW SOLUTION TO EXISTING CGNS FILE */
/* open CGNS file for modify */
    if (cg_open("grid_c.cgns",CG_MODE_MODIFY,&index_file)) cg_error_exit();
/* we know there is only one base (real working code would check!) */
    index_base=1;
/* we know there is only one zone (real working code would check!) */
    index_zone=1;
/* define flow solution node name (user can give any name) */
    strcpy(solname,"FlowSolution");
/* create flow solution node (NOTE USE OF CellCenter HERE) */
    cg_sol_write(index_file,index_base,index_zone,solname,CellCenter,&index_flow);
/* go to position within tree at FlowSolution_t node */
    cg_goto(index_file,index_base,"Zone_t",index_zone,"FlowSolution_t",index_flow,"end");
/* write rind information under FlowSolution_t node (ilo,ihi,jlo,jhi,klo,khi) */
    irinddata[0]=1;
    irinddata[1]=1;
    irinddata[2]=1;
    irinddata[3]=1;
    irinddata[4]=0;
    irinddata[5]=0;
    cg_rind_write(irinddata);
/* write flow solution (user must use SIDS-standard names here) */
    cg_field_write(index_file,index_base,index_zone,index_flow,
        RealDouble,"Density",r[0][0],&index_field);
    cg_field_write(index_file,index_base,index_zone,index_flow,
        RealDouble,"Pressure",p[0][0],&index_field);
/* close CGNS file */
    cg_close(index_file);
    printf("\nSuccessfully added flow solution data to file grid_c.cgns\n");
    printf("\nNote:  if the original CGNS file already had a FlowSolution_t node,");
    printf("\n          it has been overwritten\n");
    return 0;
}
int main ()
{
    int n, nn, i, j, k, ni, nj, nk;
    int dims[3], grind[2], erind[2];

    num_coord = NUM_I * NUM_J * NUM_K;
    num_element = (NUM_I - 1) * (NUM_J - 1) * (NUM_K - 1);
    xcoord = (float *) malloc(4 * num_coord * sizeof(float));
    nmap = (int *) malloc((num_coord + 8 * num_element) * sizeof(int));
    if (NULL == xcoord || NULL == nmap) {
        fprintf(stderr, "malloc failed for data\n");
        exit(1);
    }
    ycoord = xcoord + num_coord;
    zcoord = ycoord + num_coord;
    solution = zcoord + num_coord;
    elements = nmap + num_coord;

    for (n = 0; n < num_coord; n++)
        solution[n] = (float)n;

    unlink("rind.cgns");
    if (cg_open("rind.cgns", CG_MODE_WRITE, &cgfile))
        cg_error_exit();

    /*--- structured grid with rind ---*/

    printf ("writing structured base with rind\n");
    fflush (stdout);

    for (n = 0, k = 0; k < NUM_K; k++) {
        for (j = 0; j < NUM_J; j++) {
            for (i = 0; i < NUM_I; i++) {
                compute_coord(n++, i, j, k);
            }
        }
    }

    if (cg_base_write(cgfile, "Structured", CellDim, PhyDim, &cgbase) ||
        cg_goto(cgfile, cgbase, "end") ||
        cg_dataclass_write(NormalizedByUnknownDimensional) ||
        cg_zone_write(cgfile, cgbase, "Zone", size, Structured, &cgzone))
        cg_error_exit();

    /* can't use cg_coord_write to write rind coordinates
       need to use cg_grid_write to create the node, cg_goto to set
       position at the node, then write rind and coordinates as an array */

    dims[0] = NUM_I;
    dims[1] = NUM_J;
    dims[2] = NUM_K;

    if (cg_grid_write(cgfile, cgbase, cgzone, "GridCoordinates", &cggrid) ||
        cg_goto(cgfile, cgbase, "Zone_t", cgzone,
            "GridCoordinates_t", cggrid, "end") ||
        cg_rind_write(rind) ||
        cg_array_write("CoordinateX", RealSingle, 3, dims, xcoord) ||
        cg_array_write("CoordinateY", RealSingle, 3, dims, ycoord) ||
        cg_array_write("CoordinateZ", RealSingle, 3, dims, zcoord))
        cg_error_exit();

    /* a similiar technique is used for the solution with rind,
       but we use cg_field_write instead of cg_array_write
       and the solution dimensions come from the zone sizes */

    if (cg_sol_write(cgfile, cgbase, cgzone, "VertexSolution",
            Vertex, &cgsol) ||
        cg_goto(cgfile, cgbase, "Zone_t", cgzone,
            "FlowSolution_t", cgsol, "end") ||
        cg_rind_write(rind) ||
        cg_field_write(cgfile, cgbase, cgzone, cgsol, RealSingle,
            "Density", solution, &cgfld))
        cg_error_exit();

    /*--- unstructured with rind ---*/

    printf ("writing unstructured base with rind\n");
    fflush (stdout);

    /* rind here has dimension rind[2], so need to put all the
       rind coordinates at the beginning and/or end of the array.
       Just for grins, I'll put some at both ends, although
       it's probably best to put the rind coordinates at the end.
       I'll use the nmap array for building elements */

    ni = size[0] + rind[0];
    nj = size[1] + rind[2];
    nk = size[2] + rind[4];

    for (n = 0, i = 0; i < rind[0]; i++) {
        for (k = 0; k < NUM_K; k++) {
            for (j = 0; j < NUM_J; j++) {
                compute_coord (n, i, j, k);
                nn = INDEX(i, j, k);
                nmap[nn] = ++n;
            }
        }
    }
    for (j = 0; j < rind[2]; j++) {
        for (k = 0; k < NUM_K; k++) {
            for (i = rind[0]; i < ni; i++) {
                compute_coord (n, i, j, k);
                nn = INDEX(i, j, k);
                nmap[nn] = ++n;
            }
        }
    }
    for (k = 0; k < rind[4]; k++) {
        for (j = rind[2]; j < nj; j++) {
            for (i = rind[0]; i < ni; i++) {
                compute_coord (n, i, j, k);
                nn = INDEX(i, j, k);
                nmap[nn] = ++n;
            }
        }
    }
    grind[0] = n;

    for (k = rind[4]; k < nk; k++) {
        for (j = rind[2]; j < nj; j++) {
            for (i = rind[0]; i < ni; i++) {
                compute_coord (n, i, j, k);
                nn = INDEX(i, j, k);
                nmap[nn] = ++n;
            }
        }
    }
    grind[1] = num_coord - n;

    for (i = ni; i < NUM_I; i++) {
        for (k = 0; k < NUM_K; k++) {
            for (j = 0; j < NUM_J; j++) {
                compute_coord (n, i, j, k);
                nn = INDEX(i, j, k);
                nmap[nn] = ++n;
            }
        }
    }
    for (j = nj; j < NUM_J; j++) {
        for (k = 0; k < NUM_K; k++) {
            for (i = rind[0]; i < ni; i++) {
                compute_coord (n, i, j, k);
                nn = INDEX(i, j, k);
                nmap[nn] = ++n;
            }
        }
    }
    for (k = nk; k < NUM_K; k++) {
        for (j = rind[2]; j < nj; j++) {
            for (i = rind[0]; i < ni; i++) {
                compute_coord (n, i, j, k);
                nn = INDEX(i, j, k);
                nmap[nn] = ++n;
            }
        }
    }

    /* rind elements are like the coordinates, they need to go
       at the beginning and/or end of the element array, although
       at the end is probably best */

    for (n = 0, i = 0; i < rind[0]; i++) {
        for (k = 0; k < NUM_K - 1; k++) {
            for (j = 0; j < NUM_J - 1; j++) {
                compute_element(n++, i, j, k);
            }
        }
    }
    for (j = 0; j < rind[2]; j++) {
        for (k = 0; k < NUM_K - 1; k++) {
            for (i = rind[0]; i < ni - 1; i++) {
                compute_element(n++, i, j, k);
            }
        }
    }
    for (k = 0; k < rind[4]; k++) {
        for (j = rind[2]; j < nj - 1; j++) {
            for (i = rind[0]; i < ni - 1; i++) {
                compute_element(n++, i, j, k);
            }
        }
    }
    erind[0] = n;

    for (k = rind[4]; k < nk - 1; k++) {
        for (j = rind[2]; j < nj - 1; j++) {
            for (i = rind[0]; i < ni - 1; i++) {
                compute_element(n++, i, j, k);
            }
        }
    }
    erind[1] = num_element - n;

    for (i = ni - 1; i < NUM_I - 1; i++) {
        for (k = 0; k < NUM_K - 1; k++) {
            for (j = 0; j < NUM_J - 1; j++) {
                compute_element(n++, i, j, k);
            }
        }
    }
    for (j = nj - 1; j < NUM_J - 1; j++) {
        for (k = 0; k < NUM_K - 1; k++) {
            for (i = rind[0]; i < ni - 1; i++) {
                compute_element(n++, i, j, k);
            }
        }
    }
    for (k = nk - 1; k < NUM_K - 1; k++) {
        for (j = rind[2]; j < nj - 1; j++) {
            for (i = rind[0]; i < ni - 1; i++) {
                compute_element(n++, i, j, k);
            }
        }
    }

    /* create base, zone and write coordinates.
       As for the structured case, the rind coordinates
       and elements are not included in the zone totals */

    dims[0] = num_coord - grind[0] - grind[1];
    dims[1] = num_element - erind[0] - erind[1];
    dims[2] = 0;

    if (cg_base_write(cgfile, "Unstructured", CellDim, PhyDim, &cgbase) ||
        cg_goto(cgfile, cgbase, "end") ||
        cg_dataclass_write(NormalizedByUnknownDimensional) ||
        cg_zone_write(cgfile, cgbase, "Zone", dims, Unstructured, &cgzone) ||
        cg_grid_write(cgfile, cgbase, cgzone, "GridCoordinates", &cggrid) ||
        cg_goto(cgfile, cgbase, "Zone_t", cgzone,
            "GridCoordinates_t", cggrid, "end") ||
        cg_rind_write(grind) ||
        cg_array_write("CoordinateX", RealSingle, 1, &num_coord, xcoord) ||
        cg_array_write("CoordinateY", RealSingle, 1, &num_coord, ycoord) ||
        cg_array_write("CoordinateZ", RealSingle, 1, &num_coord, zcoord))
        cg_error_exit();

    /* to write the elements with rind elements,
       write all the elements, then use goto to add rind */

    if (cg_section_write(cgfile, cgbase, cgzone, "Elements", HEXA_8,
            1, num_element, 0, elements, &cgsect) ||
        cg_goto(cgfile, cgbase, "Zone_t", cgzone,
            "Elements_t", cgsect, "end") ||
        cg_rind_write(erind))
        cg_error_exit();

    /* write solution a vertices with rind */

    if (cg_sol_write(cgfile, cgbase, cgzone, "VertexSolution",
            Vertex, &cgsol) ||
        cg_goto(cgfile, cgbase, "Zone_t", cgzone,
            "FlowSolution_t", cgsol, "end") ||
        cg_rind_write(grind) ||
        cg_field_write(cgfile, cgbase, cgzone, cgsol, RealSingle,
            "Density", solution, &cgfld))
        cg_error_exit();

    cg_close(cgfile);
    return 0;
}