UCS Test using Voronoi technique in UDEC7

Hello,

I am currently working on a uniaxial compressive test simulation using Voronoi tessellation technique on UDEC7. For the boundary conditions, I am using a null value of x-velocities on the top/bottom of the sample and a constant value for y-velocities to simulate the loading.

My objective now is to write a FISH function to calculate the top and bottom stresses (by dividing the sum of reaction forces on the top and the bottom edges of the sample by the corresponding diameter), as well as the deformation of the sample. This method was already elaborated in an existing example of UCS Test (Voronoi sample) in 3DEC7, and below is shown the existing code in the 3DEC model.
I am trying now to write an equivalent function in UDEC, but I am facing some difficulties regarding the list definition, as I haven’t found an equivalent FISH command of ‘block.gp.list’ in UDEC.

I would like to ask for other suggestions of command or existing functions that help me to calculate these results in UDEC.

Your help is appreciated!
Mariam

Hello MariamJ,
I don’t know about equivalent function of block.gp.list, however I have one idea. Instead of getting reaction forces near the top and bottom, will it be okay to get contact stresses near the top and bottom interfaces? If yes, then you can use block.contact.head to get index of all the contacts. Here I don’t know how to get the specific index number of contacts which are near top and bottom interface. For each contact you can get normal force using block.contact.force.normal and you can get contact length using block.contact.length. Dividing the normal force by contact length will give you normal stress. I am doing UCS test with rock sample modelled using Voronoi blocks. I posted a question previously in which you can find a FISH script with some functions commands mentioned above. I hope that helps you.

1 Like

Hi Mariam,

You can loop on the block list, then the zone list and then for each zone your find the 3 corresponding gridpoints.
Something like this :

fish define  calc_bound_force` 

    bi = block.head
    loop while bi # 0
    zi = block.zone(bi)    
        loop while zi#0
        a1=block.zone.gp(zi,1)
        a2=block.zone.gp(zi,2)
        a3=block.zone.gp(zi,3)
  ; here you sum your forces for some selected gridpoints (for example located in a given group). But pay attention not to take the same gridpoint several times. You can mark for example gridpoints that were already taken into account by changing the value in their extra.


      zi = block.zone.next(zi)
        
      endloop 

    bi = block.next(bi)
    end_loop

end

Hello Rima,

Thank you for your suggestions, I will try this method.
However, I have also developed the function shown below. 76 is the Y-position of the top surface and 38 is the diameter of the sample.

Regards;

This should work fine.
You just need to make sure that the increment dx=1 is small enough to get the totality of the gridpoints at the top. This depends on your meshing size.
The way you verify that you are not taking the same gridpoints twice is fne two. An alternative way is to mark the extra of every gridpoint that you have already considered with for example “block.gp.extra(gpi,1)=10” (where gpi=block.gp.near(u,76)) and then add a condition “if (block.gp.extra(gpi,1)#10” for the next gridpoints.

1 Like

Hello,

Thank you for your suggestions. And if you are willing to get the index number of the gridpoints located at the top and bottom boundary, you can benefit from the function below.

Regards;
Mariam

As @Rima already mentioned, I think it is a bad approach when it implicitly assumes that all gridpoints are at least 1m apart or else gridpoints are missed. Others may use this function without considering this and getting wrong results. Also the method can’t be easily used on models with explicitly modeled top platen in large-strain, since the top coordinate may change and therefore points of the platen may be falsely evaluated later on.

A more clear approach would be to 1) mark all top gridpoints one before starting cycling with e.g. a group and then 2) evaluating only gridpoints of that group:

fish def groupGridpoints ;marks all top gridpoints, use this once before cycling
    bi=block.head
    loop while bi#0
        gi=block.gp(bi) ;gets a list of gridpoints of each block
        loop while gi#0
            if block.gp.pos.y(gi)==76 ;could also be an argument passed into this function
                block.gp.group(gi,"Position")="top"
            end_if
        gi=block.gp.next(gi)
        endloop
    bi=block.next(bi)
    endloop
end
@groupGridpoints

fish def getReaction
    totalforce=0.0
    bi=block.head
    loop while bi#0
        gi=block.gp(bi)
        loop while gi#0
            if block.gp.group(gi,"Position")=="top" then
            totalforce=totalforce+block.gp.reaction.y(gi)
            end_if
        gi=block.gp.next(gi)
        endloop
    bi=block.next(bi)
    endloop
    reaction=-totalforce/38.0
end
@getReaction

Hello ,

Noted! Thank you, it’s appreciated.

Regards;
Mariam