Forum Navigation
You need to log in to create posts and topics.

Slicing atoms (and calculating surface area) in each frame of a trajectory

Hi.

I have a series of simulation dumps with an indentation experiment I am performing. I am interested in calculating the area of the contact surface between the sample and the indenter. My idea was to use the Slice modifier to keep just the atoms at indenter height and then make the Construct Surface Mesh modifier calculate the surface of this layer of atoms.  I can perform this individually on each frame, but as I got quite a few of them, it was my intention to load the whole trajectory with the import_file("simulation.dump.*") feature. Then I figured I could put the setting up of modifiers for my pipeline inside the for loop so as to update the height of the slice for each frame to keep track of the indenter. I read the warning in the manual about repeating modifiers in the list, I thought I could by pass that, by ending my for statement with the clear() method for lists on the modifier list.

The result: no error message whatsoever, script won't go pass frame 0. By commenting and uncommenting I found out the script stops going through the loop when and only when  I apply compute method inside it (which of course is absolutely necessary).

I've changed my approach (instead "slicing" via numpy array subsetting) because I became convinced that I can't update my modifiers inside the for loop and that the spirit of the law here is that only compute statements must go inside it. But I need confirmation: Can it or can't it be done in this way?

Dear Gonzalo,

Yes, normally it is not correct to insert new modifiers into a pipeline inside of a for-loop over the frames of a simulation. Typically, you should do this only before the for-loop. However, it is always okay to change/update the parameters of the existing modifiers within the for-loop. And you are right: Calling the Pipeline.compute() method inside the for-loop is typically what you want to do -otherwise Ovito wouldn't evaluate the pipeline and perform any calculation.

I'm concerned by your statement that script execution stops when you call compute() within the for-loop. This behavior seems weird. Please post the full script code so I can get a better picture of what you are doing.

-Alex

Dear Alex:

Thank you so much for your answer. I am attaching my script with this message. You will see a bunch of empty lists, this is realated to another issue I ran into. When I tried to store the computations of the for loop on a python list and then print it, my list ended up as empty as it started. This problem persisted even when I went ahead with my new approach that did not involve setting up modifiers inside the for loop. Once more, numpy came to the rescue, as creating an empty numpy array (of the appropiate shape, of course) and then filling it through the for loop successfully bypasses the issue.

Uploaded files:
  • You need to login to have access to uploads.

Dear Gonzalo,

I had a look at your script and as a general remark, this is how you would typically set up your pipeline and then loop over the different frames:

#CONSTANTS
dt = 0.001 	#ps		#timeindenterDepth
indentationSpeed = 1.0		#Angstrom/ps	#indentation speed
sphereRadius = 50.0 	#Angstrom 		#radius of sphere

#...

pipeline = import_file(path+simulationDump) #UPPER CONTACT AREA (WITH INDENTER) THROUGH OVITO
pipeline0 = import_file(path+simulationDump)    #LOWER CONTACT AREA (WITH SIMULATION BOX) THROUGH OVITO 
pipeline1 = import_file(path+simulationDump)    #UPPER CONTACT AREA (WITH INDENTER) WITH VERGELES' FORMULA
pipeline2 = import_file(path+simulationDump)    #LOWER CONTACT AREA (WITH SIMULATION BOX)WITH VERGELES' FORMULA

#First set up the different pipelines
slice_mod = SliceModifier(distance =  0, normal = (0,0,1) ,inverse = True)
pipeline.modifiers.append(slice_mod)
pipeline.modifiers.append(ConstructSurfaceModifier(radius = 80))  


slice_mod0 = SliceModifier(...
pipeline0.append(slice_mod0)    
#...

#Loop over all frames 
for frame in range(pipeline.source.num_frames):
    step = frame*1000
    indenterDepth = indentationSpeed*dt*step #Angstrom
    indenterHeight = sphereRadius-indenterDepth #Angstrom
    
    #and then simply edit the settings of the modifiers instead of appending a new instance of this modifier for each frame
    slice_mod.distance = indenterHeight
    
    # now evalute the pipeline for the current frame
    data = pipeline.compute(frame)

If you like you can get back to us after you adapted your script and still run into problems.

-Constanze

Dear Constanze:

Thank you so much for your answer. I tried out your idea but it didn't do as intended. The problem is more or less the same, it does nothing unless I comment out just the most important part, namely:

slice_mod.distance = indenterHeight

Any guess as to why this may happen? Does it have anything to do with my OVITO version (3.0.0.)? Also, do you know anything about my additional issue with storing the output of the for loop in an empty Python list?

I am attaching my implementation of your idea, in case you would like to give it a look.

Uploaded files:
  • You need to login to have access to uploads.

Dear Gonzalo,

sorry I'm still having trouble finding out what causes you problems. I tested your script "constanzes_script.py" with some example data of mine and it works just fine both under linux and windows. I used the latest developer version ovito-3.0.0-dev469.

So when I execute:

"C:\Program Files\Ovito\ovitos.exe" constanzes_script.py

I get the following terminal output

0.000000 0.000000 50.000000 50.000000
1000.000000 1.000000 49.000000 49.000000
2000.000000 2.000000 48.000000 48.000000
3000.000000 3.000000 47.000000 47.000000
4000.000000 4.000000 46.000000 46.000000
5000.000000 5.000000 45.000000 45.000000
6000.000000 6.000000 44.000000 44.000000
7000.000000 7.000000 43.000000 43.000000
8000.000000 8.000000 42.000000 42.000000

which means that

slice_mod.distance = indenterHeight

correctly updates the distance of the slice plane in the slice modifier.

Could you please show me a screenshot of your terminal output, so we can figure out together what's going on?

-Constanze

 

 

Dear Constanze:

I updated my working version to ovito-3.0.0-dev469 and the script worked perfectly. Could it be a bug of previous dev versions?

Thank you so much for your help and time in any case.

Dear Gonzalo,

we haven't been aware of any problems with the previous developer versions, but I'm glad this issue is resolved. Just let us know if you run into problems again.

-Constanze