Skip to content

pair_e3gnn.cpp should use pair-wise force. #298

@YutackPark

Description

@YutackPark

현재 해당 cpp 파일은 레거시로 인해 pair-wise force 가 아니라, atom-wise force 로 미분하는 방법을 쓰고 있음.

이 방법은 stress, atomic_stress 와 compatible 하지 않음. (왜냐하면 virial 구할 때 pair_wise force 정보가 필요한데 다 날아가니까). Stress 의 경우 (이것도 레거시 때문에) strain tensor 를 추가해서 구하는 bypass 로 동작 중.

이번에 atomic_stress 나오면서 문제가 다시 터져서 #297 , 해당 PR 에서 atom-wise force 를 쓰도록 강제하는 deploy.py 코드를 수정하고, pair_e3gnn.cpp 도 edge force 를 쓰도록 바꿔야함. cpp 에서 (해당 방법 구현 자체는 이미 pair_e3gnn_parallel.cpp 에 되어있음, pair_e3gnn_parallel.cpp 는 autograd 자체를 pytorch 에서 안함. 그래서 cpp 에서 중간에 edge force byproduct 를 자연스럽게 얻을 수 있음.)

    grad_module = ForceStressOutput()
    model.replace_module('force_output', grad_module)
    new_grad_key = grad_module.get_grad_key()
    model.key_grad = new_grad_key

https://github.com/MDIL-SNU/SevenNet/blob/main/sevenn/nn/force_output.py
pair_e3gnn.cpp가 위 모듈의 ForceStressOutput 으로 deploy.py 가 replace 하는 걸, ForceStressOutputFromEdge 모듈을 consistent 하게 쓰도록 (python 부분은 이미 해당 모듈을 쓰도록 되어있음) 수정하면 됨. Atomc stress 도 해당 ForceStressOutputFromEdge 모듈에 flag 를 추가해서 구하도록 #297 의 contributor 에게 얘기함.

이 때, pair_force 를 주면 사실 나머지 (virial) 은 램스의 fdotr 이 똑같은 연산을 해주기 때문에, 옵션이 두 가지임.

  1. pytorch의 force_output.py 에 있는 모듈을 그대로 사용하고, 값을 .cpp 에서 assign 해준다 (기존방법). 이 경우, fdotr 이 뭔가 난리치지 않도록, atomic stress 에서는 해당 부분 꺼줘야 한다고 함 (Add atomic_virial option #297 이 PR 의 _stress.cpp 참조)

  2. force_output.py 의 모듈을 deploy 할때 지워버리고, autograd 를 직접 lammps 에서 call 한다. r_ij 로 energy 를 미분. 그리고 F_ij 를 램스에게 넘겨주고, virial 계산은 램스에게 맡긴다. (pair_e3gnn_parallel.cpp 이 하는 방법)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions