bool GLGPUDataset::Pos(NodeIdType id, float X[3]) const
{
  int idx[3];

  Nid2Idx(id, idx);
  Idx2Pos(idx, X);

  return true;
}
void GLGPU3DDataset::ComputeSupercurrentField(int slot)
{
  const int nvoxels = dims()[0]*dims()[1]*dims()[2];

  if (_J[slot] != NULL) free(_J[slot]);
  _J[slot] = (double*)malloc(3*sizeof(double)*nvoxels);

  double *J = _J[slot];
  memset(J, 0, 3*sizeof(double)*nvoxels);
 
  double u, v, rho2;
  double du[3], dv[3], A[3], j[3];

  // central difference
  for (int x=1; x<dims()[0]-1; x++) {
    for (int y=1; y<dims()[1]-1; y++) {
      for (int z=1; z<dims()[2]-1; z++) {
        int idx[3] = {x, y, z}; 
        double pos[3]; 
        Idx2Pos(idx, pos);

        du[0] = 0.5 * (Re(x+1, y, z, slot) - Re(x-1, y, z, slot)) / dx();
        du[1] = 0.5 * (Re(x, y+1, z, slot) - Re(x, y-1, z, slot)) / dy();
        du[2] = 0.5 * (Re(x, y, z+1, slot) - Re(x, y, z-1, slot)) / dz();
        
        dv[0] = 0.5 * (Im(x+1, y, z, slot) - Im(x-1, y, z, slot)) / dx();
        dv[1] = 0.5 * (Im(x, y+1, z, slot) - Im(x, y-1, z, slot)) / dy();
        dv[2] = 0.5 * (Im(x, y, z+1, slot) - Im(x, y, z-1, slot)) / dz();

        this->A(pos, A, slot);

        u = Re(x, y, z, slot); 
        v = Im(x, y, z, slot);
        rho2 = u*u + v*v;

        texel3Dv(J, dims(), 3, x, y, z, 0) = j[0] = (u*dv[0] - v*du[0]) - rho2*(A[0] + Kex()); // + Kex(); 
        texel3Dv(J, dims(), 3, x, y, z, 1) = j[1] = (u*dv[1] - v*du[1]) - rho2*A[1];
        texel3Dv(J, dims(), 3, x, y, z, 2) = j[2] = (u*dv[2] - v*du[2]) - rho2*A[2];

        // fprintf(stderr, "J={%f, %f, %f}\n", j[0], j[1], j[2]);
      }
    }
  }
}