ubermag / help

Repository for raising issues and requesting help on Ubermag
BSD 2-Clause "Simplified" License
11 stars 3 forks source link

Grains with Random Anisotrpy (Voronoi) #110

Open Ahsanu8 opened 3 years ago

Ahsanu8 commented 3 years ago

Hi Ubermag team,

Is there any example grain with random anisotropy? In OOMMF there is an example on this site (https://www.ctcms.nist.gov/~jlau/OOMMF/Voronoi/), with published work (https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4651613/). Can we have grains in 3 dimensions?

Kind Regards,

marijanbeg commented 3 years ago

Hi @ahsu83, thank you for your question. Creating grains in Ubermag eventually comes to writing a Python function which is then used to create a field object, later used to define a parameter.

We would recommend writing a Python function for this and we would be very interested in using your example in our documentation.

marijanbeg commented 3 years ago

Hi @ahsu83, we have recently done something on this topic, so please keep an eye on other issues where another Ubermag user will post the solution we did.

Ahsanu8 commented 3 years ago

Hi @marijanbeg. Thanks, I am the same person who contacted you recently. I will post both of my attempts here (like the one in which I considered 48 cubes with random anisotropy and fidimag example (https://fidimag.readthedocs.io/en/latest/user_guide/ipynb/anisotropic-grain-structure.html), https://fidimag.readthedocs.io/en/latest/user_guide/ipynb/Simulating%20an%20Anisotropic%20Grain%20Structure.html).

I will take a little bit of time to modify the file you send. Thanks for that file. :)

Kind Regards, Ahsan

Ahsanu8 commented 3 years ago

Hi, I attached the jupyter file. It has a little bit of modification. This file creates grains of different sizes.

So the question is how we can have grains of fixed size and create the desired number of grains. I kept increasing the number of grains which gave me a number the average size of grains close to 10nm.

I think something has to be done in the following section of the code. For that we need to fix the distance between the grain centers. Like if somehow we fix the distance between then it might give fix sized grains.

import numpy as np

from scipy.spatial import cKDTree import numpy as np

d = 10e-9 np.random.seed(10) Ngrains = 72 grain_centres = np.random.uniform(-3d, 3d, (Ngrains, 3)) grain_centres voronoi_kdtree = cKDTree(grain_centres) Grain Hysterics 0.5 - Jupyter Notebook.pdf

Kind Regards

marijanbeg commented 3 years ago

Reopening issue...

marijanbeg commented 3 years ago

Hi @ahsu83, thank you.

If you want grains of the same size, you have to specify grain centre points equally distributed throughout the sample. You can get this functionality using df.Mesh object, where each discretisation cell is one grain. For example:

grains_mesh = df.Mesh(region=region, cell=(10e-9, 10e-9, 10e-9))  # 10nm grains
grain_centres = list(grains_mesh)  # This extracts cell centre points 

Could you please try this?

Please note that even though you cannot attach .ipynb file here, you can "zip" it and attach it. This helps us a lot because we can run the notebooks you send us and look for issues.

Ahsanu8 commented 3 years ago

Hi @marijanbeg, Thank you very much. That's a very good idea. It worked. It can give us desirable grains size and we can control the number of grains.

The only problem is it gives grains of cubic shape.

I did a simulation using grains_mesh method to get a fixed number of grains in a region specified with all grains to have the same size. Since ubermag is based on the finite element method so it gave me cubic grains. So from this method, I found that how many grains of some specific size I can accommodate in the region. e.g. I have 150 grains. I used them in the previous code where the grains centers found from np.random.uniform. It gives me non-uniform grains (one way to make non-cubic grains in some regions, you can see grains are around 12nm).

Is there any way to find the average size of grains in noncubic one?

Or any other way we make grains of non-cubic shape using

grains_mesh = df.Mesh(region=region, cell=(10e-9, 10e-9, 10e-9)) # 10nm grains

of equal size?

Anyway, your suggestion worked perfectly, thanks for it. I attached two files in zip. Grains ipython files .zip

Kind Regards, Ahsan

marijanbeg commented 3 years ago

HI @ahsu83, that is good news. I am glad it works.

This is a tricky question you are asking. Maybe if I explain to you how the algorithm works:

  1. You specify the central points of grains. In the first notebook we exchanged, these centres were random and in the newest one, their distribution in space is regular.
  2. To each centre point we assign a random anisotropy axis (one point - one random u)
  3. Then for each cell in our mesh, we find which grain centre point (from the set of grain centre points we generated earlier in point 1) is the nearest.
  4. We assign the same anisotropy axis to that point as we assigned to the centre point (point 2).
  5. We repeat this for all points in the mesh.
  6. (For more details, you can google some nearest neighbour classification algorithms in machine learning.)

You can see that this algorithm is strongly dependent on how you generate grain centre points. By choosing their positions, you can control the size and shape of your grains.

It is a non-trivial question of how to make a random distribution of points in three dimensions and to ensure the distance between all of them is 10 nm, but not to be on a regular grid. What I can suggest is you generate a regular distribution of points and add some randomness to them, so that they are all displaced from their original locations. This way you can ensure that:

Other two points:

Does this make sense? What do you think?

This is a very interesting problem and we would be very interested in seeing the final solution which we can share with others as a tutorial.

Ahsanu8 commented 3 years ago

Hi @marijanbeg, Thanks for the detailed explanation related to the algorithm. Yes, these are very good suggestions. My typo, yes ubermag based on finite-difference.

I think adding randomness in grains is a very good idea. We can do it by using np.random.uniform. I tried it in the attached file. It gives very good non-cubic grains. The average size of grains stays close to 12nm (x= 2d/5, y = (2d)/5, z = (2*d)/5, d = 30nm) The important thing for this code is to create a random direction of magnetic anisotropy in grains.

The noncubic shape decrease with an increase in the interval from which we select the randomness in grains and with a decrease in the cell size before the micromagnetic simulation for the mesh. (so there are two ways to get deformed noncubic grains).

(1) np.random.uniform(-3e-9, 3e-9, size=(Ngrains,3)) => changing the intervals (2) mesh = df.Mesh(region=region, cell=(1e-9, 1e-9, 1e-9)) => decreasing the cell size for simulations(will increase the simulation time).

If someone needs a more deformed shape they can use our other code where we choose centers completely random. But there they will need to play with a number of grains(Ngrains) to average the size to the desired value.

The advantage of this code is we won't have any restrictions on the number of grains. Like if someone wants to simulate 1000 grains(or even more) they can do it.

If the code needs more modification we can do it also.

Now another step is, how we can change the inter-grains exchange interactions. In original code of oommf in their paper on page 59. The Paper is attached. I guess this code won't complete until we are able to change the exchange interaction between grains. Grains.zip

Kind Regards, Ahsan v114.n01.a05.pdf

marijanbeg commented 3 years ago

Hi @ahsu83, that's good news.

Regarding the exchange between individual grains, you can define a field object that has the value of exchange energy constant at each discretisation cell. For those cells that are at an interface, you can set a different value that at those inside grains. This field object can then be passed as mm.Exchange(A=Afield).

Ahsanu8 commented 3 years ago

Hi, @marijanbeg Is there any example of defining a function that gives exchange energy constant as A1 between grains but A2 inside the grains. We define initially the cubic grain of somewhat 12nm and then deformed the grain to a noncubic shape. After that, I changed the cell size back to somewhat 2nm to have micromagnetic simulations. So now I am confused about how I can set some specific exchange constant between 12nm grains but normal exchange constant inside the grain.

Regards, Ahsan

marijanbeg commented 3 years ago

Hi @ahsu83, thank you for your question. Exchange energy constant is always defined between cells. Using field object to define it gives you freedom to define it the way you want. You can have a look at: https://math.nist.gov/oommf/doc/userguide20a2/userguide/Standard_Oxs_Ext_Child_Clas.html#EP for details.

Ahsanu8 commented 3 years ago

Hi @marijanbeg, I defined the strength of magnetic anisotropy in each region by using a function

def Kmag(pos):     x, y, z = pos     , test_point_regions = voronoi_kdtree.query(np.array([[x, y, z]]), k=1)     region = test_point_regions[0]     return strengths[region]

K = df.Field(mesh, dim=3, value=K_mag)

Do you think dim = 3 in this case?

Also what type of function I should write if I need magnetic exchange interaction of A1 within the grains and at the boundaries, it should be A2. Can I use function like above and with if and else statement. I am just stuck in this step that how I can define the function and then using, A = df.Field(mesh, dim=1, value=A_fun) define exchange constant. Grain with centres spaced regularly .zip

download

marijanbeg commented 3 years ago

Hi @ahsu83, thank you for the update. Here are some suggestions:

Could you please draft the code, and I would be happy to fix/debug it?

Semaida commented 2 years ago

@ahsu83 @marijanbeg Thank you very much for your greeting dialogue. Are there examples of composite materials (hard particles and soft particles) with random anisotropy (Voronoi)?

marijanbeg commented 2 years ago

Hi @Semaida, thank you for your question. We do not have an example in our documentation, but we would be very happy to include an example from you or from anyone else. :)

Ahsanu8 commented 2 years ago

Hi @Semaida, For hard and soft magnetic particles we will need to define the different parameters for the different regions in each particle. We can also do it by randomly assigning these parameters. I will think about it and will come back here. If you have any ideas you can share them here.

Semaida commented 2 years ago

@ahsu83 Thank you for your reply. I’m already using OOMMF, but the exchange coupling between the hard and soft magnetic particles in bilayer system. I want to randomly distribute hard and soft magnetic particles according to this paper: https://www.sciencedirect.com/science/article/pii/S0304885320325890?via%3Dihub exchangespring.zip

marijanbeg commented 2 years ago

Ubermag Team would like to encourage your discussion, and we would be happy to assist when necessary :)

AnastasiaFed commented 2 years ago

Dear Forum members! We solve in Ubermag the micromagnetic problem devoted to obtain hysteresis loops of 30-nm permalloy (Ni80Fe20) film as a function of the grain size. We use https://github.com/ubermag/help/files/6131357/Grains.zip as an example. Unfortunately, the coercivity does not change with the grain size (the loops are the same), and its amplitude does not correspond to the measurement results (MOKE shows that the film has a coercivity of the order of 1-3 Oe, in calculations - at a level from tens to hundreds of Oe). When substituting well-known Ni80Fe20 parameters, such as Aex=1.3e-11, Ms=700e3, K=200, the coercive force is of the order of more than 100 Oe. Moreover, the simulation becomes very slow when trying to optimize (increase geometry dimensions). The script is attached to this message. Thank you for your help in advance!

Question.pdf Question_v2.pdf