-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multipoles #133
base: master
Are you sure you want to change the base?
Multipoles #133
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
from enum import Enum | ||
from typing import Dict, List, Optional | ||
|
||
from pydantic import Schema, constr, validator | ||
|
||
from .basemodels import ProtoModel | ||
from .types import Array | ||
|
||
|
||
class Singlepole(ProtoModel): | ||
"""Model for charges, dipoles, or quadrupoles, etc.""" | ||
|
||
angular_momentum: int = Schema(..., description="Angular momentum for this singlepole.") | ||
exponents: List[float] = Schema(..., description="Exponents for this singlepole.") | ||
geometry: Array[float] = Schema(..., description="Location of the singlepoles.") | ||
coefficients: List[List[float]] = Schema(..., description="Coefficients for each AM component. Psi4 AM ordering convention: https://github.com/evaleev/libint/blob/5458ab2fb2fd51dcd19f1e8122a451f2a0808074/doc/progman/progman.tex#L1006-L1008") | ||
|
||
@validator('geometry') | ||
def _must_be_3n(cls, v, values, **kwargs): | ||
npts = len(values['exponents']) | ||
try: | ||
v = v.reshape(npts, 3) | ||
except (ValueError, AttributeError): | ||
raise ValueError("Geometry must be castable to shape (N,3)!") | ||
return v | ||
|
||
@validator('angular_momentum') | ||
def _must_be_am(cls, v, values, **kwargs): | ||
if v < 0: | ||
raise ValueError(f"Positive, please: {v}") | ||
|
||
return v | ||
|
||
@validator('coefficients', whole=True) | ||
def _must_be_nover3_by_am(cls, v, values, **kwargs): | ||
npts = len(values['exponents']) | ||
am = values['angular_momentum'] | ||
ncoeff = (am + 1) * (am + 2) / 2 | ||
if len(v) != npts: | ||
raise ValueError(f"The length of coefficients does not match number of points. {len(values['coefficients'])} != {npts}") | ||
for ipts in v: | ||
if len(ipts) != ncoeff: | ||
raise ValueError(f"The length of coefficients AM does not match the AM. {len(ipts)} != {coeff}") | ||
|
||
return v | ||
|
||
|
||
class Multipoles(ProtoModel): | ||
|
||
poles: List[Singlepole] = [] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The idea being here that we would have a point charge @andysim do you anticipate the centers to overlap between charges/dipoles/etc? In general, what order of magnitude range do we expect in the number of these elements? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes on your first question. Probably Multipoles gets the fancy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the CCA standard, we should probably avoid Psi4 in schema objects.
Is there such a thing as spherical vs cartesian multipoles?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, we'll fix that up. first memory was Rob notes but actually found at Libint notes.
Andy says most everyone works in Cartesians internally, though he has some spherical stuff. And everyone works in Cartesians externally (this case). Plus, easy to reverse on (at least here and in the Psi4 connection).