<commit_before>
#pragma once

#include "physics/rigid_motion.hpp"

#include <utility>

#include "geometry/identity.hpp"
#include "geometry/linear_map.hpp"

namespace principia {
namespace physics {
namespace internal_rigid_motion {

using geometry::LinearMap;

template<typename FromFrame, typename ToFrame>
RigidMotion<FromFrame, ToFrame>::RigidMotion(
    RigidTransformation<FromFrame, ToFrame> const& rigid_transformation,
    AngularVelocity<FromFrame> const& angular_velocity_of_to_frame,
    Velocity<FromFrame> const& velocity_of_to_frame_origin)
    : rigid_transformation_(rigid_transformation),
      angular_velocity_of_to_frame_(angular_velocity_of_to_frame),
      velocity_of_to_frame_origin_(velocity_of_to_frame_origin) {}

template<typename FromFrame, typename ToFrame>
template<typename F, typename T, typename>
RigidMotion<FromFrame, ToFrame>::RigidMotion(
    RigidTransformation<FromFrame, ToFrame> const& rigid_transformation,
    AngularVelocity<ToFrame> const& angular_velocity_of_from_frame,
    Velocity<ToFrame> const& velocity_of_from_frame_origin)
    : RigidMotion(
          RigidMotion<ToFrame, FromFrame>(rigid_transformation.Inverse(),
                                          angular_velocity_of_from_frame,
                                          velocity_of_from_frame_origin)
              .Inverse()) {}

template<typename FromFrame, typename ToFrame>
RigidTransformation<FromFrame, ToFrame> const&
RigidMotion<FromFrame, ToFrame>::rigid_transformation() const {
  return rigid_transformation_;
}

template<typename FromFrame, typename ToFrame>
OrthogonalMap<FromFrame, ToFrame> const&
RigidMotion<FromFrame, ToFrame>::orthogonal_map() const {
  return rigid_transformation_.linear_map();
}

template<typename FromFrame, typename ToFrame>
template<typename F>
AngularVelocity<
    typename RigidMotion<FromFrame, ToFrame>::template other_frame_t<F>>
RigidMotion<FromFrame, ToFrame>::angular_velocity_of() const {
  if constexpr (std::is_same_v<F, ToFrame>) {
    return angular_velocity_of_to_frame_;
  } else if constexpr (std::is_same_v<F, FromFrame>) {
    return Inverse().angular_velocity_of_to_frame_;
  } else {
    static_assert(std::disjunction_v<std::is_same<F, ToFrame>,
                                     std::is_same<F, FromFrame>>,
                  "Nonsensical frame");
  }
}

template<typename FromFrame, typename ToFrame>
template<typename F>
Velocity<typename RigidMotion<FromFrame, ToFrame>::template other_frame_t<F>>
RigidMotion<FromFrame, ToFrame>::velocity_of_origin_of() const {
  if constexpr (std::is_same_v<F, ToFrame>) {
    return velocity_of_to_frame_origin_;
  } else if constexpr (std::is_same_v<F, FromFrame>) {
    return Inverse().velocity_of_to_frame_origin_;
  } else {
    static_assert(std::disjunction_v<std::is_same<F, ToFrame>,
                                     std::is_same<F, FromFrame>>,
                  "Nonsensical frame");
  }
}

template<typename FromFrame, typename ToFrame>
DegreesOfFreedom<ToFrame> RigidMotion<FromFrame, ToFrame>::operator()(
    DegreesOfFreedom<FromFrame> const& degrees_of_freedom) const {
  return {rigid_transformation_(degrees_of_freedom.position()),
          orthogonal_map()(
              degrees_of_freedom.velocity() - velocity_of_to_frame_origin_ -
              angular_velocity_of_to_frame_ *
                  (degrees_of_freedom.position() -
                   rigid_transformation_.Inverse()(ToFrame::origin)) /
                  Radian)};
}

template<typename FromFrame, typename ToFrame>
RigidMotion<ToFrame, FromFrame>
RigidMotion<FromFrame, ToFrame>::Inverse() const {
  return RigidMotion<ToFrame, FromFrame>(
      rigid_transformation_.Inverse(),
      -orthogonal_map()(angular_velocity_of_to_frame_),
      (*this)({FromFrame::origin, FromFrame::unmoving}).velocity());
}

template<typename FromFrame, typename ToFrame>
RigidMotion<FromFrame, ToFrame>
RigidMotion<FromFrame, ToFrame>::MakeNonRotatingMotion(
    DegreesOfFreedom<ToFrame> const& degrees_of_freedom_of_from_frame_origin) {
  if constexpr (FromFrame::handedness == ToFrame::handedness) {
    return RigidMotion(RigidTransformation<FromFrame, ToFrame>(
                           FromFrame::origin,
                           degrees_of_freedom_of_from_frame_origin.position(),
                           geometry::Identity<FromFrame, ToFrame>().Forget()),
                       ToFrame::nonrotating,
                       degrees_of_freedom_of_from_frame_origin.velocity());
  } else {
    // TODO(phl): This is extremely dubious.  We apply the sun_looking_glass
    // permutation because we "know" that we have World and RigidPart here.
    return RigidMotion(
        RigidTransformation<FromFrame, ToFrame>(
            FromFrame::origin,
            degrees_of_freedom_of_from_frame_origin.position(),
            geometry::Permutation<FromFrame, ToFrame>(
                geometry::Permutation<FromFrame,
                                      ToFrame>::CoordinatePermutation::XZY)
                .template Forget<OrthogonalMap>()),
        ToFrame::nonrotating,
        degrees_of_freedom_of_from_frame_origin.velocity());
  }
}

template<typename FromFrame, typename ToFrame>
void RigidMotion<FromFrame, ToFrame>::WriteToMessage(
    not_null<serialization::RigidMotion*> const message) const {
  rigid_transformation_.WriteToMessage(message->mutable_rigid_transformation());
  angular_velocity_of_to_frame_.WriteToMessage(
      message->mutable_angular_velocity_of_to_frame());
  velocity_of_to_frame_origin_.WriteToMessage(
      message->mutable_velocity_of_to_frame_origin());
}

template<typename FromFrame, typename ToFrame>
RigidMotion<FromFrame, ToFrame>
RigidMotion<FromFrame, ToFrame>::ReadFromMessage(
    serialization::RigidMotion const& message) {
  return RigidMotion(RigidTransformation<FromFrame, ToFrame>::ReadFromMessage(
                         message.rigid_transformation()),
                     AngularVelocity<FromFrame>::ReadFromMessage(
                         message.angular_velocity_of_to_frame()),
                     Velocity<FromFrame>::ReadFromMessage(
                         message.velocity_of_to_frame_origin()));
}

template<typename FromFrame, typename ToFrame>
template<typename F, typename T, typename>
RigidMotion<FromFrame, ToFrame> RigidMotion<FromFrame, ToFrame>::Identity() {
  return RigidMotion(RigidTransformation<FromFrame, ToFrame>::Identity(),
                     FromFrame::nonrotating,
                     FromFrame::unmoving);
}

template<typename FromFrame, typename ThroughFrame, typename ToFrame>
RigidMotion<FromFrame, ToFrame> operator*(
    RigidMotion<ThroughFrame, ToFrame> const& left,
    RigidMotion<FromFrame, ThroughFrame> const& right) {
  return RigidMotion<FromFrame, ToFrame>(
      left.rigid_transformation() * right.rigid_transformation(),
      right.angular_velocity_of_to_frame_ +
          right.orthogonal_map().Inverse()(left.angular_velocity_of_to_frame_),
      right.Inverse()(left.Inverse()(
          {ToFrame::origin, ToFrame::unmoving})).velocity());
}

template<typename FromFrame, typename ToFrame>
std::ostream& operator<<(std::ostream& out,
                         RigidMotion<FromFrame, ToFrame> const& rigid_motion) {
  return out << "{transformation: " << rigid_motion.rigid_transformation()
             << ", angular velocity: "
             << rigid_motion.template angular_velocity_of<ToFrame>()
             << ", velocity: "
             << rigid_motion.template velocity_of_origin_of<ToFrame>()
             << "}";
}

template<typename FromFrame, typename ToFrame>
std::ostream& operator<<(std::ostream& out,
                         AcceleratedRigidMotion<FromFrame, ToFrame> const&
                             accelerated_rigid_motion) {
  return out
         << "{motion: " << accelerated_rigid_motion.rigid_motion()
         << ", angular acceleration: "
         << accelerated_rigid_motion.template angular_acceleration_of<ToFrame>()
         << ", acceleration: "
         << accelerated_rigid_motion
                .template acceleration_of_origin_of<ToFrame>()
         << "}";
}

template<typename FromFrame, typename ToFrame>
AcceleratedRigidMotion<FromFrame, ToFrame>::AcceleratedRigidMotion(
    RigidMotion<FromFrame, ToFrame> const& rigid_motion,
    Bivector<AngularAcceleration, FromFrame> const&
        angular_acceleration_of_to_frame,
    Vector<Acceleration, FromFrame> const& acceleration_of_to_frame_origin)
    : rigid_motion_(rigid_motion),
      angular_acceleration_of_to_frame_(angular_acceleration_of_to_frame),
      acceleration_of_to_frame_origin_(acceleration_of_to_frame_origin) {}

template<typename FromFrame, typename ToFrame>
RigidMotion<FromFrame, ToFrame> const&
AcceleratedRigidMotion<FromFrame, ToFrame>::rigid_motion() const {
  return rigid_motion_;
}

template<typename FromFrame, typename ToFrame>
template<typename F>
Bivector<AngularAcceleration,
         typename AcceleratedRigidMotion<FromFrame, ToFrame>::
             template other_frame_t<F>>
AcceleratedRigidMotion<FromFrame, ToFrame>::angular_acceleration_of() const {
  if constexpr (std::is_same_v<F, ToFrame>) {
    return angular_acceleration_of_to_frame_;
  } else if constexpr (std::is_same_v<F, FromFrame>) {
    static_assert(!std::is_same_v<F, FromFrame>,
                  "Time to implement AcceleratedRigidMotion::Inverse");
  } else {
    static_assert(std::is_same_v<F, ToFrame> || std::is_same_v<F, FromFrame>,
                  "Nonsensical frame");
  }
}

template<typename FromFrame, typename ToFrame>
template<typename F>
Vector<Acceleration,
       typename AcceleratedRigidMotion<FromFrame, ToFrame>::
           template other_frame_t<F>>
AcceleratedRigidMotion<FromFrame, ToFrame>::acceleration_of_origin_of() const {
  if constexpr (std::is_same_v<F, ToFrame>) {
    return acceleration_of_to_frame_origin_;
  } else if constexpr (std::is_same_v<F, FromFrame>) {
    static_assert(!std::is_same_v<F, FromFrame>,
                  "Time to implement AcceleratedRigidMotion::Inverse");
  } else {
    static_assert(std::is_same_v<F, ToFrame> || std::is_same_v<F, FromFrame>,
                  "Nonsensical frame");
  }
}

}  // namespace internal_rigid_motion
}  // namespace physics
}  // namespace principia
<commit_msg>Some more disjunctions.<commit_after>
#pragma once

