Esempio n. 1
0
void colvar::cvc::debug_gradients(cvm::atom_group *group)
{
  // this function should work for any scalar variable:
  // the only difference will be the name of the atom group (here, "group")
  // NOTE: this assumes that groups for this cvc are non-overlapping,
  // since atom coordinates are modified only within the current group

  if (group->b_dummy) return;

  cvm::rotation const rot_0 = group->rot;
  cvm::rotation const rot_inv = group->rot.inverse();

  cvm::real x_0 = x.real_value;
  if ((x.type() == colvarvalue::type_vector) && (x.size() == 1)) x_0 = x[0];

  // cvm::log("gradients     = "+cvm::to_str (gradients)+"\n");

  cvm::atom_group *group_for_fit = group->ref_pos_group ? group->ref_pos_group : group;
  cvm::atom_pos fit_gradient_sum, gradient_sum;

  // print the values of the fit gradients
  if (group->b_rotate || group->b_center) {
    if (group->b_fit_gradients) {
      size_t j;

      // fit_gradients are in the simulation frame: we should print them in the rotated frame
      cvm::log("Fit gradients:\n");
      for (j = 0; j < group_for_fit->fit_gradients.size(); j++) {
        cvm::log((group->ref_pos_group ? std::string("refPosGroup") : group->key) +
                 "[" + cvm::to_str(j) + "] = " +
                 (group->b_rotate ?
                  cvm::to_str(rot_0.rotate(group_for_fit->fit_gradients[j])) :
                  cvm::to_str(group_for_fit->fit_gradients[j])));
      }
    }
  }

  // debug the gradients
  for (size_t ia = 0; ia < group->size(); ia++) {

    // tests are best conducted in the unrotated (simulation) frame
    cvm::rvector const atom_grad = (group->b_rotate ?
                                    rot_inv.rotate((*group)[ia].grad) :
                                    (*group)[ia].grad);
    gradient_sum += atom_grad;

    for (size_t id = 0; id < 3; id++) {
      // (re)read original positions
      group->read_positions();
      // change one coordinate
      (*group)[ia].pos[id] += cvm::debug_gradients_step_size;
      group->calc_required_properties();
      calc_value();
      cvm::real x_1 = x.real_value;
      if ((x.type() == colvarvalue::type_vector) && (x.size() == 1)) x_1 = x[0];
      cvm::log("Atom "+cvm::to_str(ia)+", component "+cvm::to_str(id)+":\n");
      cvm::log("dx(actual) = "+cvm::to_str(x_1 - x_0,
                            21, 14)+"\n");
      cvm::real const dx_pred = (group->fit_gradients.size()) ?
        (cvm::debug_gradients_step_size * (atom_grad[id] + group->fit_gradients[ia][id])) :
        (cvm::debug_gradients_step_size * atom_grad[id]);
      cvm::log("dx(interp) = "+cvm::to_str(dx_pred,
                            21, 14)+"\n");
      cvm::log("|dx(actual) - dx(interp)|/|dx(actual)| = "+
                cvm::to_str(std::fabs(x_1 - x_0 - dx_pred) /
                            std::fabs(x_1 - x_0), 12, 5)+"\n");
    }
  }

  if ((group->b_fit_gradients) && (group->ref_pos_group != NULL)) {
    cvm::atom_group *ref_group = group->ref_pos_group;
    group->read_positions();
    group->calc_required_properties();

    for (size_t ia = 0; ia < ref_group->size(); ia++) {

      // fit gradients are in the unrotated (simulation) frame
      cvm::rvector const atom_grad = ref_group->fit_gradients[ia];
      fit_gradient_sum += atom_grad;

      for (size_t id = 0; id < 3; id++) {
        // (re)read original positions
        group->read_positions();
        ref_group->read_positions();
        // change one coordinate
        (*ref_group)[ia].pos[id] += cvm::debug_gradients_step_size;
        group->calc_required_properties();
        calc_value();

        cvm::real const x_1 = x.real_value;
        cvm::log("refPosGroup atom "+cvm::to_str(ia)+", component "+cvm::to_str (id)+":\n");
        cvm::log("dx(actual) = "+cvm::to_str (x_1 - x_0,
                               21, 14)+"\n");

        cvm::real const dx_pred = cvm::debug_gradients_step_size * atom_grad[id];

        cvm::log("dx(interp) = "+cvm::to_str (dx_pred,
                               21, 14)+"\n");
        cvm::log ("|dx(actual) - dx(interp)|/|dx(actual)| = "+
                  cvm::to_str(std::fabs (x_1 - x_0 - dx_pred) /
                               std::fabs (x_1 - x_0),
                               12, 5)+
                  ".\n");
      }
    }
  }

  cvm::log("Gradient sum: " +  cvm::to_str(gradient_sum) +
        "  Fit gradient sum: " + cvm::to_str(fit_gradient_sum) +
        "  Total " + cvm::to_str(gradient_sum + fit_gradient_sum));

  return;
}
Esempio n. 2
0
void colvar::cvc::debug_gradients (cvm::atom_group &group)
{
  // this function should work for any scalar variable:
  // the only difference will be the name of the atom group (here, "group")

  if (group.b_dummy) return;

  cvm::rotation const rot_0 = group.rot;
  cvm::rotation const rot_inv = group.rot.inverse();

  cvm::real const x_0 = x.real_value;

  // cvm::log ("gradients     = "+cvm::to_str (gradients)+"\n");

  // it only makes sense to debug the fit gradients
  // when the fitting group is the same as this group
  if (group.b_rotate || group.b_center)
    if (group.b_fit_gradients && (group.ref_pos_group == NULL)) {
      group.calc_fit_gradients();
      if (group.b_rotate) {
        // fit_gradients are in the original frame, we should print them in the rotated frame
        for (size_t j = 0; j < group.fit_gradients.size(); j++) {
          group.fit_gradients[j] = rot_0.rotate (group.fit_gradients[j]);
        }
      }
      cvm::log ("fit_gradients = "+cvm::to_str (group.fit_gradients)+"\n");
      if (group.b_rotate) {
        for (size_t j = 0; j < group.fit_gradients.size(); j++) {
          group.fit_gradients[j] = rot_inv.rotate (group.fit_gradients[j]);
        }
      }
    }

  for (size_t ia = 0; ia < group.size(); ia++) {

    // tests are best conducted in the unrotated (simulation) frame
    cvm::rvector const atom_grad = group.b_rotate ?
      rot_inv.rotate (group[ia].grad) :
      group[ia].grad;

    for (size_t id = 0; id < 3; id++) {
      // (re)read original positions
      group.read_positions();
      // change one coordinate
      group[ia].pos[id] += cvm::debug_gradients_step_size;
      // (re)do the fit (if defined)
      if (group.b_center || group.b_rotate) {
        group.calc_apply_roto_translation();
      }
      calc_value();
      cvm::real const x_1 = x.real_value;
      cvm::log ("Atom "+cvm::to_str (ia)+", component "+cvm::to_str (id)+":\n");
      cvm::log ("dx(actual) = "+cvm::to_str (x_1 - x_0,
                             21, 14)+"\n");
      //cvm::real const dx_pred = (group.fit_gradients.size() && (group.ref_pos_group == NULL)) ?
      cvm::real const dx_pred = (group.fit_gradients.size()) ?
        (cvm::debug_gradients_step_size * (atom_grad[id] + group.fit_gradients[ia][id])) :
        (cvm::debug_gradients_step_size * atom_grad[id]);
      cvm::log ("dx(interp) = "+cvm::to_str (dx_pred,
                             21, 14)+"\n");
      cvm::log ("|dx(actual) - dx(interp)|/|dx(actual)| = "+
                cvm::to_str (std::fabs (x_1 - x_0 - dx_pred) /
                             std::fabs (x_1 - x_0), 12, 5)+"\n");
    }
  }

/*
 * The code below is WIP
 */
//   if (group.ref_pos_group != NULL) {
//     cvm::atom_group &ref = *group.ref_pos_group;
//     group.calc_fit_gradients();
//
//     for (size_t ia = 0; ia < ref.size(); ia++) {
//
//       for (size_t id = 0; id < 3; id++) {
//         // (re)read original positions
//         group.read_positions();
//         ref.read_positions();
//         // change one coordinate
//         ref[ia].pos[id] += cvm::debug_gradients_step_size;
//         group.calc_apply_roto_translation();
//         calc_value();
//         cvm::real const x_1 = x.real_value;
//         cvm::log ("refPosGroup atom "+cvm::to_str (ia)+", component "+cvm::to_str (id)+":\n");
//         cvm::log ("dx(actual) = "+cvm::to_str (x_1 - x_0,
//                                21, 14)+"\n");
//         //cvm::real const dx_pred = (group.fit_gradients.size() && (group.ref_pos_group == NULL)) ?
//         // cvm::real const dx_pred = (group.fit_gradients.size()) ?
//         //  (cvm::debug_gradients_step_size * (atom_grad[id] + group.fit_gradients[ia][id])) :
//         //  (cvm::debug_gradients_step_size * atom_grad[id]);
//         cvm::real const dx_pred = cvm::debug_gradients_step_size * ref.fit_gradients[ia][id];
//         cvm::log ("dx(interp) = "+cvm::to_str (dx_pred,
//                                21, 14)+"\n");
//         cvm::log ("|dx(actual) - dx(interp)|/|dx(actual)| = "+
//                   cvm::to_str (std::fabs (x_1 - x_0 - dx_pred) /
//                                std::fabs (x_1 - x_0),
//                                12, 5)+
//                   ".\n");
//       }
//     }
//   }

  return;
}