From 1b536d272c974eb475631791d516145ebda53a95 Mon Sep 17 00:00:00 2001 From: dyzheng Date: Wed, 16 Sep 2026 23:23:55 +0800 Subject: [PATCH] Fix(deltaspin): free pre_hr/B_I_data caches on cal_pre_HR() reinitialization reset_dspin_operator() sets DeltaSpin::initialized=false, so the next cal_pre_HR() runs again on the same operator. It called pre_hr.clear() on a vector of raw HContainer pointers, which does not free the pointed-to objects, and it never reset B_I_data. In DFT+U+DeltaSpin LCAO runs (where reset_dspin_operator() is called when the constraints change) this leaked memory linearly with the number of reinitializations. Delete the old HContainers before clearing pre_hr, and clear/resize B_I_data so unconstrained atoms do not keep stale overlap data. Fixes #6524. --- .../source_lcao/module_operator_lcao/dspin_lcao.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/source/source_lcao/module_operator_lcao/dspin_lcao.cpp b/source/source_lcao/module_operator_lcao/dspin_lcao.cpp index 6d487b2fe21..8f8e975587b 100644 --- a/source/source_lcao/module_operator_lcao/dspin_lcao.cpp +++ b/source/source_lcao/module_operator_lcao/dspin_lcao.cpp @@ -228,8 +228,21 @@ void hamilt::DeltaSpin>::cal_pre_HR() } this->paraV = this->hR->get_paraV(); ModuleBase::timer::start("DeltaSpin", "cal_pre_HR"); + // Reset the caches from a possible previous initialization: + // pre_hr holds raw HContainer pointers, so clear() alone would leak them, + // and stale B_I_data would survive for atoms that are no longer constrained. + for (auto& hr : this->pre_hr) + { + delete hr; + } this->pre_hr.clear(); this->pre_hr.resize(this->ucell->nat, nullptr); + for (auto& b : this->B_I_data) + { + b.clear(); + } + this->B_I_data.clear(); + this->B_I_data.resize(this->ucell->nat); const int npol = this->ucell->get_npol(); size_t memory_cost = 0;