#include "physics/rigid_motion.hpp"

#include <utility>

#include "geometry/identity.hpp"
#include "geometry/linear_map.hpp"

namespace principia {
namespace physics {
namespace internal_rigid_motion {

using geometry::LinearMap;

template<typename FromFrame, typename ToFrame>
RigidMotion<FromFrame, ToFrame>::RigidMotion(
    RigidTransformation<FromFrame, ToFrame> const& rigid_transformation,
    AngularVelocity<FromFrame> const& angular_velocity_of_to_frame,
    Velocity<FromFrame> const& velocity_of_to_frame_origin)
    : rigid_transformation_(rigid_transformation),
      angular_velocity_of_to_frame_(angular_velocity_of_to_frame),
      velocity_of_to_frame_origin_(velocity_of_to_frame_origin) {}

template<typename FromFrame, typename ToFrame>
template<typename F, typename T, typename>
RigidMotion<FromFrame, ToFrame>::RigidMotion(
    RigidTransformation<FromFrame, ToFrame> const& rigid_transformation,
    AngularVelocity<ToFrame> const& angular_velocity_of_from_frame,
    Velocity<ToFrame> const& velocity_of_from_frame_origin)
    : RigidMotion(
          RigidMotion<ToFrame, FromFrame>(rigid_transformation.Inverse(),
                                          angular_velocity_of_from_frame,
                                          velocity_of_from_frame_origin)
              .Inverse()) {}

template<typename FromFrame, typename ToFrame>
RigidTransformation<FromFrame, ToFrame> const&
RigidMotion<FromFrame, ToFrame>::rigid_transformation() const {
  return rigid_transformation_;
}

template<typename FromFrame, typename ToFrame>
OrthogonalMap<FromFrame, ToFrame> const&
RigidMotion<FromFrame, ToFrame>::orthogonal_map() const {
  return rigid_transformation_.linear_map();
}

template<typename FromFrame, typename ToFrame>
template<typename F>
AngularVelocity<
    typename RigidMotion<FromFrame, ToFrame>::template other_frame_t<F>>
RigidMotion<FromFrame, ToFrame>::angular_velocity_of() const {
  if constexpr (std::is_same_v<F, ToFrame>) {
    return angular_velocity_of_to_frame_;
  } else if constexpr (std::is_same_v<F, FromFrame>) {
    return Inverse().angular_velocity_of_to_frame_;
  } else {
    static_assert(std::is_same_v<F, ToFrame> || std::is_same_v<F, FromFrame>,
                  "Nonsensical frame");
  }
}

template<typename FromFrame, typename ToFrame>
template<typename F>
Velocity<typename RigidMotion<FromFrame, ToFrame>::template other_frame_t<F>>
RigidMotion<FromFrame, ToFrame>::velocity_of_origin_of() const {
  if constexpr (std::is_same_v<F, ToFrame>) {
    return velocity_of_to_frame_origin_;
  } else if constexpr (std::is_same_v<F, FromFrame>) {
    return Inverse().velocity_of_to_frame_origin_;
  } else {
    static_assert(std::is_same_v<F, ToFrame> || std::is_same_v<F, FromFrame>,
                  "Nonsensical frame");
  }
}

template<typename FromFrame, typename ToFrame>
DegreesOfFreedom<ToFrame> RigidMotion<FromFrame, ToFrame>::operator()(
    DegreesOfFreedom<FromFrame> const& degrees_of_freedom) const {
  return {rigid_transformation_(degrees_of_freedom.position()),
          orthogonal_map()(
              degrees_of_freedom.velocity() - velocity_of_to_frame_origin_ -
              angular_velocity_of_to_frame_ *
                  (degrees_of_freedom.position() -
                   rigid_transformation_.Inverse()(ToFrame::origin)) /
                  Radian)};
}

template<typename FromFrame, typename ToFrame>
RigidMotion<ToFrame, FromFrame>
RigidMotion<FromFrame, ToFrame>::Inverse() const {
  return RigidMotion<ToFrame, FromFrame>(
      rigid_transformation_.Inverse(),
      -orthogonal_map()(angular_velocity_of_to_frame_),
      (*this)({FromFrame::origin, FromFrame::unmoving}).velocity());
}

template<typename FromFrame, typename ToFrame>
RigidMotion<FromFrame, ToFrame>
RigidMotion<FromFrame, ToFrame>::MakeNonRotatingMotion(
    DegreesOfFreedom<ToFrame> const& degrees_of_freedom_of_from_frame_origin) {
  if constexpr (FromFrame::handedness == ToFrame::handedness) {
    return RigidMotion(RigidTransformation<FromFrame, ToFrame>(
                           FromFrame::origin,
                           degrees_of_freedom_of_from_frame_origin.position(),
                           geometry::Identity<FromFrame, ToFrame>().Forget()),
                       ToFrame::nonrotating,
                       degrees_of_freedom_of_from_frame_origin.velocity());
  } else {
    // TODO(phl): This is extremely dubious.  We apply the sun_looking_glass
    // permutation because we "know" that we have World and RigidPart here.
    return RigidMotion(
        RigidTransformation<FromFrame, ToFrame>(
            FromFrame::origin,
            degrees_of_freedom_of_from_frame_origin.position(),
            geometry::Permutation<FromFrame, ToFrame>(
                geometry::Permutation<FromFrame,
                                      ToFrame>::CoordinatePermutation::XZY)
                .template Forget<OrthogonalMap>()),
        ToFrame::nonrotating,
        degrees_of_freedom_of_from_frame_origin.velocity());
  }
}

template<typename FromFrame, typename ToFrame>
void RigidMotion<FromFrame, ToFrame>::WriteToMessage(
    not_null<serialization::RigidMotion*> const message) const {
  rigid_transformation_.WriteToMessage(message->mutable_rigid_transformation());
  angular_velocity_of_to_frame_.WriteToMessage(
      message->mutable_angular_velocity_of_to_frame());
  velocity_of_to_frame_origin_.WriteToMessage(
      message->mutable_velocity_of_to_frame_origin());
}

template<typename FromFrame, typename ToFrame>
RigidMotion<FromFrame, ToFrame>
RigidMotion<FromFrame, ToFrame>::ReadFromMessage(
    serialization::RigidMotion const& message) {
  return RigidMotion(RigidTransformation<FromFrame, ToFrame>::ReadFromMessage(
                         message.rigid_transformation()),
                     AngularVelocity<FromFrame>::ReadFromMessage(
                         message.angular_velocity_of_to_frame()),
                     Velocity<FromFrame>::ReadFromMessage(
                         message.velocity_of_to_frame_origin()));
}

template<typename FromFrame, typename ToFrame>
template<typename F, typename T, typename>
RigidMotion<FromFrame, ToFrame> RigidMotion<FromFrame, ToFrame>::Identity() {
  return RigidMotion(RigidTransformation<FromFrame, ToFrame>::Identity(),
                     FromFrame::nonrotating,
                     FromFrame::unmoving);
}

template<typename FromFrame, typename ThroughFrame, typename ToFrame>
RigidMotion<FromFrame, ToFrame> operator*(
    RigidMotion<ThroughFrame, ToFrame> const& left,
    RigidMotion<FromFrame, ThroughFrame> const& right) {
  return RigidMotion<FromFrame, ToFrame>(
      left.rigid_transformation() * right.rigid_transformation(),
      right.angular_velocity_of_to_frame_ +
          right.orthogonal_map().Inverse()(left.angular_velocity_of_to_frame_),
      right.Inverse()(left.Inverse()(
          {ToFrame::origin, ToFrame::unmoving})).velocity());
}

template<typename FromFrame, typename ToFrame>
std::ostream& operator<<(std::ostream& out,
                         RigidMotion<FromFrame, ToFrame> const& rigid_motion) {
  return out << "{transformation: " << rigid_motion.rigid_transformation()
             << ", angular velocity: "
             << rigid_motion.template angular_velocity_of<ToFrame>()
             << ", velocity: "
             << rigid_motion.template velocity_of_origin_of<ToFrame>()
             << "}";
}

template<typename FromFrame, typename ToFrame>
std::ostream& operator<<(std::ostream& out,
                         AcceleratedRigidMotion<FromFrame, ToFrame> const&
                             accelerated_rigid_motion) {
  return out
         << "{motion: " << accelerated_rigid_motion.rigid_motion()
         << ", angular acceleration: "
         << accelerated_rigid_motion.template angular_acceleration_of<ToFrame>()
         << ", acceleration: "
         << accelerated_rigid_motion
                .template acceleration_of_origin_of<ToFrame>()
         << "}";
}

template<typename FromFrame, typename ToFrame>
AcceleratedRigidMotion<FromFrame, ToFrame>::AcceleratedRigidMotion(
    RigidMotion<FromFrame, ToFrame> const& rigid_motion,
    Bivector<AngularAcceleration, FromFrame> const&
        angular_acceleration_of_to_frame,
    Vector<Acceleration, FromFrame> const& acceleration_of_to_frame_origin)
    : rigid_motion_(rigid_motion),
      angular_acceleration_of_to_frame_(angular_acceleration_of_to_frame),
      acceleration_of_to_frame_origin_(acceleration_of_to_frame_origin) {}

template<typename FromFrame, typename ToFrame>
RigidMotion<FromFrame, ToFrame> const&
AcceleratedRigidMotion<FromFrame, ToFrame>::rigid_motion() const {
  return rigid_motion_;
}

template<typename FromFrame, typename ToFrame>
template<typename F>
Bivector<AngularAcceleration,
         typename AcceleratedRigidMotion<FromFrame, ToFrame>::
             template other_frame_t<F>>
AcceleratedRigidMotion<FromFrame, ToFrame>::angular_acceleration_of() const {
  if constexpr (std::is_same_v<F, ToFrame>) {
    return angular_acceleration_of_to_frame_;
  } else if constexpr (std::is_same_v<F, FromFrame>) {
    static_assert(!std::is_same_v<F, FromFrame>,
                  "Time to implement AcceleratedRigidMotion::Inverse");
  } else {
    static_assert(std::is_same_v<F, ToFrame> || std::is_same_v<F, FromFrame>,
                  "Nonsensical frame");
  }
}

template<typename FromFrame, typename ToFrame>
template<typename F>
Vector<Acceleration,
       typename AcceleratedRigidMotion<FromFrame, ToFrame>::
           template other_frame_t<F>>
AcceleratedRigidMotion<FromFrame, ToFrame>::acceleration_of_origin_of() const {
  if constexpr (std::is_same_v<F, ToFrame>) {
    return acceleration_of_to_frame_origin_;
  } else if constexpr (std::is_same_v<F, FromFrame>) {
    static_assert(!std::is_same_v<F, FromFrame>,
                  "Time to implement AcceleratedRigidMotion::Inverse");
  } else {
    static_assert(std::is_same_v<F, ToFrame> || std::is_same_v<F, FromFrame>,
                  "Nonsensical frame");
  }
}

}  // namespace internal_rigid_motion
}  // namespace physics
}  // namespace principia
<|endoftext|>


