Skip to content

Implemented disorder in the DCA Loop using the CT-AUX solver - #365

Open
anirudha-mirmira wants to merge 45 commits into
CompFUSE:masterfrom
anirudha-mirmira:master
Open

Implemented disorder in the DCA Loop using the CT-AUX solver#365
anirudha-mirmira wants to merge 45 commits into
CompFUSE:masterfrom
anirudha-mirmira:master

Conversation

@anirudha-mirmira

@anirudha-mirmira anirudha-mirmira commented Jun 16, 2026

Copy link
Copy Markdown

Summary

Support DCA calculations for systems with static on-site disorder. The crux of the implementation is the idea that the addition of disorder configurations breaks the translational symmetry and requires the cluster problem to be solved with two real space indices (for the 2D case) instead of a single displacement index. The disorder averaging, which is carried out analogously to the CPA, restores translational symmetry, thereby allowing for the solution of the cluster problem with a single displacement and subsequently a single momentum index.

The flow proceeds as follows: Subsequent to the calculation of the cluster excluded G0(d), the real space indices are unfolded to get G0(r1,r2), the disorder configurations (box or binary) are added. This disordered_G0(r1,r2) is the bare line the walkers uses to walk the chains, followed by an two index M(r1,r2) accumulation. The resulting interacting G(r1,r2) is disorder averaged, folded back into a single displacement index G(d), transformed to G(k) and fed into the cluster finalization step.

CMake Options

The new code has an associated -DDCA_WITH_DISORDER=ON gate, which defines DISORDERED_G0 flag. The disorder parts are separated with #ifdef DISORDERED_G0 conditionals. The -DDCA_WITH_DISORDER=OFF flag results is identical to the clean code except in the places as noted below

Main differences from the DCA++ main branch

These are the changes to existing, shared code paths:

  • g0_interpolation now uses the two r-index signature G0(r1, r2) in both the clean and
    disordered cases.
    : The clean code calculated a single index as subtract(r2,r1) in the g0_interpolation routines, which is now calculated after inputting both the indices separately;

  • Fixed a latent divide-by-sign bug in local_G_k_w (used by computeErrorBars) in
    both branches: the get_accumulated_sign was used where the scalar accumulated
    get_accumulated_phase was intended (missed by the Feb-2023 Phase refactor).

  • CMake files where a new CMake option DCA_WITH_DISORDER (OFF by default) defining DISORDERED_G0, plus a
    new DisorderParameters block (with MPI broadcast) and disorder-related parameter wiring.

Features

  • Generates disorder configuration (equally weighted) using random numbers picked from a binary or box distribution. Additionally, in the binary case, a unique-configs: true parameter allows for the generation of strictly unique configurations
  • The disorder generation works even in the MPI case with a broadcasted seed, which ensures each rank solves the QMC for an identically disordered ensemble.
  • Error bars and stat tests: The disordered case generates a disorder averaged (translationally invariant) G_k_w and S_k_w per rank allowing calculation of error bars and statistical testing
  • Input handling: A missing disorder block in the input is handled elegantly with fallback to the clean limit calculation. Improperly configured num-configurations: 0 is handled with a warning and calculation with a single configuration

Example disorder block in input

Disorder is configured by adding a disorder block to the run's JSON input. The presence of
the block is what enables the disorder flow; omit it for a clean run.

"disorder": {
  "distribution": "binary",
  "potential": 0.1,
  "density": 0.5,
  "num-configurations": 4,
  "unique-configs": false
}
  • distribution - "binary" or "box" (any other value is a hard error).
  • potential - disorder strength: V for binary (levels ±V/2), or the full box width W.
  • density - fraction of sites at +V/2 for the binary distribution (ignored by box). For values away from 0.5, adjust-chemical-potential in the physics block should be false to prevent chemical potential adjustment from undoing the effect of the shifted average potential.
  • num-configurations - number of disorder realizations in the ensemble (equal weights).
  • unique-configs - if true, enforce distinct binary realizations (no-op for box).

Tests

Added and tested disorder tests gated on DCA_WITH_DISORDER AND NOT DCA_WITH_CUDA AND NOT DCA_WITH_HIP, which test the following:

  • parameter parsing
  • walker-reads-correct-G0
  • accumulation and orientation of the r1,r2 unfolding
  • full disorder loop
  • two statistical tests (U=4 V=0 vs. clean ED reference; box+binary ensemble at V=0.1 - sanity checks).

Limitations

  • CPU only. A DCA_WITH_DISORDER + CUDA/HIP configuration is a deliberate hard CMake error: the GPU version is not implemented. The common G0_interpolation in the GPU case has the original signature and the two index version is not implemented.
  • Single particle quantities only - G4 averaging and two index handling is not implemented in the disorder path
  • Static, site-local, spin-symmetric disorder only - The potential enters as a frequency-independent term applied identically to both spins. Bond/off-diagonal, frequency-dependent, and spin-dependent (magnetic) disorder are not supported.
  • Two distributions only - Only binary and box are accepted; any other distribution
    value is a hard error.
  • Optimization after profiling, etc. has not been carried out in the case of disorder

