Exemple #1
0
/*! Given a level of active and passive forces MAGNITUDES this 
	computes what force is applied at each insertion point, and in 
	what DIRECTION.	Geometry needs to be up-to-date 
	(use updateGeometry() ).
*/
void Tendon::updateInsertionForces()
{
	SbVec3f pPrev,pCur,pNext;
	position tmpPos;
	vec3 dPrev,dNext,dRes,c;

	std::list<TendonInsertionPoint*>::iterator insPt, prevInsPt, nextInsPt, newInsPt;

	for (insPt=insPointList.begin(); insPt!=insPointList.end(); insPt++)
	{
		prevInsPt = insPt;
		nextInsPt = insPt;
		nextInsPt ++;

		if (insPt!=insPointList.begin())
		{
			prevInsPt--;
			pPrev = (*prevInsPt)->getWorldPosition();
		}

		pCur = (*insPt)->getWorldPosition();
		
		if (nextInsPt != insPointList.end() )
			pNext = (*nextInsPt)->getWorldPosition();
		
		/*compute resultant force on insertion point*/
		if (insPt == insPointList.begin())
		{
			/*first insertion point: no force at the moment*/
			(*insPt)->insertionForce=vec3(0,0,0);
		}
		else if ( nextInsPt != insPointList.end() )
		{
			/*middle insertion points: force is resultant of forces along connectors to pPrev and pNext*/
			dPrev = vec3(pPrev) - vec3(pCur);
			dNext = vec3(pNext) - vec3(pCur);
			dPrev = ( (float)1 / dPrev.len() ) * dPrev;
			dNext = ( (float)1 / dNext.len() ) * dNext;
			dRes = getTotalForce() * (dPrev + dNext);
			(*insPt)->insertionForce = dRes;
		}
		else
		{
			/*last insertion point: force is applied in direction to pPrev */
			dPrev = vec3(pPrev) - vec3(pCur);
			dPrev = ( (float)1 / dPrev.len() ) * dPrev;
			dRes = getTotalForce() * dPrev;
			(*insPt)->insertionForce = dRes;
		}
	}
}
	void CSPhysXObject_Character::frame(const float &elapsedtime)
	{
		float et = elapsedtime;
		
		// add the gravity each frame
		PxVec3 disp(0,0,0);
		if (!m_Jumping) disp = PxVec3(0, -32.0f, 0);
		vector3df tf = getTotalForce();
		m_TotalForce = vector3df(0, 0, 0);
		disp += PxVec3(tf.X, tf.Y, tf.Z);
		disp.y += getHeight(et);
		PxU32 collisionFlags = moveCharacter(disp, et, 0);
		if (collisionFlags & PxControllerFlag::eCOLLISION_DOWN) stopJump();
		
	}
