void ComponentMovement::createMotorJoints() { ASSERT(physicsEngine, "Null pointer: physicsEngine"); dBodyID body = getBodyID(); ASSERT(body, "Cannot create motor joints: No physics body available"); amotor = dJointCreateAMotor(physicsEngine->getWorld(), 0); dJointAttach(amotor, body, 0); dJointSetAMotorNumAxes(amotor, 3); dJointSetAMotorAxis (amotor, 0, 1, 1, 0, 0); dJointSetAMotorAxis (amotor, 1, 1, 0, 1, 0); dJointSetAMotorAxis (amotor, 2, 1, 0, 0, 1); dJointSetAMotorParam(amotor, dParamFMax, maxForce); dJointSetAMotorParam(amotor, dParamFMax2, maxForce); dJointSetAMotorParam(amotor, dParamFMax3, maxForce); dJointSetAMotorParam(amotor, dParamVel, 0); dJointSetAMotorParam(amotor, dParamVel2, 0); dJointSetAMotorParam(amotor, dParamVel3, 0); lmotor = dJointCreateLMotor(physicsEngine->getWorld(), 0); dJointAttach(lmotor, body, 0); dJointSetLMotorNumAxes(lmotor, 2); dJointSetLMotorAxis (lmotor, 0, 1, 1, 0, 0); dJointSetLMotorAxis (lmotor, 1, 1, 0, 1, 0); dJointSetLMotorParam(lmotor, dParamFMax, maxForce); dJointSetLMotorParam(lmotor, dParamFMax2, maxForce); dJointSetLMotorParam(lmotor, dParamVel, 0); dJointSetLMotorParam(lmotor, dParamVel2, 0); }
inline virtual void registerWithWorld(std::shared_ptr<gecom::WorldProxy> world) { B2PhysicsComponent::registerWithWorld(world); b2BodyDef def; def.type = b2_dynamicBody; def.fixedRotation = true; def.position.Set(getParent()->getPosition().x(), getParent()->getPosition().y()); def.linearDamping = 0.6f; setB2Body(world->createBody(def, shared_from_this())); auto bbb = std::make_shared<b2PolygonShape>(); bbb->SetAsBox(m_half_width, m_half_height); auto fix = std::make_shared<b2FixtureDef>(); fix->shape = bbb.get(); fix->density = 130; fix->friction = 0.99f; world->createFixture(getBodyID(), fix, bbb); }
void checkSphWallLubricationForce() { const uint_t timestep (timeloop_->getCurrentTimeStep()+1); // variables for output of total force - requires MPI-reduction pe::Vec3 forceSphr1(0); // temporary variables real_t gap (0); for( auto blockIt = blocks_->begin(); blockIt != blocks_->end(); ++blockIt ) { for( auto curSphereIt = pe::BodyIterator::begin<pe::Sphere>( *blockIt, bodyStorageID_); curSphereIt != pe::BodyIterator::end<pe::Sphere>(); ++curSphereIt ) { pe::SphereID sphereI = ( curSphereIt.getBodyID() ); if ( sphereI->getID() == id1_ ) { for( auto globalBodyIt = globalBodyStorage_->begin(); globalBodyIt != globalBodyStorage_->end(); ++globalBodyIt) { if( globalBodyIt->getID() == id2_ ) { pe::PlaneID planeJ = static_cast<pe::PlaneID>( globalBodyIt.getBodyID() ); gap = pe::getSurfaceDistance(sphereI, planeJ); break; } } break; } } } WALBERLA_MPI_SECTION() { mpi::reduceInplace( gap, mpi::MAX ); } WALBERLA_ROOT_SECTION() { if (gap < real_comparison::Epsilon<real_t>::value ) { gap = walberla::math::Limits<real_t>::inf(); WALBERLA_LOG_INFO_ON_ROOT( "Sphere still too far from wall to calculate gap!" ); } else { WALBERLA_LOG_INFO_ON_ROOT( "Gap between sphere and wall: " << gap ); } } // get force on sphere for( auto blockIt = blocks_->begin(); blockIt != blocks_->end(); ++blockIt ) { for( auto bodyIt = pe::BodyIterator::begin<pe::Sphere>( *blockIt, bodyStorageID_); bodyIt != pe::BodyIterator::end<pe::Sphere>(); ++bodyIt ) { if( bodyIt->getID() == id1_ ) { forceSphr1 += bodyIt->getForce(); } } } // MPI reduction of pe forces over all processes WALBERLA_MPI_SECTION() { mpi::reduceInplace( forceSphr1[0], mpi::SUM ); mpi::reduceInplace( forceSphr1[1], mpi::SUM ); mpi::reduceInplace( forceSphr1[2], mpi::SUM ); } WALBERLA_LOG_INFO_ON_ROOT("Total force on sphere " << id1_ << " : " << forceSphr1); if ( print_ ) { WALBERLA_ROOT_SECTION() { std::ofstream file1; std::string filename1("Gap_LubricationForceBody1.txt"); file1.open( filename1.c_str(), std::ofstream::app ); file1.setf( std::ios::unitbuf ); file1.precision(15); file1 << gap << " " << forceSphr1[0] << std::endl; file1.close(); } } WALBERLA_ROOT_SECTION() { if ( timestep == uint_t(26399) ) { // according to the formula from Ding & Aidun 2003 // F = 6 * M_PI * rho_L * nu_L * relative velocity of both bodies=relative velocity of the sphere * r * r * 1/gap // the correct analytically calculated value is 339.292006996217 // in this geometry setup the relative error is 0.183515322065561 % real_t analytical = real_c(6.0) * walberla::math::M_PI * real_c(1.0) * nu_L_ * real_c(-vel_[0]) * radius_ * radius_ * real_c(1.0)/gap; real_t relErr = std::fabs( analytical - forceSphr1[0] ) / analytical * real_c(100.0); WALBERLA_CHECK_LESS( relErr, real_t(1) ); } } }
void checkSphSphLubricationForce() { const uint_t timestep (timeloop_->getCurrentTimeStep()+1); // variables for output of total force - requires MPI-reduction pe::Vec3 forceSphr1(0); pe::Vec3 forceSphr2(0); // temporary variables real_t gap (0); // calculate gap between the two spheres for( auto blockIt = blocks_->begin(); blockIt != blocks_->end(); ++blockIt ) { for( auto curSphereIt = pe::BodyIterator::begin<pe::Sphere>( *blockIt, bodyStorageID_); curSphereIt != pe::BodyIterator::end<pe::Sphere>(); ++curSphereIt ) { pe::SphereID sphereI = ( curSphereIt.getBodyID() ); if ( sphereI->getID() == id1_ ) { for( auto blockIt2 = blocks_->begin(); blockIt2 != blocks_->end(); ++blockIt2 ) { for( auto oSphereIt = pe::BodyIterator::begin<pe::Sphere>( *blockIt2, bodyStorageID_); oSphereIt != pe::BodyIterator::end<pe::Sphere>(); ++oSphereIt ) { pe::SphereID sphereJ = ( oSphereIt.getBodyID() ); if ( sphereJ->getID() == id2_ ) { gap = pe::getSurfaceDistance( sphereI, sphereJ ); break; } } } break; } } } WALBERLA_MPI_SECTION() { mpi::reduceInplace( gap, mpi::MAX ); } WALBERLA_ROOT_SECTION() { if (gap < real_comparison::Epsilon<real_t>::value ) { // shadow copies have not been synced yet as the spheres are outside the overlap region gap = walberla::math::Limits<real_t>::inf(); WALBERLA_LOG_INFO_ON_ROOT( "Spheres still too far apart to calculate gap!" ); } else { WALBERLA_LOG_INFO_ON_ROOT( "Gap between sphere 1 and 2: " << gap ); } } // get force on spheres for( auto blockIt = blocks_->begin(); blockIt != blocks_->end(); ++blockIt ) { for( auto bodyIt = pe::BodyIterator::begin<pe::Sphere>( *blockIt, bodyStorageID_); bodyIt != pe::BodyIterator::end<pe::Sphere>(); ++bodyIt ) { if( bodyIt->getID() == id1_ ) { forceSphr1 += bodyIt->getForce(); } else if( bodyIt->getID() == id2_ ) { forceSphr2 += bodyIt->getForce(); } } } // MPI reduction of pe forces over all processes WALBERLA_MPI_SECTION() { mpi::reduceInplace( forceSphr1[0], mpi::SUM ); mpi::reduceInplace( forceSphr1[1], mpi::SUM ); mpi::reduceInplace( forceSphr1[2], mpi::SUM ); mpi::reduceInplace( forceSphr2[0], mpi::SUM ); mpi::reduceInplace( forceSphr2[1], mpi::SUM ); mpi::reduceInplace( forceSphr2[2], mpi::SUM ); } WALBERLA_LOG_INFO_ON_ROOT("Total force on sphere " << id1_ << " : " << forceSphr1); WALBERLA_LOG_INFO_ON_ROOT("Total force on sphere " << id2_ << " : " << forceSphr2); if ( print_ ) { WALBERLA_ROOT_SECTION() { std::ofstream file1; std::string filename1("Gap_LubricationForceBody1.txt"); file1.open( filename1.c_str(), std::ofstream::app ); file1.setf( std::ios::unitbuf ); file1.precision(15); file1 << gap << " " << forceSphr1[0] << std::endl; file1.close(); std::ofstream file2; std::string filename2("Gap_LubricationForceBody2.txt"); file2.open( filename2.c_str(), std::ofstream::app ); file2.setf( std::ios::unitbuf ); file2.precision(15); file2 << gap << " " << forceSphr2[0] << std::endl; file2.close(); } } WALBERLA_ROOT_SECTION() { if ( timestep == uint_t(1000) ) { // both force x-components should be the same only with inverted signs WALBERLA_CHECK_FLOAT_EQUAL ( forceSphr2[0], -forceSphr1[0] ); // according to the formula from Ding & Aidun 2003 // F = 3/2 * M_PI * rho_L * nu_L * relative velocity of both spheres * r * r * 1/gap // the correct analytically calculated value is 339.2920063998 // in this geometry setup the relative error is 0.1246489711 % real_t analytical = real_c(3.0)/real_c(2.0) * walberla::math::M_PI * real_c(1.0) * nu_L_ * real_c(2.0) * real_c(vel_[0]) * radius_ * radius_ * real_c(1.0)/gap; real_t relErr = std::fabs( analytical - forceSphr2[0] ) / analytical * real_c(100.0); WALBERLA_CHECK_LESS( relErr, real_t(1) ); } } }
void Balaenidae::doDynamics() { doDynamics(getBodyID()); }
void Buggy::doDynamics() { doDynamics(getBodyID()); }