How to obtain the coordination number of particles in EDEM API?

Longzhu
Longzhu New Altair Community Member
edited November 2023 in Community Q&A

Hi EDEMer!

I have recently encountered some problems with the EDEM API.

I want to obtain the coordination number of particles ,so I chose to use "element1.coordinationNumber" attribute  in the  "IPluginContactModelV3_5_0.h" files ,but I found that this attribute cannot be identified in EDEM software,Even if the particle has a coordination number, the value of this attribute is still 0.

These pictures are my code and debugging results, I defined an unsigned int type ' RTERT ' to call “element1.coordinationNumber”,We can find that the value of ' RTERT ' in the program is always 0, but in EDEM, the value of coordination number is not zero.

If you can help me answer, I will be very grateful!

imageimageimage

Tagged:

Answers

  • Stephen Cole
    Stephen Cole
    Altair Employee
    edited November 2023

    Hi Juhan,

    The coordination number also requires 'usesCoordinationNumber():

    Indicates whether the plugin wishes to use coordination number.

    The coordination number is the number of particle-particle contacts a particle has. This is only valid in the particle-particle contact model chain.

    If this function returns true, coordination number will be calculated in EDEM and passed to the calculateForce(...) method as part of the SDiscreteElement parameters.

    If you don't use coordination number in your code, please return false to avoid performance loss.

    Returns
    Bool to indicate if coordination number is to be used and the values of coordination number are passed to calculateForce(...) method.

     

    In your header file you can add:

     

    bool usesCoordinationNumber() override;

    then in the main .cpp file:

     

    bool CustomName::usesCoordinationNumber() { 	return true; }


    Regards

    Stephen

  • Longzhu
    Longzhu New Altair Community Member
    edited November 2023

    Hi Stephen !

    I added the 'usesCoordinationNumber():' in my code, but it still doesn 't work, although the value of "test" is not zero, it is not equal to the coordination number in the EDEM software.

    Is my code written wrong?imageimageimage

     

  • Stephen Cole
    Stephen Cole
    Altair Employee
    edited November 2023

    Hi Stephen !

    I added the 'usesCoordinationNumber():' in my code, but it still doesn 't work, although the value of "test" is not zero, it is not equal to the coordination number in the EDEM software.

    Is my code written wrong?imageimageimage

     

    Hi Yuhan,

    There are a couple of issues needed to be considered, but mostly that the middle particle in this case has 2 contacts therefore the Contact Model will be called twice.  So you are adding the value twice and removing the previous value twice.  I'd actually expect you to get 4 or 0 rather than 1 for the middle case but it depends on the starting conditions.

    Reason thinking it would be 4 is that you are adding 2 twice and removing 0 twice initially.  Then next time-step you would add 2 twice again but remove 4 twice and so on.  However if it goes from 0 to 1 to 2 coordination number in  different time-steps then the logic would be different.

    I believe what you should do is check if there is a difference between the current and previous values (if no difference don't update it), and then only add the fraction of the delta.  So if there is two contacts and 1/2 the value, if there is 3 contacts add 1/3 the value as these will all be included by EDEM.

    For example I believe this should work, although I haven't tested it:

    		int test1 = element1.coordinationNumber; 		int test2 = element2.coordinationNumber;  		const double* mCoordValue1 = elem1CustomProperties->getValue(iCOORD); 		double* mCoordDelta1 = elem1CustomProperties->getDelta(iCOORD); 		const double* mCoordValue2 = elem2CustomProperties->getValue(iCOORD); 		double* mCoordDelta2 = elem2CustomProperties->getDelta(iCOORD); 		if (test1 != mCoordValue1[0]) 		{ 			double delta = test1 - mCoordValue1[0]; 			mCoordDelta1[0] += delta / test1; 		} 		if (test2 != mCoordValue2[0]) 		{ 			double delta = test2 - mCoordValue2[0]; 			mCoordDelta2[0] += delta / test2; 		}

     

    The other point to consider is if there are no contacts.  You are always going to be showing the value of the last time-step that the particle had contacts.  So if a particle has 1 contact then looses contact it will always show 1 until it gains a new contact.  It depends on how you use the code if you need to resolve this further...


    Regards

    Stephen