Skip to content

Automate elastic_constants by AD-DFPT as a postprocessing#1172

Merged
mfherbst merged 18 commits intomasterfrom
elastic-postprocess
Apr 20, 2026
Merged

Automate elastic_constants by AD-DFPT as a postprocessing#1172
mfherbst merged 18 commits intomasterfrom
elastic-postprocess

Conversation

@niklasschmitz
Copy link
Copy Markdown
Collaborator

@niklasschmitz niklasschmitz commented Oct 15, 2025

Following up on the ideas at #1162.

This PR aims to automate the clamped-ion elastic constants as a convenient postprocessing function elastic_constants(scfres) for 1) the generic case of not using symmetry (most expensive, 6xDFPT on a fully unfolded kgrid...), 2.1) the most common case of cubic crystals (least expensive, 1xDFPT on a partially unfolded kgrid). Optimizations for other the point groups could be implemented later following a similar pattern.

progress:

Comment thread test/elastic.jl Outdated
Comment thread test/elastic.jl Outdated
Comment thread src/postprocess/elastic.jl Outdated
Comment thread src/postprocess/elastic.jl Outdated
Comment thread src/postprocess/elastic.jl Outdated
@mfherbst mfherbst mentioned this pull request Jan 8, 2026
@niklasschmitz niklasschmitz marked this pull request as ready for review February 5, 2026 20:17
Comment thread src/postprocess/elastic.jl Outdated
@mfherbst
Copy link
Copy Markdown
Member

Something that bothers me as well is that it's basically impossible to send any kind of parameters to the DFPT solver in your implementation. There is the ResponseOptions for this purpose. Maybe just taking one as a keyword argument from the elastic constant wrapper function would be simple solution ?

@mfherbst
Copy link
Copy Markdown
Member

Also in

strained_lattice = DFTK.voigt_strain_to_full(0.01 * strain_pattern) * model0.lattice

The displacement 0.01 should depend on the SYMMETRY_TOLERANCE

@niklasschmitz
Copy link
Copy Markdown
Collaborator Author

Something that bothers me as well is that it's basically impossible to send any kind of parameters to the DFPT solver in your implementation. There is the ResponseOptions for this purpose. Maybe just taking one as a keyword argument from the elastic constant wrapper function would be simple solution ?

Agreed. I now added the more general solution to pass arbitrary kwargs_scf... to elastic_tensor.

The displacement 0.01 should depend on the SYMMETRY_TOLERANCE

Makese sense. I added tol_symmetry as keyword argument and displace by 100 * tol_symmetry (the 1e-5 default SYMMETRY_TOLERANCE gets 1e-3 strain).

Comment thread examples/elastic_constants.jl Outdated
Comment thread examples/elastic_constants.jl Outdated
Comment thread src/postprocess/elastic.jl Outdated
Comment thread src/postprocess/elastic.jl Outdated
Comment thread src/postprocess/elastic.jl Outdated
@mfherbst mfherbst enabled auto-merge (squash) April 19, 2026 19:57
@mfherbst mfherbst merged commit 421de8f into master Apr 20, 2026
10 checks passed
@mfherbst mfherbst deleted the elastic-postprocess branch April 20, 2026 09:46
Comment thread src/input_output.jl
Comment on lines 370 to +377
if hasproperty(scfres, :mixing)
dict["mixing"] = string(scfres.mixing)
end
for sym in (:is_converged, :nbandsalg, :fermialg, :diagtolalg, :solver, :eigensolver)
if hasproperty(scfres, sym)
dict[string(sym)] = string(getproperty(scfres, sym))
end
end
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is code duplication and I'm not sure if the strings you get out of solver and eigensolver are very useful. E.g. eigensolver could just be a large bunch of numbers (which could blow up the size of the json). Have you checked that ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

It seems to work fine for the function arguments, it just prints the name. On examples/silicon.jl it looks like this:

julia> dict = Dict()
Dict{Any, Any}()

julia> for sym in (:is_converged, :nbandsalg, :fermialg, :diagtolalg, :solver, :eigensolver)
     if hasproperty(scfres, sym)
         dict[string(sym)] = string(getproperty(scfres, sym))
     end
 end

julia> dict
Dict{Any, Any} with 6 entries:
  "nbandsalg"    => "AdaptiveBands(4, 7, 1.0e-6, 0.01)"
  "eigensolver"  => "lobpcg_hyper"
  "is_converged" => "ScfConvergenceDensity(1.0e-8)"
  "diagtolalg"   => "AdaptiveDiagtol(0.2, nothing, 0.005, 0.03)"
  "solver"       => "anderson"
  "fermialg"     => "FermiTwoStage()"

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.

2 participants