Skip to content

Commit

Permalink
implement the molecular viewer
Browse files Browse the repository at this point in the history
  • Loading branch information
tjira committed Nov 10, 2024
1 parent 0c2e436 commit 05c3cdb
Show file tree
Hide file tree
Showing 18 changed files with 842 additions and 79 deletions.
39 changes: 22 additions & 17 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ add_executable(acorn
# add the graphic files
if(GRAPHIC)
target_sources(acorn PRIVATE
src/buffer.cpp
src/geometry.cpp
src/mesh.cpp
src/shader.cpp
src/trajectory.cpp
src/viewer.cpp

external/src/glad.c
Expand Down Expand Up @@ -129,23 +134,23 @@ endif()
enable_testing()

# add general tests
add_test(NAME hf COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn -i ${PROJECT_SOURCE_DIR}/example/input/hf.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME mp2 COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn -i ${PROJECT_SOURCE_DIR}/example/input/mp2.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME mp3 COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn -i ${PROJECT_SOURCE_DIR}/example/input/mp3.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME mp4 COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn -i ${PROJECT_SOURCE_DIR}/example/input/mp4.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME fci COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn -i ${PROJECT_SOURCE_DIR}/example/input/fci.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME ccd COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn -i ${PROJECT_SOURCE_DIR}/example/input/ccd.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME ccd-t COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn -i ${PROJECT_SOURCE_DIR}/example/input/ccd-t.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME ccsd COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn -i ${PROJECT_SOURCE_DIR}/example/input/ccsd.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME ccsd-t COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn -i ${PROJECT_SOURCE_DIR}/example/input/ccsd-t.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME qdyn_1d_imaginary_one-state COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn -i ${PROJECT_SOURCE_DIR}/example/input/qdyn_1d_imaginary_one-state.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME qdyn_2d_imaginary_one-state COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn -i ${PROJECT_SOURCE_DIR}/example/input/qdyn_2d_imaginary_one-state.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME qdyn_1d_real_one-state COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn -i ${PROJECT_SOURCE_DIR}/example/input/qdyn_1d_real_one-state.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME qdyn_2d_real_one-state COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn -i ${PROJECT_SOURCE_DIR}/example/input/qdyn_2d_real_one-state.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME qdyn_1d_real_two-state COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn -i ${PROJECT_SOURCE_DIR}/example/input/qdyn_1d_real_two-state.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME cdyn_1d_two-state_fs-adia COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn -i ${PROJECT_SOURCE_DIR}/example/input/cdyn_1d_two-state_fs-adia.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME cdyn_1d_two-state_lz-adia COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn -i ${PROJECT_SOURCE_DIR}/example/input/cdyn_1d_two-state_lz-adia.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME cdyn_1d_two-state_lz-dia COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn -i ${PROJECT_SOURCE_DIR}/example/input/cdyn_1d_two-state_lz-dia.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME hf COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn run ${PROJECT_SOURCE_DIR}/example/input/hf.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME mp2 COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn run ${PROJECT_SOURCE_DIR}/example/input/mp2.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME mp3 COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn run ${PROJECT_SOURCE_DIR}/example/input/mp3.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME mp4 COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn run ${PROJECT_SOURCE_DIR}/example/input/mp4.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME fci COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn run ${PROJECT_SOURCE_DIR}/example/input/fci.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME ccd COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn run ${PROJECT_SOURCE_DIR}/example/input/ccd.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME ccd-t COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn run ${PROJECT_SOURCE_DIR}/example/input/ccd-t.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME ccsd COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn run ${PROJECT_SOURCE_DIR}/example/input/ccsd.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME ccsd-t COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn run ${PROJECT_SOURCE_DIR}/example/input/ccsd-t.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME qdyn_1d_imaginary_one-state COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn run ${PROJECT_SOURCE_DIR}/example/input/qdyn_1d_imaginary_one-state.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME qdyn_2d_imaginary_one-state COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn run ${PROJECT_SOURCE_DIR}/example/input/qdyn_2d_imaginary_one-state.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME qdyn_1d_real_one-state COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn run ${PROJECT_SOURCE_DIR}/example/input/qdyn_1d_real_one-state.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME qdyn_2d_real_one-state COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn run ${PROJECT_SOURCE_DIR}/example/input/qdyn_2d_real_one-state.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME qdyn_1d_real_two-state COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn run ${PROJECT_SOURCE_DIR}/example/input/qdyn_1d_real_two-state.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME cdyn_1d_two-state_fs-adia COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn run ${PROJECT_SOURCE_DIR}/example/input/cdyn_1d_two-state_fs-adia.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME cdyn_1d_two-state_lz-adia COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn run ${PROJECT_SOURCE_DIR}/example/input/cdyn_1d_two-state_lz-adia.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(NAME cdyn_1d_two-state_lz-dia COMMAND ${PROJECT_SOURCE_DIR}/bin/acorn run ${PROJECT_SOURCE_DIR}/example/input/cdyn_1d_two-state_lz-dia.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})

# add expected results of general tests
set_property(TEST hf PROPERTY PASS_REGULAR_EXPRESSION "FINAL HF ENERGY: -74.965901" )
Expand Down
25 changes: 25 additions & 0 deletions include/buffer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include <glad/glad.h>
#include <glm/glm.hpp>
#include <vector>

struct Vertex {
glm::vec3 position, normal = glm::vec3(0), color = glm::vec3(1);
};

class Buffer {
public:
Buffer(const Buffer& buffer) : data(buffer.getData()) {generate();};
Buffer(const std::vector<Vertex>& data) : data(data) {generate();};
Buffer() : data(0) {generate();}; ~Buffer();
Buffer& operator=(const Buffer& buffer);
void bind() const;
void generate();
std::vector<Vertex> getData() const { return data; }
size_t getSize() const { return data.size(); };

private:
std::vector<Vertex> data;
unsigned int vao, vbo;
};
49 changes: 48 additions & 1 deletion include/constant.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,55 @@
#pragma once

#define PERIODIC_TABLE "H He Li Be B C N O F Ne Na Mg Al Si P S Cl Ar K Ca Sc Ti V Cr Mn Fe Co Ni Cu Zn Ga Ge As Se Br Kr Rb Sr Y Zr Nb Mo Tc Ru Rh Pd Ag Cd In Sn Sb Te I Xe Cs Ba La Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb Lu Hf Ta W Re Os Ir Pt Au Hg Tl Pb Bi Po At Rn Fr Ra Ac Th Pa U Np Pu Am Cm Bk Cf Es Fm Md No Lr Rf Db Sg Bh Hs Mt Ds Rg Cn Nh Fl Mc Lv Ts Og"
#include <glm/glm.hpp>
#include <string>
#include <unordered_map>

#define OCCUPIED_ORBITALS "abcdefghijklmnopqrstuvwxyz"
#define VIRTUAL_ORBITALS "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

#define ANGSTROM_TO_BOHR 1.889726124626

struct Atom {
float radius, covalent; glm::vec3 color; double mass;
};

inline std::unordered_map<std::string, Atom> ptable = {
{ "H", {.radius = 053.0f, .covalent = 032.0f, .color = {255.0f / 255.0f, 255.0f / 255.0f, 255.0f / 255.0f}, .mass = 001.0078 }},
{"He", {.radius = 031.0f, .covalent = 046.0f, .color = {217.0f / 255.0f, 255.0f / 255.0f, 255.0f / 255.0f}, .mass = 004.0026 }},
{"Li", {.radius = 167.0f, .covalent = 133.0f, .color = {204.0f / 255.0f, 128.0f / 255.0f, 255.0f / 255.0f}, .mass = 006.9410 }},
{"Be", {.radius = 112.0f, .covalent = 102.0f, .color = {194.0f / 255.0f, 255.0f / 255.0f, 000.0f / 255.0f}, .mass = 009.0122 }},
{ "C", {.radius = 067.0f, .covalent = 075.0f, .color = {144.0f / 255.0f, 144.0f / 255.0f, 144.0f / 255.0f}, .mass = 012.0110 }},
{ "N", {.radius = 056.0f, .covalent = 071.0f, .color = {048.0f / 255.0f, 080.0f / 255.0f, 248.0f / 255.0f}, .mass = 014.0067 }},
{ "O", {.radius = 048.0f, .covalent = 063.0f, .color = {255.0f / 255.0f, 013.0f / 255.0f, 013.0f / 255.0f}, .mass = 015.9994 }},
{ "F", {.radius = 042.0f, .covalent = 064.0f, .color = {144.0f / 255.0f, 224.0f / 255.0f, 080.0f / 255.0f}, .mass = 018.9984 }},
{"Ne", {.radius = 038.0f, .covalent = 067.0f, .color = {179.0f / 255.0f, 227.0f / 255.0f, 245.0f / 255.0f}, .mass = 020.1797 }},
{ "P", {.radius = 098.0f, .covalent = 111.0f, .color = {255.0f / 255.0f, 128.0f / 255.0f, 000.0f / 255.0f}, .mass = 030.9738 }},
{ "S", {.radius = 088.0f, .covalent = 103.0f, .color = {255.0f / 255.0f, 255.0f / 255.0f, 048.0f / 255.0f}, .mass = 032.0650 }},
{"Cl", {.radius = 079.0f, .covalent = 099.0f, .color = {031.0f / 255.0f, 240.0f / 255.0f, 031.0f / 255.0f}, .mass = 035.4530 }},
{"Xe", {.radius = 108.0f, .covalent = 131.0f, .color = {066.0f / 255.0f, 158.0f / 255.0f, 176.0f / 255.0f}, .mass = 131.2930 }},
{"El", {.radius = 020.0f, .covalent = 020.0f, .color = {066.0f / 255.0f, 158.0f / 255.0f, 176.0f / 255.0f}, .mass = 000.0000 }}
};

inline std::unordered_map<int, std::string> an2sm = {
{ 1, "H" },
{ 2, "He"},
{ 6, "C" },
{ 7, "N" },
{ 8, "O" },
{ 9, "F" },
{15, "P" },
{16, "S" },
{17, "Cl" }
};

inline std::unordered_map<std::string, int> sm2an = {
{ "H", 1},
{"He", 2},
{ "C", 6},
{ "N", 7},
{ "O", 8},
{ "F", 9},
{ "P", 15},
{ "S", 16},
{"Cl", 17}
};
32 changes: 32 additions & 0 deletions include/geometry.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#pragma once

#include "glfwpointer.h"
#include "constant.h"
#include "mesh.h"
#include <GLFW/glfw3.h>
#include <glm/gtc/matrix_transform.hpp>
#include <sstream>

class Geometry {
struct Object {
glm::mat4 get_model(glm::mat4 s = glm::mat4(1)) const {
return translate * rotate * s * scale;
}
glm::vec3 get_position() const {
return glm::vec3(translate[3]);
}
glm::mat4 translate, rotate, scale; std::string name;
};

public:
static Geometry Load(std::stringstream& file);
glm::vec3 get_center() const;
void move(const glm::vec3& vector);
void render(const Shader& shader) const;
void rebind(float factor);

inline static std::unordered_map<std::string, Mesh> meshes;

private:
std::vector<Object> objects;
};
8 changes: 7 additions & 1 deletion include/glfwpointer.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@

#define WIDTH 1024
#define HEIGHT 576
#define SUBDIVISIONS 2
#define SECTORS 16
#define SMOOTH 1
#define BINDINGFACTOR 0.013
#define BONDSIZE 0.09
#define ATOMSIZEFACTOR 0.007

struct GLFWwindow;

Expand All @@ -15,7 +21,7 @@ struct GLFWPointer {
glm::mat4 view, proj;
} camera;
struct Flags {
bool fullscreen = false, pause = false;
bool fullscreen = false, info = false, options = false, pause = false, plot = false, system = false, ptable = false;
} flags;
struct Light {
float ambient = 0.4f, diffuse = 0.2f, specular = 0.4f, shininess = 4.0f;
Expand Down
20 changes: 20 additions & 0 deletions include/mesh.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once

#include "buffer.h"
#include "shader.h"
#include <algorithm>

class Mesh {
public:
Mesh() {}; Mesh(std::vector<Vertex> data, const std::string& name = "mesh") : name(name), model(1.0f), buffer(data) {};
static Mesh Cylinder(int sectors, bool smooth, const std::string& name = "cylinder");
static Mesh Icosphere(int subdivisions, bool smooth, const std::string& name = "icosphere");
std::string getName() const;
glm::vec3 getPosition() const;
void render(const Shader& shader, const glm::mat4& transform = glm::mat4(1.0f)) const;
void setColor(const glm::vec3& color);
void setModel(const glm::mat4& model);

private:
std::string name; glm::mat4 model; Buffer buffer;
};
17 changes: 17 additions & 0 deletions include/shader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include <glad/glad.h>
#include <glm/glm.hpp>
#include <stdexcept>
#include <vector>

class Shader {
public:
~Shader(); Shader(const std::string& vertex, const std::string& fragment);
void check_error(unsigned int shader, const std::string& title) const;
template <typename T> void set(const std::string& name, T value) const;
void use() const;

private:
unsigned int id;
};
16 changes: 16 additions & 0 deletions include/trajectory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

#include "geometry.h"
#include <chrono>
#include <fstream>
#include <sstream>

class Trajectory {
public:
static Trajectory Load(const std::string& movie);
void move(const glm::vec3& vector);
void render(const Shader& shader);

private:
std::chrono::high_resolution_clock::time_point timestamp; std::vector<Geometry> geoms; bool paused = false; float wait = 15.997; int frame = 0;
};
6 changes: 3 additions & 3 deletions include/viewer.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#pragma once

#include "glfwpointer.h"
#include <glad/glad.h>
#include "trajectory.h"
#include <GLFW/glfw3.h>
#include <glm/gtc/matrix_transform.hpp>
#include <ImGuiFileDialog.h>
#include <backends/imgui_impl_glfw.h>
#include <backends/imgui_impl_opengl3.h>
Expand All @@ -12,7 +12,7 @@
class Viewer {
public:
Viewer(const std::vector<std::string>& inputs);
void gui_plot(const std::vector<Eigen::MatrixXd>& matrices, std::vector<std::tuple<int, std::vector<int>, int>>& indices) const;
void gui(const std::vector<Eigen::MatrixXd>& matrices, std::vector<std::tuple<int, std::vector<int>, int>>& indices);
Eigen::MatrixXd read(const std::string& path) const;

private:
Expand Down
4 changes: 2 additions & 2 deletions script/general/library.sh
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ cd external/pytorch-v2.5.0 && cmake -B build \
pip install glad && glad --api="gl=4.2" --generator="c" --profile="core" --out-path="$PWD/external"

# copy headers
cp -r external/glm/* external/imgui-1.91.4/*.h external/imgui-1.91.4/backends external/ImGuiFileDialog-0.6.7/*.h external/ImGuiFileDialog-0.6.7/dirent external/implot-0.16/*.h external/include
cp -r external/imgui-1.91.4/*.h external/imgui-1.91.4/backends external/ImGuiFileDialog-0.6.7/*.h external/ImGuiFileDialog-0.6.7/dirent external/implot-0.16/*.h external/include && mv external/glm external/include

# copy sources
cp -r external/imgui-1.91.4/*.cpp external/imgui-1.91.4/backends external/ImGuiFileDialog-0.6.7/*.cpp external/implot-0.16/*.cpp external/src
Expand All @@ -143,4 +143,4 @@ cp -r external/imgui-1.91.4/*.cpp external/imgui-1.91.4/backends external/ImGuiF
[ $STATIC == 1 ] && rm -f external/lib/*.s*

# remove sources
cd external && rm -rf eigen-3.4.0 fftw-3.3.10 glfw-3.4 glm imgui-1.91.4 ImGuiFileDialog-0.6.7 implot-0.16 libint-2.9.0 numactl-2.0.18 OpenBLAS-0.3.28 pytorch-v2.5.0 bin share *.tar.gz *.zip ; cd ..
cd external && rm -rf eigen-3.4.0 fftw-3.3.10 glfw-3.4 imgui-1.91.4 ImGuiFileDialog-0.6.7 implot-0.16 libint-2.9.0 numactl-2.0.18 OpenBLAS-0.3.28 pytorch-v2.5.0 bin share *.tar.gz *.zip ; cd ..
29 changes: 29 additions & 0 deletions src/buffer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "buffer.h"

Buffer::~Buffer() {
glDeleteVertexArrays(1, &vao), glDeleteBuffers(1, &vbo);
};

Buffer& Buffer::operator=(const Buffer& buffer) {
glDeleteVertexArrays(1, &vao), glDeleteBuffers(1, &vbo); this->data = buffer.data, generate(); return *this;
}

void Buffer::bind() const {
glBindVertexArray(vao);
}

void Buffer::generate() {
// generate and bind the buffers
glGenVertexArrays(1, &vao), glGenBuffers(1, &vbo), glBindBuffer(GL_ARRAY_BUFFER, vbo), glBindVertexArray(vao);

// set position, normal and collor attributes
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position));
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, normal));
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, color));

// enable attributes
glEnableVertexAttribArray(0), glEnableVertexAttribArray(1), glEnableVertexAttribArray(2);

// set the data
glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(Vertex), data.data(), GL_STATIC_DRAW);
}
Loading

0 comments on commit 05c3cdb

Please sign in to comment.