<commit_before>/*!
	@file
	@author		Albert Semenov
	@date		05/2008
*/

#include "MyGUI_OgreDataManager.h"
#include "MyGUI_OgreDiagnostic.h"
#include "MyGUI_OgreDataStream.h"

#include <Ogre.h>

#include "MyGUI_LastHeader.h"

namespace MyGUI
{

	OgreDataManager::OgreDataManager() :
		mIsInitialise(false)
	{
	}

	void OgreDataManager::initialise(const std::string& _group)
	{
		MYGUI_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice");
		MYGUI_LOG(Info, "* Initialise: " << getClassTypeName());

		mGroup = _group;

		MYGUI_LOG(Info, getClassTypeName() << " successfully initialized");
		mIsInitialise = true;
	}

	void OgreDataManager::shutdown()
	{
		MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised");
		MYGUI_LOG(Info, "* Shutdown: " << getClassTypeName());

		MYGUI_LOG(Info, getClassTypeName() << " successfully shutdown");
		mIsInitialise = false;
	}

	IDataStream* OgreDataManager::getData(const std::string& _name)
	{
		try
		{
			Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(_name, mGroup, true);
			OgreDataStream* data = new OgreDataStream(stream);

			return data;
		}
		catch(Ogre::FileNotFoundException)
		{
		}

		return nullptr;
	}

	bool OgreDataManager::isDataExist(const std::string& _name)
	{
		const VectorString& files = getDataListNames(_name);
		return (files.size() == 1);
	}

	const VectorString& OgreDataManager::getDataListNames(const std::string& _pattern)
	{
		return getDataListNames(_pattern, false);
	}

	const VectorString& OgreDataManager::getDataListNames(const std::string& _pattern, bool _fullpath)
	{
		static VectorString result;
		result.clear();

		Ogre::FileInfoListPtr pFileInfo = Ogre::ResourceGroupManager::getSingleton().findResourceFileInfo(mGroup, _pattern);

		result.reserve(pFileInfo->size());

		for (Ogre::FileInfoList::iterator fi = pFileInfo->begin(); fi != pFileInfo->end(); ++fi )
		{
			if (fi->path.empty())
			{
				bool found = false;
				for (VectorString::iterator iter=result.begin(); iter!=result.end(); ++iter)
				{
					if (*iter == fi->filename)
					{
						found = true;
						break;
					}
				}
				if (!found)
				{
					result.push_back(_fullpath ? fi->archive->getName() + "/" + fi->filename : fi->filename);
				}

			}
		}

		pFileInfo.setNull();

		return result;
	}

	const std::string& OgreDataManager::getDataPath(const std::string& _name)
	{
		static std::string result;

		const VectorString& files = getDataListNames(_name, true);
		result = files.size() == 1 ? files[0] : "";

		return result;
	}

} // namespace MyGUI
<commit_msg>add log to ogre data manager<commit_after>/*!
	@file
	@author		Albert Semenov
	@date		05/2008
*/

#include "MyGUI_OgreDataManager.h"
#include "MyGUI_OgreDiagnostic.h"
#include "MyGUI_OgreDataStream.h"

#include <Ogre.h>

#include "MyGUI_LastHeader.h"

namespace MyGUI
{

	OgreDataManager::OgreDataManager() :
		mIsInitialise(false)
	{
	}

	void OgreDataManager::initialise(const std::string& _group)
	{
		MYGUI_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice");
		MYGUI_LOG(Info, "* Initialise: " << getClassTypeName());

		mGroup = _group;

		MYGUI_LOG(Info, getClassTypeName() << " successfully initialized");
		mIsInitialise = true;
	}

	void OgreDataManager::shutdown()
	{
		MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised");
		MYGUI_LOG(Info, "* Shutdown: " << getClassTypeName());

		MYGUI_LOG(Info, getClassTypeName() << " successfully shutdown");
		mIsInitialise = false;
	}

	IDataStream* OgreDataManager::getData(const std::string& _name)
	{
		try
		{
			Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(_name, mGroup, true);
			OgreDataStream* data = new OgreDataStream(stream);

			return data;
		}
		catch(Ogre::FileNotFoundException _e)
		{
			MYGUI_LOG(Warning, _e.getDescription());
		}

		return nullptr;
	}

	bool OgreDataManager::isDataExist(const std::string& _name)
	{
		const VectorString& files = getDataListNames(_name);
		return (files.size() == 1);
	}

	const VectorString& OgreDataManager::getDataListNames(const std::string& _pattern)
	{
		return getDataListNames(_pattern, false);
	}

	const VectorString& OgreDataManager::getDataListNames(const std::string& _pattern, bool _fullpath)
	{
		static VectorString result;
		result.clear();

		Ogre::FileInfoListPtr pFileInfo = Ogre::ResourceGroupManager::getSingleton().findResourceFileInfo(mGroup, _pattern);

		result.reserve(pFileInfo->size());

		for (Ogre::FileInfoList::iterator fi = pFileInfo->begin(); fi != pFileInfo->end(); ++fi )
		{
			if (fi->path.empty())
			{
				bool found = false;
				for (VectorString::iterator iter=result.begin(); iter!=result.end(); ++iter)
				{
					if (*iter == fi->filename)
					{
						found = true;
						break;
					}
				}
				if (!found)
				{
					result.push_back(_fullpath ? fi->archive->getName() + "/" + fi->filename : fi->filename);
				}

			}
		}

		pFileInfo.setNull();

		return result;
	}

	const std::string& OgreDataManager::getDataPath(const std::string& _name)
	{
		static std::string result;

		const VectorString& files = getDataListNames(_name, true);
		result = files.size() == 1 ? files[0] : "";

		return result;
	}

} // namespace MyGUI
<|endoftext|>


<commit_before>/*
Highly Optimized Object-Oriented Molecular Dynamics (HOOMD) Open
Source Software License
Copyright (c) 2008 Ames Laboratory Iowa State University
All rights reserved.

Redistribution and use of HOOMD, in source and binary forms, with or
without modification, are permitted, provided that the following
conditions are met:

* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

* Neither the name of the copyright holder nor the names HOOMD's
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.

Disclaimer

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND
CONTRIBUTORS ``AS IS''  AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.

IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS  BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4103 4244 )
#endif

#include <iostream>

//! Name the unit test module
#define BOOST_TEST_MODULE ElectrostaticLongRangePPPMTests
#include "boost_utf_configure.h"

#include <boost/test/floating_point_comparison.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>

#include "ParticleData.h"

#include <math.h>

using namespace std;
using namespace boost;

//You need a fft defined in order to pass this text
#ifdef USE_FFTW

#include "ElectrostaticLongRangePPPM.h"
#include "FFTClass.h"
#include "FftwWrapper.h"

/*! \file ElectrostaticLongRange_PPPM_test.cc
	\brief Implements unit tests for ElectrostaticLongRangePPPM and descendants
	\ingroup unit_tests
*/

//! Helper macro for testing if two numbers are close
#define MY_BOOST_CHECK_CLOSE(a,b,c) BOOST_CHECK_CLOSE(a,Scalar(b),Scalar(c))
//! Helper macro for testing if a number is small
#define MY_BOOST_CHECK_SMALL(a,c) BOOST_CHECK_SMALL(a,Scalar(c))

//! Tolerance in percent to use for comparing various ElectrostaticLongRangePPPM to each other
const Scalar tol = Scalar(1);
//! minimum force worth computing
const Scalar MIN_force=Scalar(1.0e-9);

//! Typedef ElectrostaticLongRangePPPM factory
typedef function<shared_ptr<ElectrostaticLongRangePPPM> (shared_ptr<ParticleData> pdata,unsigned int Mmesh_x,unsigned int Mmesh_y,unsigned int Mmesh_z, unsigned int P_order_a, Scalar alpha, shared_ptr<FFTClass> FFTP,bool third_law_m)> LongRangePPPM_creator;

