Skip to content
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

Lattice Optimization #8

Open
wants to merge 29 commits into
base: main
Choose a base branch
from

Conversation

CedricTravelletti
Copy link
Contributor

This PR implements lattice optimization, following the ASE implementation.

Comment on lines 5 to 16
using DFTK
export minimize_energy!


function update_state(original_system, new_system, state)
if bounding_box(original_system) != bounding_box(new_system)
return DFTK.DFTKState()
else
return state
end
end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is there DFTK-specific stuff in here, that should not be the case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see you did this because there is no generic way to do this right now. This is a flaw in AtomsCalculators and something we should change.

My suggestion for what to do would be the following. In AtomsCalculators you introduce a calculator_state(calculator) function, which returns a state object and a method update_state(algorithm, state, original_system, new_system), which does some magic to update the state. We supply two fallbacks

struct DummyState end
calculator_state(::AbstractCalculator) = DummyState()
update_state(::Any, ::DummyState, ::Any, ::Any) = DummyState()

in AtomsCalculators. In this way there is zero additional implementation cost for people who don't want to by into this, but for DFT methods it helps.

In DFTK we then add the code you put here with

function update_state(algorithm, state::DFTKState, original_system, new_system)
    if bounding_box(original_system) != bounding_box(new_system)
        DFTK.DFTKState()
    else
        state
    end
end

and additionally

calculator_state(calc::DFTKCalculator) = calc.state

The rest I guess is clear: In here you just use calculator_state instead of accessing calc.state directly to make sure the dummy stuff works as well.

Note that I added additionally an algorithm argument, which you should expose to minimize_energy!. In this way the interpolation algorithm can be easily swapped.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Added PR to DFTK and AtomsCalculators implementing the changes.

new_system = update_not_clamped_positions(system, x * u"bohr")
energy = AtomsCalculators.potential_energy(new_system, calculator; kwargs...)
state = update_state(system, new_system, calculator.state)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need a function to extract the state from the calcuator. Not all calculators may have state in which case the returned state would just be a dummy.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I think I would use a marker struct on the update_state, which simplifies later to provide different "update algorithms". We can discuss offline what I have in mind here.

OptimizationFunction(f; grad=g!)
end

function minimize_energy!(system, calculator; solver=Optim.LBFGS(), kwargs...)
function minimize_energy!(system, calculator; pressure=0.0, procedure="relax",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't do this procedure thing. Think about the separation of "what" and "how". The procedure selects the "how", so it should be a type 😄.

On a practical level this means you should use a marker struct. By the way if you use marker structs, then you can also use these to automatically adapt your definition of f and g! in the above lines of code depending on the marker structs. This makes it super easy to later try other parametrisations or introduce more complicated claming techniques etc.

src/strain.jl Outdated Show resolved Hide resolved
src/strain.jl Outdated Show resolved Hide resolved
src/strain.jl Outdated
reduce(hcat, bbox)
end

# TODO: deprecate.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

???

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now removed.

@cortner
Copy link
Member

cortner commented May 21, 2024

what is the situation here? I was about to write an alternative geometry optimization wrapper porting the JuLIP implementation. But if this is ready or close to ready, then I will hold off.

Copy link
Member

@cortner cortner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, I meant to just leave a single comment. Just let me know in the conversation if this is on track or you need help or I should do something separate to meet my current requirements.

@@ -0,0 +1,31 @@

function voigt_to_full(v)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you are messing with the types here, and also below in full_to_voigt.

julia> function full_to_voigt(A)
           [A[1, 1], A[2, 2], A[3, 3], 2. * A[2, 3], 2. * A[1, 3], 2. * A[1, 2]]
       end
full_to_voigt (generic function with 1 method)

julia> 

julia> A = rand(Float32, 3,3)
3×3 Matrix{Float32}:
 0.934422  0.399876  0.339769
 0.241855  0.856102  0.199015
 0.573214  0.554009  0.683092

julia> full_to_voigt(A)
6-element Vector{Float64}:
 0.9344218969345093
 0.8561021089553833
 0.6830916404724121
 0.39803004264831543
 0.6795381307601929
 0.7997522354125977

@mfherbst
Copy link
Member

@CedricTravelletti Correct me if I'm wrong, but I believe the current state is that this is stalled until the Lux model state PR goes in (which should hopefully be very soon).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants