Skip to content
3 changes: 2 additions & 1 deletion .github/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
### New features

* Add partial extended xyz support (https://github.com/briling/v/pull/18)
* Read and print lattice parameters to/from extxyz header (#39)
* Add `j` hotkey to jump to a frame inside and CLI option `frame:%d` to start with a specific frame (https://github.com/briling/v/pull/5)
* Add `bmax` CLI argument for max. bond length (920202b)
* Add `com` and `exitcom` CLI argument for `gui:0` and on-exit command sequences, respectively
Expand All @@ -17,6 +18,7 @@
* Read molecules from the standard input (#28)
* Show infrared intensities and mode masses (#35)
* Improve the text-in-corner look (de242c7, #36)
* Add `u` to the headless mode (#37)
* Improve data structures and code readability

### Fixes
Expand All @@ -28,7 +30,6 @@
* Fix text blinking when playing animation (80cae88, #36)

### Coming in the next version:
* extended xyz (#16, #17)
* high-symmetry determination bugs (#21)
* how to build on mac (#34)

Expand Down
73 changes: 66 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,14 @@ To build:
```
./v file [file2 ... fileN] [options]
```
A filename `-` stands for the standard input.
A filename `-` stands for the standard input (xyz files only).

Show the reference:
```
./v
```

### Options
<details open><summary><strong>Command-line options</strong></summary>

| | |
Expand Down Expand Up @@ -81,6 +82,7 @@ Show the reference:

</details>

### Keyboard
<details open><summary><strong>Keyboard reference</strong></summary>

| | |
Expand Down Expand Up @@ -120,15 +122,17 @@ Show the reference:

</details>

<details open><summary><strong>Mouse (in development)</strong></summary>
### Mouse

One can also use the mouse to rotate the molecule and zoom in/out.
</details>

<details open><summary><strong>Headless mode (in development)</strong></summary>
### Additional commands

If run in the headless mode with `gui:0`, the symbols from the standard input are processed
#### Headless mode

If run in the headless mode with `gui:0`, the symbols from the standard input are processed
as if the corresponding keys were pressed in the normal mode.
Right now, only `p`, `x`, `z`, and `.` are available.
Right now, `p`, `x`, `z`, `u`, and `.` are available.
Command-line option `com:%s` overrides the standard input.
These examples are equivalent:
```
Expand All @@ -142,8 +146,60 @@ D*h
D*h
```

#### Normal mode
In the normal mode, the symbols from the CLI option `exitcom:` are executed immediately before closing.
For example,
```
./v mol/mol0001.xyz exitcom:z
```
automatically prints the last xyz coordinates when the user closes the window.




### Boundary conditions
Two types of boundary conditions are recognized:
* PBC (3D)
* spherical confinement

#### PBC
PBC can be read from the xyz [file header](https://ase-lib.org/ase/io/formatoptions.html#extxyz)
by specifying `Lattice="ax ay az bx by bz cx cy cz"`:
```
./v mol/MOL_3525.ext.xyz
```
Currently, only the PBC in all three dimensions are supported.

The same can be passed via the command-line, in which case it overrides the one from the file:
```
./v mol/MOL_3525.xyz cell:8.929542,0,0,4.197206,8.892922,0,0.480945,2.324788,10.016044
```
For orthogonal/cubic cell:
```
./v mol/1372_D02.340_1.out bonds:0 cell:20.23,20.23,20.23
./v mol/1372_D02.340_1.out bonds:0 cell:20.23
```
In Bohr instead of Å:
```
./v mol/1372_D02.340_1.out bonds:0 cell:b10.7
```
Finally, to disable the cell from the file:
```
./v mol/MOL_3525.ext.xyz cell:0
```

#### Spherical confinement
Spherical confinement can be specified from the command-line by the following:
```
./v mol/mol0001.xyz shell:2 # sphere with r = 2 Å is put around the molecule
./v mol/mol0001.xyz shell:b4 # sphere with r = 2 Bohr
./v mol/mol0001.xyz shell:2,3 # spheres with r = 2 and 3 Å (e.g., soft and hard boundaries)
./v mol/mol0001.xyz shell:b4,5 # spheres with r = 4 and 5 Bohr
```

</details>


## Examples [↑](#contents)
* `mol/C3H6~mCPBA_01x11.qm.out` — geometries + vibrations
```
Expand All @@ -166,7 +222,7 @@ D*h
![Adamantane mode animation](figures/C10H16.qm.out.gif)
* `mol/1372_D02.340_1.out` — PBC simulation
```
./v mol/1372_D02.340_1.out bonds:0 cell:b10.7,10.7,1.07 font:-*-*-medium-*-*--15-*-*-*-*-*-*-1
./v mol/1372_D02.340_1.out bonds:0 cell:b10.7 font:-*-*-medium-*-*--15-*-*-*-*-*-*-1
```
![Atoms in cell with PBC](figures/1372_D02.340_1.out_1087.gif)
* `mol/mol0001.xyz`, `mol/mol0002.xyz` — `.xyz` files with atomic numbers and atomic symbols
Expand All @@ -177,6 +233,9 @@ D*h

* `mol/MOL_3525.xyz` — organic crystal with non-orthogonal cell
```
./v mol/MOL_3525.ext.xyz
```
```
./v mol/MOL_3525.xyz cell:8.929542,0.0,0.0,4.197206,8.892922,0.0,0.480945,2.324788,10.016044 font:-*-*-medium-*-*--15-*-*-*-*-*-*-1
```
![Organic crystal cell](figures/MOL_3525.xyz_1.gif)
Expand Down
3 changes: 2 additions & 1 deletion obj/v/ac3_print.d
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
obj/v/ac3_print.o obj-pic/v/ac3_print.o: src/v/ac3_print.c src/v/v.h \
src/mol/mol.h src/mol/common.h src/v/pars.h src/math/vec3.h
src/mol/mol.h src/mol/common.h src/v/pars.h src/math/matrix.h \
src/math/vecn.h src/math/vec3.h
2 changes: 1 addition & 1 deletion obj/v/ac3_read.d
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
obj/v/ac3_read.o obj-pic/v/ac3_read.o: src/v/ac3_read.c src/v/v.h \
src/mol/mol.h src/mol/common.h src/v/pars.h src/math/vecn.h \
src/math/vec3.h
src/math/vec3.h src/math/matrix.h src/math/vecn.h
2 changes: 1 addition & 1 deletion obj/v/ac3_read_xyz.d
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
obj/v/ac3_read_xyz.o obj-pic/v/ac3_read_xyz.o: src/v/ac3_read_xyz.c \
src/v/v.h src/mol/mol.h src/mol/common.h src/v/pars.h
src/v/v.h src/mol/mol.h src/mol/common.h src/v/pars.h src/math/vecn.h
2 changes: 1 addition & 1 deletion obj/v/cli.d
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
obj/v/cli.o obj-pic/v/cli.o: src/v/cli.c src/v/v.h src/mol/mol.h \
src/mol/common.h src/v/pars.h src/math/vecn.h src/math/matrix.h \
src/math/vecn.h src/math/vec3.h
src/math/vecn.h
16 changes: 8 additions & 8 deletions src/v/ac3_draw.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,20 @@ static int cmpz(const void * p1, const void * p2){
return 0;
}

void ac3_draw(atcoord * ac, rendpars rend){
void ac3_draw(atcoord * ac, rendpars * rend){
int n = ac->n;
kzstr * kz = malloc(sizeof(kzstr)*n);
int * ks = (rend.bonds>0) ? malloc(sizeof(int)*n) : NULL;
int * ks = (rend->bonds>0) ? malloc(sizeof(int)*n) : NULL;

double resol = world.size * RESOL_SCALE;
double r1 = rend.r * resol * rend.scale;
double r1 = rend->r * resol * rend->scale;

for(int k=0; k<n; k++){
kz[k].k = k;
kz[k].z = ac->r[k*3+2];
}
qsort(kz, n, sizeof(kzstr), cmpz);
if(rend.bonds>0){
if(rend->bonds>0){
for(int i=0; i<n; i++){
ks[ kz[i].k ] = i;
}
Expand All @@ -61,19 +61,19 @@ void ac3_draw(atcoord * ac, rendpars rend){
XDrawArc(world.dis, world.canv, q>0?world.gc_black:world.gc_dot[1], x-r, y-r, 2*r, 2*r, 0, 360*64);
}

if(rend.num == 1){
if(rend->num == 1){
char text[16];
snprintf(text, sizeof(text), "%d", k+1);
XDRAWSTRING(world.dis, world.canv, world.gc_black, x, y, text, strlen(text));
}
else if(rend.num == -1){
else if(rend->num == -1){
char text[16];
const char * s = getname(q);
s ? snprintf(text, sizeof(text), "%s", s) : snprintf(text, sizeof(text), "%d", q );
XDRAWSTRING(world.dis, world.canv, world.gc_black, x, y, text, strlen(text));
}

if(rend.bonds>0){
if(rend->bonds>0){
for(int j=k*BONDS_MAX; j<(k+1)*BONDS_MAX; j++){
int k1 = ac->bonds.a[j];
if(k1 == -1 ){
Expand All @@ -92,7 +92,7 @@ void ac3_draw(atcoord * ac, rendpars rend){
}
double dd = BOND_OFFSET * r / sqrt(r2d);
XDrawLine(world.dis, world.canv, world.gc_black, x+dd*dx, y+dd*dy, x1, y1);
if(rend.bonds==2){
if(rend->bonds==2){
char text[16];
snprintf(text, sizeof(text), "%.3lf", ac->bonds.r[j]);
XDRAWSTRING(world.dis, world.canv, world.gc_black, x+dx/2, y+dy/2, text, strlen(text));
Expand Down
47 changes: 30 additions & 17 deletions src/v/ac3_print.c
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
#include "v.h"
#include "matrix.h"
#include "vec3.h"

void ac3_print(atcoord * ac, rendpars rend){
void ac3_print(atcoord * ac, rendpars * rend){
PRINTOUT(stdout, "$molecule\ncart\n");
for(int k=0; k<ac->n; k++){
PRINTOUT(stdout, "%3d % lf % lf % lf",
ac->q[k],
rend.xy0[0] + ac->r[k*3 ],
rend.xy0[1] + ac->r[k*3+1],
rend->xy0[0] + ac->r[k*3 ],
rend->xy0[1] + ac->r[k*3+1],
ac->r[k*3+2]);
if(rend.bonds>0){
if(rend->bonds>0){
for(int j=0; j<BONDS_MAX; j++){
int k1 = ac->bonds.a[k*BONDS_MAX+j];
if(k1 == -1 ){
Expand All @@ -24,8 +25,20 @@ void ac3_print(atcoord * ac, rendpars rend){
return;
}

void ac3_print_xyz(atcoord * ac, rendpars rend){
PRINTOUT(stdout, "%d\n\n", ac->n);
void ac3_print_xyz(atcoord * ac, rendpars * rend){
PRINTOUT(stdout, "%d\n", ac->n);
if(ac->cell.boundary==CELL){
double C[9];
mx_multmx(3,3,3, C, rend->ac3rmx, ac->cell.rot_to_lab_basis);
PRINTOUT(stdout, "Lattice=\"%lf %lf %lf %lf %lf %lf %lf %lf %lf\"\n",
C[0], C[3], C[6],
C[1], C[4], C[7],
C[2], C[5], C[8]);
}
else{
PRINTOUT(stdout, "\n");
}

for(int k=0; k<ac->n; k++){
const char * s = getname(ac->q[k]);
int ok = s && s[0];
Expand All @@ -36,32 +49,32 @@ void ac3_print_xyz(atcoord * ac, rendpars rend){
PRINTOUT(stdout, " %3d", ac->q[k]);
}
PRINTOUT(stdout, " % lf % lf % lf\n",
rend.xy0[0] + ac->r[k*3 ],
rend.xy0[1] + ac->r[k*3+1],
ac->r[k*3+2]);
rend->xy0[0] + ac->r[k*3 ],
rend->xy0[1] + ac->r[k*3+1],
ac->r[k*3+2]);
}
return;
}

void ac3_print2fig(atcoord * ac, rendpars rend, double vert[9]){
void ac3_print2fig(atcoord * ac, rendpars * rend){
int n = ac->n;
for(int i=0; i<n; i++){
PRINTOUT(stdout, "atom %3d% 13.7lf% 13.7lf% 13.7lf\n", ac->q[i],
rend.xy0[0] + ac->r[i*3 ],
rend.xy0[1] + ac->r[i*3+1],
rend->xy0[0] + ac->r[i*3 ],
rend->xy0[1] + ac->r[i*3+1],
ac->r[i*3+2]);
}

if(vert){
if(ac->cell.boundary==CELL){
for(int i=0; i<8; i++){
double v[3];
r3mx(v, vert+3*i, rend.ac3rmx);
r3mx(v, ac->cell.vertices+3*i, rend->ac3rmx);
PRINTOUT(stdout, "atom %3d% 13.7lf% 13.7lf% 13.7lf\n", 0,
rend.xy0[0] + v[0], rend.xy0[1] + v[1], v[2]);
rend->xy0[0] + v[0], rend->xy0[1] + v[1], v[2]);
}
}

if(rend.bonds>0){
if(rend->bonds>0){
for(int k=0; k<n; k++){
for(int j=0; j<BONDS_MAX; j++){
int k1 = ac->bonds.a[k*BONDS_MAX+j];
Expand All @@ -75,7 +88,7 @@ void ac3_print2fig(atcoord * ac, rendpars rend, double vert[9]){
}
}

if(vert){
if(ac->cell.boundary==CELL){
#define LINE(I,J) PRINTOUT(stdout, "bond %3d %3d % 3d\n", (J)+n+1, (I)+n+1, -1)
for(int i=0; i<8; i+=2){
LINE(i,i+1); // || z-axis
Expand Down
Loading
Loading