//! Test the ability of the Short Range Electrostatic force compute to actually calculate forces
/*! \param LongRangePPPM_object_n1 I have no idea: the write of this code needs to document it better
	\note With the creator as a parameter, the same code can be used to test any derived child
		of ElectrostaticLongRangePPPM
*/
void LongRangePPPM_PositionGrid(LongRangePPPM_creator LongRangePPPM_object_n1)
	{
	cout << "Testing charge distribution on the grid in class ElectrostaticLongRangePPPM" << endl;
	// Simple test to check that the charge is defined correctly on the grid
	shared_ptr<ParticleData> pdata_6(new ParticleData(6, BoxDim(20.0,40.0,60.0), 1));
	ParticleDataArrays arrays = pdata_6->acquireReadWrite();

	// six charges are located near the edge of the box
	arrays.x[0]=Scalar(-9.6);arrays.y[0]=Scalar(0.0);arrays.z[0]=Scalar(0.0);arrays.charge[0]=1.0;
    arrays.x[1]=Scalar(9.6);arrays.y[1]=Scalar(0.0);arrays.z[1]=Scalar(0.0);arrays.charge[1]=-2.0;
	arrays.x[2]=Scalar(0.0);arrays.y[2]=Scalar(-19.5);arrays.z[2]=Scalar(0.0);arrays.charge[2]=1.0;
    arrays.x[3]=Scalar(0.0);arrays.y[3]=Scalar(19.5);arrays.z[3]=Scalar(0.0);arrays.charge[3]=3.0;
    arrays.x[4]=Scalar(0.0);arrays.y[4]=Scalar(0.0);arrays.z[4]=Scalar(-29.4);arrays.charge[4]=-1.0;
    arrays.x[5]=Scalar(0.0);arrays.y[5]=Scalar(0.0);arrays.z[5]=Scalar(29.4);arrays.charge[5]=-2.0;

	// allow for acquiring data in the future
	pdata_6->release();

    // Define mesh parameters as well as order of the distribution, etc..
	unsigned int Nmesh_x=40;
	unsigned int Nmesh_y=80;
	unsigned int Nmesh_z=120;
	unsigned int P_order=6;
	Scalar alpha=4.0;
	shared_ptr<FftwWrapper> FFTW(new  FftwWrapper(Nmesh_x,Nmesh_y,Nmesh_z));
	bool third_law=false;

	shared_ptr<ElectrostaticLongRangePPPM> PPPM_6=LongRangePPPM_object_n1(pdata_6,Nmesh_x,Nmesh_y,Nmesh_z,P_order,alpha,FFTW,third_law);
	// An ElectrostaticLongRangePPPM object with specified value of grid parameters, alpha, and fft routine instantiated

	// now let us check that the charges are correctly distributed

	//First check that the polynomials used to spread the charge on the grid are what they should be
	//This may eliminate unpleasant bugs

	//The values of the coefficents are taken from Appendix E in the Deserno and Holm paper

	Scalar **Exact=new Scalar*[P_order];
	for(unsigned int i=0;i<P_order;i++) Exact[i]=new Scalar[P_order];

	Exact[0][0]=1.0;Exact[0][1]=-10.0;Exact[0][2]=40.0;Exact[0][3]=-80.0;Exact[0][4]=80.0;Exact[0][5]=-32.0;
	Exact[1][0]=237.0;Exact[1][1]=-750.0;Exact[1][2]=840.0;Exact[1][3]=-240.0;Exact[1][4]=-240.0;Exact[1][5]=160.0;
	Exact[2][0]=1682.0;Exact[2][1]=-1540.0;Exact[2][2]=-880.0;Exact[2][3]=1120.0;Exact[2][4]=160.0;Exact[2][5]=-320.0;
	Exact[3][0]=1682.0;Exact[3][1]=1540.0;Exact[3][2]=880.0;Exact[3][3]=-1120.0;Exact[3][4]=-160.0;Exact[3][5]=320.0;
	Exact[4][0]=237.0;Exact[4][1]=750.0;Exact[4][2]=840.0;Exact[4][3]=240.0;Exact[4][4]=-240.0;Exact[4][5]=-160.0;
	Exact[5][0]=1.0;Exact[5][1]=10.0;Exact[5][2]=40.0;Exact[5][3]=80.0;Exact[5][4]=80.0;Exact[5][5]=32.0;

	for(unsigned int i=0;i<P_order;i++){
		for(unsigned int j=0;j<P_order;j++){
				Exact[i][j]*=static_cast<Scalar>(1/3840.0);
		}
	}

	for(unsigned int i=0;i<P_order;i++){
		for(unsigned int j=0;j<P_order;j++){
				MY_BOOST_CHECK_CLOSE(Exact[i][j],PPPM_6->Poly_coeff_Grid(i,j),tol);
		}
	}

	//Check passed, now let us compute the charges on the grid

}

//! ElectrostaticShortRange creator for unit tests
shared_ptr<ElectrostaticLongRangePPPM> base_class_PPPM_creator(shared_ptr<ParticleData> pdata,unsigned int Nmesh_x,unsigned int Nmesh_y,unsigned int Nmesh_z, unsigned int P_order, Scalar alpha,shared_ptr<FFTClass> FFTW,bool third_law_m)
	{
	return shared_ptr<ElectrostaticLongRangePPPM>(new ElectrostaticLongRangePPPM(pdata, Nmesh_x, Nmesh_y, Nmesh_z, P_order,alpha,FFTW,third_law_m));
	}

//! boost test case for particle test on CPU
BOOST_AUTO_TEST_CASE(LongRangePPPM_PositionGrid_test)
{
	LongRangePPPM_creator LongRangePPPM_creator_base = bind(base_class_PPPM_creator, _1, _2, _3, _4, _5,_6,_7,_8);
	LongRangePPPM_PositionGrid(LongRangePPPM_creator_base);
}

#else

// We can't have the unit test passing if the code wasn't even compiled!
BOOST_AUTO_TEST_CASE(dummy_test)
	{
	BOOST_FAIL("ElectrostaticLongRange_PPPM not compiled");
	}
#endif

#ifdef WIN32
#pragma warning( pop )
#endif
<commit_msg>back up of PPPM test, compiles but does not work yet ticket #79<commit_after>/*
Highly Optimized Object-Oriented Molecular Dynamics (HOOMD) Open
Source Software License
Copyright (c) 2008 Ames Laboratory Iowa State University
All rights reserved.

Redistribution and use of HOOMD, in source and binary forms, with or
without modification, are permitted, provided that the following
conditions are met:

* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

* Neither the name of the copyright holder nor the names HOOMD's
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.

Disclaimer

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND
CONTRIBUTORS ``AS IS''  AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.

IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS  BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4103 4244 )
#endif

#include <iostream>

//! Name the unit test module
#define BOOST_TEST_MODULE ElectrostaticLongRangePPPMTests
#include "boost_utf_configure.h"

#include <boost/test/floating_point_comparison.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>

#include "ParticleData.h"

#include <math.h>

using namespace std;
using namespace boost;

//You need a fft defined in order to pass this text
#ifdef USE_FFTW

#include "ElectrostaticLongRangePPPM.h"
#include "FFTClass.h"
#include "FftwWrapper.h"

/*! \file ElectrostaticLongRange_PPPM_test.cc
	\brief Implements unit tests for ElectrostaticLongRangePPPM and descendants
	\ingroup unit_tests
*/

//! Helper macro for testing if two numbers are close
#define MY_BOOST_CHECK_CLOSE(a,b,c) BOOST_CHECK_CLOSE(a,Scalar(b),Scalar(c))
//! Helper macro for testing if a number is small
#define MY_BOOST_CHECK_SMALL(a,c) BOOST_CHECK_SMALL(a,Scalar(c))

//! Tolerance in percent to use for comparing various ElectrostaticLongRangePPPM to each other
const Scalar tol = Scalar(1);
//! minimum force worth computing
const Scalar MIN_force=Scalar(1.0e-9);

//! Typedef ElectrostaticLongRangePPPM factory
typedef function<shared_ptr<ElectrostaticLongRangePPPM> (shared_ptr<ParticleData> pdata,unsigned int Mmesh_x,unsigned int Mmesh_y,unsigned int Mmesh_z, unsigned int P_order_a, Scalar alpha, shared_ptr<FFTClass> FFTP,bool third_law_m)> LongRangePPPM_creator;

//! Test the ability of the Short Range Electrostatic force compute to actually calculate forces
/*! \param LongRangePPPM_object_n1 I have no idea: the write of this code needs to document it better
	\note With the creator as a parameter, the same code can be used to test any derived child
		of ElectrostaticLongRangePPPM
*/
void LongRangePPPM_PositionGrid(LongRangePPPM_creator LongRangePPPM_object_n1)
	{
	cout << "Testing charge distribution on the grid in class ElectrostaticLongRangePPPM" << endl;
	// Simple test to check that the charge is defined correctly on the grid
	shared_ptr<ParticleData> pdata_6(new ParticleData(6, BoxDim(20.0,40.0,60.0), 1));
	ParticleDataArrays arrays = pdata_6->acquireReadWrite();

	// six charges are located near the edge of the box
	arrays.x[0]=Scalar(-9.6);arrays.y[0]=Scalar(0.0);arrays.z[0]=Scalar(0.0);arrays.charge[0]=1.0;
    arrays.x[1]=Scalar(9.6);arrays.y[1]=Scalar(0.0);arrays.z[1]=Scalar(0.0);arrays.charge[1]=-2.0;
	arrays.x[2]=Scalar(0.0);arrays.y[2]=Scalar(-19.5);arrays.z[2]=Scalar(0.0);arrays.charge[2]=1.0;
    arrays.x[3]=Scalar(0.0);arrays.y[3]=Scalar(19.5);arrays.z[3]=Scalar(0.0);arrays.charge[3]=3.0;
    arrays.x[4]=Scalar(0.0);arrays.y[4]=Scalar(0.0);arrays.z[4]=Scalar(-29.4);arrays.charge[4]=-1.0;
    arrays.x[5]=Scalar(0.0);arrays.y[5]=Scalar(0.0);arrays.z[5]=Scalar(29.4);arrays.charge[5]=-2.0;

	// allow for acquiring data in the future
	pdata_6->release();

    // Define mesh parameters as well as order of the distribution, etc..
	unsigned int Nmesh_x=40;
	unsigned int Nmesh_y=80;
	unsigned int Nmesh_z=120;
	unsigned int P_order=6;
	Scalar alpha=4.0;
	shared_ptr<FftwWrapper> FFTW(new  FftwWrapper(Nmesh_x,Nmesh_y,Nmesh_z));
	bool third_law=false;

	//shared_ptr<ElectrostaticLongRangePPPM> PPPM_6=LongRangePPPM_object_n1(pdata_6,Nmesh_x,Nmesh_y,Nmesh_z,P_order,alpha,FFTW,third_law);
	// An ElectrostaticLongRangePPPM object with specified value of grid parameters, alpha, and fft routine instantiated

	// now let us check that the charges are correctly distributed

	//First check that the polynomials used to spread the charge on the grid are what they should be
	//This may eliminate unpleasant bugs

	//The values of the coefficents are taken from Appendix E in the Deserno and Holm paper

	Scalar **Exact=new Scalar*[P_order];
	for(unsigned int i=0;i<P_order;i++) Exact[i]=new Scalar[P_order];

	Exact[0][0]=1.0;Exact[0][1]=-10.0;Exact[0][2]=40.0;Exact[0][3]=-80.0;Exact[0][4]=80.0;Exact[0][5]=-32.0;
	Exact[1][0]=237.0;Exact[1][1]=-750.0;Exact[1][2]=840.0;Exact[1][3]=-240.0;Exact[1][4]=-240.0;Exact[1][5]=160.0;
	Exact[2][0]=1682.0;Exact[2][1]=-1540.0;Exact[2][2]=-880.0;Exact[2][3]=1120.0;Exact[2][4]=160.0;Exact[2][5]=-320.0;
	Exact[3][0]=1682.0;Exact[3][1]=1540.0;Exact[3][2]=880.0;Exact[3][3]=-1120.0;Exact[3][4]=-160.0;Exact[3][5]=320.0;
	Exact[4][0]=237.0;Exact[4][1]=750.0;Exact[4][2]=840.0;Exact[4][3]=240.0;Exact[4][4]=-240.0;Exact[4][5]=-160.0;
	Exact[5][0]=1.0;Exact[5][1]=10.0;Exact[5][2]=40.0;Exact[5][3]=80.0;Exact[5][4]=80.0;Exact[5][5]=32.0;

	for(unsigned int i=0;i<P_order;i++){
		for(unsigned int j=0;j<P_order;j++){
				Exact[i][j]*=static_cast<Scalar>(1/3840.0);
		}
	}

	for(unsigned int i=0;i<P_order;i++){
		for(unsigned int j=0;j<P_order;j++){
				//MY_BOOST_CHECK_CLOSE(Exact[i][j],PPPM_6->Poly_coeff_Grid(i,j),tol);
		}
	}

	//Check passed, now let us compute the charges on the grid
	for(unsigned int i=0;i<P_order;i++) delete[] Exact[i];
	delete [] Exact;
}

