Compare commits
28 Commits
impl_force
...
impl_test
| Author | SHA1 | Date | |
|---|---|---|---|
| 0fb46be75d | |||
| 382bbc7689 | |||
| 6e8a95b056 | |||
| 29dc178ec4 | |||
| 5785abd22e | |||
| 0ab41e7c0b | |||
| fff417b041 | |||
| 5c6a86815d | |||
| 0e64fe9cf5 | |||
| bbd57d0344 | |||
| 849fc5de11 | |||
| b679ccfbe6 | |||
| 393a909eb2 | |||
| 33cdd99dde | |||
| 1561940b80 | |||
| a433d213f2 | |||
| 36f0e16bce | |||
| 516c36c564 | |||
| b28e6a033e | |||
| b97a34a642 | |||
| 6e94041482 | |||
| 9373d31dbc | |||
| 5d998bd24b | |||
| b88213f200 | |||
| f1f43abea8 | |||
| 51a71a0bbc | |||
| d680f38e98 | |||
| 8c6695d245 |
304
.gitea/scripts/code_review.py
Normal file
304
.gitea/scripts/code_review.py
Normal file
@@ -0,0 +1,304 @@
|
||||
"""Code Reviewer for Gitea."""
|
||||
|
||||
import asyncio
|
||||
import fnmatch
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
from typing import Any
|
||||
|
||||
import requests
|
||||
import aiohttp
|
||||
from model import Model
|
||||
|
||||
ACCESS_TOKEN = os.getenv("ACCESS_TOKEN", "")
|
||||
HEADERS = {"Authorization": f"token {ACCESS_TOKEN}"}
|
||||
|
||||
GITHUB_EVENT_PATH = os.getenv("GITHUB_EVENT_PATH")
|
||||
try:
|
||||
with open(GITHUB_EVENT_PATH, "r") as f:
|
||||
EVENT_DATA = json.load(f)
|
||||
except FileNotFoundError:
|
||||
print("Failed to load event data.")
|
||||
exit(1)
|
||||
|
||||
FULL_CONTEXT_MODEL_NAME = os.getenv("FULL_CONTEXT_MODEL", "")
|
||||
SINGLE_CHUNK_MODEL_NAME = os.getenv("SINGLE_CHUNK_MODEL", "")
|
||||
FULL_CONTEXT_API_KEY = os.getenv("FULL_CONTEXT_API_KEY", "")
|
||||
SINGLE_CHUNK_API_KEY = os.getenv("SINGLE_CHUNK_API_KEY", "")
|
||||
|
||||
EXCLUDE_PATTERNS = os.getenv("EXCLUDE", "").split(",")
|
||||
|
||||
|
||||
def get_diff() -> str | None:
|
||||
"""Get code difference between base and head from Gitea.
|
||||
|
||||
Returns:
|
||||
str | None: code difference between base and head, or None if failed to get diff
|
||||
"""
|
||||
url = EVENT_DATA["pull_request"]["diff_url"]
|
||||
try:
|
||||
response = requests.get(url, headers=HEADERS)
|
||||
response.raise_for_status()
|
||||
return response.text
|
||||
except requests.RequestException as e:
|
||||
print(f"Failed to get diff: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def parse_diff(diff: str) -> list[dict[str, Any]]:
|
||||
"""Parse diff into list of dicts.
|
||||
|
||||
Args:
|
||||
diff: str, code difference between base and head
|
||||
|
||||
Returns:
|
||||
list[dict[str, Any]]: list of dicts, each dict represents a code chunks
|
||||
"""
|
||||
file_pattern = re.compile(
|
||||
r"(?s)diff --git a/(.+?) b/(.*?)\r?\n(.*?)(?=diff --git a/|$)", re.S
|
||||
)
|
||||
old_new_pattern = re.compile(r"(?m)^(---|\+\+\+)\s+(.*)$")
|
||||
chunk_range_pattern = re.compile(
|
||||
r"@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@(.*?)?(?=@@|\Z)",
|
||||
re.MULTILINE | re.DOTALL,
|
||||
)
|
||||
list_diff = []
|
||||
for match in file_pattern.finditer(diff):
|
||||
diff_text = match.group(3)
|
||||
|
||||
old_new_match = list(old_new_pattern.finditer(diff_text))
|
||||
if len(old_new_match) != 2:
|
||||
continue
|
||||
|
||||
old_file = old_new_match[0].group(2)
|
||||
old_file = old_file.lstrip("a/") if old_file.startswith("a/") else old_file
|
||||
|
||||
new_file = old_new_match[1].group(2)
|
||||
if new_file == "/dev/null":
|
||||
print("Neglict deleted file")
|
||||
continue
|
||||
new_file = new_file.lstrip("b/")
|
||||
if any(fnmatch.fnmatch(new_file, pattern) for pattern in EXCLUDE_PATTERNS):
|
||||
print(f"Exclude file {new_file}")
|
||||
continue
|
||||
|
||||
output_diff_text = []
|
||||
for chunk_range_match in chunk_range_pattern.finditer(diff_text):
|
||||
old_idx = int(chunk_range_match.group(1))
|
||||
new_idx = int(chunk_range_match.group(3))
|
||||
for line in chunk_range_match.group(5).splitlines():
|
||||
if line.startswith("-"):
|
||||
output_diff_text.append(f"{old_idx} None {line}")
|
||||
old_idx += 1
|
||||
elif line.startswith("+"):
|
||||
output_diff_text.append(f"None {new_idx} {line}")
|
||||
new_idx += 1
|
||||
else:
|
||||
output_diff_text.append(f"{old_idx} {new_idx} {line}")
|
||||
old_idx += 1
|
||||
new_idx += 1
|
||||
|
||||
output_diff_text = "\n".join(output_diff_text)
|
||||
list_diff.append(
|
||||
{
|
||||
"file": new_file,
|
||||
"chunk": output_diff_text,
|
||||
}
|
||||
)
|
||||
return list_diff
|
||||
|
||||
|
||||
def create_comment(
|
||||
file: str, ai_response: list[dict[str, Any]]
|
||||
) -> list[dict[str, Any]]:
|
||||
"""Create comments for single chunk review.
|
||||
|
||||
Args:
|
||||
file: str, file name
|
||||
ai_response: list[dict[str, Any]], AI response for single chunk review
|
||||
|
||||
Returns:
|
||||
list[dict[str, Any]]: comments for single chunk review
|
||||
"""
|
||||
comments = []
|
||||
for ai_response in ai_response:
|
||||
comments.append(
|
||||
{
|
||||
"body": f"[REVIEW] {ai_response['reviewComment']}",
|
||||
"path": file,
|
||||
"new_position": int(ai_response["lineNumber"]),
|
||||
}
|
||||
)
|
||||
return comments
|
||||
|
||||
|
||||
async def analyze_single_chunks(
|
||||
single_chunk_model: Model, parsed_diff: list[dict[str, Any]]
|
||||
) -> list[dict[str, Any]]:
|
||||
"""Analyze single chunks and create comments.
|
||||
|
||||
Args:
|
||||
single_chunk_model: AI Session for single chunk analysis
|
||||
parsed_diff: list[dict[str, Any]], parsed diff
|
||||
|
||||
Returns:
|
||||
list[dict[str, Any]]: comments for single chunk review
|
||||
"""
|
||||
|
||||
async def process_single_chunk(diff: dict[str, Any]):
|
||||
file = diff["file"]
|
||||
chunk = diff["chunk"]
|
||||
response = await single_chunk_model.get_response_single_chunk(
|
||||
file, title, description, chunk
|
||||
)
|
||||
response = response.strip("`").lstrip("json").strip() or "[]"
|
||||
|
||||
try:
|
||||
response_json = json.loads(response)
|
||||
return create_comment(file, response_json)
|
||||
except json.JSONDecodeError:
|
||||
print(f"Failed to parse response: {response}")
|
||||
return []
|
||||
|
||||
title = EVENT_DATA["pull_request"]["title"]
|
||||
description = EVENT_DATA["pull_request"]["body"]
|
||||
tasks = [process_single_chunk(diff) for diff in parsed_diff]
|
||||
results = await asyncio.gather(*tasks)
|
||||
|
||||
# Flatten the list of comments
|
||||
comments = [comment for result in results for comment in result]
|
||||
return comments
|
||||
|
||||
|
||||
async def get_file_content(file: str) -> str | None:
|
||||
"""Get file content from Gitea.
|
||||
|
||||
Args:
|
||||
file: str, file name
|
||||
|
||||
Returns:
|
||||
str | None: file content, or None if failed to get file content
|
||||
"""
|
||||
repo_url = EVENT_DATA["pull_request"]["head"]["repo"]["url"]
|
||||
branch = EVENT_DATA["pull_request"]["head"]["ref"]
|
||||
|
||||
replaced_file = file.replace("/", "%2F")
|
||||
url = f"{repo_url}/raw/{branch}%2F{replaced_file}?ref={branch}"
|
||||
|
||||
try:
|
||||
async with aiohttp.ClientSession(headers=HEADERS) as session:
|
||||
async with session.get(url) as response:
|
||||
response.raise_for_status()
|
||||
return await response.text()
|
||||
except aiohttp.ClientError as e: # More specific exception handling
|
||||
print(f"Network error fetching {file}: {e}")
|
||||
except asyncio.TimeoutError:
|
||||
print(f"Timeout fetching {file}")
|
||||
return None
|
||||
|
||||
|
||||
async def analyze_full_context(
|
||||
full_context_model: Model, parsed_diff: list[dict[str, Any]]
|
||||
) -> str:
|
||||
"""Analyze full context and create review.
|
||||
|
||||
Args:
|
||||
full_context_model: AI Session for full context analysis
|
||||
parsed_diff: list[dict[str, Any]], parsed diff
|
||||
|
||||
Returns:
|
||||
str: review for full context
|
||||
"""
|
||||
|
||||
async def get_file_data(diff: dict[str, Any]):
|
||||
file = diff["file"]
|
||||
chunk = diff["chunk"]
|
||||
content = get_file_content(file)
|
||||
if content is None:
|
||||
return None
|
||||
return f"File: {file}\n{content}\nDiff: {chunk}"
|
||||
|
||||
tasks = [get_file_data(diff) for diff in parsed_diff]
|
||||
file_contents_list = await asyncio.gather(*tasks)
|
||||
|
||||
file_contents = [item for item in file_contents_list if item is not None]
|
||||
|
||||
if not file_contents:
|
||||
return ""
|
||||
|
||||
title = EVENT_DATA["pull_request"]["title"]
|
||||
description = EVENT_DATA["pull_request"]["body"]
|
||||
response = await full_context_model.get_response_full_context(
|
||||
title, description, file_contents
|
||||
)
|
||||
response = response.strip("`").lstrip("markdown").strip()
|
||||
return response
|
||||
|
||||
|
||||
def post_review(
|
||||
full_context_review: str, single_chunk_comments: list[dict[str, Any]]
|
||||
) -> None:
|
||||
"""Post review to Gitea.
|
||||
|
||||
Args:
|
||||
full_context_review: str, review for full context
|
||||
single_chunk_comments: list[dict[str, Any]], comments for single chunk review
|
||||
"""
|
||||
repo_url = EVENT_DATA["pull_request"]["head"]["repo"]["url"]
|
||||
pull_number = EVENT_DATA["number"]
|
||||
commit_id = EVENT_DATA["pull_request"]["head"]["sha"]
|
||||
url = f"{repo_url}/pulls/{pull_number}/reviews"
|
||||
data = {
|
||||
"body": full_context_review,
|
||||
"event": "COMMENT",
|
||||
"comments": single_chunk_comments,
|
||||
"commit_id": commit_id,
|
||||
}
|
||||
response = requests.post(url, headers=HEADERS, json=data)
|
||||
response.raise_for_status()
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
"""Code Reviewer for Gitea: Asynchronous version."""
|
||||
if EVENT_DATA["action"] not in ["opened", "synchronized"]:
|
||||
print("Unsupported event.")
|
||||
return
|
||||
|
||||
diff = get_diff()
|
||||
if diff is None:
|
||||
return
|
||||
elif not diff:
|
||||
print("No diff found.")
|
||||
return
|
||||
|
||||
full_context_model = Model(
|
||||
model=FULL_CONTEXT_MODEL_NAME,
|
||||
api_key=FULL_CONTEXT_API_KEY,
|
||||
is_full_context=True,
|
||||
)
|
||||
single_chunk_model = Model(
|
||||
model=SINGLE_CHUNK_MODEL_NAME,
|
||||
api_key=SINGLE_CHUNK_API_KEY,
|
||||
is_full_context=False,
|
||||
)
|
||||
|
||||
parsed_diff = parse_diff(diff)
|
||||
comments_task = asyncio.create_task(
|
||||
analyze_single_chunks(single_chunk_model, parsed_diff)
|
||||
)
|
||||
|
||||
if EVENT_DATA["action"] == "opened":
|
||||
full_context_response_task = asyncio.create_task(
|
||||
analyze_full_context(full_context_model, parsed_diff)
|
||||
)
|
||||
full_context_response = await full_context_response_task
|
||||
else:
|
||||
full_context_response = ""
|
||||
|
||||
comments = await comments_task
|
||||
post_review(full_context_response, comments)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
261
.gitea/scripts/model.py
Normal file
261
.gitea/scripts/model.py
Normal file
@@ -0,0 +1,261 @@
|
||||
"""Model for code review."""
|
||||
|
||||
from enum import Enum
|
||||
from typing import Any
|
||||
|
||||
import google.generativeai as genai
|
||||
import typing_extensions as typing
|
||||
from anthropic import AsyncAnthropic
|
||||
from openai import AsyncOpenAI
|
||||
|
||||
|
||||
class GoogleResponse(typing.TypedDict):
|
||||
"""The response from Google model."""
|
||||
|
||||
lineNumber: int
|
||||
reviewComment: str
|
||||
|
||||
|
||||
class ModelProvider(Enum):
|
||||
"""The model provider."""
|
||||
|
||||
OPENAI = "openai"
|
||||
ANTHROPIC = "anthropic"
|
||||
GOOGLE = "google"
|
||||
DEEPSEEK = "deepseek"
|
||||
|
||||
@classmethod
|
||||
def from_model(cls, model: str) -> "ModelProvider":
|
||||
"""Get the model provider from the model name.
|
||||
|
||||
Args:
|
||||
model (str): The model name.
|
||||
|
||||
Returns:
|
||||
ModelProvider: The model provider.
|
||||
"""
|
||||
for prefix, provider in PREFIX_TO_MODEL.items():
|
||||
if model.startswith(prefix):
|
||||
return provider
|
||||
raise ValueError(f"Unknown model: {model}")
|
||||
|
||||
|
||||
PREFIX_TO_MODEL = {
|
||||
"gpt": ModelProvider.OPENAI,
|
||||
"o1": ModelProvider.OPENAI,
|
||||
"o3": ModelProvider.OPENAI,
|
||||
"claude": ModelProvider.ANTHROPIC,
|
||||
"gemini": ModelProvider.GOOGLE,
|
||||
"deepseek": ModelProvider.DEEPSEEK,
|
||||
}
|
||||
|
||||
|
||||
class Model:
|
||||
"""The model class.
|
||||
|
||||
Attributes:
|
||||
model (str): The model name.
|
||||
api_key (str): The API key.
|
||||
system_prompt (str): The system prompt.
|
||||
max_tokens (int): The maximum tokens.
|
||||
"""
|
||||
|
||||
def __init__( # noqa: D107
|
||||
self,
|
||||
model: str,
|
||||
api_key: str,
|
||||
is_full_context: bool,
|
||||
max_tokens: int = 4196,
|
||||
):
|
||||
self.model = model
|
||||
self.system_prompt = (
|
||||
FULL_CONTEXT_SYSTEM_PROMPT
|
||||
if is_full_context
|
||||
else SINGLE_CHUNK_SYSTEM_PROMPT
|
||||
)
|
||||
self.max_tokens = max_tokens
|
||||
self.provider = ModelProvider.from_model(model)
|
||||
self.session = self.create_session(api_key)
|
||||
|
||||
def create_session(self, api_key: str) -> Any:
|
||||
"""Create a session for the model.
|
||||
|
||||
Args:
|
||||
api_key (str): The API key.
|
||||
|
||||
Returns:
|
||||
Any: The session.
|
||||
"""
|
||||
match self.provider:
|
||||
case ModelProvider.OPENAI:
|
||||
return AsyncOpenAI(api_key=api_key)
|
||||
case ModelProvider.ANTHROPIC:
|
||||
return AsyncAnthropic(api_key=api_key)
|
||||
case ModelProvider.GOOGLE:
|
||||
genai.configure(api_key=api_key)
|
||||
return genai.GenerativeModel(
|
||||
model_name=self.model, system_instruction=self.system_prompt
|
||||
)
|
||||
case ModelProvider.DEEPSEEK:
|
||||
return AsyncOpenAI(api_key=api_key, base_url="https://api.deepseek.com")
|
||||
|
||||
async def request(self, prompt: str) -> str:
|
||||
"""Request the model to generate a response.
|
||||
|
||||
Args:
|
||||
prompt (str): The prompt to generate a response for.
|
||||
|
||||
Returns:
|
||||
str: The generated response.
|
||||
"""
|
||||
match self.provider:
|
||||
case ModelProvider.OPENAI | ModelProvider.DEEPSEEK:
|
||||
response = await self.session.chat.completions.create(
|
||||
model=self.model,
|
||||
messages=[
|
||||
{"role": "system", "content": self.system_prompt},
|
||||
{"role": "user", "content": prompt},
|
||||
],
|
||||
temperature=0.2,
|
||||
max_tokens=self.max_tokens,
|
||||
top_p=1,
|
||||
frequency_penalty=0,
|
||||
presence_penalty=0,
|
||||
)
|
||||
return response.choices[0].message.content.strip()
|
||||
case ModelProvider.ANTHROPIC:
|
||||
response = await self.session.messages.create(
|
||||
model=self.model,
|
||||
messages=[{"role": "user", "content": prompt}],
|
||||
system=[
|
||||
{
|
||||
"type": "text",
|
||||
"text": self.system_prompt,
|
||||
"cache_control": {"type": "ephemeral"},
|
||||
}
|
||||
],
|
||||
temperature=0.2,
|
||||
max_tokens=self.max_tokens,
|
||||
)
|
||||
return response.content[0].text.strip()
|
||||
case ModelProvider.GOOGLE:
|
||||
response = await self.session.generate_content_async(
|
||||
prompt,
|
||||
generation_config=genai.GenerationConfig(
|
||||
response_mime_type="application/json",
|
||||
response_schema=list[GoogleResponse],
|
||||
),
|
||||
)
|
||||
return response.text.strip()
|
||||
|
||||
async def get_response_single_chunk(
|
||||
self, file: str, title: str, description: str, chunk: str
|
||||
) -> str:
|
||||
"""Get the response for a single chunk.
|
||||
|
||||
Args:
|
||||
file (str): The file name.
|
||||
title (str): The pull request title.
|
||||
description (str): The pull request description.
|
||||
chunk (str): The diff chunk.
|
||||
|
||||
Returns:
|
||||
str: The response.
|
||||
"""
|
||||
prompt = SINGLE_CHUNK_USER_PROMPT.format(file, title, description, chunk)
|
||||
return await self.request(prompt)
|
||||
|
||||
async def get_response_full_context(
|
||||
self, title: str, description: str, file_contents: list[str]
|
||||
) -> str:
|
||||
"""Get the response for full context.
|
||||
|
||||
Args:
|
||||
title (str): The pull request title.
|
||||
description (str): The pull request description.
|
||||
file_contents (list[str]): The file contents, diffs.
|
||||
|
||||
Returns:
|
||||
str: The response.
|
||||
"""
|
||||
try:
|
||||
prompt = FULL_CONTEXT_USER_PROMPT.format(
|
||||
title, description, "\n".join(file_contents)
|
||||
)
|
||||
return await self.request(prompt)
|
||||
except Exception as e:
|
||||
print(f"Error during full context response: {e}")
|
||||
print(prompt)
|
||||
return None
|
||||
|
||||
|
||||
SINGLE_CHUNK_SYSTEM_PROMPT = (
|
||||
"Your task is to review pull requests. Instructions:\n"
|
||||
"- Provide the response in the following JSON format: "
|
||||
"""[{{"lineNumber": int, "reviewComment": str}}] \n"""
|
||||
"- lineNumber is about the line number of the code that in new file. \n"
|
||||
"- lineNumber can be found at the front of each line. \n"
|
||||
"- At the first number is old line number, the second number is new line number. \n"
|
||||
"- If the line starts with `+`, it means the line is added. \n"
|
||||
"- If the line starts with `-`, it means the line is deleted. \n"
|
||||
"- Evaluate whether the code changes and additions are appropriate "
|
||||
"and if the new code structure is suitable. \n"
|
||||
"- Do not give positive comments or compliments. \n"
|
||||
"- Provide comments and suggestions ONLY if there is something to improve"
|
||||
"otherwise return an empty array. \n"
|
||||
"- Write the comment in GitHub Markdown format. \n"
|
||||
"- Use the given description only for the overall context "
|
||||
"and only comment the code. \n"
|
||||
"- Do not suggest type hint or naming convention. \n"
|
||||
"- IMPORTANT: NEVER suggest adding comments to the code. \n"
|
||||
)
|
||||
SINGLE_CHUNK_USER_PROMPT = (
|
||||
"Review the following code diff in the file "
|
||||
"{} and take the pull request title and description into account "
|
||||
"when writing the response. \n"
|
||||
"Pull request title: {} \n"
|
||||
"Pull request description: \n"
|
||||
"--- \n"
|
||||
"{} \n"
|
||||
"--- \n"
|
||||
"Git diff to review: \n"
|
||||
"```diff \n"
|
||||
"{} \n"
|
||||
"```"
|
||||
)
|
||||
|
||||
FULL_CONTEXT_SYSTEM_PROMPT = (
|
||||
"You are an experienced software engineer specializing in reviewing pull "
|
||||
"requests. Your task is to provide an overall code review summary for a PR. "
|
||||
"Focus on assessing the following aspects:\n"
|
||||
"1. **Code Structure & Architecture:** "
|
||||
"Evaluate whether the code is well-organized, modular, "
|
||||
"and adheres to clean code principles. Suggest improvements if needed.\n"
|
||||
"2. **Refactoring Opportunities:** "
|
||||
"Identify areas where the code can be optimized or simplified without changing "
|
||||
"its behavior.\n"
|
||||
"3. **Potential Future Problems:** "
|
||||
"Highlight possible scalability, maintainability, or dependency issues that might "
|
||||
"arise in the future based on the current implementation.\n"
|
||||
"Be constructive and clear in your feedback. Avoid commenting on trivial issues "
|
||||
"or syntax errors—focus on high-level feedback.\n"
|
||||
"Precise instructions:\n"
|
||||
"- Do not give positive comments or compliments.\n"
|
||||
"- Provide comments and suggestions ONLY if there is something to improve, "
|
||||
"otherwise return an empty string.\n"
|
||||
"- Write the comment in GitHub Markdown format.\n"
|
||||
"- Do not start with 'markdown' or '```markdown'.\n"
|
||||
"- IMPORTANT: Give example code block or pseudo code if you can.\n"
|
||||
)
|
||||
|
||||
FULL_CONTEXT_USER_PROMPT = (
|
||||
"Review the following code and take the pull request title "
|
||||
"and description into account when writing the response. \n"
|
||||
"Pull request title: {} \n"
|
||||
"Pull request description: \n"
|
||||
"--- \n"
|
||||
"{} \n"
|
||||
"--- \n"
|
||||
"Code to review: \n"
|
||||
"{}"
|
||||
)
|
||||
35
.gitea/workflows/ai-review.yml
Normal file
35
.gitea/workflows/ai-review.yml
Normal file
@@ -0,0 +1,35 @@
|
||||
name: Code Review
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
review:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install aiohttp requests py-gitea openai anthropic google-generativeai
|
||||
|
||||
- name: Run Code Review
|
||||
env:
|
||||
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
|
||||
FULL_CONTEXT_MODEL: o3-mini
|
||||
FULL_CONTEXT_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
SINGLE_CHUNK_MODEL: gemini-2.0-flash-exp
|
||||
SINGLE_CHUNK_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
|
||||
EXCLUDE: "*.yml,*.yaml"
|
||||
run: python .gitea/scripts/code_review.py
|
||||
|
||||
38
.gitea/workflows/ci.yaml
Normal file
38
.gitea/workflows/ci.yaml
Normal file
@@ -0,0 +1,38 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Run rust tests
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
components: clippy
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
||||
- name: run clippy
|
||||
run: cargo clippy -- -Dwarnings
|
||||
|
||||
- name: run rust tests
|
||||
run: cargo test --verbose
|
||||
|
||||
- name: check compilation
|
||||
run: cargo check
|
||||
|
||||
lint:
|
||||
name: Check Rust code with rustfmt and clippy
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
components: rustfmt, clippy
|
||||
- name: run rustfmt
|
||||
run: cargo fmt --check
|
||||
|
||||
564
CLAUDE.md
Normal file
564
CLAUDE.md
Normal file
@@ -0,0 +1,564 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
Rust-OpenMM is a Rust port of the OpenMM molecular simulation toolkit. The project follows a test-driven development approach, converting C++ tests to Rust and implementing functionality to make them pass.
|
||||
|
||||
## Key Directories
|
||||
|
||||
- `openmm/` - Original C++ OpenMM library (reference implementation)
|
||||
- `rust-openmm/src/` - Rust implementation following the module structure:
|
||||
- `system.rs` - Core molecular system representation
|
||||
- `force/` - Force field components (trait-based)
|
||||
- `integrator/` - Time integration algorithms
|
||||
- `platform/` - Compute platform abstractions
|
||||
- `context.rs` - Simulation context binding components
|
||||
- `state.rs` - Simulation state management
|
||||
|
||||
## Development Commands
|
||||
|
||||
```bash
|
||||
# Build the project
|
||||
cargo build
|
||||
|
||||
# Run tests (most are currently ignored)
|
||||
cargo test
|
||||
|
||||
# Run tests including ignored ones
|
||||
cargo test -- --ignored
|
||||
|
||||
# Generate documentation
|
||||
cargo doc --open
|
||||
|
||||
# Check code without building
|
||||
cargo check
|
||||
|
||||
# Format code
|
||||
cargo fmt
|
||||
|
||||
# Run linter
|
||||
cargo clippy
|
||||
```
|
||||
|
||||
## Development Strategy
|
||||
|
||||
1. **Test-Driven Conversion**: Convert C++ tests first, then implement functionality
|
||||
2. **Progressive Implementation**: Use `unimplemented!()` placeholders for missing functionality
|
||||
3. **Test Organization**:
|
||||
- Unit tests: In source files using `#[cfg(test)]` modules
|
||||
- Integration tests: In `tests/` directory (for cross-module functionality)
|
||||
|
||||
## Architecture Principles
|
||||
|
||||
- **Trait-Based Design**: Forces and integrators use traits for extensibility
|
||||
- **Idiomatic Rust**: Prefer Rust patterns over direct C++ translation
|
||||
- **Modular Structure**: Each force type, integrator, and platform is a separate module
|
||||
- **Zero-Copy Where Possible**: Use references and borrowing to minimize allocations
|
||||
|
||||
## Key Dependencies
|
||||
|
||||
- `nalgebra`: Linear algebra operations (vectors, matrices)
|
||||
- `approx`: Floating-point comparisons in tests
|
||||
|
||||
## Feature Flags
|
||||
|
||||
- `cpu` (default): CPU compute platform
|
||||
- `vulkan`: Vulkan compute platform (not yet implemented)
|
||||
- 'cuda': Nvidia cuda platform
|
||||
- 'opencl': OpenCL platform
|
||||
|
||||
## C++ Reference Locations
|
||||
|
||||
When implementing new functionality, refer to:
|
||||
- Force implementations: `openmm/openmmapi/src/*Force.cpp`
|
||||
- Test cases: `openmm/tests/Test*.cpp`
|
||||
- Platform code: `openmm/platforms/*/src/`
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Adding a New Force Type
|
||||
1. Create `src/force/new_force.rs`
|
||||
2. Define struct implementing `Force` trait
|
||||
3. Add module declaration to `src/force/mod.rs`
|
||||
4. Convert corresponding C++ test from `openmm/tests/`
|
||||
|
||||
### Implementing Placeholder Methods
|
||||
Replace `unimplemented!()` with actual implementation, ensuring:
|
||||
- Proper error handling with `Result` types
|
||||
- Efficient memory usage
|
||||
- Thread safety where applicable
|
||||
|
||||
## Testing Approach
|
||||
|
||||
- Tests should closely mirror C++ test structure for validation
|
||||
- Use `approx::assert_relative_eq!` for floating-point comparisons
|
||||
- Mark incomplete tests with `#[ignore]` until implementation is ready
|
||||
|
||||
# TODO
|
||||
|
||||
## API
|
||||
### Core Objects
|
||||
- [ ] System - `openmm/openmmapi/include/openmm/System.h`
|
||||
- [ ] Context - `openmm/openmmapi/include/openmm/Context.h`
|
||||
- [ ] Platform - `openmm/openmmapi/include/openmm/Platform.h`
|
||||
- [ ] State - `openmm/openmmapi/include/openmm/State.h`
|
||||
|
||||
### Forces
|
||||
- [ ] The Force abstract class - `openmm/openmmapi/include/openmm/Force.h`
|
||||
- Common bonded and non-bonded forces
|
||||
- [ ] CMAPTorsionForce - `openmm/openmmapi/include/openmm/CMAPTorsionForce.h`
|
||||
- [ ] DrudeForce - `openmm/plugins/drude/openmmapi/include/openmm/DrudeForce.h`
|
||||
- [ ] GBSAOBCForce - `openmm/openmmapi/include/openmm/GBSAOBCForce.h`
|
||||
- [ ] GayBerneForce - `openmm/openmmapi/include/openmm/GayBerneForce.h`
|
||||
- [ ] HarmonicAngleForce - `openmm/openmmapi/include/openmm/HarmonicAngleForce.h`
|
||||
- [ ] HarmonicBondForce - `openmm/openmmapi/include/openmm/HarmonicBondForce.h`
|
||||
- [ ] NonbondedForce - `openmm/openmmapi/include/openmm/NonbondedForce.h`
|
||||
- [ ] PeriodicTorsionForce - `openmm/openmmapi/include/openmm/PeriodicTorsionForce.h`
|
||||
- [ ] RBTorsionForce - `openmm/openmmapi/include/openmm/RBTorsionForce.h`
|
||||
|
||||
- AMOEBA forces
|
||||
- [ ] AmoebaGeneralizedKirkwoodForce - `openmm/plugins/amoeba/openmmapi/include/openmm/AmoebaGeneralizedKirkwoodForce.h`
|
||||
- [ ] AmoebaMultipoleForce - `openmm/plugins/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h`
|
||||
- [ ] AmoebaTorsionTorsionForce - `openmm/plugins/amoeba/openmmapi/include/openmm/AmoebaTorsionTorsionForce.h`
|
||||
- [ ] AmoebaVdwForce - `openmm/plugins/amoeba/openmmapi/include/openmm/AmoebaVdwForce.h`
|
||||
- [ ] AmoebaWcaDispersionForce - `openmm/plugins/amoeba/openmmapi/include/openmm/AmoebaWcaDispersionForce.h`
|
||||
- [ ] HippoNonbondedForce - `openmm/plugins/amoeba/openmmapi/include/openmm/HippoNonbondedForce.h`
|
||||
|
||||
- Pseudo-forces
|
||||
- [ ] AndersenThermostat - `openmm/openmmapi/include/openmm/AndersenThermostat.h`
|
||||
- [ ] ATMForce - `openmm/openmmapi/include/openmm/ATMForce.h`
|
||||
- [ ] CMMotionRemover - `openmm/openmmapi/include/openmm/CMMotionRemover.h`
|
||||
- [ ] MonteCarloAnisotropicBarostat - `openmm/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h`
|
||||
- [ ] MonteCarloBarostat - `openmm/openmmapi/include/openmm/MonteCarloBarostat.h`
|
||||
- [ ] MonteCarloFlexibleBarostat - `openmm/openmmapi/include/openmm/MonteCarloFlexibleBarostat.h`
|
||||
- [ ] MonteCarloMembraneBarostat - `openmm/openmmapi/include/openmm/MonteCarloMembraneBarostat.h`
|
||||
- [ ] RMSDForce - `openmm/openmmapi/include/openmm/RMSDForce.h`
|
||||
- [ ] RPMDMonteCarloBarostat - `openmm/plugins/rpmd/openmmapi/include/openmm/RPMDMonteCarloBarostat.h`
|
||||
|
||||
- Customizing Force
|
||||
- [ ] CustomAngleForce - `openmm/openmmapi/include/openmm/CustomAngleForce.h`
|
||||
- [ ] CustomBondForce - `openmm/openmmapi/include/openmm/CustomBondForce.h`
|
||||
- [ ] CustomCVForce - `openmm/openmmapi/include/openmm/CustomCVForce.h`
|
||||
- [ ] CustomCentroidBondForce - `openmm/openmmapi/include/openmm/CustomCentroidBondForce.h`
|
||||
- [ ] CustomCompoundBondForce - `openmm/openmmapi/include/openmm/CustomCompoundBondForce.h`
|
||||
- [ ] CustomExternalForce - `openmm/openmmapi/include/openmm/CustomExternalForce.h`
|
||||
- [ ] CustomGBForce - `openmm/openmmapi/include/openmm/CustomGBForce.h`
|
||||
- [ ] CustomHbondForce - `openmm/openmmapi/include/openmm/CustomHbondForce.h`
|
||||
- [ ] CustomManyParticleForce - `openmm/openmmapi/include/openmm/CustomManyParticleForce.h`
|
||||
- [ ] CustomNonbondedForce - `openmm/openmmapi/include/openmm/CustomNonbondedForce.h`
|
||||
- [ ] CustomTorsionForce - `openmm/openmmapi/include/openmm/CustomTorsionForce.h`
|
||||
|
||||
### Integrators
|
||||
- [ ] The integrator abstract object - `openmm/openmmapi/include/openmm/Integrator.h`
|
||||
|
||||
- General purpose integrators
|
||||
- [ ] BrownianIntegrator - `openmm/openmmapi/include/openmm/BrownianIntegrator.h`
|
||||
- [ ] LangevinIntegrator - `openmm/openmmapi/include/openmm/LangevinIntegrator.h`
|
||||
- [ ] LangevinMiddleIntegrator - `openmm/openmmapi/include/openmm/LangevinMiddleIntegrator.h`
|
||||
- [ ] NoseHooverIntegrator - `openmm/openmmapi/include/openmm/NoseHooverIntegrator.h`
|
||||
- [ ] VariableLangevinIntegrator - `openmm/openmmapi/include/openmm/VariableLangevinIntegrator.h`
|
||||
- [ ] VariableVerletIntegrator - `openmm/openmmapi/include/openmm/VariableVerletIntegrator.h`
|
||||
- [ ] VerletIntegrator - `openmm/openmmapi/include/openmm/VerletIntegrator.h`
|
||||
|
||||
- Drude integrators
|
||||
- [ ] DrudeIntegrator - `openmm/plugins/drude/openmmapi/include/openmm/DrudeIntegrator.h`
|
||||
- [ ] DrudeLangevinIntegrator - `openmm/plugins/drude/openmmapi/include/openmm/DrudeLangevinIntegrator.h`
|
||||
- [ ] DrudeNoseHooverIntegrator - `openmm/plugins/drude/openmmapi/include/openmm/DrudeNoseHooverIntegrator.h`
|
||||
- [ ] DrudeSCFIntegrator - `openmm/plugins/drude/openmmapi/include/openmm/DrudeSCFIntegrator.h`
|
||||
|
||||
- Ring Polymer Molecular Dynamics integrators
|
||||
- [ ] RPMDIntegrator - `openmm/plugins/rpmd/openmmapi/include/openmm/RPMDIntegrator.h`
|
||||
|
||||
- Customizing Integrator
|
||||
- [ ] CustomIntegrator - `openmm/openmmapi/include/openmm/CustomIntegrator.h`
|
||||
- [ ] CompoundIntegrator - `openmm/openmmapi/include/openmm/CompoundIntegrator.h`
|
||||
|
||||
### Extra classes
|
||||
- Tabulated functions
|
||||
- [ ] TabulatedFunction - `openmm/openmmapi/include/openmm/TabulatedFunction.h`
|
||||
- [ ] Continuous1DFunction - `openmm/openmmapi/include/openmm/TabulatedFunction.h`
|
||||
- [ ] Continuous2DFunction - `openmm/openmmapi/include/openmm/TabulatedFunction.h`
|
||||
- [ ] Continuous3DFunction - `openmm/openmmapi/include/openmm/TabulatedFunction.h`
|
||||
- [ ] Discrete1DFunction - `openmm/openmmapi/include/openmm/TabulatedFunction.h`
|
||||
- [ ] Discrete2DFunction - `openmm/openmmapi/include/openmm/TabulatedFunction.h`
|
||||
- [ ] Discrete3DFunction - `openmm/openmmapi/include/openmm/TabulatedFunction.h`
|
||||
|
||||
- Virtual Sites
|
||||
- [ ] VirtualSite - `openmm/openmmapi/include/openmm/VirtualSite.h`
|
||||
- [ ] LocalCoordinatesSite - `openmm/openmmapi/include/openmm/VirtualSite.h`
|
||||
- [ ] OutOfPlaneSite - `openmm/openmmapi/include/openmm/VirtualSite.h`
|
||||
- [ ] ThreeParticleAverageSite - `openmm/openmmapi/include/openmm/VirtualSite.h`
|
||||
- [ ] TwoParticleAverageSite - `openmm/openmmapi/include/openmm/VirtualSite.h`
|
||||
|
||||
- Serialization
|
||||
- [ ] SerializationNode - `openmm/serialization/include/openmm/serialization/SerializationNode.h`
|
||||
- [ ] SerializationProxy - `openmm/serialization/include/openmm/serialization/SerializationProxy.h`
|
||||
- [ ] XmlSerializer - `openmm/serialization/include/openmm/serialization/XmlSerializer.h`
|
||||
|
||||
- Other classes
|
||||
- [ ] LocalEnergyMinimizer - `openmm/openmmapi/include/openmm/LocalEnergyMinimizer.h`
|
||||
- [ ] MinimizationReporter - `openmm/openmmapi/include/openmm/MinimizationReporter.h`
|
||||
- [ ] NoseHooverChain - `openmm/openmmapi/include/openmm/NoseHooverChain.h`
|
||||
- [ ] OpenMMException - `openmm/openmmapi/include/openmm/OpenMMException.h`
|
||||
- [ ] Vec3 - `openmm/openmmapi/include/openmm/Vec3.h`
|
||||
|
||||
## Integrated Examples
|
||||
- Cookbook examples (Python-based, reference only)
|
||||
- [ ] First Simulation
|
||||
- [ ] Changing Temperature and Pressure
|
||||
- [ ] Saving Systems to XML Files
|
||||
- [ ] Merging Molecules in a Topology
|
||||
- [ ] Adding Hydrogens to Nonstandard Molecules
|
||||
- [ ] Applying a Fixed External Force
|
||||
- [ ] Constraining Atom Positions
|
||||
- [ ] Restraining Atom Positions
|
||||
- [ ] Restraining Dihedrals
|
||||
- [ ] Analyzing Energy Contributions
|
||||
- [ ] Computing Interaction Energies
|
||||
- [ ] Querying and Modifying Charges and Other Parameters
|
||||
|
||||
- Examples
|
||||
- [ ] HelloArgon - `openmm/examples/HelloArgon.cpp`
|
||||
- [ ] HelloEthane - `openmm/examples/HelloEthane.cpp`
|
||||
- [ ] HelloSodiumChloride - `openmm/examples/HelloSodiumChloride.cpp`
|
||||
- [ ] HelloWaterBox - `openmm/examples/HelloWaterBox.cpp`
|
||||
- [ ] simulateAmber - `openmm/examples/simulateAmber.py`
|
||||
- [ ] simulateCharmm - `openmm/examples/simulateCharmm.py`
|
||||
- [ ] simulateGromacs - `openmm/examples/simulateGromacs.py`
|
||||
- [ ] simulatePdb - `openmm/examples/simulatePdb.py`
|
||||
|
||||
- Test files
|
||||
- **Core**
|
||||
- [ ] TestATMForce - `openmm/tests/TestATMForce.h`
|
||||
- [ ] TestAndersenThermostat - `openmm/tests/TestAndersenThermostat.h`
|
||||
- [ ] TestBrownianIntegrator - `openmm/tests/TestBrownianIntegrator.h`
|
||||
- [ ] TestCMAPTorsionForce - `openmm/tests/TestCMAPTorsionForce.h`
|
||||
- [ ] TestCMMotionRemover - `openmm/tests/TestCMMotionRemover.h`
|
||||
- [ ] TestCheckpoints - `openmm/tests/TestCheckpoints.h`
|
||||
- [ ] TestCompoundIntegrator - `openmm/tests/TestCompoundIntegrator.h`
|
||||
- [ ] TestCustomAngleForce - `openmm/tests/TestCustomAngleForce.h`
|
||||
- [ ] TestCustomBondForce - `openmm/tests/TestCustomBondForce.h`
|
||||
- [ ] TestCustomCPPForce - `openmm/tests/TestCustomCPPForce.h`
|
||||
- [ ] TestCustomCVForce - `openmm/tests/TestCustomCVForce.h`
|
||||
- [ ] TestCustomCentroidBondForce - `openmm/tests/TestCustomCentroidBondForce.h`
|
||||
- [ ] TestCustomCompoundBondForce - `openmm/tests/TestCustomCompoundBondForce.h`
|
||||
- [ ] TestCustomExternalForce - `openmm/tests/TestCustomExternalForce.h`
|
||||
- [ ] TestCustomGBForce - `openmm/tests/TestCustomGBForce.h`
|
||||
- [ ] TestCustomHbondForce - `openmm/tests/TestCustomHbondForce.h`
|
||||
- [ ] TestCustomIntegrator - `openmm/tests/TestCustomIntegrator.h`
|
||||
- [ ] TestCustomManyParticleForce - `openmm/tests/TestCustomManyParticleForce.h`
|
||||
- [ ] TestCustomNonbondedForce - `openmm/tests/TestCustomNonbondedForce.h`
|
||||
- [ ] TestCustomTorsionForce - `openmm/tests/TestCustomTorsionForce.h`
|
||||
- [ ] TestDispersionPME - `openmm/tests/TestDispersionPME.h`
|
||||
- [ ] TestEnforcePeriodicBox - `openmm/tests/TestEnforcePeriodicBox.cpp`
|
||||
- [ ] TestEwald - `openmm/tests/TestEwald.h`
|
||||
- [ ] TestFindExclusions - `openmm/tests/TestFindExclusions.cpp`
|
||||
- [ ] TestFindMolecules - `openmm/tests/TestFindMolecules.cpp`
|
||||
- [ ] TestGBSAOBCForce - `openmm/tests/TestGBSAOBCForce.h`
|
||||
- [ ] TestGayBerneForce - `openmm/tests/TestGayBerneForce.h`
|
||||
- [ ] TestHarmonicAngleForce - `openmm/tests/TestHarmonicAngleForce.h`
|
||||
- [x] TestBonds - closed by #10
|
||||
- [x] TestPeriodic - closed by #10
|
||||
- [ ] TestParallelComputation
|
||||
- [ ] TestHarmonicBondForce - `openmm/tests/TestHarmonicBondForce.h`
|
||||
- [x] TestBonds - closed by #8
|
||||
- [x] TestPeriodic - closed by #8
|
||||
- [ ] TestParallelComputation
|
||||
- [ ] TestLangevinIntegrator - `openmm/tests/TestLangevinIntegrator.h`
|
||||
- [ ] TestLangevinMiddleIntegrator - `openmm/tests/TestLangevinMiddleIntegrator.h`
|
||||
- [ ] TestLocalEnergyMinimizer - `openmm/tests/TestLocalEnergyMinimizer.h`
|
||||
- [ ] TestMonteCarloAnisotropicBarostat - `openmm/tests/TestMonteCarloAnisotropicBarostat.h`
|
||||
- [ ] TestMonteCarloBarostat - `openmm/tests/TestMonteCarloBarostat.h`
|
||||
- [ ] TestMonteCarloFlexibleBarostat - `openmm/tests/TestMonteCarloFlexibleBarostat.h`
|
||||
- [ ] TestNonbondedForce - `openmm/tests/TestNonbondedForce.h`
|
||||
- [ ] TestNoseHooverIntegrator - `openmm/tests/TestNoseHooverIntegrator.h`
|
||||
- [ ] TestParser - `openmm/tests/TestParser.cpp`
|
||||
- [ ] TestPeriodicTorsionForce - `openmm/tests/TestPeriodicTorsionForce.h`
|
||||
- [ ] TestRBTorsionForce - `openmm/tests/TestRBTorsionForce.h`
|
||||
- [ ] TestRMSDForce - `openmm/tests/TestRMSDForce.h`
|
||||
- [ ] TestSettle - `openmm/tests/TestSettle.h`
|
||||
- [ ] TestSplineFitter - `openmm/tests/TestSplineFitter.cpp`
|
||||
- [x] TestSystem - `openmm/tests/TestSystem.cpp`
|
||||
- closed by #6
|
||||
- [ ] TestVariableLangevinIntegrator - `openmm/tests/TestVariableLangevinIntegrator.h`
|
||||
- [ ] TestVariableVerletIntegrator - `openmm/tests/TestVariableVerletIntegrator.h`
|
||||
- [ ] TestVectorExpression - `openmm/tests/TestVectorExpression.cpp`
|
||||
- [ ] TestVectorize - `openmm/tests/TestVectorize.cpp`
|
||||
- [ ] TestVectorizeAvx - `openmm/tests/TestVectorizeAvx.cpp`
|
||||
- [ ] TestVectorizeAvx2 - `openmm/tests/TestVectorizeAvx2.cpp`
|
||||
- [ ] TestVectorizeGeneric - `openmm/tests/TestVectorizeGeneric.h`
|
||||
- [ ] TestVerletIntegrator - `openmm/tests/TestVerletIntegrator.h`
|
||||
- [ ] TestVirtualSites - `openmm/tests/TestVirtualSites.h`
|
||||
|
||||
- **Serialization**
|
||||
- [ ] TestSerializeAmoebaGeneralizedKirkwoodForce - `openmm/plugins/amoeba/serialization/tests/TestSerializeAmoebaGeneralizedKirkwoodForce.cpp`
|
||||
- [ ] TestSerializeAmoebaMultipoleForce - `openmm/plugins/amoeba/serialization/tests/TestSerializeAmoebaMultipoleForce.cpp`
|
||||
- [ ] TestSerializeAmoebaTorsionTorsionForce - `openmm/plugins/amoeba/serialization/tests/TestSerializeAmoebaTorsionTorsionForce.cpp`
|
||||
- [ ] TestSerializeAmoebaVdwForce - `openmm/plugins/amoeba/serialization/tests/TestSerializeAmoebaVdwForce.cpp`
|
||||
- [ ] TestSerializeAmoebaWcaDispersionForce - `openmm/plugins/amoeba/serialization/tests/TestSerializeAmoebaWcaDispersionForce.cpp`
|
||||
- [ ] TestSerializeHippoNonbondedForce - `openmm/plugins/amoeba/serialization/tests/TestSerializeHippoNonbondedForce.cpp`
|
||||
- [ ] TestSerializeDrudeForce - `openmm/plugins/drude/serialization/tests/TestSerializeDrudeForce.cpp`
|
||||
- [ ] TestSerializeDrudeLangevinIntegrator - `openmm/plugins/drude/serialization/tests/TestSerializeDrudeLangevinIntegrator.cpp`
|
||||
- [ ] TestSerializeDrudeNoseHooverIntegrator - `openmm/plugins/drude/serialization/tests/TestSerializeDrudeNoseHooverIntegrator.cpp`
|
||||
- [ ] TestSerializationNode - `openmm/serialization/tests/TestSerializationNode.cpp`
|
||||
- [ ] TestSerializeATMForce - `openmm/serialization/tests/TestSerializeATMForce.cpp`
|
||||
- [ ] TestSerializeAndersenThermostat - `openmm/serialization/tests/TestSerializeAndersenThermostat.cpp`
|
||||
- [ ] TestSerializeCMAPTorsion - `openmm/serialization/tests/TestSerializeCMAPTorsion.cpp`
|
||||
- [ ] TestSerializeCMMotionRemover - `openmm/serialization/tests/TestSerializeCMMotionRemover.cpp`
|
||||
- [ ] TestSerializeCustomAngleForce - `openmm/serialization/tests/TestSerializeCustomAngleForce.cpp`
|
||||
- [ ] TestSerializeCustomBondForce - `openmm/serialization/tests/TestSerializeCustomBondForce.cpp`
|
||||
- [ ] TestSerializeCustomCVForce - `openmm/serialization/tests/TestSerializeCustomCVForce.cpp`
|
||||
- [ ] TestSerializeCustomCentroidBondForce - `openmm/serialization/tests/TestSerializeCustomCentroidBondForce.cpp`
|
||||
- [ ] TestSerializeCustomCompoundBondForce - `openmm/serialization/tests/TestSerializeCustomCompoundBondForce.cpp`
|
||||
- [ ] TestSerializeCustomExternalForce - `openmm/serialization/tests/TestSerializeCustomExternalForce.cpp`
|
||||
- [ ] TestSerializeCustomGBForce - `openmm/serialization/tests/TestSerializeCustomGBForce.cpp`
|
||||
- [ ] TestSerializeCustomHbondForce - `openmm/serialization/tests/TestSerializeCustomHbondForce.cpp`
|
||||
- [ ] TestSerializeCustomManyParticleForce - `openmm/serialization/tests/TestSerializeCustomManyParticleForce.cpp`
|
||||
- [ ] TestSerializeCustomNonbondedForce - `openmm/serialization/tests/TestSerializeCustomNonbondedForce.cpp`
|
||||
- [ ] TestSerializeCustomTorsionForce - `openmm/serialization/tests/TestSerializeCustomTorsionForce.cpp`
|
||||
- [ ] TestSerializeGBSAOBCForce - `openmm/serialization/tests/TestSerializeGBSAOBCForce.cpp`
|
||||
- [ ] TestSerializeGayBerneForce - `openmm/serialization/tests/TestSerializeGayBerneForce.cpp`
|
||||
- [ ] TestSerializeHarmonicAngleForce - `openmm/serialization/tests/TestSerializeHarmonicAngleForce.cpp`
|
||||
- [ ] TestSerializeHarmonicBondForce - `openmm/serialization/tests/TestSerializeHarmonicBondForce.cpp`
|
||||
- [ ] TestSerializeIntegrator - `openmm/serialization/tests/TestSerializeIntegrator.cpp`
|
||||
- [ ] TestSerializeMonteCarloAnisotropicBarostat - `openmm/serialization/tests/TestSerializeMonteCarloAnisotropicBarostat.cpp`
|
||||
- [ ] TestSerializeMonteCarloBarostat - `openmm/serialization/tests/TestSerializeMonteCarloBarostat.cpp`
|
||||
- [ ] TestSerializeMonteCarloFlexibleBarostat - `openmm/serialization/tests/TestSerializeMonteCarloFlexibleBarostat.cpp`
|
||||
- [ ] TestSerializeMonteCarloMembraneBarostat - `openmm/serialization/tests/TestSerializeMonteCarloMembraneBarostat.cpp`
|
||||
- [ ] TestSerializeNonbondedForce - `openmm/serialization/tests/TestSerializeNonbondedForce.cpp`
|
||||
- [ ] TestSerializeNoseHooverIntegrator - `openmm/serialization/tests/TestSerializeNoseHooverIntegrator.cpp`
|
||||
- [ ] TestSerializePeriodicTorsionForce - `openmm/serialization/tests/TestSerializePeriodicTorsionForce.cpp`
|
||||
- [ ] TestSerializeRBTorsionForce - `openmm/serialization/tests/TestSerializeRBTorsionForce.cpp`
|
||||
- [ ] TestSerializeRMSDForce - `openmm/serialization/tests/TestSerializeRMSDForce.cpp`
|
||||
- [ ] TestSerializeState - `openmm/serialization/tests/TestSerializeState.cpp`
|
||||
- [ ] TestSerializeSystem - `openmm/serialization/tests/TestSerializeSystem.cpp`
|
||||
- [ ] TestSerializeTabulatedFunctions - `openmm/serialization/tests/TestSerializeTabulatedFunctions.cpp`
|
||||
|
||||
- **Platforms**
|
||||
- [ ] CPU
|
||||
- [ ] TestCpuCheckpoints - `openmm/platforms/cpu/tests/TestCpuCheckpoints.cpp`
|
||||
- [ ] TestCpuCompoundIntegrator - `openmm/platforms/cpu/tests/TestCpuCompoundIntegrator.cpp`
|
||||
- [ ] TestCpuCustomCPPForce - `openmm/platforms/cpu/tests/TestCpuCustomCPPForce.cpp`
|
||||
- [ ] TestCpuCustomGBForce - `openmm/platforms/cpu/tests/TestCpuCustomGBForce.cpp`
|
||||
- [ ] TestCpuCustomManyParticleForce - `openmm/platforms/cpu/tests/TestCpuCustomManyParticleForce.cpp`
|
||||
- [ ] TestCpuCustomNonbondedForce - `openmm/platforms/cpu/tests/TestCpuCustomNonbondedForce.cpp`
|
||||
- [ ] TestCpuDispersionPME - `openmm/platforms/cpu/tests/TestCpuDispersionPME.cpp`
|
||||
- [ ] TestCpuEwald - `openmm/platforms/cpu/tests/TestCpuEwald.cpp`
|
||||
- [ ] TestCpuGBSAOBCForce - `openmm/platforms/cpu/tests/TestCpuGBSAOBCForce.cpp`
|
||||
- [ ] TestCpuGayBerneForce - `openmm/platforms/cpu/tests/TestCpuGayBerneForce.cpp`
|
||||
- [ ] TestCpuHarmonicAngleForce - `openmm/platforms/cpu/tests/TestCpuHarmonicAngleForce.cpp`
|
||||
- [ ] TestCpuLangevinIntegrator - `openmm/platforms/cpu/tests/TestCpuLangevinIntegrator.cpp`
|
||||
- [ ] TestCpuLangevinMiddleIntegrator - `openmm/platforms/cpu/tests/TestCpuLangevinMiddleIntegrator.cpp`
|
||||
- [ ] TestCpuNeighborList - `openmm/platforms/cpu/tests/TestCpuNeighborList.cpp`
|
||||
- [ ] TestCpuNonbondedForce - `openmm/platforms/cpu/tests/TestCpuNonbondedForce.cpp`
|
||||
- [ ] TestCpuPeriodicTorsionForce - `openmm/platforms/cpu/tests/TestCpuPeriodicTorsionForce.cpp`
|
||||
- [ ] TestCpuRBTorsionForce - `openmm/platforms/cpu/tests/TestCpuRBTorsionForce.cpp`
|
||||
- [ ] TestCpuSettle - `openmm/platforms/cpu/tests/TestCpuSettle.cpp`
|
||||
- [ ] CUDA
|
||||
- [ ] TestCudaATMForce - `openmm/platforms/cuda/tests/TestCudaATMForce.cpp`
|
||||
- [ ] TestCudaAndersenThermostat - `openmm/platforms/cuda/tests/TestCudaAndersenThermostat.cpp`
|
||||
- [ ] TestCudaBrownianIntegrator - `openmm/platforms/cuda/tests/TestCudaBrownianIntegrator.cpp`
|
||||
- [ ] TestCudaCMAPTorsionForce - `openmm/platforms/cuda/tests/TestCudaCMAPTorsionForce.cpp`
|
||||
- [ ] TestCudaCMMotionRemover - `openmm/platforms/cuda/tests/TestCudaCMMotionRemover.cpp`
|
||||
- [ ] TestCudaCheckpoints - `openmm/platforms/cuda/tests/TestCudaCheckpoints.cpp`
|
||||
- [ ] TestCudaCompoundIntegrator - `openmm/platforms/cuda/tests/TestCudaCompoundIntegrator.cpp`
|
||||
- [ ] TestCudaCustomAngleForce - `openmm/platforms/cuda/tests/TestCudaCustomAngleForce.cpp`
|
||||
- [ ] TestCudaCustomBondForce - `openmm/platforms/cuda/tests/TestCudaCustomBondForce.cpp`
|
||||
- [ ] TestCudaCustomCPPForce - `openmm/platforms/cuda/tests/TestCudaCustomCPPForce.cpp`
|
||||
- [ ] TestCudaCustomCVForce - `openmm/platforms/cuda/tests/TestCudaCustomCVForce.cpp`
|
||||
- [ ] TestCudaCustomCentroidBondForce - `openmm/platforms/cuda/tests/TestCudaCustomCentroidBondForce.cpp`
|
||||
- [ ] TestCudaCustomCompoundBondForce - `openmm/platforms/cuda/tests/TestCudaCustomCompoundBondForce.cpp`
|
||||
- [ ] TestCudaCustomExternalForce - `openmm/platforms/cuda/tests/TestCudaCustomExternalForce.cpp`
|
||||
- [ ] TestCudaCustomGBForce - `openmm/platforms/cuda/tests/TestCudaCustomGBForce.cpp`
|
||||
- [ ] TestCudaCustomHbondForce - `openmm/platforms/cuda/tests/TestCudaCustomHbondForce.cpp`
|
||||
- [ ] TestCudaCustomIntegrator - `openmm/platforms/cuda/tests/TestCudaCustomIntegrator.cpp`
|
||||
- [ ] TestCudaCustomManyParticleForce - `openmm/platforms/cuda/tests/TestCudaCustomManyParticleForce.cpp`
|
||||
- [ ] TestCudaCustomNonbondedForce - `openmm/platforms/cuda/tests/TestCudaCustomNonbondedForce.cpp`
|
||||
- [ ] TestCudaCustomTorsionForce - `openmm/platforms/cuda/tests/TestCudaCustomTorsionForce.cpp`
|
||||
- [ ] TestCudaDispersionPME - `openmm/platforms/cuda/tests/TestCudaDispersionPME.cpp`
|
||||
- [ ] TestCudaEwald - `openmm/platforms/cuda/tests/TestCudaEwald.cpp`
|
||||
- [ ] TestCudaFFT3D - `openmm/platforms/cuda/tests/TestCudaFFT3D.cpp`
|
||||
- [ ] TestCudaGBSAOBCForce - `openmm/platforms/cuda/tests/TestCudaGBSAOBCForce.cpp`
|
||||
- [ ] TestCudaGayBerneForce - `openmm/platforms/cuda/tests/TestCudaGayBerneForce.cpp`
|
||||
- [ ] TestCudaHarmonicAngleForce - `openmm/platforms/cuda/tests/TestCudaHarmonicAngleForce.cpp`
|
||||
- [ ] TestCudaHarmonicBondForce - `openmm/platforms/cuda/tests/TestCudaHarmonicBondForce.cpp`
|
||||
- [ ] TestCudaLangevinIntegrator - `openmm/platforms/cuda/tests/TestCudaLangevinIntegrator.cpp`
|
||||
- [ ] TestCudaLangevinMiddleIntegrator - `openmm/platforms/cuda/tests/TestCudaLangevinMiddleIntegrator.cpp`
|
||||
- [ ] TestCudaLocalEnergyMinimizer - `openmm/platforms/cuda/tests/TestCudaLocalEnergyMinimizer.cpp`
|
||||
- [ ] TestCudaMonteCarloAnisotropicBarostat - `openmm/platforms/cuda/tests/TestCudaMonteCarloAnisotropicBarostat.cpp`
|
||||
- [ ] TestCudaMonteCarloBarostat - `openmm/platforms/cuda/tests/TestCudaMonteCarloBarostat.cpp`
|
||||
- [ ] TestCudaMonteCarloFlexibleBarostat - `openmm/platforms/cuda/tests/TestCudaMonteCarloFlexibleBarostat.cpp`
|
||||
- [ ] TestCudaMultipleForces - `openmm/platforms/cuda/tests/TestCudaMultipleForces.cpp`
|
||||
- [ ] TestCudaNonbondedForce - `openmm/platforms/cuda/tests/TestCudaNonbondedForce.cpp`
|
||||
- [ ] TestCudaNoseHooverIntegrator - `openmm/platforms/cuda/tests/TestCudaNoseHooverIntegrator.cpp`
|
||||
- [ ] TestCudaPeriodicTorsionForce - `openmm/platforms/cuda/tests/TestCudaPeriodicTorsionForce.cpp`
|
||||
- [ ] TestCudaRBTorsionForce - `openmm/platforms/cuda/tests/TestCudaRBTorsionForce.cpp`
|
||||
- [ ] TestCudaRMSDForce - `openmm/platforms/cuda/tests/TestCudaRMSDForce.cpp`
|
||||
- [ ] TestCudaRandom - `openmm/platforms/cuda/tests/TestCudaRandom.cpp`
|
||||
- [ ] TestCudaSettle - `openmm/platforms/cuda/tests/TestCudaSettle.cpp`
|
||||
- [ ] TestCudaSort - `openmm/platforms/cuda/tests/TestCudaSort.cpp`
|
||||
- [ ] TestCudaVariableLangevinIntegrator - `openmm/platforms/cuda/tests/TestCudaVariableLangevinIntegrator.cpp`
|
||||
- [ ] TestCudaVariableVerletIntegrator - `openmm/platforms/cuda/tests/TestCudaVariableVerletIntegrator.cpp`
|
||||
- [ ] TestCudaVerletIntegrator - `openmm/platforms/cuda/tests/TestCudaVerletIntegrator.cpp`
|
||||
- [ ] TestCudaVirtualSites - `openmm/platforms/cuda/tests/TestCudaVirtualSites.cpp`
|
||||
- [ ] OpenCL
|
||||
- [ ] TestOpenCLATMForce - `openmm/platforms/opencl/tests/TestOpenCLATMForce.cpp`
|
||||
- [ ] TestOpenCLAndersenThermostat - `openmm/platforms/opencl/tests/TestOpenCLAndersenThermostat.cpp`
|
||||
- [ ] TestOpenCLBrownianIntegrator - `openmm/platforms/opencl/tests/TestOpenCLBrownianIntegrator.cpp`
|
||||
- [ ] TestOpenCLCMAPTorsionForce - `openmm/platforms/opencl/tests/TestOpenCLCMAPTorsionForce.cpp`
|
||||
- [ ] TestOpenCLCMMotionRemover - `openmm/platforms/opencl/tests/TestOpenCLCMMotionRemover.cpp`
|
||||
- [ ] TestOpenCLCheckpoints - `openmm/platforms/opencl/tests/TestOpenCLCheckpoints.cpp`
|
||||
- [ ] TestOpenCLCompoundIntegrator - `openmm/platforms/opencl/tests/TestOpenCLCompoundIntegrator.cpp`
|
||||
- [ ] TestOpenCLCustomAngleForce - `openmm/platforms/opencl/tests/TestOpenCLCustomAngleForce.cpp`
|
||||
- [ ] TestOpenCLCustomBondForce - `openmm/platforms/opencl/tests/TestOpenCLCustomBondForce.cpp`
|
||||
- [ ] TestOpenCLCustomCPPForce - `openmm/platforms/opencl/tests/TestOpenCLCustomCPPForce.cpp`
|
||||
- [ ] TestOpenCLCustomCVForce - `openmm/platforms/opencl/tests/TestOpenCLCustomCVForce.cpp`
|
||||
- [ ] TestOpenCLCustomCentroidBondForce - `openmm/platforms/opencl/tests/TestOpenCLCustomCentroidBondForce.cpp`
|
||||
- [ ] TestOpenCLCustomCompoundBondForce - `openmm/platforms/opencl/tests/TestOpenCLCustomCompoundBondForce.cpp`
|
||||
- [ ] TestOpenCLCustomExternalForce - `openmm/platforms/opencl/tests/TestOpenCLCustomExternalForce.cpp`
|
||||
- [ ] TestOpenCLCustomGBForce - `openmm/platforms/opencl/tests/TestOpenCLCustomGBForce.cpp`
|
||||
- [ ] TestOpenCLCustomHbondForce - `openmm/platforms/opencl/tests/TestOpenCLCustomHbondForce.cpp`
|
||||
- [ ] TestOpenCLCustomIntegrator - `openmm/platforms/opencl/tests/TestOpenCLCustomIntegrator.cpp`
|
||||
- [ ] TestOpenCLCustomManyParticleForce - `openmm/platforms/opencl/tests/TestOpenCLCustomManyParticleForce.cpp`
|
||||
- [ ] TestOpenCLCustomNonbondedForce - `openmm/platforms/opencl/tests/TestOpenCLCustomNonbondedForce.cpp`
|
||||
- [ ] TestOpenCLCustomTorsionForce - `openmm/platforms/opencl/tests/TestOpenCLCustomTorsionForce.cpp`
|
||||
- [ ] TestOpenCLDeviceQuery - `openmm/platforms/opencl/tests/TestOpenCLDeviceQuery.cpp`
|
||||
- [ ] TestOpenCLDispersionPME - `openmm/platforms/opencl/tests/TestOpenCLDispersionPME.cpp`
|
||||
- [ ] TestOpenCLEwald - `openmm/platforms/opencl/tests/TestOpenCLEwald.cpp`
|
||||
- [ ] TestOpenCLFFT - `openmm/platforms/opencl/tests/TestOpenCLFFT.cpp`
|
||||
- [ ] TestOpenCLGBSAOBCForce - `openmm/platforms/opencl/tests/TestOpenCLGBSAOBCForce.cpp`
|
||||
- [ ] TestOpenCLGayBerneForce - `openmm/platforms/opencl/tests/TestOpenCLGayBerneForce.cpp`
|
||||
- [ ] TestOpenCLHarmonicAngleForce - `openmm/platforms/opencl/tests/TestOpenCLHarmonicAngleForce.cpp`
|
||||
- [ ] TestOpenCLHarmonicBondForce - `openmm/platforms/opencl/tests/TestOpenCLHarmonicBondForce.cpp`
|
||||
- [ ] TestOpenCLLangevinIntegrator - `openmm/platforms/opencl/tests/TestOpenCLLangevinIntegrator.cpp`
|
||||
- [ ] TestOpenCLLangevinMiddleIntegrator - `openmm/platforms/opencl/tests/TestOpenCLLangevinMiddleIntegrator.cpp`
|
||||
- [ ] TestOpenCLLocalEnergyMinimizer - `openmm/platforms/opencl/tests/TestOpenCLLocalEnergyMinimizer.cpp`
|
||||
- [ ] TestOpenCLMonteCarloAnisotropicBarostat - `openmm/platforms/opencl/tests/TestOpenCLMonteCarloAnisotropicBarostat.cpp`
|
||||
- [ ] TestOpenCLMonteCarloBarostat - `openmm/platforms/opencl/tests/TestOpenCLMonteCarloBarostat.cpp`
|
||||
- [ ] TestOpenCLMonteCarloFlexibleBarostat - `openmm/platforms/opencl/tests/TestOpenCLMonteCarloFlexibleBarostat.cpp`
|
||||
- [ ] TestOpenCLMultipleForces - `openmm/platforms/opencl/tests/TestOpenCLMultipleForces.cpp`
|
||||
- [ ] TestOpenCLNonbondedForce - `openmm/platforms/opencl/tests/TestOpenCLNonbondedForce.cpp`
|
||||
- [ ] TestOpenCLNoseHooverIntegrator - `openmm/platforms/opencl/tests/TestOpenCLNoseHooverIntegrator.cpp`
|
||||
- [ ] TestOpenCLPeriodicTorsionForce - `openmm/platforms/opencl/tests/TestOpenCLPeriodicTorsionForce.cpp`
|
||||
- [ ] TestOpenCLRBTorsionForce - `openmm/platforms/opencl/tests/TestOpenCLRBTorsionForce.cpp`
|
||||
- [ ] TestOpenCLRMSDForce - `openmm/platforms/opencl/tests/TestOpenCLRMSDForce.cpp`
|
||||
- [ ] TestOpenCLRandom - `openmm/platforms/opencl/tests/TestOpenCLRandom.cpp`
|
||||
- [ ] TestOpenCLSettle - `openmm/platforms/opencl/tests/TestOpenCLSettle.cpp`
|
||||
- [ ] TestOpenCLSort - `openmm/platforms/opencl/tests/TestOpenCLSort.cpp`
|
||||
- [ ] TestOpenCLVariableLangevinIntegrator - `openmm/platforms/opencl/tests/TestOpenCLVariableLangevinIntegrator.cpp`
|
||||
- [ ] TestOpenCLVariableVerletIntegrator - `openmm/platforms/opencl/tests/TestOpenCLVariableVerletIntegrator.cpp`
|
||||
- [ ] TestOpenCLVerletIntegrator - `openmm/platforms/opencl/tests/TestOpenCLVerletIntegrator.cpp`
|
||||
- [ ] TestOpenCLVirtualSites - `openmm/platforms/opencl/tests/TestOpenCLVirtualSites.cpp`
|
||||
- [ ] Reference
|
||||
- [ ] TestReferenceATMForce - `openmm/platforms/reference/tests/TestReferenceATMForce.cpp`
|
||||
- [ ] TestReferenceAndersenThermostat - `openmm/platforms/reference/tests/TestReferenceAndersenThermostat.cpp`
|
||||
- [ ] TestReferenceBrownianIntegrator - `openmm/platforms/reference/tests/TestReferenceBrownianIntegrator.cpp`
|
||||
- [ ] TestReferenceCMAPTorsionForce - `openmm/platforms/reference/tests/TestReferenceCMAPTorsionForce.cpp`
|
||||
- [ ] TestReferenceCMMotionRemover - `openmm/platforms/reference/tests/TestReferenceCMMotionRemover.cpp`
|
||||
- [ ] TestReferenceCheckpoints - `openmm/platforms/reference/tests/TestReferenceCheckpoints.cpp`
|
||||
- [ ] TestReferenceCompoundIntegrator - `openmm/platforms/reference/tests/TestReferenceCompoundIntegrator.cpp`
|
||||
- [ ] TestReferenceCustomAngleForce - `openmm/platforms/reference/tests/TestReferenceCustomAngleForce.cpp`
|
||||
- [ ] TestReferenceCustomBondForce - `openmm/platforms/reference/tests/TestReferenceCustomBondForce.cpp`
|
||||
- [ ] TestReferenceCustomCPPForce - `openmm/platforms/reference/tests/TestReferenceCustomCPPForce.cpp`
|
||||
- [ ] TestReferenceCustomCVForce - `openmm/platforms/reference/tests/TestReferenceCustomCVForce.cpp`
|
||||
- [ ] TestReferenceCustomCentroidBondForce - `openmm/platforms/reference/tests/TestReferenceCustomCentroidBondForce.cpp`
|
||||
- [ ] TestReferenceCustomCompoundBondForce - `openmm/platforms/reference/tests/TestReferenceCustomCompoundBondForce.cpp`
|
||||
- [ ] TestReferenceCustomExternalForce - `openmm/platforms/reference/tests/TestReferenceCustomExternalForce.cpp`
|
||||
- [ ] TestReferenceCustomGBForce - `openmm/platforms/reference/tests/TestReferenceCustomGBForce.cpp`
|
||||
- [ ] TestReferenceCustomHbondForce - `openmm/platforms/reference/tests/TestReferenceCustomHbondForce.cpp`
|
||||
- [ ] TestReferenceCustomIntegrator - `openmm/platforms/reference/tests/TestReferenceCustomIntegrator.cpp`
|
||||
- [ ] TestReferenceCustomManyParticleForce - `openmm/platforms/reference/tests/TestReferenceCustomManyParticleForce.cpp`
|
||||
- [ ] TestReferenceCustomNonbondedForce - `openmm/platforms/reference/tests/TestReferenceCustomNonbondedForce.cpp`
|
||||
- [ ] TestReferenceCustomTorsionForce - `openmm/platforms/reference/tests/TestReferenceCustomTorsionForce.cpp`
|
||||
- [ ] TestReferenceDispersionPME - `openmm/platforms/reference/tests/TestReferenceDispersionPME.cpp`
|
||||
- [ ] TestReferenceEwald - `openmm/platforms/reference/tests/TestReferenceEwald.cpp`
|
||||
- [ ] TestReferenceGBSAOBCForce - `openmm/platforms/reference/tests/TestReferenceGBSAOBCForce.cpp`
|
||||
- [ ] TestReferenceGayBerneForce - `openmm/platforms/reference/tests/TestReferenceGayBerneForce.cpp`
|
||||
- [ ] TestReferenceHarmonicAngleForce - `openmm/platforms/reference/tests/TestReferenceHarmonicAngleForce.cpp`
|
||||
- [ ] TestReferenceHarmonicBondForce - `openmm/platforms/reference/tests/TestReferenceHarmonicBondForce.cpp`
|
||||
- [ ] TestReferenceKineticEnergy - `openmm/platforms/reference/tests/TestReferenceKineticEnergy.cpp`
|
||||
- [ ] TestReferenceLangevinIntegrator - `openmm/platforms/reference/tests/TestReferenceLangevinIntegrator.cpp`
|
||||
- [ ] TestReferenceLangevinMiddleIntegrator - `openmm/platforms/reference/tests/TestReferenceLangevinMiddleIntegrator.cpp`
|
||||
- [ ] TestReferenceLocalEnergyMinimizer - `openmm/platforms/reference/tests/TestReferenceLocalEnergyMinimizer.cpp`
|
||||
- [ ] TestReferenceMonteCarloAnisotropicBarostat - `openmm/platforms/reference/tests/TestReferenceMonteCarloAnisotropicBarostat.cpp`
|
||||
- [ ] TestReferenceMonteCarloBarostat - `openmm/platforms/reference/tests/TestReferenceMonteCarloBarostat.cpp`
|
||||
- [ ] TestReferenceMonteCarloFlexibleBarostat - `openmm/platforms/reference/tests/TestReferenceMonteCarloFlexibleBarostat.cpp`
|
||||
- [ ] TestReferenceMonteCarloMembraneBarostat - `openmm/platforms/reference/tests/TestReferenceMonteCarloMembraneBarostat.cpp`
|
||||
- [ ] TestReferenceNeighborList - `openmm/platforms/reference/tests/TestReferenceNeighborList.cpp`
|
||||
- [ ] TestReferenceNonbondedForce - `openmm/platforms/reference/tests/TestReferenceNonbondedForce.cpp`
|
||||
- [ ] TestReferenceNoseHooverIntegrator - `openmm/platforms/reference/tests/TestReferenceNoseHooverIntegrator.cpp`
|
||||
- [ ] TestReferencePeriodicTorsionForce - `openmm/platforms/reference/tests/TestReferencePeriodicTorsionForce.cpp`
|
||||
- [ ] TestReferenceRBTorsionForce - `openmm/platforms/reference/tests/TestReferenceRBTorsionForce.cpp`
|
||||
- [ ] TestReferenceRMSDForce - `openmm/platforms/reference/tests/TestReferenceRMSDForce.cpp`
|
||||
- [ ] TestReferenceRandom - `openmm/platforms/reference/tests/TestReferenceRandom.cpp`
|
||||
- [ ] TestReferenceSettle - `openmm/platforms/reference/tests/TestReferenceSettle.cpp`
|
||||
- [ ] TestReferenceVariableLangevinIntegrator - `openmm/platforms/reference/tests/TestReferenceVariableLangevinIntegrator.cpp`
|
||||
- [ ] TestReferenceVariableVerletIntegrator - `openmm/platforms/reference/tests/TestReferenceVariableVerletIntegrator.cpp`
|
||||
- [ ] TestReferenceVerletIntegrator - `openmm/platforms/reference/tests/TestReferenceVerletIntegrator.cpp`
|
||||
- [ ] TestReferenceVirtualSites - `openmm/platforms/reference/tests/TestReferenceVirtualSites.cpp`
|
||||
|
||||
- **Plugins**
|
||||
- [ ] CUDA
|
||||
- [ ] TestCudaAmoebaExtrapolatedPolarization - `openmm/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaExtrapolatedPolarization.cpp`
|
||||
- [ ] TestCudaAmoebaGeneralizedKirkwoodForce - `openmm/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaGeneralizedKirkwoodForce.cpp`
|
||||
- [ ] TestCudaAmoebaMultipoleForce - `openmm/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaMultipoleForce.cpp`
|
||||
- [ ] TestCudaAmoebaTorsionTorsionForce - `openmm/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaTorsionTorsionForce.cpp`
|
||||
- [ ] TestCudaAmoebaVdwForce - `openmm/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaVdwForce.cpp`
|
||||
- [ ] TestCudaHippoNonbondedForce - `openmm/plugins/amoeba/platforms/cuda/tests/TestCudaHippoNonbondedForce.cpp`
|
||||
- [ ] TestCudaWcaDispersionForce - `openmm/plugins/amoeba/platforms/cuda/tests/TestCudaWcaDispersionForce.cpp`
|
||||
- [ ] TestCudaDrudeForce - `openmm/plugins/drude/platforms/cuda/tests/TestCudaDrudeForce.cpp`
|
||||
- [ ] TestCudaDrudeLangevinIntegrator - `openmm/plugins/drude/platforms/cuda/tests/TestCudaDrudeLangevinIntegrator.cpp`
|
||||
- [ ] TestCudaDrudeNoseHoover - `openmm/plugins/drude/platforms/cuda/tests/TestCudaDrudeNoseHoover.cpp`
|
||||
- [ ] TestCudaDrudeSCFIntegrator - `openmm/plugins/drude/platforms/cuda/tests/TestCudaDrudeSCFIntegrator.cpp`
|
||||
- [ ] TestCudaRpmd - `openmm/plugins/rpmd/platforms/cuda/tests/TestCudaRpmd.cpp`
|
||||
- [ ] OpenCL
|
||||
- [ ] TestOpenCLAmoebaExtrapolatedPolarization - `openmm/plugins/amoeba/platforms/opencl/tests/TestOpenCLAmoebaExtrapolatedPolarization.cpp`
|
||||
- [ ] TestOpenCLAmoebaGeneralizedKirkwoodForce - `openmm/plugins/amoeba/platforms/opencl/tests/TestOpenCLAmoebaGeneralizedKirkwoodForce.cpp`
|
||||
- [ ] TestOpenCLAmoebaMultipoleForce - `openmm/plugins/amoeba/platforms/opencl/tests/TestOpenCLAmoebaMultipoleForce.cpp`
|
||||
- [ ] TestOpenCLAmoebaTorsionTorsionForce - `openmm/plugins/amoeba/platforms/opencl/tests/TestOpenCLAmoebaTorsionTorsionForce.cpp`
|
||||
- [ ] TestOpenCLAmoebaVdwForce - `openmm/plugins/amoeba/platforms/opencl/tests/TestOpenCLAmoebaVdwForce.cpp`
|
||||
- [ ] TestOpenCLHippoNonbondedForce - `openmm/plugins/amoeba/platforms/opencl/tests/TestOpenCLHippoNonbondedForce.cpp`
|
||||
- [ ] TestOpenCLWcaDispersionForce - `openmm/plugins/amoeba/platforms/opencl/tests/TestOpenCLWcaDispersionForce.cpp`
|
||||
- [ ] TestOpenCLDrudeForce - `openmm/plugins/drude/platforms/opencl/tests/TestOpenCLDrudeForce.cpp`
|
||||
- [ ] TestOpenCLDrudeLangevinIntegrator - `openmm/plugins/drude/platforms/opencl/tests/TestOpenCLDrudeLangevinIntegrator.cpp`
|
||||
- [ ] TestOpenCLDrudeNoseHoover - `openmm/plugins/drude/platforms/opencl/tests/TestOpenCLDrudeNoseHoover.cpp`
|
||||
- [ ] TestOpenCLDrudeSCFIntegrator - `openmm/plugins/drude/platforms/opencl/tests/TestOpenCLDrudeSCFIntegrator.cpp`
|
||||
- [ ] TestOpenCLRpmd - `openmm/plugins/rpmd/platforms/opencl/tests/TestOpenCLRpmd.cpp`
|
||||
- [ ] Reference
|
||||
- [ ] TestReferenceAmoebaExtrapolatedPolarization - `openmm/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaExtrapolatedPolarization.cpp`
|
||||
- [ ] TestReferenceAmoebaGeneralizedKirkwoodForce - `openmm/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaGeneralizedKirkwoodForce.cpp`
|
||||
- [ ] TestReferenceAmoebaMultipoleForce - `openmm/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp`
|
||||
- [ ] TestReferenceAmoebaTorsionTorsionForce - `openmm/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaTorsionTorsionForce.cpp`
|
||||
- [ ] TestReferenceAmoebaVdwForce - `openmm/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp`
|
||||
- [ ] TestReferenceHippoNonbondedForce - `openmm/plugins/amoeba/platforms/reference/tests/TestReferenceHippoNonbondedForce.cpp`
|
||||
- [ ] TestReferenceWcaDispersionForce - `openmm/plugins/amoeba/platforms/reference/tests/TestReferenceWcaDispersionForce.cpp`
|
||||
- [ ] TestReferenceDrudeForce - `openmm/plugins/drude/platforms/reference/tests/TestReferenceDrudeForce.cpp`
|
||||
- [ ] TestReferenceDrudeLangevinIntegrator - `openmm/plugins/drude/platforms/reference/tests/TestReferenceDrudeLangevinIntegrator.cpp`
|
||||
- [ ] TestReferenceDrudeNoseHoover - `openmm/plugins/drude/platforms/reference/tests/TestReferenceDrudeNoseHoover.cpp`
|
||||
- [ ] TestReferenceDrudeSCFIntegrator - `openmm/plugins/drude/platforms/reference/tests/TestReferenceDrudeSCFIntegrator.cpp`
|
||||
- [ ] TestReferenceRpmd - `openmm/plugins/rpmd/platforms/reference/tests/TestReferenceRpmd.cpp`
|
||||
- [ ] Serialization
|
||||
- [ ] TestSerializeAmoebaGeneralizedKirkwoodForce - `openmm/plugins/amoeba/serialization/tests/TestSerializeAmoebaGeneralizedKirkwoodForce.cpp`
|
||||
- [ ] TestSerializeAmoebaMultipoleForce - `openmm/plugins/amoeba/serialization/tests/TestSerializeAmoebaMultipoleForce.cpp`
|
||||
- [ ] TestSerializeAmoebaTorsionTorsionForce - `openmm/plugins/amoeba/serialization/tests/TestSerializeAmoebaTorsionTorsionForce.cpp`
|
||||
- [ ] TestSerializeAmoebaVdwForce - `openmm/plugins/amoeba/serialization/tests/TestSerializeAmoebaVdwForce.cpp`
|
||||
- [ ] TestSerializeAmoebaWcaDispersionForce - `openmm/plugins/amoeba/serialization/tests/TestSerializeAmoebaWcaDispersionForce.cpp`
|
||||
- [ ] TestSerializeHippoNonbondedForce - `openmm/plugins/amoeba/serialization/tests/TestSerializeHippoNonbondedForce.cpp`
|
||||
- [ ] TestSerializeDrudeForce - `openmm/plugins/drude/serialization/tests/TestSerializeDrudeForce.cpp`
|
||||
- [ ] TestSerializeDrudeLangevinIntegrator - `openmm/plugins/drude/serialization/tests/TestSerializeDrudeLangevinIntegrator.cpp`
|
||||
- [ ] TestSerializeDrudeNoseHooverIntegrator - `openmm/plugins/drude/serialization/tests/TestSerializeDrudeNoseHooverIntegrator.cpp`
|
||||
- [ ] TestAmoebaExtrapolatedPolarization - `openmm/plugins/amoeba/tests/TestAmoebaExtrapolatedPolarization.h`
|
||||
- [ ] TestAmoebaGeneralizedKirkwoodForce - `openmm/plugins/amoeba/tests/TestAmoebaGeneralizedKirkwoodForce.h`
|
||||
- [ ] TestAmoebaMultipoleForce - `openmm/plugins/amoeba/tests/TestAmoebaMultipoleForce.h`
|
||||
- [ ] TestAmoebaTorsionTorsionForce - `openmm/plugins/amoeba/tests/TestAmoebaTorsionTorsionForce.h`
|
||||
- [ ] TestAmoebaVdwForce - `openmm/plugins/amoeba/tests/TestAmoebaVdwForce.h`
|
||||
- [ ] TestHippoNonbondedForce - `openmm/plugins/amoeba/tests/TestHippoNonbondedForce.h`
|
||||
- [ ] TestWcaDispersionForce - `openmm/plugins/amoeba/tests/TestWcaDispersionForce.h`
|
||||
- [ ] TestCpuPme - `openmm/plugins/cpupme/tests/TestCpuPme.cpp`
|
||||
- [ ] TestDrudeForce - `openmm/plugins/drude/tests/TestDrudeForce.h`
|
||||
- [ ] TestDrudeLangevinIntegrator - `openmm/plugins/drude/tests/TestDrudeLangevinIntegrator.h`
|
||||
- [ ] TestDrudeNoseHoover - `openmm/plugins/drude/tests/TestDrudeNoseHoover.h`
|
||||
- [ ] TestDrudeSCFIntegrator - `openmm/plugins/drude/tests/TestDrudeSCFIntegrator.h`
|
||||
- [ ] TestRpmd - `openmm/plugins/rpmd/tests/TestRpmd.h`
|
||||
@@ -5,4 +5,13 @@ edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[features]
|
||||
default = ["cpu"]
|
||||
cpu = []
|
||||
vulkan = []
|
||||
cuda = []
|
||||
opencl = []
|
||||
|
||||
[dependencies]
|
||||
nalgebra = "0.33.2"
|
||||
approx = "0.5"
|
||||
|
||||
@@ -1,2 +1,20 @@
|
||||
use crate::integrator::Integrator;
|
||||
use crate::platform::Platform;
|
||||
use crate::state::{State, StateType};
|
||||
use crate::system::System;
|
||||
use nalgebra::Vector3;
|
||||
|
||||
pub trait Context {}
|
||||
pub struct Context {
|
||||
pub system: System,
|
||||
pub integrator: Box<dyn Integrator>,
|
||||
pub platform: Box<dyn Platform>,
|
||||
}
|
||||
impl Context {
|
||||
pub fn set_positions(&mut self, _positions: Vec<Vector3<f32>>) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn get_state(&self, _state_type: StateType) -> State {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
179
src/force/harmonic_angle_force.rs
Normal file
179
src/force/harmonic_angle_force.rs
Normal file
@@ -0,0 +1,179 @@
|
||||
use crate::context::Context;
|
||||
use crate::force::Force;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct HarmonicAngleForce {}
|
||||
impl HarmonicAngleForce {
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
|
||||
pub fn add_angle(
|
||||
&mut self,
|
||||
_particle1: usize,
|
||||
_particle2: usize,
|
||||
_particle3: usize,
|
||||
_angle: f64,
|
||||
_k: f64,
|
||||
) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn set_angle_parameters(
|
||||
&mut self,
|
||||
_angle_id: usize,
|
||||
_particle1: usize,
|
||||
_particle2: usize,
|
||||
_particle3: usize,
|
||||
_angle: f64,
|
||||
_k: f64,
|
||||
) {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Force for HarmonicAngleForce {
|
||||
fn update_parameters_in_context(&mut self, _context: &mut Context) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn set_periodic_boundary_conditions(&mut self, _status: bool) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn use_periodic_boundary_conditions(&self) -> bool {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HarmonicAngleForce {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::HarmonicAngleForce;
|
||||
use crate::context::Context;
|
||||
use crate::force::Force;
|
||||
use crate::integrator::VerletIntegrator;
|
||||
use crate::platform::CPU;
|
||||
use crate::state::StateType;
|
||||
use crate::system::System;
|
||||
use approx::assert_relative_eq;
|
||||
use nalgebra::Vector3;
|
||||
use std::f64::consts::PI;
|
||||
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_harmonic_angle_force() {
|
||||
let mut system = System::new();
|
||||
system.add_particle(1.0);
|
||||
system.add_particle(1.0);
|
||||
system.add_particle(1.0);
|
||||
system.add_particle(1.0);
|
||||
let integrator = VerletIntegrator { dt: 0.01 };
|
||||
|
||||
let mut forcefield = HarmonicAngleForce::new();
|
||||
forcefield.add_angle(0, 1, 2, PI / 3.0, 1.1);
|
||||
forcefield.add_angle(1, 2, 3, PI / 2.0, 1.2);
|
||||
|
||||
system.add_force(Box::new(forcefield.clone()));
|
||||
assert_eq!(forcefield.use_periodic_boundary_conditions(), false);
|
||||
assert_eq!(system.use_periodic_boundary_conditions(), false);
|
||||
|
||||
let mut context = Context {
|
||||
system,
|
||||
integrator: Box::new(integrator),
|
||||
platform: Box::new(CPU),
|
||||
};
|
||||
|
||||
let mut positions = vec![Vector3::zeros(); 4];
|
||||
positions[0] = Vector3::new(0.0, 2.0, 0.0);
|
||||
positions[1] = Vector3::new(0.0, 0.0, 0.0);
|
||||
positions[2] = Vector3::new(1.0, 0.0, 0.0);
|
||||
positions[3] = Vector3::new(2.0, 1.0, 0.0);
|
||||
|
||||
context.set_positions(positions);
|
||||
let state = context.get_state(StateType::Either);
|
||||
let forces = state.get_forces();
|
||||
let torque1 = 1.1 * PI / 6.0;
|
||||
let torque2 = 1.2 * PI / 4.0;
|
||||
assert_relative_eq!(forces[0], Vector3::new(torque1, 0.0, 0.0));
|
||||
assert_relative_eq!(forces[3], Vector3::new(-0.5 * torque2, 0.5 * torque2, 0.0));
|
||||
assert_relative_eq!(forces[1], -forces[0] - forces[2]);
|
||||
assert_relative_eq!(
|
||||
state.get_potential_energy(),
|
||||
0.5 * 1.1 * PI / 6.0 * PI / 6.0 + 0.5 * 1.2 * PI / 4.0 * PI / 4.0
|
||||
);
|
||||
|
||||
forcefield.set_angle_parameters(0, 0, 1, 2, PI / 3.1, 1.3);
|
||||
forcefield.set_angle_parameters(1, 1, 2, 3, PI / 2.1, 1.4);
|
||||
forcefield.update_parameters_in_context(&mut context);
|
||||
|
||||
let state = context.get_state(StateType::Either);
|
||||
let forces = state.get_forces();
|
||||
let dtheta1 = (PI / 2.0) - (PI / 3.1);
|
||||
let dtheta2 = (3.0 * PI / 4.0) - (PI / 2.1);
|
||||
let torque1 = 1.3 * dtheta1;
|
||||
let torque2 = 1.4 * dtheta2;
|
||||
assert_relative_eq!(forces[0], Vector3::new(torque1, 0.0, 0.0));
|
||||
assert_relative_eq!(forces[3], Vector3::new(-0.5 * torque2, 0.5 * torque2, 0.0));
|
||||
assert_relative_eq!(forces[1], -forces[0] - forces[2]);
|
||||
assert_relative_eq!(
|
||||
state.get_potential_energy(),
|
||||
0.5 * 1.3 * dtheta1 * dtheta1 + 0.5 * 1.4 * dtheta2 * dtheta2
|
||||
);
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_harmonic_angle_force_with_periodic_boundary_conditions() {
|
||||
let mut system = System {};
|
||||
system.add_particle(1.0);
|
||||
system.add_particle(1.0);
|
||||
system.add_particle(1.0);
|
||||
system.set_default_periodic_box_vectors(
|
||||
Vector3::new(3.0, 0.0, 0.0),
|
||||
Vector3::new(0.0, 1.5, 0.0),
|
||||
Vector3::new(0.0, 0.0, 3.0),
|
||||
);
|
||||
|
||||
let integrator = VerletIntegrator { dt: 0.01 };
|
||||
let mut forcefield = HarmonicAngleForce {};
|
||||
forcefield.add_angle(0, 1, 2, PI / 3.0, 1.1);
|
||||
forcefield.set_periodic_boundary_conditions(true);
|
||||
|
||||
system.add_force(Box::new(forcefield));
|
||||
|
||||
let mut context = Context {
|
||||
system,
|
||||
integrator: Box::new(integrator),
|
||||
platform: Box::new(CPU),
|
||||
};
|
||||
|
||||
let mut positions = vec![Vector3::zeros(); 3];
|
||||
positions[0] = Vector3::new(0.0, 1.0, 0.0);
|
||||
positions[1] = Vector3::new(0.0, 0.0, 0.0);
|
||||
positions[2] = Vector3::new(1.0, 0.0, 0.0);
|
||||
context.set_positions(positions);
|
||||
|
||||
let state = context.get_state(StateType::Either);
|
||||
let forces = state.get_forces();
|
||||
|
||||
let torque = 1.1 * PI / 6.0;
|
||||
assert_relative_eq!(forces[0], Vector3::new(2.0 * torque, 0.0, 0.0));
|
||||
assert_relative_eq!(forces[2], Vector3::new(0.0, -torque, 0.0));
|
||||
|
||||
let energy = state.get_potential_energy();
|
||||
assert_relative_eq!(energy, 0.5 * 1.1 * (PI / 6.0) * (PI / 6.0));
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_harmonic_angle_force_parallel_computation() {
|
||||
// TODO: Rust-OpenMM
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
151
src/force/harmonic_bond_force.rs
Normal file
151
src/force/harmonic_bond_force.rs
Normal file
@@ -0,0 +1,151 @@
|
||||
use crate::context::Context;
|
||||
use crate::force::Force;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct HarmonicBondForce {}
|
||||
impl HarmonicBondForce {
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
|
||||
pub fn add_bond(&mut self, _particle1: usize, _particle2: usize, _length: f64, _k: f64) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn set_bond_parameters(
|
||||
&mut self,
|
||||
_particle1: usize,
|
||||
_particle2: usize,
|
||||
_length: f64,
|
||||
_k: f64,
|
||||
) {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
impl Force for HarmonicBondForce {
|
||||
fn update_parameters_in_context(&mut self, _context: &mut Context) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn set_periodic_boundary_conditions(&mut self, _status: bool) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn use_periodic_boundary_conditions(&self) -> bool {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HarmonicBondForce {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::HarmonicBondForce;
|
||||
use crate::context::Context;
|
||||
use crate::force::Force;
|
||||
use crate::integrator::VerletIntegrator;
|
||||
use crate::platform::CPU;
|
||||
use crate::state::StateType;
|
||||
use crate::system::System;
|
||||
use approx::assert_relative_eq;
|
||||
use nalgebra::Vector3;
|
||||
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_harmonic_bond_force() {
|
||||
let mut system = System {};
|
||||
system.add_particle(1.0);
|
||||
system.add_particle(1.0);
|
||||
system.add_particle(1.0);
|
||||
let integrator = VerletIntegrator { dt: 0.01 };
|
||||
|
||||
let mut forcefield = HarmonicBondForce {};
|
||||
forcefield.add_bond(0, 1, 1.5, 0.8);
|
||||
forcefield.add_bond(1, 2, 1.2, 0.7);
|
||||
|
||||
system.add_force(Box::new(forcefield.clone()));
|
||||
|
||||
let mut context = Context {
|
||||
system,
|
||||
integrator: Box::new(integrator),
|
||||
platform: Box::new(CPU),
|
||||
};
|
||||
let mut positions = vec![Vector3::zeros(); 3];
|
||||
positions[0] = Vector3::new(0.0, 2.0, 0.0);
|
||||
positions[1] = Vector3::new(0.0, 0.0, 0.0);
|
||||
positions[2] = Vector3::new(1.0, 0.0, 0.0);
|
||||
context.set_positions(positions);
|
||||
|
||||
let state = context.get_state(StateType::Either);
|
||||
let forces = state.get_forces();
|
||||
assert_relative_eq!(forces[0], Vector3::new(0.0, -0.8 * 0.5, 0.0));
|
||||
assert_relative_eq!(forces[2], Vector3::new(0.7 * 0.2, 0.0, 0.0));
|
||||
assert_relative_eq!(forces[1], -forces[0] - forces[2]);
|
||||
|
||||
let energy = state.get_potential_energy();
|
||||
assert_relative_eq!(energy, 0.5 * 0.8 * 0.5 * 0.5 + 0.5 * 0.7 * 0.2 * 0.2);
|
||||
|
||||
forcefield.set_bond_parameters(0, 0, 1.6, 0.9);
|
||||
forcefield.set_bond_parameters(1, 1, 1.3, 0.8);
|
||||
forcefield.update_parameters_in_context(&mut context);
|
||||
|
||||
let state = context.get_state(StateType::Both);
|
||||
let forces = state.get_forces();
|
||||
assert_relative_eq!(forces[0], Vector3::new(0.0, -0.9 * 0.4, 0.0));
|
||||
assert_relative_eq!(forces[2], Vector3::new(0.8 * 0.3, 0.0, 0.0));
|
||||
assert_relative_eq!(forces[1], -forces[0] - forces[2]);
|
||||
|
||||
let energy = state.get_potential_energy();
|
||||
assert_relative_eq!(energy, 0.5 * 0.9 * 0.4 * 0.4 + 0.5 * 0.8 * 0.3 * 0.3);
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_harmonic_bond_force_with_periodic_boundary_conditions() {
|
||||
let mut system = System {};
|
||||
system.add_particle(1.0);
|
||||
system.add_particle(1.0);
|
||||
system.set_default_periodic_box_vectors(
|
||||
Vector3::new(3.0, 0.0, 0.0),
|
||||
Vector3::new(0.0, 3.0, 0.0),
|
||||
Vector3::new(0.0, 0.0, 3.0),
|
||||
);
|
||||
|
||||
let integrator = VerletIntegrator { dt: 0.01 };
|
||||
let mut forcefield = HarmonicBondForce {};
|
||||
forcefield.add_bond(0, 1, 1.2, 0.8);
|
||||
forcefield.set_periodic_boundary_conditions(true);
|
||||
|
||||
system.add_force(Box::new(forcefield));
|
||||
|
||||
let mut context = Context {
|
||||
system,
|
||||
integrator: Box::new(integrator),
|
||||
platform: Box::new(CPU),
|
||||
};
|
||||
|
||||
let mut positions = vec![Vector3::zeros(); 2];
|
||||
positions[0] = Vector3::new(0.0, 2.0, 0.0);
|
||||
positions[1] = Vector3::new(0.0, 0.0, 0.0);
|
||||
context.set_positions(positions);
|
||||
|
||||
let state = context.get_state(StateType::Both);
|
||||
let forces = state.get_forces();
|
||||
assert_relative_eq!(forces[0], Vector3::new(0.0, -0.8 * 0.2, 0.0));
|
||||
assert_relative_eq!(forces[1], Vector3::new(0.0, 0.8 * 0.2, 0.0));
|
||||
|
||||
let energy = state.get_potential_energy();
|
||||
assert_relative_eq!(energy, 0.5 * 0.8 * 0.2 * 0.2);
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_harmonic_bond_force_parallel_computation() {
|
||||
// TODO: Rust-OpenMM
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
15
src/force/mod.rs
Normal file
15
src/force/mod.rs
Normal file
@@ -0,0 +1,15 @@
|
||||
use std::fmt::Debug;
|
||||
|
||||
use crate::context::Context;
|
||||
|
||||
pub trait Force: Debug {
|
||||
fn update_parameters_in_context(&mut self, context: &mut Context);
|
||||
fn set_periodic_boundary_conditions(&mut self, status: bool);
|
||||
fn use_periodic_boundary_conditions(&self) -> bool;
|
||||
}
|
||||
|
||||
pub mod harmonic_angle_force;
|
||||
pub use harmonic_angle_force::HarmonicAngleForce;
|
||||
|
||||
pub mod harmonic_bond_force;
|
||||
pub use harmonic_bond_force::HarmonicBondForce;
|
||||
6
src/integrator/mod.rs
Normal file
6
src/integrator/mod.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
pub trait Integrator {}
|
||||
|
||||
pub struct VerletIntegrator {
|
||||
pub dt: f64,
|
||||
}
|
||||
impl Integrator for VerletIntegrator {}
|
||||
@@ -1,7 +1,8 @@
|
||||
|
||||
|
||||
|
||||
pub mod system;
|
||||
pub mod context;
|
||||
pub mod force;
|
||||
pub mod platform;
|
||||
pub mod state;
|
||||
pub mod system;
|
||||
|
||||
pub mod integrator;
|
||||
pub mod virtual_site;
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
|
||||
pub trait Platform {}
|
||||
7
src/platform/mod.rs
Normal file
7
src/platform/mod.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
pub trait Platform {}
|
||||
|
||||
pub struct CPU;
|
||||
pub struct OpenCL;
|
||||
|
||||
impl Platform for CPU {}
|
||||
impl Platform for OpenCL {}
|
||||
23
src/state.rs
23
src/state.rs
@@ -1,3 +1,24 @@
|
||||
use nalgebra::Vector3;
|
||||
|
||||
pub enum StateType {
|
||||
Both,
|
||||
Either,
|
||||
Forces,
|
||||
Energy,
|
||||
}
|
||||
|
||||
pub trait State {}
|
||||
pub struct State {
|
||||
pub state_type: StateType,
|
||||
pub forces: Vec<Vector3<f64>>,
|
||||
pub energy: f64,
|
||||
}
|
||||
|
||||
impl State {
|
||||
pub fn get_forces(&self) -> &Vec<Vector3<f64>> {
|
||||
&self.forces
|
||||
}
|
||||
|
||||
pub fn get_potential_energy(&self) -> f64 {
|
||||
self.energy
|
||||
}
|
||||
}
|
||||
|
||||
210
src/system.rs
210
src/system.rs
@@ -1,3 +1,211 @@
|
||||
use crate::force::Force;
|
||||
use crate::virtual_site::VirtualSite;
|
||||
use nalgebra::Vector3;
|
||||
pub struct System {}
|
||||
impl System {
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
|
||||
pub fn add_particle(&mut self, _mass: f32) {
|
||||
// Todo: Rust-OpenMM
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub trait System {}
|
||||
pub fn get_num_particles(&self) -> usize {
|
||||
// Todo: Rust-OpenMM
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn get_particle_mass(&self, _index: usize) -> f32 {
|
||||
// Todo: Rust-OpenMM
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn set_particle_mass(&mut self, _index: usize, _mass: f32) {
|
||||
// Todo: Rust-OpenMM
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn is_virtual_site(&self, _index: usize) -> bool {
|
||||
// Todo: Rust-OpenMM
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn get_virtual_site(&self, _index: usize) -> Option<Box<dyn VirtualSite>> {
|
||||
// Todo: Rust-OpenMM
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn set_virtual_site(&mut self, _index: usize, _vsite: Option<Box<dyn VirtualSite>>) {
|
||||
// Todo: Rust-OpenMM
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn add_constraint(&mut self, _p1: usize, _p2: usize, _dist: f32) {
|
||||
// Todo: Rust-OpenMM
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn remove_constraint(&mut self, _index: usize) {
|
||||
// Todo: Rust-OpenMM
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn get_num_constraints(&self) -> usize {
|
||||
// Todo: Rust-OpenMM
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn get_constraint_parameters(&self, _index: usize) -> (usize, usize, f32) {
|
||||
// Todo: Rust-OpenMM
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn set_constraint_parameters(&mut self, _index: usize, _p1: usize, _p2: usize, _dist: f32) {
|
||||
// Todo: Rust-OpenMM
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn add_force(&mut self, _force: Box<dyn Force>) {
|
||||
// Todo: Rust-OpenMM
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn remove_force(&mut self, _index: usize) {
|
||||
// Todo: Rust-OpenMM
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn get_num_forces(&self) -> usize {
|
||||
// Todo: Rust-OpenMM
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn get_force(&self, _index: usize) -> Box<dyn Force> {
|
||||
// Todo: Rust-OpenMM
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn set_default_periodic_box_vectors(
|
||||
&mut self,
|
||||
_a: Vector3<f32>,
|
||||
_b: Vector3<f32>,
|
||||
_c: Vector3<f32>,
|
||||
) {
|
||||
// Todo: Rust-OpenMM
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn use_periodic_boundary_conditions(&self) -> bool {
|
||||
// Todo: Rust-OpenMM
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for System {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::force::{HarmonicAngleForce, HarmonicBondForce};
|
||||
use crate::system::System;
|
||||
use crate::virtual_site::TwoParticleAverageSite;
|
||||
|
||||
// Todo: Rust-OpenMM
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_system_particles() {
|
||||
let num_particles = 10;
|
||||
let mut system = System {};
|
||||
|
||||
for i in 0..num_particles {
|
||||
system.add_particle(1.0 + 0.1 * i as f32);
|
||||
}
|
||||
system.set_particle_mass(5, 100.0);
|
||||
assert_eq!(system.get_num_particles(), num_particles);
|
||||
|
||||
for i in 0..num_particles {
|
||||
let expected_mass = if i == 5 { 100.0 } else { 1.0 + 0.1 * i as f32 };
|
||||
assert_eq!(system.get_particle_mass(i), expected_mass);
|
||||
}
|
||||
}
|
||||
|
||||
// Todo: Rust-OpenMM
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_system_constraints() {
|
||||
let num_particles = 10;
|
||||
let mut system = System {};
|
||||
|
||||
for i in 0..num_particles - 1 {
|
||||
system.add_constraint(i, i + 1, 0.2 * i as f32);
|
||||
}
|
||||
system.remove_constraint(5);
|
||||
system.set_constraint_parameters(3, 0, 5, 99.0);
|
||||
assert_eq!(system.get_num_constraints(), num_particles - 2);
|
||||
|
||||
for i in 0..num_particles - 2 {
|
||||
let (p1, p2, dist) = system.get_constraint_parameters(i);
|
||||
if i == 3 {
|
||||
assert_eq!(p1, 0);
|
||||
assert_eq!(p2, 5);
|
||||
assert_eq!(dist, 99.0);
|
||||
} else {
|
||||
let j = if i < 5 { i } else { i + 1 };
|
||||
assert_eq!(p1, j);
|
||||
assert_eq!(p2, j + 1);
|
||||
assert_eq!(dist, 0.2 * j as f32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Todo: Rust-OpenMM
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_system_force() {
|
||||
let mut system = System {};
|
||||
let bonds = HarmonicBondForce {};
|
||||
system.add_force(Box::new(bonds));
|
||||
|
||||
let angles = HarmonicAngleForce {};
|
||||
system.add_force(Box::new(angles));
|
||||
|
||||
assert_eq!(system.get_num_forces(), 2);
|
||||
// Todo: Rust-OpenMM
|
||||
// assert_eq!(system.get_force(0), Box::new(bonds));
|
||||
// assert_eq!(system.get_force(1), Box::new(angles));
|
||||
|
||||
system.remove_force(0);
|
||||
assert_eq!(system.get_num_forces(), 1);
|
||||
// Todo: Rust-OpenMM
|
||||
// assert_eq!(system.get_force(0), Box::new(angles));
|
||||
}
|
||||
|
||||
// Todo: Rust-OpenMM
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_system_virtual_site() {
|
||||
let mut system = System {};
|
||||
let num_particles = 10;
|
||||
for i in 0..num_particles {
|
||||
system.add_particle(1.0);
|
||||
assert!(!system.is_virtual_site(i));
|
||||
}
|
||||
|
||||
let vsite = TwoParticleAverageSite::new(2, 3, 0.4, 0.6);
|
||||
system.set_virtual_site(4, Some(Box::new(vsite)));
|
||||
for i in 0..num_particles {
|
||||
assert_eq!(system.is_virtual_site(i), i == 4);
|
||||
}
|
||||
// Todo: Rust-OpenMM
|
||||
// assert_eq!(system.get_virtual_site(4), Some(Box::new(vsite)));
|
||||
system.set_virtual_site(4, None);
|
||||
for i in 0..num_particles {
|
||||
assert!(!system.is_virtual_site(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
17
src/virtual_site.rs
Normal file
17
src/virtual_site.rs
Normal file
@@ -0,0 +1,17 @@
|
||||
use std::fmt::Debug;
|
||||
|
||||
pub trait VirtualSite: Debug {}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct TwoParticleAverageSite {
|
||||
pub p1: usize,
|
||||
pub p2: usize,
|
||||
pub weight1: f32,
|
||||
pub weight2: f32,
|
||||
}
|
||||
impl TwoParticleAverageSite {
|
||||
pub fn new(_p1: usize, _p2: usize, _weight1: f32, _weight2: f32) -> Self {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
impl VirtualSite for TwoParticleAverageSite {}
|
||||
Reference in New Issue
Block a user