示例#1
0
// #include <QuantumStateITPP.h>
template <class StateType> StateType StateTensor(const StateType& psi_1, const StateType& psi_2){
	StateType tmp(psi_1.size()*psi_2.size());
	for (int i =0; i<psi_1.size(); i++){
		tmp.coefficients.set_subvector(i*psi_2.size(),psi_1.coefficients(i)*psi_2.coefficients);
	}
	return tmp;
}
void  VarianceDiffusionStrategy<StateType>::diffuse(const ParticleList &_src, ParticleList &_dest)
{
	if(_src.size() == 0) return;
	if(_dest.size() != _src.size()) _dest = _src;

	const unsigned numDofs = _src[0].state.size();

	unsigned index = 0;
	StateType noise = _dest[0].state;

	if(mVariance.size() != noise.size())
	{
		TRACE("------------- variance has wrong size. (should not be possible) ---------- ABORTING");
		return;
	}

	if(mVarianceFactor.size() != noise.size())
	{
		TRACE("----------resizing variance factors. (should not happen) -------------- ");
		mVarianceFactor.resize(noise.size(), 1);
	}

	// iterate over all source particles
	for(ParticleListConstIterator it = _src.begin(); it != _src.end(); it++)
	{
		// for every dof
		for(unsigned i=0; i < numDofs; i++)
		{
			noise[i] = this->mNormDistGenerator() *  mVariance[i] * mVarianceFactor[i];
		}

		_dest[index].state = noise;
		_dest[index].state += _src[index].state;

		index++;
	}
}
示例#3
0
void
RigidBody::GetState(StateType& State)
{
	// Copy the elements of the member variables that describe the state of 
	// the rigid body into the state vector.
	StateType::iterator it = State.begin();
	if (State.size() != m_CountStateVectors)
	{
		State.resize(m_CountStateVectors);
	}
	*it++ = m_Position;
	*it++ = bnu::column(m_Rotate, 0);
	*it++ = bnu::column(m_Rotate, 1);
	*it++ = bnu::column(m_Rotate, 2);
	*it++ = m_AngularMomentum;
	*it = m_LinearMomentum;
}
示例#4
0
void
RigidBody::GetStateDerivative(StateType& State)
{
	//Work out the state derivatives and place them in State
	StateType::iterator it = State.begin();
	bnu::vector<double> AngularMomentum;
	bnu::vector<double> Temp0;
	bnu::vector<double> Temp1;
	if (State.size() != m_CountStateVectors)
	{
		State.resize(m_CountStateVectors);
	}
	bnu::vector<double> LinearVelocity(m_LinearMomentum/m_Mass);

	/* Inertia Tensor = R*IBodyInv*RTranspose*/
	bnu::matrix<double> InertiaTensorInv((bnu::prod(m_Rotate, m_BodySpaceInertiaTensorInv)));
	InertiaTensorInv = bnu::prod(InertiaTensorInv, bnu::trans(m_Rotate));

	/* omega = IInv * angularmomentum*/
	bnu::vector<double> Omega(bnu::prod(InertiaTensorInv, m_AngularMomentum));

	*it++ = LinearVelocity;

	/* work out the derivative of R(t) and copy the result into the state array*/
	Temp0 = bnu::column(m_Rotate, 0);
	Cross(m_AngularMomentum, Temp0, Temp1);
	*it++ = Temp1;

	Temp0 = bnu::column(m_Rotate, 1);
	Cross(m_AngularMomentum, Temp0, Temp1);
	*it++ = Temp1;

	Temp0 = bnu::column(m_Rotate, 2);
	Cross(m_AngularMomentum, Temp0, Temp1);
	*it++ = Temp1;

	/* copy force and torque into the array */
	*it++ = m_Force;
	*it++ = m_Torque;

}
inline int CashKarp54(const SystemType &dxdt, StateType &x, double &t,
                      double &h, double relTol, double absTol,
                      double maxStepSize) {
  // Constants from Butcher tableau, see: http://en.wikipedia.org/wiki/Cash-Karp_method
  // and http://en.wikipedia.org/wiki/Runge-Kutta_methods
  const double c2 = 1.0 / 5.0;
  const double c3 = 3.0 / 10.0;
  const double c4 = 3.0 / 5.0;
  const double c5 = 1.0;
  const double c6 = 7.0 / 8.0;

  const double b5th1 = 37.0 / 378.0;
  const double b5th2 = 0.0;
  const double b5th3 = 250.0 / 621.0;
  const double b5th4 = 125.0 / 594.0;
  const double b5th5 = 0.0;
  const double b5th6 = 512.0 / 1771.0;

  const double b4th1 = 2825.0 / 27648.0;
  const double b4th2 = 0.0;
  const double b4th3 = 18575.0 / 48384.0;
  const double b4th4 = 13525.0 / 55296.0;
  const double b4th5 = 277.0 / 14336.0;
  const double b4th6 = 1.0 / 4.0;

  const double bDiff1 = b5th1 - b4th1;
  const double bDiff2 = b5th2 - b4th2;
  const double bDiff3 = b5th3 - b4th3;
  const double bDiff4 = b5th4 - b4th4;
  const double bDiff5 = b5th5 - b4th5;
  const double bDiff6 = b5th6 - b4th6;

  const double a21 = 1.0 / 5.0;
  const double a31 = 3.0 / 40.0;
  const double a32 = 9.0 / 40.0;
  const double a41 = 3.0 / 10.0;
  const double a42 = -9.0 / 10.0;
  const double a43 = 6.0 / 5.0;
  const double a51 = -11.0 / 54.0;
  const double a52 = 5.0 / 2.0;
  const double a53 = -70.0 / 27.0;
  const double a54 = 35.0 / 27.0;
  const double a61 = 1631.0 / 55296.0;
  const double a62 = 175.0 / 512.0;
  const double a63 = 575.0 / 13824.0;
  const double a64 = 44275.0 / 110592.0;
  const double a65 = 253.0 / 4096.0;

  const std::size_t stateSize = x.size();
  StateType tempState; // used to store state for next k value and later used
                       // for error difference

  StateType k1;
  dxdt(x, k1, t); // fill k1

  for (std::size_t i = 0; i < stateSize; ++i)
    tempState[i] = x[i] + h * a21 * k1[i];
  StateType k2;
  dxdt(tempState, k2, t + c2 * h); // fill k2

  for (std::size_t i = 0; i < stateSize; ++i)
    tempState[i] = x[i] + h * (a31 * k1[i] + a32 * k2[i]);
  StateType k3;
  dxdt(tempState, k3, t + c3 * h); // fill k3

  for (std::size_t i = 0; i < stateSize; ++i)
    tempState[i] = x[i] + h * (a41 * k1[i] + a42 * k2[i] + a43 * k3[i]);
  StateType k4;
  dxdt(tempState, k4, t + c4 * h); // fill k4

  for (std::size_t i = 0; i < stateSize; ++i)
    tempState[i] =
        x[i] +
        h * (a51 * k1[i] + a52 * k2[i] + a53 * k3[i] + a54 * k4[i]);
  StateType k5;
  dxdt(tempState, k5, t + c5 * h); // fill k5

  for (std::size_t i = 0; i < stateSize; ++i)
    tempState[i] = x[i] +
                   h * (a61 * k1[i] + a62 * k2[i] + a63 * k3[i] +
                        a64 * k4[i] + a65 * k5[i]);
  StateType k6;
  dxdt(tempState, k6, t + c6 * h); // fill k6

  StateType order5Solution;
  for (std::size_t i = 0; i < stateSize; ++i)
    order5Solution[i] =
        h * (b5th1 * k1[i] + b5th2 * k2[i] + b5th3 * k3[i] +
             b5th4 * k4[i] + b5th5 * k5[i] + b5th6 * k6[i]);

  // difference between order 4 and 5, used for error check, reusing tempState
  // variable
  for (std::size_t i = 0; i < stateSize; ++i)
    tempState[i] = h * (bDiff1 * k1[i] + bDiff2 * k2[i] + bDiff3 * k3[i] +
                        bDiff4 * k4[i] + bDiff5 * k5[i] + bDiff6 * k6[i]);

  StateType potentialSolution;
  for (std::size_t i = 0; i < stateSize; ++i)
    potentialSolution[i] = x[i] + order5Solution[i];

  // boost odeint syle error step sizing method
  StateType errorValueList;
  for (std::size_t i = 0; i < stateSize; ++i)
    errorValueList[i] =
        std::abs(tempState[i] / (absTol + relTol * (potentialSolution[i])));
  double maxErrorValue =
      *(std::max_element(errorValueList.begin(), errorValueList.end()));

  // reject step and decrease step size
  if (maxErrorValue > 1.0) {
    h = h * std::max(0.9 * std::pow(maxErrorValue, -0.25), 0.2);
    return 0;
  }

  // use the step
  t += h;
  for (std::size_t i = 0; i < stateSize; ++i)
      x[i] = potentialSolution[i];

  // if error is small enough then increase step size
  if (maxErrorValue < 0.5) {
    h = std::min(h * std::min(0.9 * std::pow(maxErrorValue, -0.20), 5.0),
                 maxStepSize);
  }

  return 1;
}