//! ElectrostaticShortRange creator for unit tests
shared_ptr<ElectrostaticLongRangePPPM> base_class_PPPM_creator(shared_ptr<ParticleData> pdata,unsigned int Nmesh_x,unsigned int Nmesh_y,unsigned int Nmesh_z, unsigned int P_order, Scalar alpha,shared_ptr<FFTClass> FFTW,bool third_law_m)
	{
	return shared_ptr<ElectrostaticLongRangePPPM>(new ElectrostaticLongRangePPPM(pdata, Nmesh_x, Nmesh_y, Nmesh_z, P_order,alpha,FFTW,third_law_m));
	}

//! boost test case for particle test on CPU
BOOST_AUTO_TEST_CASE(LongRangePPPM_PositionGrid_test)
{
	LongRangePPPM_creator LongRangePPPM_creator_base = bind(base_class_PPPM_creator, _1, _2, _3, _4, _5,_6,_7,_8);
	LongRangePPPM_PositionGrid(LongRangePPPM_creator_base);
}

#else

// We can't have the unit test passing if the code wasn't even compiled!
BOOST_AUTO_TEST_CASE(dummy_test)
	{
	BOOST_FAIL("ElectrostaticLongRange_PPPM not compiled");
	}
#endif

#ifdef WIN32
#pragma warning( pop )
#endif
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <vector>

#include "../../include/ktt.h"

int main(int argc, char** argv)
{
    // Initialize platform and device index
    size_t platformIndex = 0;
    size_t deviceIndex = 0;

    if (argc >= 2)
    {
        platformIndex = std::stoul(std::string{ argv[1] });
        if (argc >= 3)
        {
            deviceIndex = std::stoul(std::string{ argv[2] });
        }
    }

    // Declare kernel parameters
    const std::string kernelFile = std::string("../examples/coulomb_sum_3d/coulomb_kernel_3d.cl");
    const std::string referenceKernelFile = std::string("../examples/coulomb_sum_3d/coulomb_kernel_3d_reference.cl");
    const int gridSize = 128;
    const int atoms = 4000;

    ktt::DimensionVector ndRangeDimensions(gridSize, gridSize, gridSize);
    ktt::DimensionVector workGroupDimensions(1, 1, 1);
    ktt::DimensionVector referenceWorkGroupDimensions(16, 16, 1);

    // Declare data variables
    float gridSpacing;
    std::vector<float> atomInfoX(atoms);
    std::vector<float> atomInfoY(atoms);
    std::vector<float> atomInfoZ(atoms);
    std::vector<float> atomInfoW(atoms);
    std::vector<float> atomInfo(atoms*4);
    std::vector<float> energyGrid(gridSize*gridSize*gridSize, 0.0f);

    // Initialize data
    gridSpacing = 0.5; // in Angstroms
    for (int i = 0; i < atoms; i++)
    {
        atomInfoX.at(i) = static_cast<float>((float)rand() / (RAND_MAX/20));
        atomInfoY.at(i) = static_cast<float>((float)rand() / (RAND_MAX/20));
        atomInfoZ.at(i) = static_cast<float>((float)rand() / (RAND_MAX/20));
        atomInfoW.at(i) = static_cast<float>((float)rand() / (RAND_MAX/20));
        atomInfo.at(i*4) = atomInfoX.at(i);
        atomInfo.at(i*4+1) = atomInfoY.at(i);
        atomInfo.at(i*4+2) = atomInfoZ.at(i);
        atomInfo.at(i*4+3) = atomInfoW.at(i);
    }

    ktt::Tuner tuner(platformIndex, deviceIndex);

    size_t kernelId = tuner.addKernelFromFile(kernelFile, std::string("directCoulombSum"), ndRangeDimensions, workGroupDimensions);
    size_t referenceKernelId = tuner.addKernelFromFile(referenceKernelFile, std::string("directCoulombSumReference"), ndRangeDimensions, referenceWorkGroupDimensions);

    size_t aiId = tuner.addArgument(atomInfo, ktt::ArgumentMemoryType::ReadOnly);
    size_t aixId = tuner.addArgument(atomInfoX, ktt::ArgumentMemoryType::ReadOnly);
    size_t aiyId = tuner.addArgument(atomInfoY, ktt::ArgumentMemoryType::ReadOnly);
    size_t aizId = tuner.addArgument(atomInfoZ, ktt::ArgumentMemoryType::ReadOnly);
    size_t aiwId = tuner.addArgument(atomInfoW, ktt::ArgumentMemoryType::ReadOnly);
    size_t aId = tuner.addArgument(atoms);
    size_t gsId = tuner.addArgument(gridSpacing);
    size_t gridId = tuner.addArgument(energyGrid, ktt::ArgumentMemoryType::WriteOnly);

    tuner.addParameter(kernelId, "WORK_GROUP_SIZE_X", { 16, 32 },
        ktt::ThreadModifierType::Local,
        ktt::ThreadModifierAction::Multiply,
        ktt::Dimension::X);
    tuner.addParameter(kernelId, "WORK_GROUP_SIZE_Y", { 1, 2, 4, 8 },
        ktt::ThreadModifierType::Local,
        ktt::ThreadModifierAction::Multiply,
        ktt::Dimension::Y);
    tuner.addParameter(kernelId, "WORK_GROUP_SIZE_Z", { 1 });
    tuner.addParameter(kernelId, "Z_ITERATIONS", { 1, 2, 4, 8, 16, 32 },
        ktt::ThreadModifierType::Global,
        ktt::ThreadModifierAction::Divide,
        ktt::Dimension::Z);
    tuner.addParameter(kernelId, "INNER_UNROLL_FACTOR", { 0, 1, 2, 4, 8, 16, 32 });
    tuner.addParameter(kernelId, "USE_CONSTANT_MEMORY", { 0, 1 });
    tuner.addParameter(kernelId, "USE_SOA", { 0, 1 });
    tuner.addParameter(kernelId, "VECTOR_SIZE", { 1, 2 , 4, 8, 16 });
    tuner.addParameter(kernelId, "ONE", { 1 }); //XXX helper, must be always

    auto lt = [](std::vector<size_t> vector) { return vector.at(0) < vector.at(1); };
    tuner.addConstraint(kernelId, lt, { "INNER_UNROLL_FACTOR", "Z_ITERATIONS" } );
    auto vec = [](std::vector<size_t> vector) { return vector.at(0) || vector.at(1) == 1; };
    tuner.addConstraint(kernelId, vec, { "USE_SOA", "VECTOR_SIZE" } );

    tuner.setKernelArguments(kernelId, std::vector<size_t>{ aiId, aixId, aiyId, aizId, aiwId, aId, gsId, gridId });
    tuner.setKernelArguments(referenceKernelId, std::vector<size_t>{ aiId, aixId, aiyId, aizId, aiwId, aId, gsId, gridId });

    tuner.setReferenceKernel(kernelId, referenceKernelId, std::vector<ktt::ParameterValue>{}, std::vector<size_t>{ gridId });
    tuner.setValidationMethod(ktt::ValidationMethod::SideBySideComparison, 0.1);

    tuner.setSearchMethod(kernelId, ktt::SearchMethod::RandomSearch, std::vector<double> { 0.1 });

    tuner.tuneKernel(kernelId);
    tuner.printResult(kernelId, std::cout, ktt::PrintFormat::Verbose);
    tuner.printResult(kernelId, std::string("output.csv"), ktt::PrintFormat::CSV);

    return 0;
}
<commit_msg>Revert "bugfix in argument handling"<commit_after>#include <iostream>
#include <string>
#include <vector>

#include "../../include/ktt.h"

