void Phrase::CreateFromString(const std::vector<FactorType> &factorOrder, const StringPiece &phraseString, const StringPiece &factorDelimiter)
{
  FactorCollection &factorCollection = FactorCollection::Instance();

  for (util::TokenIter<util::AnyCharacter, true> word_it(phraseString, util::AnyCharacter(" \t")); word_it; ++word_it) {
    Word &word = AddWord();
    size_t index = 0;
    for (util::TokenIter<util::MultiCharacter, false> factor_it(*word_it, util::MultiCharacter(factorDelimiter)); 
        factor_it && (index < factorOrder.size()); 
        ++factor_it, ++index) {
      word[factorOrder[index]] = factorCollection.AddFactor(*factor_it);
    }
    if (index != factorOrder.size()) {
      TRACE_ERR( "[ERROR] Malformed input: '" << *word_it << "'" <<  std::endl
                 << "In '" << phraseString << "'" << endl
                 << "  Expected input to have words composed of " << factorOrder.size() << " factor(s) (form FAC1|FAC2|...)" << std::endl
                 << "  but instead received input with " << index << " factor(s).\n");
      abort();
    }
  }
}
Example #2
0
	// This method does the actual simulation stuff
	// It runs for the indicated number of iterations           
  // restart=true means that the counting of iterations is started with the end
  // value of the previous run
	bool MicroCanonicalMD::simulateIterations(Size iterations, bool restart)
	{
		// local variables
		double current_energy = 0;
		Size max_number = 0;

		Atom *atom_ptr = 0;
		Size force_update_freq = 0;
		Size iteration = 0;

    if (!restart)
    {
      // reset the current number of iteration and the simulation time  to the values given
      // in the options 
      number_of_iteration_  = (Size)options.getInteger(MolecularDynamics::Option::NUMBER_OF_ITERATION);
      current_time_ = options.getReal(MolecularDynamics::Option::CURRENT_TIME);
    }
    else
    {
			// the values from the last simulation run are used; increase by one to start in the
			// next iteration 
			number_of_iteration_++; 
    }

		// determine the largest value for the iteration counter 
	  max_number = number_of_iteration_ + iterations;

		// pre-calculate some needed factors
	  calculateFactors();

		// make sure that the MD simulation operates on the same set of atoms
		// as the forcefield  does (this may have changed since setup was called)
	  atom_vector_ = force_field_ptr_->getAtoms();


		// First check whether the  force field and the MD instance
		// are valid
		if (!valid_ || force_field_ptr_ == 0 || !force_field_ptr_->isValid())
		{
			Log.error() << "MD simulation not possible! " << "MD class is  not valid." << std::endl;
			return false;
		}


		// Get the frequency for updating the Force Field pair lists
		force_update_freq = force_field_ptr_->getUpdateFrequency();

		// If the simulation runs with periodic boundary conditions, update the
		// list and position of molecules
		if (force_field_ptr_->periodic_boundary.isEnabled())
		{
			force_field_ptr_->periodic_boundary.updateMolecules();
		}

		// Calculate the forces at the beginning of the simulation
		force_field_ptr_->updateForces();

		// DEBUG ???
		//force_field_ptr_->updateEnergy();	
		// only done for debugging purposes 



		// This is the main loop of the MD simulation. The Velocity-Verlet method
		// is used for the propagation of atomic positions  and velocities 
		for (iteration = number_of_iteration_; iteration < max_number; iteration++)
		{
			// The force field data structures must be  updated regularly
			if (iteration % force_update_freq == 0)
			{
				force_field_ptr_->update();
			}

			// If the simulation runs with periodic boundary conditions, update the
			// list and position of molecules
			if (force_field_ptr_->periodic_boundary.isEnabled())
			{
				force_field_ptr_->periodic_boundary.updateMolecules();
			}

			// In regular intervals, calculate and  output the current energy
			if (iteration % energy_output_frequency_ == 0)
			{
				current_energy = force_field_ptr_->updateEnergy();
				updateInstantaneousTemperature();

				Log.info()
					<< "Microcanonical MD simulation System has potential energy "
					<< current_energy << " kJ/mol at time " << current_time_ + (double) iteration *time_step_ << " ps " << std::endl;

				Log.info()
					<< "Microcanonical MD simulation System has kinetic energy "
					<< kinetic_energy_ << " kJ/mol at time " << current_time_ + (double) iteration *time_step_ << " ps " << std::endl;        
			}

			// Calculate new atomic positions and new tentative velocities 
			vector<Atom*>::iterator atom_it(atom_vector_.begin());
			vector<AuxFactors>::iterator factor_it(mass_factor_.begin());
			for (; atom_it != atom_vector_.end(); ++atom_it, ++factor_it)
			{
				atom_ptr = *atom_it;

				// First calculate the new atomic position
				// x(t+1) = x(t) + time_step_ * v(t) + time_step_^2/(2*mass) * F(t)
				atom_ptr->setPosition(atom_ptr->getPosition()
															 + (float)time_step_ * atom_ptr->getVelocity() + (float)factor_it->factor1 * atom_ptr->getForce());

				// calculate a tentative  velocity 'v_tent' for the next iteration
				// v_tent(t+1) = v(t) + time_step_ / (2 * mass) * F(t)
				atom_ptr->setVelocity(atom_ptr->getVelocity() + (float)factor_it->factor2 * atom_ptr->getForce());
			}	// next atom 


			// Determine the forces for the next iteration
			force_field_ptr_->updateForces();

			for (atom_it = atom_vector_.begin(),
					 factor_it = mass_factor_.begin(); atom_it != atom_vector_.end(); ++atom_it, ++factor_it)
			{
				atom_ptr = *atom_it;

				// Calculate the final velocity for the next iteration
				atom_ptr->setVelocity(atom_ptr->getVelocity() + (float)factor_it->factor2 * atom_ptr->getForce());
			}	// next atom

			// Take a snapshot in regular intervals if desired              
			if (snapshot_manager_ptr_ != 0 && iteration % snapshot_frequency_ == 0)
			{
				snapshot_manager_ptr_->takeSnapShot();
			}

			if (abort_by_energy_enabled_)
			{
				if ((Maths::isNan(force_field_ptr_->getEnergy()))
					|| (force_field_ptr_->getEnergy() > abort_energy_))
				{
					return false;
				}
			}

		}	// next iteration 

		// update the current time
		current_time_ += (double)iterations * time_step_;

    // set the current iteration
    number_of_iteration_ = iteration - 1; 

		// update the current temperature in the system
		force_field_ptr_->updateEnergy();
		updateInstantaneousTemperature();

		return true;
	}	// end of simulateIterations()