Ejemplo n.º 1
0
static PyObject *center(PyObject *self, PyObject *args) {
  int molid, frame;
  PyObject *selected;
  PyObject *weightobj = NULL;
  AtomSel *sel;
  // parse arguments
  if (!PyArg_ParseTuple(args, (char *)"iiO!|O",
        &molid, &frame, &PyTuple_Type, &selected, &weightobj))
    return NULL;
  VMDApp *app = get_vmdapp();
  // get selection
  if (!(sel = sel_from_py(molid, frame, selected, app)))
    return NULL;
  // get weight
  float *weight = parse_weight(sel, weightobj);
  if (!weight) return NULL;
  float cen[3];
  // compute center
  int ret_val = measure_center(sel, sel->coordinates(app->moleculeList),
      weight, cen);
  delete [] weight;
  delete sel;
  if (ret_val < 0) {
    PyErr_SetString(PyExc_ValueError, measure_error(ret_val));
    return NULL;
  }
  // return as (x, y, z)
  PyObject *cenobj = PyTuple_New(3);
  for (int i=0; i<3; i++)
    PyTuple_SET_ITEM(cenobj, i, PyFloat_FromDouble(cen[i]));
  return cenobj;
}
Ejemplo n.º 2
0
static PyObject *py_rmsd(PyObject *self, PyObject *args) {
  int mol1, frame1, mol2, frame2;
  PyObject *selected1, *selected2, *weightobj = NULL;
  if (!PyArg_ParseTuple(args, (char *)"iiO!iiO!O:atomselection.rmsd",
        &mol1, &frame1, &PyTuple_Type, &selected1,
        &mol2, &frame2, &PyTuple_Type, &selected2,
				&weightobj))
    return NULL;
  VMDApp *app = get_vmdapp();
  AtomSel *sel1 = sel_from_py(mol1, frame1, selected1, app);
  AtomSel *sel2 = sel_from_py(mol2, frame2, selected2, app);
  if (!sel1 || !sel2) {
    delete sel1;
    delete sel2;
    return NULL;
  }
  const Timestep *ts1 =app->moleculeList->mol_from_id(mol1)->get_frame(frame1); 
  const Timestep *ts2 =app->moleculeList->mol_from_id(mol2)->get_frame(frame2); 
  if (!ts1 || !ts2) {
    PyErr_SetString(PyExc_ValueError, "No coordinates in selection");
    delete sel1;
    delete sel2;
    return NULL;
  }
  float *weight = parse_weight(sel1, weightobj);
  if (!weight) {
    delete sel1;
    delete sel2;
    return NULL;
  }
  float rmsd;
  int rc = measure_rmsd(sel1, sel2, sel1->selected, ts1->pos, ts2->pos,
      weight, &rmsd);
  delete sel1;
  delete sel2;
  delete [] weight;
  if (rc < 0) {
    PyErr_SetString(PyExc_ValueError, measure_error(rc));
    return NULL;
  }
  return PyFloat_FromDouble(rmsd);
}
Ejemplo n.º 3
0
static PyObject *minmax(PyObject *self, PyObject *args) {
  int molid, frame;
  PyObject *selected;

  if (!PyArg_ParseTuple(args, (char *)"iiO!", 
                        &molid, &frame, &PyTuple_Type, &selected))
    return NULL;  // bad args

  VMDApp *app = get_vmdapp();
  AtomSel *sel = sel_from_py(molid, frame, selected, app);
  if (!sel) return NULL;
  const Timestep *ts = app->moleculeList->mol_from_id(molid)->get_frame(frame); 
  if (!ts) {
    PyErr_SetString(PyExc_ValueError, "No coordinates in selection");
    delete sel;
    return NULL;
  }
  float min[3], max[3];
  int rc = measure_minmax(sel->num_atoms, sel->on, ts->pos, NULL, min, max);
  delete sel;
  if (rc < 0) {
    PyErr_SetString(PyExc_ValueError, measure_error(rc));
    return NULL;
  }
  PyObject *mintuple, *maxtuple, *result;
  mintuple = PyTuple_New(3);
  maxtuple = PyTuple_New(3);
  result = PyTuple_New(2);
  for (int i=0; i<3; i++) {
    PyTuple_SET_ITEM(mintuple, i, PyFloat_FromDouble(min[i]));
    PyTuple_SET_ITEM(maxtuple, i, PyFloat_FromDouble(max[i]));
  }
  PyTuple_SET_ITEM(result, 0, mintuple);
  PyTuple_SET_ITEM(result, 1, maxtuple);
  return result;
}
Ejemplo n.º 4
0
static PyObject *sasa(PyObject *self, PyObject *args, PyObject *keywds) {
  int molid = -1, frame = -1;
  float srad = 0;
  PyObject *selobj = NULL, *restrictobj = NULL;
  int samples = -1;
  const int *sampleptr = NULL;
  PyObject *pointsobj = NULL;

  static char *kwlist[] = {
    (char *)"srad", (char *)"molid", (char *)"frame", (char *)"selected",
    (char *)"samples", (char *)"points", (char *)"restrict"
  };
  if (!PyArg_ParseTupleAndKeywords(args, keywds, 
        (char *)"fiiO!|iO!O!:atomselection.sasa", kwlist, 
        &srad, &molid, &frame, &PyTuple_Type, &selobj, 
        &samples, &PyList_Type, &pointsobj, &PyTuple_Type, &restrictobj))
    return NULL;

  // validate srad
  if (srad < 0) {
    PyErr_SetString(PyExc_ValueError, (char *)"atomselect.sasa: srad must be non-negative.");
    return NULL;
  }

  // validate selection
  VMDApp *app = get_vmdapp();
  AtomSel *sel = sel_from_py(molid, frame, selobj, app);
  if (!sel) return NULL;

  // fetch the radii and coordinates
  const float *radii = 
    app->moleculeList->mol_from_id(sel->molid())->extraflt.data("radius");
  const float *coords = sel->coordinates(app->moleculeList);

  // if samples was given and is valid, use it
  if (samples > 1) sampleptr = &samples;

  // if restrict is given, validate it
  AtomSel *restrictsel = NULL;
  if (restrictobj) {
    if (!(restrictsel = sel_from_py(molid, frame, restrictobj, app))) {
      delete sel;
      return NULL;
    }
  }

  // if points are requested, fetch them
  ResizeArray<float> sasapts;
  ResizeArray<float> *sasaptsptr = pointsobj ? &sasapts : NULL;
 
  // go!
  float sasa = 0;
  int rc = measure_sasa(sel, coords, radii, srad, &sasa, 
        sasaptsptr, restrictsel, sampleptr);
  delete sel;
  delete restrictsel;
  if (rc) {
    PyErr_SetString(PyExc_ValueError, (char *)measure_error(rc));
    return NULL;
  }

  // append surface points to the provided list object.
  if (pointsobj) {
    for (int i=0; i<sasapts.num(); i++) {
      PyList_Append(pointsobj, PyFloat_FromDouble(sasapts[i]));
    }
  }

  // return the total SASA.
  return PyFloat_FromDouble(sasa);
}
Ejemplo n.º 5
0
static PyObject *py_align(PyObject *self, PyObject *args) {
  int selmol, selframe, refmol, refframe, movemol, moveframe;
  PyObject *selobj, *refobj, *moveobj, *weightobj = NULL;
  if (!PyArg_ParseTuple(args, (char *)"iiO!iiO!iiO!O:atomselection.align",
        &selmol, &selframe, &PyTuple_Type, &selobj,
        &refmol, &refframe, &PyTuple_Type, &refobj,
        &movemol, &moveframe, &PyTuple_Type, &moveobj,
        &weightobj))
    return NULL;

  // check if movemol is -1.  If so, use the sel molecule and timestep instead
  if (movemol == -1) {
    movemol = selmol;
    moveobj = NULL;
  }
  VMDApp *app = get_vmdapp();
  AtomSel *sel=NULL, *ref=NULL, *move=NULL;
  if (!(sel = sel_from_py(selmol, selframe, selobj, app)) ||
      !(ref = sel_from_py(refmol, refframe, refobj, app)) ||
      !(move = sel_from_py(movemol, moveframe, moveobj, app))) {
    delete sel;
    delete ref;
    delete move;
    return NULL;
  }
  const float *selts, *refts;
  float *movets;
  if (!(selts = sel->coordinates(app->moleculeList)) ||
      !(refts = ref->coordinates(app->moleculeList)) || 
      !(movets = move->coordinates(app->moleculeList))) {
    delete sel;
    delete ref;
    delete move;
    PyErr_SetString(PyExc_ValueError, "No coordinates in selection");
    return NULL;
  }
  float *weight = parse_weight(sel, weightobj);
  if (!weight) {
    delete sel;
    delete ref;
    delete move;
    return NULL;
  }
  // Find the matrix that aligns sel with ref.  Apply the transformation to
  // the atoms in move.
  // XXX need to add support for the "order" parameter as in Tcl.
  Matrix4 mat;
  int rc = measure_fit(sel, ref, selts, refts, weight, NULL, &mat);
  delete [] weight;
  delete sel;
  delete ref;
  if (rc < 0) {
    delete move;
    PyErr_SetString(PyExc_ValueError, (char *)measure_error(rc));
    return NULL;
  }
  for (int i=0; i<move->num_atoms; i++) {
    if (move->on[i]) {
      float *pos = movets+3*i;
      mat.multpoint3d(pos, pos);
    }
  }
  Molecule *mol = app->moleculeList->mol_from_id(move->molid());
  mol->force_recalc(DrawMolItem::MOL_REGEN);
  delete move;
  Py_INCREF(Py_None);
  return Py_None;
}
Ejemplo n.º 6
0
int main(int argc, char *argv[]) {
    int num_elem, num_sides;
    int n_threads, n_blocks_elem, n_blocks_reduction, n_blocks_sides;
    int i, n, n_p, timesteps, n_quad, n_quad1d;

    double dt, t, endtime;
    double *min_radius;
    double min_r;
    double *V1x, *V1y, *V2x, *V2y, *V3x, *V3y;
    double *sides_x1, *sides_x2;
    double *sides_y1, *sides_y2;

    double *r1_local, *r2_local, *w_local;

    double *s_r, *oned_w_local;

    int *left_elem, *right_elem;
    int *elem_s1, *elem_s2, *elem_s3;
    int *left_side_number, *right_side_number;

    FILE *mesh_file, *out_file;

    char line[100];
    char *mesh_filename;
    char *out_filename;
    char *rho_out_filename;
    char *u_out_filename;
    char *v_out_filename;
    char *E_out_filename;
    char *outfile_base;
    int outfile_len;

    double *Uu1, *Uu2, *Uu3;
    double *Uv1, *Uv2, *Uv3;

    // get input 
    endtime = -1;
    if (get_input(argc, argv, &n, &timesteps, &endtime, &mesh_filename, &out_filename)) {
        return 1;
    }

    // TODO: this should be cleaner, obviously
    rho_out_filename = "output/uniform_rho.out";
    u_out_filename = "output/uniform_u.out";
    v_out_filename = "output/uniform_v.out";
    E_out_filename = "output/uniform_E.out";

    // set the order of the approximation & timestep
    n_p = (n + 1) * (n + 2) / 2;

    // open the mesh to get num_elem for allocations
    mesh_file = fopen(mesh_filename, "r");
    if (!mesh_file) {
        printf("\nERROR: mesh file not found.\n");
        return 1;
    }
    fgets(line, 100, mesh_file);
    sscanf(line, "%i", &num_elem);

    // allocate vertex points
    V1x = (double *) malloc(num_elem * sizeof(double));
    V1y = (double *) malloc(num_elem * sizeof(double));
    V2x = (double *) malloc(num_elem * sizeof(double));
    V2y = (double *) malloc(num_elem * sizeof(double));
    V3x = (double *) malloc(num_elem * sizeof(double));
    V3y = (double *) malloc(num_elem * sizeof(double));

    elem_s1 = (int *) malloc(num_elem * sizeof(int));
    elem_s2 = (int *) malloc(num_elem * sizeof(int));
    elem_s3 = (int *) malloc(num_elem * sizeof(int));

    // TODO: these are too big; should be a way to figure out how many we actually need
    left_side_number  = (int *)   malloc(3*num_elem * sizeof(int));
    right_side_number = (int *)   malloc(3*num_elem * sizeof(int));

    sides_x1    = (double *) malloc(3*num_elem * sizeof(double));
    sides_x2    = (double *) malloc(3*num_elem * sizeof(double));
    sides_y1    = (double *) malloc(3*num_elem * sizeof(double));
    sides_y2    = (double *) malloc(3*num_elem * sizeof(double)); 
    left_elem   = (int *) malloc(3*num_elem * sizeof(int));
    right_elem  = (int *) malloc(3*num_elem * sizeof(int));

    for (i = 0; i < 3*num_elem; i++) {
        right_elem[i] = -1;
    }

    // read in the mesh and make all the mappings
    read_mesh(mesh_file, &num_sides, num_elem,
                         V1x, V1y, V2x, V2y, V3x, V3y,
                         left_side_number, right_side_number,
                         sides_x1, sides_y1, 
                         sides_x2, sides_y2, 
                         elem_s1, elem_s2, elem_s3,
                         left_elem, right_elem);

    // close the file
    fclose(mesh_file);

    // initialize the gpu
    init_gpu(num_elem, num_sides, n_p,
             V1x, V1y, V2x, V2y, V3x, V3y,
             left_side_number, right_side_number,
             sides_x1, sides_y1,
             sides_x2, sides_y2, 
             elem_s1, elem_s2, elem_s3,
             left_elem, right_elem);

    n_threads          = 256;
    n_blocks_elem      = (num_elem  / n_threads) + ((num_elem  % n_threads) ? 1 : 0);
    n_blocks_sides     = (num_sides / n_threads) + ((num_sides % n_threads) ? 1 : 0);
    n_blocks_reduction = (num_elem  / 256) + ((num_elem  % 256) ? 1 : 0);

    // find the min inscribed circle
    preval_inscribed_circles(d_J, d_V1x, d_V1y, d_V2x, d_V2y, d_V3x, d_V3y, num_elem);
    min_radius = (double *) malloc(num_elem * sizeof(double));

    /*
    // find the min inscribed circle. do it on the gpu if there are at least 256 elements
    if (num_elem >= 256) {
        //min_reduction<<<n_blocks_reduction, 256>>>(d_J, d_reduction, num_elem);
        cudaThreadSynchronize();
        checkCudaError("error after min_jacobian.");

        // each block finds the smallest value, so need to sort through n_blocks_reduction
        min_radius = (double *) malloc(n_blocks_reduction * sizeof(double));
        cudaMemcpy(min_radius, d_reduction, n_blocks_reduction * sizeof(double), cudaMemcpyDeviceToHost);
        min_r = min_radius[0];
        for (i = 1; i < n_blocks_reduction; i++) {
            min_r = (min_radius[i] < min_r) ? min_radius[i] : min_r;
        }
        free(min_radius);

    } else {
        */
        // just grab all the radii and sort them since there are so few of them
        min_radius = (double *) malloc(num_elem * sizeof(double));
        memcpy(min_radius, d_J, num_elem * sizeof(double));
        min_r = min_radius[0];
        for (i = 1; i < num_elem; i++) {
            min_r = (min_radius[i] < min_r) ? min_radius[i] : min_r;
        }
        free(min_radius);
    //}

    // pre computations
    preval_jacobian(d_J, d_V1x, d_V1y, d_V2x, d_V2y, d_V3x, d_V3y, num_elem); 

    preval_side_length(d_s_length, d_s_V1x, d_s_V1y, d_s_V2x, d_s_V2y, 
                                                      num_sides); 
    //cudaThreadSynchronize();
    preval_normals(d_Nx, d_Ny, 
                   d_s_V1x, d_s_V1y, d_s_V2x, d_s_V2y,
                   d_V1x, d_V1y, 
                   d_V2x, d_V2y, 
                   d_V3x, d_V3y, 
                   d_left_side_number, num_sides); 

    preval_normals_direction(d_Nx, d_Ny, 
                             d_V1x, d_V1y, 
                             d_V2x, d_V2y, 
                             d_V3x, d_V3y, 
                             d_left_elem, d_left_side_number, num_sides); 

    preval_partials(d_V1x, d_V1y,
                    d_V2x, d_V2y,
                    d_V3x, d_V3y,
                    d_xr,  d_yr,
                    d_xs,  d_ys, num_elem);

    // get the correct quadrature rules for this scheme
    set_quadrature(n, &r1_local, &r2_local, &w_local, 
                   &s_r, &oned_w_local, &n_quad, &n_quad1d);

    // evaluate the basis functions at those points and store on GPU
    preval_basis(r1_local, r2_local, s_r, w_local, oned_w_local, n_quad, n_quad1d, n_p);

    // initial conditions
    init_conditions(d_c, d_J, d_V1x, d_V1y, d_V2x, d_V2y, d_V3x, d_V3y,
                    n_quad, n_p, num_elem);

    printf("Computing...\n");
    printf(" ? %i degree polynomial interpolation (n_p = %i)\n", n, n_p);
    printf(" ? %i precomputed basis points\n", n_quad * n_p);
    printf(" ? %i elements\n", num_elem);
    printf(" ? %i sides\n", num_sides);
    printf(" ? min radius = %lf\n", min_r);
    printf(" ? endtime = %lf\n", endtime);

    time_integrate_rk4(n_quad, n_quad1d, n_p, n, num_elem, num_sides, endtime, min_r);

    // evaluate at the vertex points and copy over data
    Uu1 = (double *) malloc(num_elem * sizeof(double));
    Uu2 = (double *) malloc(num_elem * sizeof(double));
    Uu3 = (double *) malloc(num_elem * sizeof(double));

    Uv1 = (double *) malloc(num_elem * sizeof(double));
    Uv2 = (double *) malloc(num_elem * sizeof(double));
    Uv3 = (double *) malloc(num_elem * sizeof(double));

    // evaluate rho and write to file 
    eval_u(d_c, d_Uv1, d_Uv2, d_Uv3, num_elem, n_p, 0);
    memcpy(Uv1, d_Uv1, num_elem * sizeof(double));
    memcpy(Uv2, d_Uv2, num_elem * sizeof(double));
    memcpy(Uv3, d_Uv3, num_elem * sizeof(double));
    out_file  = fopen(rho_out_filename , "w");
    fprintf(out_file, "View \"Density \" {\n");
    for (i = 0; i < num_elem; i++) {
        fprintf(out_file, "ST (%lf,%lf,0,%lf,%lf,0,%lf,%lf,0) {%lf,%lf,%lf};\n", 
                               V1x[i], V1y[i], V2x[i], V2y[i], V3x[i], V3y[i],
                               d_Uv1[i], d_Uv2[i], d_Uv3[i]);
    }
    fprintf(out_file,"};");
    fclose(out_file);

    // evaluate the u and v vectors and write to file
    eval_u_velocity(d_c, d_Uv1, d_Uv2, d_Uv3, num_elem, n_p, 1);
    memcpy(Uu1, d_Uv1, num_elem * sizeof(double));
    memcpy(Uu2, d_Uv2, num_elem * sizeof(double));
    memcpy(Uu3, d_Uv3, num_elem * sizeof(double));
    eval_u_velocity(d_c, d_Uv1, d_Uv2, d_Uv3, num_elem, n_p, 2);
    memcpy(Uv1, d_Uv1, num_elem * sizeof(double));
    memcpy(Uv2, d_Uv2, num_elem * sizeof(double));
    memcpy(Uv3, d_Uv3, num_elem * sizeof(double));
    out_file  = fopen(u_out_filename , "w");
    fprintf(out_file, "View \"u \" {\n");
    for (i = 0; i < num_elem; i++) {
        fprintf(out_file, "VT (%lf,%lf,0,%lf,%lf,0,%lf,%lf,0) {%lf,%lf,0,%lf,%lf,0,%lf,%lf,0};\n", 
                               V1x[i], V1y[i], V2x[i], V2y[i], V3x[i], V3y[i],
                               Uu1[i], Uv1[i], Uu2[i], Uv2[i], Uu3[i], Uv3[i]);
    }
    fprintf(out_file,"};");
    fclose(out_file);

    // evaluate E and write to file
    eval_u(d_c, d_Uv1, d_Uv2, d_Uv3, num_elem, n_p, 3);
    memcpy(Uv1, d_Uv1, num_elem * sizeof(double));
    memcpy(Uv2, d_Uv2, num_elem * sizeof(double));
    memcpy(Uv3, d_Uv3, num_elem * sizeof(double));
    out_file  = fopen(E_out_filename , "w");
    fprintf(out_file, "View \"E \" {\n");
    for (i = 0; i < num_elem; i++) {
        fprintf(out_file, "ST (%lf,%lf,0,%lf,%lf,0,%lf,%lf,0) {%lf,%lf,%lf};\n", 
                               V1x[i], V1y[i], V2x[i], V2y[i], V3x[i], V3y[i],
                               Uv1[i], Uv2[i], Uv3[i]);
    }
    fprintf(out_file,"};");
    fclose(out_file);

    // plot pressure
    eval_p(d_c, d_Uv1, d_Uv2, d_Uv3, num_elem, n_p, 3);
    memcpy(Uv1, d_Uv1, num_elem * sizeof(double));
    memcpy(Uv2, d_Uv2, num_elem * sizeof(double));
    memcpy(Uv3, d_Uv3, num_elem * sizeof(double));
    out_file  = fopen("output/p.out" , "w");
    fprintf(out_file, "View \"E \" {\n");
    for (i = 0; i < num_elem; i++) {
        fprintf(out_file, "ST (%lf,%lf,0,%lf,%lf,0,%lf,%lf,0) {%lf,%lf,%lf};\n", 
                               V1x[i], V1y[i], V2x[i], V2y[i], V3x[i], V3y[i],
                               Uv1[i], Uv2[i], Uv3[i]);
    }
    fprintf(out_file,"};");
    fclose(out_file);

    measure_error(d_c, d_Uv1, d_Uv2, d_Uv3, 
                  d_V1x, d_V1y, d_V2x, d_V2y, d_V3x, d_V3y,
                  num_elem, n_p);

    memcpy(Uv1, d_Uv1, num_elem * sizeof(double));
    memcpy(Uv2, d_Uv2, num_elem * sizeof(double));
    memcpy(Uv3, d_Uv3, num_elem * sizeof(double));
    out_file  = fopen("output/p_error.out" , "w");
    fprintf(out_file, "View \"p \" {\n");
    for (i = 0; i < num_elem; i++) {
        fprintf(out_file, "ST (%lf,%lf,0,%lf,%lf,0,%lf,%lf,0) {%lf,%lf,%lf};\n", 
                               V1x[i], V1y[i], V2x[i], V2y[i], V3x[i], V3y[i],
                               Uv1[i], Uv2[i], Uv3[i]);
    }
    fprintf(out_file,"};");
    fclose(out_file);

    // free variables
    free_gpu();
    
    free(Uu1);
    free(Uu2);
    free(Uu3);
    free(Uv1);
    free(Uv2);
    free(Uv3);

    free(V1x);
    free(V1y);
    free(V2x);
    free(V2y);
    free(V3x);
    free(V3y);

    free(elem_s1);
    free(elem_s2);
    free(elem_s3);

    free(sides_x1);
    free(sides_x2);
    free(sides_y1);
    free(sides_y2);

    free(left_elem);
    free(right_elem);
    free(left_side_number);
    free(right_side_number);

    free(r1_local);
    free(r2_local);
    free(w_local);
    free(s_r);
    free(oned_w_local);

    return 0;
}