int main(int argc, char** argv)
{
    // Initialize platform and device index
    size_t platformIndex = 0;
    size_t deviceIndex = 0;

    if (argc >= 2)
    {
        platformIndex = std::stoul(std::string{ argv[1] });
        if (argc >= 3)
        {
            deviceIndex = std::stoul(std::string{ argv[2] });
        }
    }

    // Declare kernel parameters
    const std::string kernelFile = std::string("../examples/coulomb_sum_3d/coulomb_kernel_3d.cl");
    const std::string referenceKernelFile = std::string("../examples/coulomb_sum_3d/coulomb_kernel_3d_reference.cl");
    const int gridSize = 128;
    const int atoms = 4000;

    ktt::DimensionVector ndRangeDimensions(gridSize, gridSize, gridSize);
    ktt::DimensionVector workGroupDimensions(1, 1, 1);
    ktt::DimensionVector referenceWorkGroupDimensions(16, 16, 1);

    // Declare data variables
    float gridSpacing;
    std::vector<float> atomInfoX(atoms);
    std::vector<float> atomInfoY(atoms);
    std::vector<float> atomInfoZ(atoms);
    std::vector<float> atomInfoW(atoms);
    std::vector<float> atomInfo(atoms*4);
    std::vector<float> energyGrid(gridSize*gridSize*gridSize, 0.0f);

    // Initialize data
    gridSpacing = 0.5; // in Angstroms
    for (int i = 0; i < atoms; i++)
    {
        atomInfoX.at(i) = static_cast<float>((float)rand() / (RAND_MAX/20));
        atomInfoY.at(i) = static_cast<float>((float)rand() / (RAND_MAX/20));
        atomInfoZ.at(i) = static_cast<float>((float)rand() / (RAND_MAX/20));
        atomInfoW.at(i) = static_cast<float>((float)rand() / (RAND_MAX/20));
        atomInfo.at(i*4) = atomInfoX.at(i);
        atomInfo.at(i*4+1) = atomInfoY.at(i);
        atomInfo.at(i*4+2) = atomInfoZ.at(i);
        atomInfo.at(i*4+3) = atomInfoW.at(i);
    }

    ktt::Tuner tuner(platformIndex, deviceIndex);

    size_t kernelId = tuner.addKernelFromFile(kernelFile, std::string("directCoulombSum"), ndRangeDimensions, workGroupDimensions);
    size_t referenceKernelId = tuner.addKernelFromFile(referenceKernelFile, std::string("directCoulombSumReference"), ndRangeDimensions, referenceWorkGroupDimensions);

    size_t aiId = tuner.addArgument(atomInfo, ktt::ArgumentMemoryType::ReadOnly);
    size_t aixId = tuner.addArgument(atomInfoX, ktt::ArgumentMemoryType::ReadOnly);
    size_t aiyId = tuner.addArgument(atomInfoY, ktt::ArgumentMemoryType::ReadOnly);
    size_t aizId = tuner.addArgument(atomInfoZ, ktt::ArgumentMemoryType::ReadOnly);
    size_t aiwId = tuner.addArgument(atomInfoW, ktt::ArgumentMemoryType::ReadOnly);
    size_t aId = tuner.addArgument(atoms);
    size_t gsId = tuner.addArgument(gridSpacing);
    size_t gridId = tuner.addArgument(atomInfoW, ktt::ArgumentMemoryType::WriteOnly);

    tuner.addParameter(kernelId, "WORK_GROUP_SIZE_X", { 16, 32 },
        ktt::ThreadModifierType::Local,
        ktt::ThreadModifierAction::Multiply,
        ktt::Dimension::X);
    tuner.addParameter(kernelId, "WORK_GROUP_SIZE_Y", { 1, 2, 4, 8 },
        ktt::ThreadModifierType::Local,
        ktt::ThreadModifierAction::Multiply,
        ktt::Dimension::Y);
    tuner.addParameter(kernelId, "WORK_GROUP_SIZE_Z", { 1 });
    tuner.addParameter(kernelId, "Z_ITERATIONS", { 1, 2, 4, 8, 16, 32 },
        ktt::ThreadModifierType::Global,
        ktt::ThreadModifierAction::Divide,
        ktt::Dimension::Z);
    tuner.addParameter(kernelId, "INNER_UNROLL_FACTOR", { 0, 1, 2, 4, 8, 16, 32 });
    tuner.addParameter(kernelId, "USE_CONSTANT_MEMORY", { 0, 1 });
    tuner.addParameter(kernelId, "USE_SOA", { 0, 1 });
    tuner.addParameter(kernelId, "VECTOR_SIZE", { 1, 2 , 4, 8, 16 });
    tuner.addParameter(kernelId, "ONE", { 1 }); //XXX helper, must be always

    auto lt = [](std::vector<size_t> vector) { return vector.at(0) < vector.at(1); };
    tuner.addConstraint(kernelId, lt, { "INNER_UNROLL_FACTOR", "Z_ITERATIONS" } );
    auto vec = [](std::vector<size_t> vector) { return vector.at(0) || vector.at(1) == 1; };
    tuner.addConstraint(kernelId, vec, { "USE_SOA", "VECTOR_SIZE" } );

    tuner.setKernelArguments(kernelId, std::vector<size_t>{ aiId, aixId, aiyId, aizId, aiwId, aId, gsId, gridId });
    tuner.setKernelArguments(referenceKernelId, std::vector<size_t>{ aiId, aixId, aiyId, aizId, aiwId, aId, gsId, gridId });

    tuner.setReferenceKernel(kernelId, referenceKernelId, std::vector<ktt::ParameterValue>{}, std::vector<size_t>{ gridId });
    tuner.setValidationMethod(ktt::ValidationMethod::SideBySideComparison, 0.1);

    tuner.setSearchMethod(kernelId, ktt::SearchMethod::RandomSearch, std::vector<double> { 0.1 });

    tuner.tuneKernel(kernelId);
    tuner.printResult(kernelId, std::cout, ktt::PrintFormat::Verbose);
    tuner.printResult(kernelId, std::string("output.csv"), ktt::PrintFormat::CSV);

    return 0;
}
<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 4      *
*                (c) 2006-2009 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#define SOFA_COMPONENT_CONSTRAINTSET_PRECOMPUTEDCONSTRAINTCORRECTION_CPP
#include "PrecomputedConstraintCorrection.inl"
#include <sofa/defaulttype/Vec3Types.h>
#include <sofa/core/ObjectFactory.h>

