GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
Numpy v1.13.1
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
POV-Ray 3.7.0.unofficial
This article is related to ADDA (light scattering simulator based on the discrete dipole approximation).
About
In this article, a tool to make Povray file and png files of the particle shape is introduced.
By using the Matplotlib, it took 43 minutes to show the Chebyshev particle with N=206,800.
(see. this article for the detail).
Instead of using the Matplotlib, Povray is used to render the images.
The tool processes as follows:
- read (x,y,z) positions in the [LN-IntField-Y]
- [LN-IntField-Y] is the symbolic link of [IntField-Y]
- created Povray file based on the coordinates
- for 4 views (slant, top, front, and side)
- render the image by executing the Povray
IntField-Y: Input file
The following is the example command to create [IntField-Y] using ADDA.
./adda -shape cylinder 1.5 -store_int_field -grid 26 -maxiter 10
Where, the -maxiter
is used because the calculation do not need to be finished with the high accuracy. Only the position information in the 'IntField-Y' is used.
In another case, the users can use [IntField-Y] for the calculation where the iterative solver converges with the desired accuracy where the -maxiter
is not specified.
code
Requirements
Following tools are required.
- Python 3 (e.g. Python 3.5.2)
- Numpy (e.g. Numpy v1.13.1)
- Povray (e.g. POV-Ray 3.7.0.unofficial)
Python script (make_pov_png_180121.py v0.1-v0.7)
Following is the Python script named make_pov_png_180121.py
used to create Povray file and png files.
import numpy as np
import sys
import subprocess as sb
'''
v0.7 Jan. 27, 2018
- ** rename [make_pov_180121.py] to [make_pov_png_180121.py]
- create also (top, front, side) images
- refactor > reposition constants definitions
- execute povray command
- add make_pov_file()
- read [IntField-Y] file instead of (x,y,z) file
v0.6 Jan. 27, 2018
- refactor
+ from [IN_FILE] to [IN_FILE_XYZ]
v0.5 Jan. 23, 2018
- convert [right-handed] to [left-handed] coordinate
+ interchange y and z
v0.4 Jan. 23, 2018 viewing geometry
- [light_source] takes [LOCX], [LOCY], [LOCZ]
- change [camera.location]
+ main() change [CONFIG_FORMAT]
+ add calc_xyz()
+ [CONFIG_FORMAT] takes [LOCX], [LOCY], [LOCZ]
+ add [VIEW_RADIUS]
+ add [ELEVATION_DEG], [AZIMUTH_DEG]
v0.3 Jan., 21, 2018
- each particle is colored
- [SHAPE_FORMAT] has color value template
+ [RED], [GREEN], [BLUE]
v0.2 Jan., 21, 2018
- tweak [MONOMER_RADIUS] from 0.5 to 0.25
v0.1 Jan., 21, 2018
- output [.pov] file
+ add main()
- add [SHAPE_FORMAT]
- add [CONFIG_FORMAT]
'''
# tested on Python 3.5.2
# coding rule: PEP8
CONFIG_FORMAT = """
camera {
location <LOCX, LOCY, LOCZ>
look_at <0, 0, 0>
}
light_source { <LOCX, LOCY, LOCZ>
color rgb <1.0, 1.0, 1.0>
}
background{color rgb <1.0,1.0,1.0>}
"""
SHAPE_FORMAT = """
sphere { <XXX, YYY, ZZZ>, RRR
texture {
pigment { color rgb <RED,GREEN,BLUE> }
finish { ambient 0.4 }
}
}
"""
# IN_FILE_XYZ = 'LN-SHAPE'
IN_FILE_INTFIELD_Y = 'LN-IntField-Y' # LN: symbolic link file
OUT_FILE = "shape_180121.pov"
MONOMER_RADIUS = 0.25
RGBSET = [
[0.40000000000000002, 0.76078431372549016, 0.6470588235294118],
[0.40000000000000002, 0.76078431372549016, 0.6470588235294118],
[0.9882352941176471, 0.55294117647058827, 0.3843137254901961],
[0.55294117647058827, 0.62745098039215685, 0.79607843137254897],
[0.90588235294117647, 0.54117647058823526, 0.76470588235294112],
[0.65098039215686276, 0.84705882352941175, 0.32941176470588235],
[0.65098039215686276, 0.84705882352941175, 0.32941176470588235],
[1.0, 0.85098039215686272, 0.18431372549019609],
[0.89803921568627454, 0.7686274509803922, 0.58039215686274515],
[0.70196078431372544, 0.70196078431372544, 0.70196078431372544],
[0.70196078431372544, 0.70196078431372544, 0.70196078431372544],
]
X_MAX = 10 # used to set colors based on the x position
def calc_xyz(theta_deg, phi_deg, radius):
ath = np.deg2rad(theta_deg)
aph = np.deg2rad(phi_deg)
x = radius * np.cos(aph) * np.sin(ath)
y = radius * np.sin(aph) * np.sin(ath)
z = radius * np.cos(ath)
return x, y, z
def read_IntFieldY(filepath):
# skip 1st row (title)
dat = np.genfromtxt(filepath, skip_header=1)
# extract only first 3 columns (x,y,z)
wrk = dat[:, :3]
return wrk
def make_pov_file(filepath, azenith, aazimuth):
# dat = np.genfromtxt(IN_FILE_XYZ)
dat = read_IntFieldY(filepath)
with open(OUT_FILE, 'wb+') as fd:
# camera position and lightsource position
cax, cay, caz = calc_xyz(azenith, aazimuth, VIEW_RADIUS)
wrk = CONFIG_FORMAT.replace('LOCX', '%s' % cax)
wrk = wrk.replace('LOCY', '%s' % caz) # left-handed coord.
wrk = wrk.replace('LOCZ', '%s' % cay) # left-handed coord.
wrk = np.array(wrk).reshape(1,)
np.savetxt(fd, wrk, fmt='%s')
# each monomer
for elem in dat:
wrk = SHAPE_FORMAT.replace('XXX', '%s' % elem[0])
# position (left-handed coordinate)
wrk = wrk.replace('YYY', '%s' % elem[2])
wrk = wrk.replace('ZZZ', '%s' % elem[1])
#
wrk = wrk.replace('RRR', '%s' % MONOMER_RADIUS)
# color
# clidx = (elem[0] - (-50)) / (50 - (-50))
clidx = (elem[0] - (-X_MAX)) / (X_MAX - (-X_MAX))
clidx = clidx * len(RGBSET)
if clidx < 0.0:
clidx = 0.0
if clidx > X_MAX:
clidx = X_MAX
acol = RGBSET[int(clidx)]
wrk = wrk.replace('RED', '%s' % acol[0])
wrk = wrk.replace('GREEN', '%s' % acol[1])
wrk = wrk.replace('BLUE', '%s' % acol[2])
#
wrk = np.array(wrk).reshape(1,)
np.savetxt(fd, wrk, fmt='%s')
print('[%s] is created' % OUT_FILE)
def make_png_file(infile, azenith, aazimuth, suffix):
make_pov_file(infile, azenith, aazimuth)
outfile = OUT_FILE.replace('.', suffix + '.')
cmd = 'mv %s %s' % (OUT_FILE, outfile)
sb.call(cmd.split())
cmd = 'povray ' + outfile
sb.call(cmd.split())
#
msg = ''
msg += '[%s] is created\n' % outfile
msg += '[%s] is created\n' % outfile.replace('pov', 'png')
return msg
# viewing geometry
ELEVATION_DEG = 30.0 # elevation angle [degree]
AZIMUTH_DEG = -60.0 # azimuth angle [degree]
VIEW_RADIUS = 30.0 # radius of the viewing geometry
#
zenith_deg = 90.0 - ELEVATION_DEG # zenith angle [degree]
def main():
infile = IN_FILE_INTFIELD_Y
msg = ''
msg += make_png_file(infile, zenith_deg, AZIMUTH_DEG, '_slant')
msg += make_png_file(infile, 0, 0, '_top')
msg += make_png_file(infile, 90, 0, '_front')
msg += make_png_file(infile, 90, -90, '_side')
print(msg)
msg = 'To view images at once, open [view_180128.html]\n'
msg += 'on your web browser\n'
msg += 'e.g. google-chrome view_180128.html'
print(msg)
if __name__ == '__main__':
main()
html to view outputs (view_180128.html v0.1)
The following is a html file to view the output files on the Web browser.
<!--
v0.1 Jan. 28, 2018
- show 4 images
-->
<html>
<table>
<tr>
<td>slant (Theta=60deg, Phi=-60deg)</td><td>top</td>
</tr>
<tr>
<td><img src=shape_180121_slant.png></td>
<td><img src=shape_180121_top.png></td>
</tr>
<tr>
<td>front</td><td>side</td>
</tr>
<tr>
<td><img src=shape_180121_front.png></td>
<td><img src=shape_180121_side.png></td>
</tr>
</table>
</html>
How to use
1. prepare [LN-IntField-Y]
Following is the example of the symbolic linkage of the ADDA output.
$ln -fs ../CALC_180117_MUELLER/gHN_N0500_THETA_1p0/run44242_chebyshev_g104_m1.5/IntField-Y LN-IntField-Y
Also, instead of the symbolic link, the user can copy the ADDA output in the name of [LN-IntField-Y].
2. run the script
$python3 make_pov_png_180121.py
...
...
...
...
...
...
Render Time:
Photon Time: No photons
Radiosity Time: No radiosity
Trace Time: 0 hours 0 minutes 0 seconds (0.122 seconds)
using 8 thread(s) with 0.523 CPU-seconds total
POV-Ray finished
[shape_180121_slant.pov] is created
[shape_180121_slant.png] is created
[shape_180121_top.pov] is created
[shape_180121_top.png] is created
[shape_180121_front.pov] is created
[shape_180121_front.png] is created
[shape_180121_side.pov] is created
[shape_180121_side.png] is created
To view images at once, open [view_180128.html]
on your web browser
e.g. google-chrome view_180128.html
3. view the images
As shown in the Step2, output files can be viewed by reading [view_180128.html].
For example, with the Google Chrome, following command can be used (depending on the OS).
(Or, drag and drop the [view_180182.html] file onto the web browser).
$google-chrome view_180128.html
Then, in the web browser, the user can see the following images.
Output example
bisphere
command: './adda -shape bisphere 1.0 -store_int_field -grid 26 -maxiter 10 '
N=18,656
Processing time: 8.287sec
Capsule
command: './adda -shape capsule 1.5 -store_int_field -grid 26 -maxiter 10 '
N=30,280
Processing time: 9.986sec
Cylinder
command: './adda -shape cylinder 1.5 -store_int_field -grid 26 -maxiter 10 '
N=21,600
Processing time: 8.524sec
Egg
command: './adda -shape egg 0.7 0.5 -store_int_field -grid 26 -maxiter 10 '
N=13,748
Processing time: 7.740sec
Sphere
command: './adda -shape sphere -store_int_field -grid 26 -maxiter 10 '
N=9,328
Processing time: 6.968sec
Chebyshev
command: './adda -shape chebyshev 0.7 12 -grid 104 -store_int_field -maxiter 10 -eq_rad 6.299605 '
N=206,800
Processing time: 32.261sec