PDoakORNL and others added 30 commits May 26, 2026 16:56
add data member to dca_loop data, should still be more
discovered much wider access to dca_data g0_r_t than expected
…ed quantities and added another TWO_K_DISORDER flag for the WIP involving k1,k2
…at the code runs. Concurrency barriers for prettier printing of disorder output
… disorder averaging procedure. Also wrote a test for the edited accumulation
anirudha-mirmira and others added 15 commits June 5, 2026 14:36
…m cluster GF and added a dummy disorder block.
…(replaced earlier code) and dumping of disorder configurations. Wired new disorder config generation to the dca_loop.
…iagonal short-circuits, implemented compatible local_G_k_w
… calculated as FT from w rather than the erroneous inversion, tail from clean G0_cl_exl; MAJOR CHANGE: g0_interpolation now uses the two r-index signatures even in clean case. Cleanup and a walker unit test added
…ed with the CMake option -DDCA_WITH_DISORDER=ON
…al copy of disorder averaged G and Sigma and error bars
… only when Cmake option -DDCA_WITH_DISORDER=ON; Stat test revealed bug in local_G_k_w division by sign, fixed both disorder and clean branches (other parts were fixed in 2023)
Delete dead, never-compiled early-iteration disorder files: apply_disorder.{cpp,hpp}
(in include/ and src/), make_disorder.hpp, and two committed-by-accident Emacs lock
symlinks (.#apply_disorder.{cpp,hpp}). None are referenced by any CMakeLists or #include;
the live disorder generation path is makeDisorderConfigurations.hpp.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Brings the CT-AUX site-disorder work (DCA_WITH_DISORDER / DISORDERED_G0) onto master.

Conflict: include/.../ctaux/ctaux_walker.hpp — resolved by taking master's version.
disorder_two_k's only changes to this file were clang-format reflow (no logic); master's
85e58ac carries the real change there (re-enabled NDEBUG delayed-spin check) plus the
Matrix::resize memory-corruption fix elsewhere. All other overlaps (parameters.hpp,
output_parameters.hpp, the parameters test CMake/test) auto-merged in disjoint regions.

Verified on the merged tree (DCA_WITH_DISORDER=ON): main_dca builds, 7/7 disorder unit
tests pass. Master's new readInput checks (OutputParameters::validate,
checkModelSections) accept the disorder inputs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@anirudha-mirmira

Copy link
Copy Markdown
Author

Commit f5a4f67 also resolves #364

@PDoakORNL PDoakORNL left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@anirudha-mirmira These are my comments based on the work you did which looks good, it would have been nice to retain the ability to run both disorder and standard calculations without recompilation but that can probably be restored.

Most of what I see holding this back from merge is other delta's inherited from the starting branch and its divergence for master. We should discuss directly.

std::cout << "\n\t\t symmetrize measurements has started \t" << dca::util::print_time() << "\n";

#ifdef DISORDERED_G0
// No Symmetrize overload for the two-site <nu,R,nu,R,w> domain, and crystal symmetry only holds

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I believe the symmetrization is also a linear operation and therefore will commute with the sum. One reason not to symmetrize here is the possibility it introduce more floating point error. The other is we don't have the symmetrization overload written.

My intuition is that applying the symmetrization to each configuration or once to the summed M will make little difference unless the sampling is insufficient.

// on every rank (every rank generates the same disorder ensemble) and fixed for the whole
// run (the ensemble is the same in every DCA iteration, i.e. quenched disorder). No separate
// seed broadcast is needed here.
constexpr unsigned disorder_seed_offset = 0x9e3779b9u; // golden ratio; arbitrary but fixed

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This seems perfectly fine and its useful to know the behavior of Parameters.
but more import are the assumptions MakeDisorderConfigurations makes wrt Parameters, i.e. its requirements of Parameters for this class to function as described.

The following assumptions are made here:

  1. The global seed is read from input and an identical value is returned by parameters.get_seed() in all contexts parameters is available.
  2. the parmeters.get_seed() value is immutable

One might assume Parameters are immutable over a DCA run but the code violates this for instance with chemical potential.

#ifdef DISORDERED_G0
// The two-particle (G4) accumulator measures against the clean G0_k_w_cluster_excluded, which is
// inconsistent with the disordered walker; fail fast rather than produce wrong G4 under disorder.
if (parameters_.isAccumulatingG4())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is much better than having it still go and be wrong.

using typename BaseClass::Accumulator;
using Walker = stdthreadqmci::StdThreadQmciWalker<typename BaseClass::Walker, Data>;
using SpGreensFunction = typename BaseClass::SpGreensFunction;
using SpDisorderedGreensFunction = typename BaseClass::SpDisorderedGreensFunction;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This breaks the CTINT build and in a way that is not going to be clear to most people building the code. Some clean way of dealing with this is needed. An intelligible compilation or cmake error would be fine until disorder is supported for ctint.

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