namespace sofa
{
namespace component
{
namespace constraintset
{

#ifndef SOFA_FLOAT

template<>
SOFA_COMPONENT_CONSTRAINTSET_API void PrecomputedConstraintCorrection<defaulttype::Vec3dTypes>::draw()
{
    if (!getContext()->getShowBehaviorModels() || !m_rotations.getValue()) return;

    // we draw the rotations associated to each node //

    simulation::Node *node = dynamic_cast<simulation::Node *>(getContext());

    sofa::component::forcefield::TetrahedronFEMForceField<defaulttype::Vec3dTypes>* forceField = NULL;
    sofa::component::container::RotationFinder<defaulttype::Vec3dTypes>* rotationFinder = NULL;

    if (node != NULL)
    {
        //		core::behavior::BaseForceField* _forceField = node->forceField[1];
        forceField = node->get<component::forcefield::TetrahedronFEMForceField<defaulttype::Vec3dTypes> > ();
        if (forceField == NULL)
        {
            rotationFinder = node->get<component::container::RotationFinder<defaulttype::Vec3dTypes> > ();
            if (rotationFinder == NULL)
            {
                sout << "No rotation defined : only defined for TetrahedronFEMForceField and RotationFinder!";
                return;
            }
        }
    }

    VecCoord& x = *mstate->getX();
    for (unsigned int i=0; i< x.size(); i++)
    {
        Transformation Ri;
        if (forceField != NULL)
        {
            forceField->getRotation(Ri, i);
        }
        else // rotationFinder has been defined
        {
            Ri = rotationFinder->getRotations()[i];
        }

        sofa::defaulttype::Matrix3 RotMat;

        for (unsigned int a=0; a<3; a++)
        {
            for (unsigned int b=0; b<3; b++)
            {
                RotMat[a][b] = Ri(a,b);
            }
        }

        sofa::defaulttype::Quat q;
        q.fromMatrix(RotMat);

        helper::gl::Axis::draw(x[i], q  , this->debugViewFrameScale.getValue());

    }
}

template<>
SOFA_COMPONENT_CONSTRAINTSET_API void PrecomputedConstraintCorrection<defaulttype::Rigid3dTypes>::rotateConstraints(bool back)
{
    VecCoord& x = *mstate->getX();
    VecConst& constraints = *mstate->getC();
    VecCoord& x0 = *mstate->getX0();

    unsigned int numConstraints = constraints.size();
    //	int sizemax=0;
    //	int index_const = -1;
    // on fait tourner les normales (en les ramenant dans le "pseudo" repere initial) //
    for(unsigned int curRowConst = 0; curRowConst < numConstraints; curRowConst++)
    {
        ConstraintIterator itConstraint;
        std::pair< ConstraintIterator, ConstraintIterator > iter=constraints[curRowConst].data();
        for (itConstraint=iter.first; itConstraint!=iter.second; itConstraint++)
        {
            unsigned int dof = itConstraint->first;
            Deriv& n = itConstraint->second;
            const int localRowNodeIdx = dof;
            Quat q;
            if (m_restRotations.getValue())
                q = x[localRowNodeIdx].getOrientation() * x0[localRowNodeIdx].getOrientation().inverse();
            else
                q = x[localRowNodeIdx].getOrientation();

            Vec3d n_i = q.inverseRotate(n.getVCenter());
            Vec3d wn_i= q.inverseRotate(n.getVOrientation());
            if(back)
            {
                n_i = q.rotate(n.getVCenter());
                wn_i= q.rotate(n.getVOrientation());
            }

            // on passe les normales du repere global au repere local
            n.getVCenter() = n_i;
            n.getVOrientation() = wn_i;

        }
    }
}

template<>
SOFA_COMPONENT_CONSTRAINTSET_API void PrecomputedConstraintCorrection<defaulttype::Vec1dTypes>::rotateConstraints(bool /*back*/)
{
}

template<>
SOFA_COMPONENT_CONSTRAINTSET_API void PrecomputedConstraintCorrection<defaulttype::Rigid3dTypes>::rotateResponse()
{

    VecDeriv& dx = *mstate->getDx();
    VecCoord& x = *mstate->getX();
    VecCoord& x0 = *mstate->getX0();
    for(unsigned int j = 0; j < dx.size(); j++)
    {
        // on passe les deplacements du repere local (au repos) au repere global
        Deriv temp ;
        Quat q;
        if (m_restRotations.getValue())
            q = x[j].getOrientation() * x0[j].getOrientation().inverse();
        else
            q = x[j].getOrientation();

        temp.getVCenter()		= q.rotate(dx[j].getVCenter());
        temp.getVOrientation()  = q.rotate(dx[j].getVOrientation());
        dx[j] = temp;
    }
}

template<>
SOFA_COMPONENT_CONSTRAINTSET_API void PrecomputedConstraintCorrection<defaulttype::Vec1dTypes>::rotateResponse()
{
}

#endif
#ifndef SOFA_DOUBLE

template<>
SOFA_COMPONENT_CONSTRAINTSET_API void PrecomputedConstraintCorrection<defaulttype::Vec3fTypes>::rotateConstraints(bool back)
{
    VecConst& constraints = *mstate->getC();
    unsigned int numConstraints = constraints.size();

    simulation::Node *node = dynamic_cast<simulation::Node *>(getContext());

    sofa::component::forcefield::TetrahedronFEMForceField<defaulttype::Vec3fTypes>* forceField = NULL;
    sofa::component::container::RotationFinder<defaulttype::Vec3fTypes>* rotationFinder = NULL;

    if (node != NULL)
    {
        forceField = node->get<component::forcefield::TetrahedronFEMForceField<defaulttype::Vec3fTypes> > ();
        if (forceField == NULL)
        {
            rotationFinder = node->get<component::container::RotationFinder<defaulttype::Vec3fTypes> > ();
            if (rotationFinder == NULL)
            {
                sout << "No rotation defined : only defined for TetrahedronFEMForceField and RotationFinder!";
                return;
            }
        }
    }
    else
    {
        sout << "Error getting context in method: PrecomputedConstraintCorrection<defaulttype::Vec3dTypes>::rotateConstraints()";
        return;
    }

    //sout << "start rotating normals " << g_timer_elapsed(timer, &micro) << sendl;
    //	int sizemax=0;
    //	int index_const = -1;
    // on fait tourner les normales (en les ramenant dans le "pseudo" repere initial) //
    for(unsigned int curRowConst = 0; curRowConst < numConstraints; curRowConst++)
    {
        ConstraintIterator itConstraint;

        std::pair< ConstraintIterator, ConstraintIterator > iter=constraints[curRowConst].data();
        for (itConstraint=iter.first; itConstraint!=iter.second; itConstraint++)
        {
            unsigned int dof = itConstraint->first;
            Deriv& n = itConstraint->second;
            const int localRowNodeIdx = dof;
            Transformation Ri;
            if (forceField != NULL)
            {
                forceField->getRotation(Ri, localRowNodeIdx);
            }
            else // rotationFinder has been defined
            {
                Ri = rotationFinder->getRotations()[localRowNodeIdx];
            }
            if(!back)
                Ri.transpose();
            // on passe les normales du repere global au repere local
            Deriv n_i = Ri * n;
            n.x() =  n_i.x();
            n.y() =  n_i.y();
            n.z() =  n_i.z();
        }
        /*
        // test pour voir si on peut reduire le nombre de contrainte
        if (sizeCurRowConst > sizemax)
        {
        sizemax = sizeCurRowConst;
        index_const = curRowConst;
        }
        */
    }
}

template<>
SOFA_COMPONENT_CONSTRAINTSET_API void PrecomputedConstraintCorrection<defaulttype::Rigid3fTypes>::rotateConstraints(bool back)
{
    VecCoord& x = *mstate->getX();
    VecConst& constraints = *mstate->getC();
    VecCoord& x0 = *mstate->getX0();

    unsigned int numConstraints = constraints.size();
    //	int sizemax=0;
    //	int index_const = -1;
    // on fait tourner les normales (en les ramenant dans le "pseudo" repere initial) //
    for(unsigned int curRowConst = 0; curRowConst < numConstraints; curRowConst++)
    {
        ConstraintIterator itConstraint;

        std::pair< ConstraintIterator, ConstraintIterator > iter=constraints[curRowConst].data();
        for (itConstraint=iter.first; itConstraint!=iter.second; itConstraint++)
        {
            unsigned int dof = itConstraint->first;
            Deriv& n = itConstraint->second;
            const int localRowNodeIdx = dof;
            Quat q;
            if (m_restRotations)
                q = x[localRowNodeIdx].getOrientation() * x0[localRowNodeIdx].getOrientation().inverse();
            else
                q = x[localRowNodeIdx].getOrientation();

            Vec3d n_i = q.inverseRotate(n.getVCenter());
            Vec3d wn_i= q.inverseRotate(n.getVOrientation());
            if(back)
            {
                n_i = q.rotate(n.getVCenter());
                wn_i= q.rotate(n.getVOrientation());
            }

            // on passe les normales du repere global au repere local
            n.getVCenter() = n_i;
            n.getVOrientation() = wn_i;

        }
    }
}

template<>
SOFA_COMPONENT_CONSTRAINTSET_API void PrecomputedConstraintCorrection<defaulttype::Vec1fTypes>::rotateConstraints(bool /*back*/)
{
}

template<>
SOFA_COMPONENT_CONSTRAINTSET_API void PrecomputedConstraintCorrection<defaulttype::Vec3fTypes>::rotateResponse()
{
    simulation::Node *node = dynamic_cast<simulation::Node *>(getContext());

    sofa::component::forcefield::TetrahedronFEMForceField<defaulttype::Vec3fTypes>* forceField = NULL;
    sofa::component::container::RotationFinder<defaulttype::Vec3fTypes>* rotationFinder = NULL;

    if (node != NULL)
    {
        //		core::behavior::BaseForceField* _forceField = node->forceField[1];
        forceField = node->get<component::forcefield::TetrahedronFEMForceField<defaulttype::Vec3fTypes> > ();
        if (forceField == NULL)
        {
            rotationFinder = node->get<component::container::RotationFinder<defaulttype::Vec3fTypes> > ();
            if (rotationFinder == NULL)
            {
                sout << "No rotation defined : only defined for TetrahedronFEMForceField and RotationFinder!";
                return;
            }
        }
    }
    else
    {
        sout << "Error getting context in method: PrecomputedConstraintCorrection<defaulttype::Vec3dTypes>::rotateConstraints()";
        return;
    }

    VecDeriv& dx = *mstate->getDx();
    for(unsigned int j = 0; j < dx.size(); j++)
    {
        Transformation Rj;
        if (forceField != NULL)
        {
            forceField->getRotation(Rj, j);
        }
        else // rotationFinder has been defined
        {
            Rj = rotationFinder->getRotations()[j];
        }
        // on passe les deplacements du repere local au repere global
        const Deriv& temp = Rj * dx[j];
        dx[j] = temp;
    }
}

template<>
SOFA_COMPONENT_CONSTRAINTSET_API void PrecomputedConstraintCorrection<defaulttype::Rigid3fTypes>::rotateResponse()
{

    VecDeriv& dx = *mstate->getDx();
    VecCoord& x = *mstate->getX();
    VecCoord& x0 = *mstate->getX0();
    for(unsigned int j = 0; j < dx.size(); j++)
    {
        // on passe les deplacements du repere local (au repos) au repere global
        Deriv temp ;
        Quat q;
        if (m_restRotations)
            q = x[j].getOrientation() * x0[j].getOrientation().inverse();
        else
            q = x[j].getOrientation();

        temp.getVCenter()		= q.rotate(dx[j].getVCenter());
        temp.getVOrientation()  = q.rotate(dx[j].getVOrientation());
        dx[j] = temp;
    }
}

template<>
SOFA_COMPONENT_CONSTRAINTSET_API void PrecomputedConstraintCorrection<defaulttype::Vec1fTypes>::rotateResponse()
{
}

#endif

using namespace sofa::defaulttype;

SOFA_DECL_CLASS(PrecomputedConstraintCorrection)

int PrecomputedConstraintCorrectionClass = core::RegisterObject("Component computing contact forces within a simulated body using the compliance method.")
#ifndef SOFA_FLOAT
        .add< PrecomputedConstraintCorrection<Vec3dTypes> >()
//     .add< PrecomputedConstraintCorrection<Vec2dTypes> >()
        .add< PrecomputedConstraintCorrection<Vec1dTypes> >()
        .add< PrecomputedConstraintCorrection<Rigid3dTypes> >()
#endif
#ifndef SOFA_DOUBLE
        .add< PrecomputedConstraintCorrection<Vec3fTypes> >()
//     .add< PrecomputedConstraintCorrection<Vec2fTypes> >()
        .add< PrecomputedConstraintCorrection<Vec1fTypes> >()
        .add< PrecomputedConstraintCorrection<Rigid3fTypes> >()
#endif
        ;

#ifndef SOFA_FLOAT
template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Vec3dTypes>;
//template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Vec2dTypes>;
template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Vec1dTypes>;
//template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Vec6dTypes>;
template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Rigid3dTypes>;
//template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Rigid2dTypes>;
#endif
#ifndef SOFA_DOUBLE
template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Vec3fTypes>;
//template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Vec2fTypes>;
template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Vec1fTypes>;
//template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Vec6fTypes>;
template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Rigid3fTypes>;
//template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Rigid2fTypes>;
#endif

} // namespace collision

} // namespace component

} // namespace sofa
<commit_msg>r7900/sofa-dev : FIX : Forgotten modifications.<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 4      *
*                (c) 2006-2009 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#define SOFA_COMPONENT_CONSTRAINTSET_PRECOMPUTEDCONSTRAINTCORRECTION_CPP
#include "PrecomputedConstraintCorrection.inl"
#include <sofa/defaulttype/Vec3Types.h>
#include <sofa/core/ObjectFactory.h>