Exemple #3
0
void Tendon::applyForces()
{
	Link *link;
	vec3 force;
	position pos;
	SbVec3f tmp;
	std::list<TendonInsertionPoint*>::iterator insPt;

	if (getTotalForce() > 0)
		for (insPt=insPointList.begin(); insPt!=insPointList.end(); insPt++)
		{
			link = (*insPt)->getAttachedLink();	
			/*convert insertion point location to world coordinates*/
			tmp = ( (*insPt)->attachPoint ).toSbVec3f();
			pos = position(tmp) * ( link->getTran() );

			/*insertion point force is already stored in world coordinates*/
			force = (*insPt)->insertionForce; 
			link->addForceAtPos( force , pos );
		}
}
Exemple #4
0
void colvarproxy_namd::calculate()
{
  if (first_timestep) {

    this->setup();
    colvars->setup();
    colvars->setup_input();
    colvars->setup_output();

    first_timestep = false;

  } else {
    // Use the time step number inherited from GlobalMaster
    if ( step - previous_NAMD_step == 1 ) {
      colvars->it++;
    }
    // Other cases could mean:
    // - run 0
    // - beginning of a new run statement
    // then the internal counter should not be incremented
  }

  previous_NAMD_step = step;

  {
    Vector const a = lattice->a();
    Vector const b = lattice->b();
    Vector const c = lattice->c();
    unit_cell_x.set(a.x, a.y, a.z);
    unit_cell_y.set(b.x, b.y, c.z);
    unit_cell_z.set(c.x, c.y, c.z);
  }

  if (!lattice->a_p() && !lattice->b_p() && !lattice->c_p()) {
    boundaries_type = boundaries_non_periodic;
    reset_pbc_lattice();
  } else if (lattice->a_p() && lattice->b_p() && lattice->c_p()) {
    if (lattice->orthogonal()) {
      boundaries_type = boundaries_pbc_ortho;
    } else {
      boundaries_type = boundaries_pbc_triclinic;
    }
    colvarproxy_system::update_pbc_lattice();
  } else {
    boundaries_type = boundaries_unsupported;
  }

  if (cvm::debug()) {
    log(std::string(cvm::line_marker)+
        "colvarproxy_namd, step no. "+cvm::to_str(colvars->it)+"\n"+
        "Updating atomic data arrays.\n");
  }

  // must delete the forces applied at the previous step: we can do
  // that because they have already been used and copied to other
  // memory locations
  modifyForcedAtoms().clear();
  modifyAppliedForces().clear();

  // prepare local arrays
  for (size_t i = 0; i < atoms_ids.size(); i++) {
    atoms_positions[i] = cvm::rvector(0.0, 0.0, 0.0);
    atoms_total_forces[i] = cvm::rvector(0.0, 0.0, 0.0);
    atoms_new_colvar_forces[i] = cvm::rvector(0.0, 0.0, 0.0);
  }

  for (size_t i = 0; i < atom_groups_ids.size(); i++) {
    atom_groups_total_forces[i] = cvm::rvector(0.0, 0.0, 0.0);
    atom_groups_new_colvar_forces[i] = cvm::rvector(0.0, 0.0, 0.0);
  }

  // create the atom map if needed
  size_t const n_all_atoms = Node::Object()->molecule->numAtoms;
  if (atoms_map.size() != n_all_atoms) {
    atoms_map.resize(n_all_atoms);
    atoms_map.assign(n_all_atoms, -1);
    update_atoms_map(getAtomIdBegin(), getAtomIdEnd());
  }

  // if new atomic positions or forces have been communicated by other GlobalMasters, add them to the atom map
  if ((int(atoms_ids.size()) < (getAtomIdEnd() - getAtomIdBegin())) ||
      (int(atoms_ids.size()) < (getForceIdEnd() - getForceIdBegin()))) {
    update_atoms_map(getAtomIdBegin(), getAtomIdEnd());
    update_atoms_map(getForceIdBegin(), getForceIdEnd());
  }

  {
    if (cvm::debug()) {
      log("Updating positions arrays.\n");
    }
    size_t n_positions = 0;
    AtomIDList::const_iterator a_i = getAtomIdBegin();
    AtomIDList::const_iterator a_e = getAtomIdEnd();
    PositionList::const_iterator p_i = getAtomPositionBegin();

    for ( ; a_i != a_e; ++a_i, ++p_i ) {
      atoms_positions[atoms_map[*a_i]] = cvm::rvector((*p_i).x, (*p_i).y, (*p_i).z);
      n_positions++;
    }

    // The following had to be relaxed because some atoms may be forced without their position being requested
    // if (n_positions < atoms_ids.size()) {
    //   cvm::error("Error: did not receive the positions of all atoms.\n", BUG_ERROR);
    // }
  }

  if (total_force_requested && cvm::step_relative() > 0) {

    // sort the force arrays the previous step
    // (but only do so if there *is* a previous step!)

    {
      if (cvm::debug()) {
        log("Updating total forces arrays.\n");
      }
      size_t n_total_forces = 0;
      AtomIDList::const_iterator a_i = getForceIdBegin();
      AtomIDList::const_iterator a_e = getForceIdEnd();
      ForceList::const_iterator f_i = getTotalForce();

      for ( ; a_i != a_e; ++a_i, ++f_i ) {
        atoms_total_forces[atoms_map[*a_i]] = cvm::rvector((*f_i).x, (*f_i).y, (*f_i).z);
        n_total_forces++;
      }

      if (n_total_forces < atoms_ids.size()) {
        cvm::error("Error: total forces were requested, but total forces "
                   "were not received for all atoms.\n"
                   "The most probable cause is combination of energy "
                   "minimization with a biasing method that requires MD (e.g. ABF).\n"
                   "Always run minimization and ABF separately.", INPUT_ERROR);
      }
    }

    {
      if (cvm::debug()) {
        log("Updating group total forces arrays.\n");
      }
      ForceList::const_iterator f_i = getGroupTotalForceBegin();
      ForceList::const_iterator f_e = getGroupTotalForceEnd();
      size_t i = 0;
      if ((f_e - f_i) != ((int) atom_groups_ids.size())) {
        cvm::error("Error: total forces were requested for scalable groups, "
                   "but they are not in the same number from the number of groups.\n"
                   "The most probable cause is combination of energy "
                   "minimization with a biasing method that requires MD (e.g. ABF).\n"
                   "Always run minimization and ABF separately.", INPUT_ERROR);
      }
      for ( ; f_i != f_e; f_i++, i++) {
        atom_groups_total_forces[i] = cvm::rvector((*f_i).x, (*f_i).y, (*f_i).z);
      }
    }
  }

  {
    if (cvm::debug()) {
      log("Updating group positions arrays.\n");
    }
    // update group data (only coms available so far)
    size_t ig;
    // note: getGroupMassBegin() could be used here, but masses and charges
    // have already been calculated from the last call to setup()
    PositionList::const_iterator gp_i = getGroupPositionBegin();
    for (ig = 0; gp_i != getGroupPositionEnd(); gp_i++, ig++) {
      atom_groups_coms[ig] = cvm::rvector(gp_i->x, gp_i->y, gp_i->z);
    }
  }

  if (cvm::debug()) {
    log("atoms_ids = "+cvm::to_str(atoms_ids)+"\n");
    log("atoms_ncopies = "+cvm::to_str(atoms_ncopies)+"\n");
    log("atoms_masses = "+cvm::to_str(atoms_masses)+"\n");
    log("atoms_charges = "+cvm::to_str(atoms_charges)+"\n");
    log("atoms_positions = "+cvm::to_str(atoms_positions)+"\n");
    log("atoms_total_forces = "+cvm::to_str(atoms_total_forces)+"\n");
    log(cvm::line_marker);

    log("atom_groups_ids = "+cvm::to_str(atom_groups_ids)+"\n");
    log("atom_groups_ncopies = "+cvm::to_str(atom_groups_ncopies)+"\n");
    log("atom_groups_masses = "+cvm::to_str(atom_groups_masses)+"\n");
    log("atom_groups_charges = "+cvm::to_str(atom_groups_charges)+"\n");
    log("atom_groups_coms = "+cvm::to_str(atom_groups_coms)+"\n");
    log("atom_groups_total_forces = "+cvm::to_str(atom_groups_total_forces)+"\n");
    log(cvm::line_marker);
  }

  // call the collective variable module
  if (colvars->calc() != COLVARS_OK) {
    cvm::error("Error in the collective variables module.\n", COLVARS_ERROR);
  }

  if (cvm::debug()) {
    log(cvm::line_marker);
    log("atoms_new_colvar_forces = "+cvm::to_str(atoms_new_colvar_forces)+"\n");
    log(cvm::line_marker);
    log("atom_groups_new_colvar_forces = "+cvm::to_str(atom_groups_new_colvar_forces)+"\n");
    log(cvm::line_marker);
  }

  // communicate all forces to the MD integrator
  for (size_t i = 0; i < atoms_ids.size(); i++) {
    cvm::rvector const &f = atoms_new_colvar_forces[i];
    modifyForcedAtoms().add(atoms_ids[i]);
    modifyAppliedForces().add(Vector(f.x, f.y, f.z));
  }

  {
    // zero out the applied forces on each group
    modifyGroupForces().resize(modifyRequestedGroups().size());
    ForceList::iterator gf_i = modifyGroupForces().begin();
    for (int ig = 0; gf_i != modifyGroupForces().end(); gf_i++, ig++) {
      cvm::rvector const &f = atom_groups_new_colvar_forces[ig];
      *gf_i = Vector(f.x, f.y, f.z);
    }
  }

  // send MISC energy
  reduction->submit();

  // NAMD does not destruct GlobalMaster objects, so we must remember
  // to write all output files at the end of a run
  if (step == simparams->N) {
    colvars->write_restart_file(cvm::output_prefix()+".colvars.state");
    colvars->write_output_files();
  }
}