Author Topic: Best way to visualize polycrystal grains with Polyhedral Template Matching  (Read 1116 times)

kkuppart

  • Newbie
  • *
  • Posts: 1
Hello,

Polyhedral template matching produces a quaternion of values, and while  visualizing one of those values, say Orientation.X seems to work too, is there a more robust way to visualize using all of them? How is it used to visualize the polycrystal in Figure 12 in https://arxiv.org/pdf/1603.05143.pdf ?

Best regards,

Kristian Kuppart

Alexander Stukowski

  • Administrator
  • Hero Member
  • *****
  • Posts: 555
Re: Best way to visualize polycrystal grains with Polyhedral Template Matching
« Reply #1 on: February 24, 2017, 09:35:32 AM »
Hi Kristian,

The four components of the orientation quaternion computed by PTM need to be mapped to the three RGB color components for each atom. Peter Larsen, the author of the paper you referred to, gave me a Python script for this calculation (which involves mapping the quaternion to Rodrigues space). I developed a Python modifier function for OVITO from this, which you can put into the data pipeline after you calculated the per-atom orientations using the PTM modifier:

Code: [Select]
from ovito.data import *
import math
import numpy as np
 
def elementwise_multiplication(a, b):
 
    a[:,0] = np.multiply(a[:,0], b)
    a[:,1] = np.multiply(a[:,1], b)
    a[:,2] = np.multiply(a[:,2], b)
     
def project_quaternions_into_rodrigues_space(qs):
 
    if len(qs.shape) != 2:
        raise Exception("qs must be a 2-dimensional array")
 
    if qs.shape[1] != 4:
        raise Exception("qs must be a n x 4 dimensional array")
         
    rs = np.copy(qs[:,:3])
    elementwise_multiplication(rs, 1 / qs[:,3])
    return rs
 
def quaternions_to_colors(qs):
 
    if len(qs.shape) != 2:
        raise Exception("qs must be a 2-dimensional array")
 
    if qs.shape[1] != 4:
        raise Exception("qs must be a n x 4 dimensional array")
 
    m1 = math.radians(62.8)
    m0 = -m1
 
    rs = project_quaternions_into_rodrigues_space(qs)
    rr = np.linalg.norm(rs, axis=1)
    rr = np.maximum(rr, 1E-9)    #hack
 
    elementwise_multiplication(rs, 1 / rr)
 
    theta = 2 * np.arctan(rr)
    elementwise_multiplication(rs, theta)
    rs -= m0
 
    elementwise_multiplication(rs, 1 / (m1 - m0))
    return rs

def modify(frame, input, output):
color_property = output.create_particle_property(ParticleProperty.Type.Color)
color_property.marray[:] = quaternions_to_colors(input.particle_properties.orientation.array)