namespace sofa
{
namespace component
{
namespace constraintset
{

#ifndef SOFA_FLOAT

template<>
SOFA_COMPONENT_CONSTRAINTSET_API void PrecomputedConstraintCorrection<defaulttype::Vec3dTypes>::draw()
{
    if (!getContext()->getShowBehaviorModels() || !m_rotations.getValue()) return;

    // we draw the rotations associated to each node //

    simulation::Node *node = dynamic_cast<simulation::Node *>(getContext());

    sofa::component::forcefield::TetrahedronFEMForceField<defaulttype::Vec3dTypes>* forceField = NULL;
    sofa::component::container::RotationFinder<defaulttype::Vec3dTypes>* rotationFinder = NULL;

    if (node != NULL)
    {
        //		core::behavior::BaseForceField* _forceField = node->forceField[1];
        forceField = node->get<component::forcefield::TetrahedronFEMForceField<defaulttype::Vec3dTypes> > ();
        if (forceField == NULL)
        {
            rotationFinder = node->get<component::container::RotationFinder<defaulttype::Vec3dTypes> > ();
            if (rotationFinder == NULL)
            {
                sout << "No rotation defined : only defined for TetrahedronFEMForceField and RotationFinder!";
                return;
            }
        }
    }

    VecCoord& x = *mstate->getX();
    for (unsigned int i=0; i< x.size(); i++)
    {
        Transformation Ri;
        if (forceField != NULL)
        {
            forceField->getRotation(Ri, i);
        }
        else // rotationFinder has been defined
        {
            Ri = rotationFinder->getRotations()[i];
        }

        sofa::defaulttype::Matrix3 RotMat;

        for (unsigned int a=0; a<3; a++)
        {
            for (unsigned int b=0; b<3; b++)
            {
                RotMat[a][b] = Ri(a,b);
            }
        }

        sofa::defaulttype::Quat q;
        q.fromMatrix(RotMat);

        helper::gl::Axis::draw(x[i], q  , this->debugViewFrameScale.getValue());

    }
}

template<>
SOFA_COMPONENT_CONSTRAINTSET_API void PrecomputedConstraintCorrection<defaulttype::Rigid3dTypes>::rotateConstraints(bool back)
{
    VecCoord& x = *mstate->getX();
    VecConst& constraints = *mstate->getC();
    VecCoord& x0 = *mstate->getX0();

    unsigned int numConstraints = constraints.size();
    //	int sizemax=0;
    //	int index_const = -1;
    // on fait tourner les normales (en les ramenant dans le "pseudo" repere initial) //
    for(unsigned int curRowConst = 0; curRowConst < numConstraints; curRowConst++)
    {
        ConstraintIterator itConstraint;
        std::pair< ConstraintIterator, ConstraintIterator > iter=constraints[curRowConst].data();
        for (itConstraint=iter.first; itConstraint!=iter.second; itConstraint++)
        {
            unsigned int dof = itConstraint->first;
            Deriv& n = itConstraint->second;
            const int localRowNodeIdx = dof;
            Quat q;
            if (m_restRotations.getValue())
                q = x[localRowNodeIdx].getOrientation() * x0[localRowNodeIdx].getOrientation().inverse();
            else
                q = x[localRowNodeIdx].getOrientation();

            Vec3d n_i = q.inverseRotate(n.getVCenter());
            Vec3d wn_i= q.inverseRotate(n.getVOrientation());
            if(back)
            {
                n_i = q.rotate(n.getVCenter());
                wn_i= q.rotate(n.getVOrientation());
            }

            // on passe les normales du repere global au repere local
            n.getVCenter() = n_i;
            n.getVOrientation() = wn_i;

        }
    }
}

template<>
SOFA_COMPONENT_CONSTRAINTSET_API void PrecomputedConstraintCorrection<defaulttype::Vec1dTypes>::rotateConstraints(bool /*back*/)
{
}

template<>
SOFA_COMPONENT_CONSTRAINTSET_API void PrecomputedConstraintCorrection<defaulttype::Rigid3dTypes>::rotateResponse()
{

    VecDeriv& dx = *mstate->getDx();
    VecCoord& x = *mstate->getX();
    VecCoord& x0 = *mstate->getX0();
    for(unsigned int j = 0; j < dx.size(); j++)
    {
        // on passe les deplacements du repere local (au repos) au repere global
        Deriv temp ;
        Quat q;
        if (m_restRotations.getValue())
            q = x[j].getOrientation() * x0[j].getOrientation().inverse();
        else
            q = x[j].getOrientation();

        temp.getVCenter()		= q.rotate(dx[j].getVCenter());
        temp.getVOrientation()  = q.rotate(dx[j].getVOrientation());
        dx[j] = temp;
    }
}

template<>
SOFA_COMPONENT_CONSTRAINTSET_API void PrecomputedConstraintCorrection<defaulttype::Vec1dTypes>::rotateResponse()
{
}

#endif
#ifndef SOFA_DOUBLE

template<>
SOFA_COMPONENT_CONSTRAINTSET_API void PrecomputedConstraintCorrection<defaulttype::Vec3fTypes>::rotateConstraints(bool back)
{
    VecConst& constraints = *mstate->getC();
    unsigned int numConstraints = constraints.size();

    simulation::Node *node = dynamic_cast<simulation::Node *>(getContext());

    sofa::component::forcefield::TetrahedronFEMForceField<defaulttype::Vec3fTypes>* forceField = NULL;
    sofa::component::container::RotationFinder<defaulttype::Vec3fTypes>* rotationFinder = NULL;

    if (node != NULL)
    {
        forceField = node->get<component::forcefield::TetrahedronFEMForceField<defaulttype::Vec3fTypes> > ();
        if (forceField == NULL)
        {
            rotationFinder = node->get<component::container::RotationFinder<defaulttype::Vec3fTypes> > ();
            if (rotationFinder == NULL)
            {
                sout << "No rotation defined : only defined for TetrahedronFEMForceField and RotationFinder!";
                return;
            }
        }
    }
    else
    {
        sout << "Error getting context in method: PrecomputedConstraintCorrection<defaulttype::Vec3dTypes>::rotateConstraints()";
        return;
    }

    //sout << "start rotating normals " << g_timer_elapsed(timer, &micro) << sendl;
    //	int sizemax=0;
    //	int index_const = -1;
    // on fait tourner les normales (en les ramenant dans le "pseudo" repere initial) //
    for(unsigned int curRowConst = 0; curRowConst < numConstraints; curRowConst++)
    {
        ConstraintIterator itConstraint;

        std::pair< ConstraintIterator, ConstraintIterator > iter=constraints[curRowConst].data();
        for (itConstraint=iter.first; itConstraint!=iter.second; itConstraint++)
        {
            unsigned int dof = itConstraint->first;
            Deriv& n = itConstraint->second;
            const int localRowNodeIdx = dof;
            Transformation Ri;
            if (forceField != NULL)
            {
                forceField->getRotation(Ri, localRowNodeIdx);
            }
            else // rotationFinder has been defined
            {
                Ri = rotationFinder->getRotations()[localRowNodeIdx];
            }
            if(!back)
                Ri.transpose();
            // on passe les normales du repere global au repere local
            Deriv n_i = Ri * n;
            n.x() =  n_i.x();
            n.y() =  n_i.y();
            n.z() =  n_i.z();
        }
        /*
        // test pour voir si on peut reduire le nombre de contrainte
        if (sizeCurRowConst > sizemax)
        {
        sizemax = sizeCurRowConst;
        index_const = curRowConst;
        }
        */
    }
}

template<>
SOFA_COMPONENT_CONSTRAINTSET_API void PrecomputedConstraintCorrection<defaulttype::Rigid3fTypes>::rotateConstraints(bool back)
{
    VecCoord& x = *mstate->getX();
    VecConst& constraints = *mstate->getC();
    VecCoord& x0 = *mstate->getX0();

    unsigned int numConstraints = constraints.size();
    //	int sizemax=0;
    //	int index_const = -1;
    // on fait tourner les normales (en les ramenant dans le "pseudo" repere initial) //
    for(unsigned int curRowConst = 0; curRowConst < numConstraints; curRowConst++)
    {
        ConstraintIterator itConstraint;

        std::pair< ConstraintIterator, ConstraintIterator > iter=constraints[curRowConst].data();
        for (itConstraint=iter.first; itConstraint!=iter.second; itConstraint++)
        {
            unsigned int dof = itConstraint->first;
            Deriv& n = itConstraint->second;
            const int localRowNodeIdx = dof;
            Quat q;
            if (m_restRotations.getValue())
                q = x[localRowNodeIdx].getOrientation() * x0[localRowNodeIdx].getOrientation().inverse();
            else
                q = x[localRowNodeIdx].getOrientation();

            Vec3d n_i = q.inverseRotate(n.getVCenter());
            Vec3d wn_i= q.inverseRotate(n.getVOrientation());
            if(back)
            {
                n_i = q.rotate(n.getVCenter());
                wn_i= q.rotate(n.getVOrientation());
            }

            // on passe les normales du repere global au repere local
            n.getVCenter() = n_i;
            n.getVOrientation() = wn_i;

        }
    }
}

template<>
SOFA_COMPONENT_CONSTRAINTSET_API void PrecomputedConstraintCorrection<defaulttype::Vec1fTypes>::rotateConstraints(bool /*back*/)
{
}

template<>
SOFA_COMPONENT_CONSTRAINTSET_API void PrecomputedConstraintCorrection<defaulttype::Vec3fTypes>::rotateResponse()
{
    simulation::Node *node = dynamic_cast<simulation::Node *>(getContext());

    sofa::component::forcefield::TetrahedronFEMForceField<defaulttype::Vec3fTypes>* forceField = NULL;
    sofa::component::container::RotationFinder<defaulttype::Vec3fTypes>* rotationFinder = NULL;

    if (node != NULL)
    {
        //		core::behavior::BaseForceField* _forceField = node->forceField[1];
        forceField = node->get<component::forcefield::TetrahedronFEMForceField<defaulttype::Vec3fTypes> > ();
        if (forceField == NULL)
        {
            rotationFinder = node->get<component::container::RotationFinder<defaulttype::Vec3fTypes> > ();
            if (rotationFinder == NULL)
            {
                sout << "No rotation defined : only defined for TetrahedronFEMForceField and RotationFinder!";
                return;
            }
        }
    }
    else
    {
        sout << "Error getting context in method: PrecomputedConstraintCorrection<defaulttype::Vec3dTypes>::rotateConstraints()";
        return;
    }

    VecDeriv& dx = *mstate->getDx();
    for(unsigned int j = 0; j < dx.size(); j++)
    {
        Transformation Rj;
        if (forceField != NULL)
        {
            forceField->getRotation(Rj, j);
        }
        else // rotationFinder has been defined
        {
            Rj = rotationFinder->getRotations()[j];
        }
        // on passe les deplacements du repere local au repere global
        const Deriv& temp = Rj * dx[j];
        dx[j] = temp;
    }
}

template<>
SOFA_COMPONENT_CONSTRAINTSET_API void PrecomputedConstraintCorrection<defaulttype::Rigid3fTypes>::rotateResponse()
{

    VecDeriv& dx = *mstate->getDx();
    VecCoord& x = *mstate->getX();
    VecCoord& x0 = *mstate->getX0();
    for(unsigned int j = 0; j < dx.size(); j++)
    {
        // on passe les deplacements du repere local (au repos) au repere global
        Deriv temp ;
        Quat q;
        if (m_restRotations.getValue())
            q = x[j].getOrientation() * x0[j].getOrientation().inverse();
        else
            q = x[j].getOrientation();

        temp.getVCenter()		= q.rotate(dx[j].getVCenter());
        temp.getVOrientation()  = q.rotate(dx[j].getVOrientation());
        dx[j] = temp;
    }
}

template<>
SOFA_COMPONENT_CONSTRAINTSET_API void PrecomputedConstraintCorrection<defaulttype::Vec1fTypes>::rotateResponse()
{
}

#endif

using namespace sofa::defaulttype;

SOFA_DECL_CLASS(PrecomputedConstraintCorrection)

int PrecomputedConstraintCorrectionClass = core::RegisterObject("Component computing contact forces within a simulated body using the compliance method.")
#ifndef SOFA_FLOAT
        .add< PrecomputedConstraintCorrection<Vec3dTypes> >()
//     .add< PrecomputedConstraintCorrection<Vec2dTypes> >()
        .add< PrecomputedConstraintCorrection<Vec1dTypes> >()
        .add< PrecomputedConstraintCorrection<Rigid3dTypes> >()
#endif
#ifndef SOFA_DOUBLE
        .add< PrecomputedConstraintCorrection<Vec3fTypes> >()
//     .add< PrecomputedConstraintCorrection<Vec2fTypes> >()
        .add< PrecomputedConstraintCorrection<Vec1fTypes> >()
        .add< PrecomputedConstraintCorrection<Rigid3fTypes> >()
#endif
        ;

#ifndef SOFA_FLOAT
template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Vec3dTypes>;
//template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Vec2dTypes>;
template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Vec1dTypes>;
//template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Vec6dTypes>;
template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Rigid3dTypes>;
//template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Rigid2dTypes>;
#endif
#ifndef SOFA_DOUBLE
template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Vec3fTypes>;
//template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Vec2fTypes>;
template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Vec1fTypes>;
//template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Vec6fTypes>;
template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Rigid3fTypes>;
//template class SOFA_COMPONENT_CONSTRAINTSET_API PrecomputedConstraintCorrection<Rigid2fTypes>;
#endif

} // namespace collision

} // namespace component

} // namespace sofa
<|endoftext|>