Reference the axis of a rotating Geometry for custom factory (EDEM API Tutorial 6: Snooker Factory)

Semih Özen
Semih Özen New Altair Community Member
edited October 2022 in Community Q&A

Hi, 

I've been using the Edem API Tutorial 6 to get a feeling for custom factories. So far I have:

  • adjusted the code to create particles every 0.2 seconds at a fixed location on the table
  • with a Z-Velocity of 1.0 (gravity off) 
  • adjusted code is attached below

I am now rotating the table (could be any other geometry) along the X-axis and I want the particles to reference the rotating Z-Axis of the table and spawn along that Z-direction. The Particle are spawning along the local/global? Z-Axis currently (see attached image)

It would be very useful if someone could name some API/Classes/Methods in the documentation to look for. Or any other suggestions to handle this problem.

Some ideas of mine:

  • Reference the coordinates of the table with some getMethod()? or the initial velocity of the rotation with getVelocity()?
  • Calculate the normal to a rotating object, and set the direction of the velocity of the particles to that normal

I appreciate all suggestions.

Semih

image

// Calculate number of iteration int numIteration = 0; // spawn a particle every after time double timerStep = 0.0; // [s]  NApi::ECalculateResult CSnooker::createParticle( 	double  time, 	double  timestep, 	bool& particleCreated, 	bool& additionalParticleRequired, 	char    type[NApi::API_BASIC_STRING_LENGTH], 	double& scale, 	double& posX, 	double& posY, 	double& posZ, 	double& velX, 	double& velY, 	double& velZ, 	double& angVelX, 	double& angVelY, 	double& angVelZ, 	double  orientation[9], 	NApiCore::ICustomPropertyDataApi_1_0* propData, 	NApiCore::ICustomPropertyDataApi_1_0* simData) { 	if (time > 9 || m_numberCreated >= 100) 	{ 		particleCreated = false; 		additionalParticleRequired = false; 		return eSuccess; 	} 	if (timerStep - time < 1e-04) { 		// Mark that we are creating a particle 		particleCreated = true;  		// Set some fixed values for all particles we create 		velX = 0.0; 		velY = 0.0; 		velZ = 0.0;  		angVelX = 0.0; 		angVelY = 0.0; 		angVelZ = 0.0;  		for (unsigned int i = 0; i < 9; i++) 		{ 			orientation[i] = 0.0; 		}  		scale = 1.0;  		// Z position is the same for all aprticles (just above the table 		// X and Y vary 		posZ = 0.025;  		strncpy(type, "red", API_BASIC_STRING_LENGTH); 		posZ = 0.1; 		posX = 1; 		posY = 0.5; 		velZ = 1.0;  		// Mark the particle as created 		m_numberCreated++; 		timerStep += 0.2;  		// We are creating 21 particles, if we've done them all 		// then no more are required 		additionalParticleRequired = (100 != m_numberCreated); 		return eSuccess; 	} 	else { 		// timerStep += 0.1; 	} 	// Count the number of iteration 	numIteration++; }
Tagged:

Best Answer

  • RWood
    RWood
    Altair Employee
    edited October 2022 Answer ✓

    Hi,

         "Calculate the normal to a rotating object, and set the direction of the velocity of the particles to that normal"

    That would be my approach. You've probably seen that there's no easy way to get the orientation of the geometry within a factory. You can get the orientation of an element in a contact model, but that doesn't help you in a factory.

    Off the top of my head, I would do something like define a normal vector to the geometry, manually, and keep track of it's orientation based on the rotations being applied in EDEM - again you would have to apply the rotations manually. So if you have a kinematic that rotates around an axis, you would have to apply that rotation to your normal vector as well, within your factory. Not particularly elegant, I know. 

    You could also use the coupling interface which has a getGeometryPosition() method, write that to either a text file or simulation custom property, and reference the rotation matrix from that. That could be quite a neat way to do it actually, but has the downside that you'd not be able to run the simulation with another coupling. 

    You could also do the same kind of thing using edemPy and then use that to write to a file or custom property. The first issue that jumps into my head about using edemPy is that generally you would use it to post-process, whereas here you'd want the data each timestep. Not a big deal, you could either write all the geometry data out first or have some kind of condition in your python/API plugin that pauses until the next lot of geometry data is available, but something you'd have to think about.

    A few ideas.

    Cheers,

    Richard

Answers

  • RWood
    RWood
    Altair Employee
    edited October 2022 Answer ✓

    Hi,

         "Calculate the normal to a rotating object, and set the direction of the velocity of the particles to that normal"

    That would be my approach. You've probably seen that there's no easy way to get the orientation of the geometry within a factory. You can get the orientation of an element in a contact model, but that doesn't help you in a factory.

    Off the top of my head, I would do something like define a normal vector to the geometry, manually, and keep track of it's orientation based on the rotations being applied in EDEM - again you would have to apply the rotations manually. So if you have a kinematic that rotates around an axis, you would have to apply that rotation to your normal vector as well, within your factory. Not particularly elegant, I know. 

    You could also use the coupling interface which has a getGeometryPosition() method, write that to either a text file or simulation custom property, and reference the rotation matrix from that. That could be quite a neat way to do it actually, but has the downside that you'd not be able to run the simulation with another coupling. 

    You could also do the same kind of thing using edemPy and then use that to write to a file or custom property. The first issue that jumps into my head about using edemPy is that generally you would use it to post-process, whereas here you'd want the data each timestep. Not a big deal, you could either write all the geometry data out first or have some kind of condition in your python/API plugin that pauses until the next lot of geometry data is available, but something you'd have to think about.

    A few ideas.

    Cheers,

    Richard