88
99#include " basic_funcs.h"
1010#include " source_base/constants.h"
11- #include " source_base/global_variable.h"
1211#include " source_io/module_parameter/parameter.h"
1312
1413/* *
7271 * - decay_grad thresholds are not too aggressive
7372 */
7473template <>
75- void spinconstrain::SpinConstrain<std::complex <double >>::run_lambda_loop(int outer_step, bool rerun)
74+ void spinconstrain::SpinConstrain<std::complex <double >>::run_lambda_loop(int outer_step, bool rerun, std::ostream& ofs_running )
7675{
7776 int nat = this ->get_nat ();
7877 int ntype = this ->get_ntype ();
@@ -107,7 +106,7 @@ void spinconstrain::SpinConstrain<std::complex<double>>::run_lambda_loop(int out
107106
108107 double inner_loop_duration = 0.0 ;
109108
110- this ->print_header ();
109+ this ->print_header (ofs_running );
111110
112111 // =============================================================
113112 // MAIN OPTIMIZATION LOOP
@@ -129,9 +128,9 @@ void spinconstrain::SpinConstrain<std::complex<double>>::run_lambda_loop(int out
129128 // Save initial lambda: for unconstrained components (constrain==0), set to 0
130129 where_fill_scalar_else_2d (this ->constrain_ , 0 , zero, this ->lambda_ , initial_lambda);
131130
132- print_2d (" initial lambda (eV/uB): " , initial_lambda, this ->nspin_ , ModuleBase::Ry_to_eV, GlobalV:: ofs_running);
133- print_2d (" initial spin (uB): " , spin, this ->nspin_ , 1.0 , GlobalV:: ofs_running);
134- print_2d (" target spin (uB): " , this ->target_mag_ , this ->nspin_ , 1.0 , GlobalV:: ofs_running);
131+ print_2d (" initial lambda (eV/uB): " , initial_lambda, this ->nspin_ , ModuleBase::Ry_to_eV, ofs_running);
132+ print_2d (" initial spin (uB): " , spin, this ->nspin_ , 1.0 , ofs_running);
133+ print_2d (" target spin (uB): " , this ->target_mag_ , this ->nspin_ , 1.0 , ofs_running);
135134 i_step++;
136135 }
137136 else
@@ -171,7 +170,7 @@ void spinconstrain::SpinConstrain<std::complex<double>>::run_lambda_loop(int out
171170 new_spin = this ->Mi_ ;
172171
173172 // Check if gradient dM/dlambda has decayed below threshold
174- bool GradLessThanBound = this ->check_gradient_decay (new_spin, spin, delta_lambda, dnu_last_step);
173+ bool GradLessThanBound = this ->check_gradient_decay (new_spin, spin, delta_lambda, dnu_last_step, false , ofs_running );
175174 if (i_step >= this ->nsc_min_ && GradLessThanBound)
176175 {
177176 // Gradient has decayed: further optimization yields diminishing returns
@@ -186,8 +185,8 @@ void spinconstrain::SpinConstrain<std::complex<double>>::run_lambda_loop(int out
186185 - iterstart)).count () / static_cast <double >(1e6 );
187186#endif
188187 inner_loop_duration += duration;
189- GlobalV:: ofs_running << " Total TIME(s) = " << inner_loop_duration << std::endl;
190- this ->print_termination ();
188+ ofs_running << " Total TIME(s) = " << inner_loop_duration << std::endl;
189+ this ->print_termination (ofs_running );
191190 break ;
192191 }
193192 spin = new_spin;
@@ -260,7 +259,7 @@ void spinconstrain::SpinConstrain<std::complex<double>>::run_lambda_loop(int out
260259 - iterstart)).count () / static_cast <double >(1e6 );
261260#endif
262261 inner_loop_duration += duration;
263- if (this ->check_rms_stop (outer_step, i_step, rms_error, duration, inner_loop_duration))
262+ if (this ->check_rms_stop (outer_step, i_step, rms_error, duration, inner_loop_duration, ofs_running ))
264263 {
265264 // Save RMS for ESolver to display in the SCF iteration table.
266265 this ->last_rms_error_ = rms_error;
@@ -283,15 +282,15 @@ void spinconstrain::SpinConstrain<std::complex<double>>::run_lambda_loop(int out
283282 }
284283 mean_error = sum_2d (temp_1) / nat;
285284 rms_error = std::sqrt (mean_error);
286- GlobalV:: ofs_running<<" Current RMS: " <<rms_error<<std::endl;
285+ ofs_running<<" Current RMS: " <<rms_error<<std::endl;
287286
288287 // If RMS is still large after full update, recursively rerun
289288 // with higher precision (full PW solver instead of subspace only)
290289 if (rms_error > this ->current_sc_thr_ * 10 && rerun == true && this ->higher_mag_prec == true )
291290 {
292291 std::cout<<" DeltaSpin: RMS error too large (" <<rms_error<<" ), rerun inner loop with full PW solver" <<std::endl;
293292 std::cout<<std::endl;
294- this ->run_lambda_loop (outer_step, false );
293+ this ->run_lambda_loop (outer_step, false , ofs_running );
295294 }
296295 }
297296 break ;
@@ -317,7 +316,7 @@ void spinconstrain::SpinConstrain<std::complex<double>>::run_lambda_loop(int out
317316 }
318317
319318 // Cap step size to prevent overshooting
320- this ->check_restriction (search, alpha_trial);
319+ this ->check_restriction (search, alpha_trial, ofs_running );
321320
322321 // =============================================================
323322 // CUMULATIVE STEP UPDATE
@@ -356,7 +355,7 @@ void spinconstrain::SpinConstrain<std::complex<double>>::run_lambda_loop(int out
356355
357356 // Find optimal step size via linear interpolation
358357 alpha_opt = this ->cal_alpha_opt (spin, spin_plus, alpha_trial);
359- this ->check_restriction (search, alpha_opt);
358+ this ->check_restriction (search, alpha_opt, ofs_running );
360359
361360 // Correct dnu: dnu += (alpha_opt - alpha_trial) * search
362361 alpha_plus = alpha_opt - alpha_trial;
@@ -423,7 +422,7 @@ void spinconstrain::SpinConstrain<std::complex<double>>::run_lambda_loop(int out
423422 * step, lambda_eV_uB, Mi_x_0, Mi_y_0, Mi_z_0, Mi_x_1, ...
424423 */
425424template <>
426- void spinconstrain::SpinConstrain<std::complex <double >>::run_lambda_linear_scan(int outer_step)
425+ void spinconstrain::SpinConstrain<std::complex <double >>::run_lambda_linear_scan(int outer_step, std::ostream& ofs_running )
427426{
428427 int nat = this ->get_nat ();
429428 int ntype = this ->get_ntype ();
@@ -433,7 +432,7 @@ void spinconstrain::SpinConstrain<std::complex<double>>::run_lambda_linear_scan(
433432 int nsteps = PARAM .inp .sc_scan_steps ;
434433
435434 if (nsteps <= 0 ) {
436- GlobalV:: ofs_running << " [DS-DIAG] linear_scan: sc_scan_steps <= 0, skipping" << std::endl;
435+ ofs_running << " [DS-DIAG] linear_scan: sc_scan_steps <= 0, skipping" << std::endl;
437436 return ;
438437 }
439438
@@ -442,15 +441,15 @@ void spinconstrain::SpinConstrain<std::complex<double>>::run_lambda_linear_scan(
442441 double lambda_end_ry = lambda_end / ModuleBase::Ry_to_eV;
443442 double lambda_step = (lambda_end_ry - lambda_start_ry) / (nsteps - 1 );
444443
445- GlobalV:: ofs_running << " \n " << std::string (80 , ' =' ) << std::endl;
446- GlobalV:: ofs_running << " [DS-DIAG] === LINEAR LAMBDA SCAN START ===" << std::endl;
447- GlobalV:: ofs_running << " [DS-DIAG] Scan range: " << lambda_start << " -> " << lambda_end << " eV/uB" << std::endl;
448- GlobalV:: ofs_running << " [DS-DIAG] Number of steps: " << nsteps << std::endl;
449- GlobalV:: ofs_running << " [DS-DIAG] Lambda step size: " << lambda_step * ModuleBase::Ry_to_eV << " eV/uB" << std::endl;
450- GlobalV:: ofs_running << " [DS-DIAG] nat = " << nat << " , ntype = " << ntype << std::endl;
451- GlobalV:: ofs_running << " [DS-DIAG] nspin_ = " << this ->nspin_ << " , npol_ = " << this ->npol_ << std::endl;
452- GlobalV:: ofs_running << " [DS-DIAG] p_operator = " << (this ->p_operator ? " valid" : " NULL" ) << std::endl;
453- GlobalV:: ofs_running << " [DS-DIAG] constrain_ size = " << this ->constrain_ .size () << std::endl;
444+ ofs_running << " \n " << std::string (80 , ' =' ) << std::endl;
445+ ofs_running << " [DS-DIAG] === LINEAR LAMBDA SCAN START ===" << std::endl;
446+ ofs_running << " [DS-DIAG] Scan range: " << lambda_start << " -> " << lambda_end << " eV/uB" << std::endl;
447+ ofs_running << " [DS-DIAG] Number of steps: " << nsteps << std::endl;
448+ ofs_running << " [DS-DIAG] Lambda step size: " << lambda_step * ModuleBase::Ry_to_eV << " eV/uB" << std::endl;
449+ ofs_running << " [DS-DIAG] nat = " << nat << " , ntype = " << ntype << std::endl;
450+ ofs_running << " [DS-DIAG] nspin_ = " << this ->nspin_ << " , npol_ = " << this ->npol_ << std::endl;
451+ ofs_running << " [DS-DIAG] p_operator = " << (this ->p_operator ? " valid" : " NULL" ) << std::endl;
452+ ofs_running << " [DS-DIAG] constrain_ size = " << this ->constrain_ .size () << std::endl;
454453
455454 // Check if any constraints are defined; if not, set all atoms as constrained
456455 bool has_constraints = false ;
@@ -462,7 +461,7 @@ void spinconstrain::SpinConstrain<std::complex<double>>::run_lambda_linear_scan(
462461 }
463462
464463 if (!has_constraints) {
465- GlobalV:: ofs_running << " [DS-DIAG] No constraints found in STRU, setting all atoms as constrained" << std::endl;
464+ ofs_running << " [DS-DIAG] No constraints found in STRU, setting all atoms as constrained" << std::endl;
466465 for (int ia = 0 ; ia < nat; ia++) {
467466 if (this ->nspin_ == 4 ) {
468467 this ->constrain_ [ia] = ModuleBase::Vector3<int >(1 , 1 , 1 );
@@ -474,11 +473,11 @@ void spinconstrain::SpinConstrain<std::complex<double>>::run_lambda_linear_scan(
474473 }
475474
476475 for (int ia = 0 ; ia < nat; ia++) {
477- GlobalV:: ofs_running << " [DS-DIAG] Atom " << ia << " constrain = ("
476+ ofs_running << " [DS-DIAG] Atom " << ia << " constrain = ("
478477 << this ->constrain_ [ia].x << " , " << this ->constrain_ [ia].y << " , " << this ->constrain_ [ia].z << " )"
479478 << " target_mag = (" << this ->target_mag_ [ia].x << " , " << this ->target_mag_ [ia].y << " , " << this ->target_mag_ [ia].z << " )" << std::endl;
480479 }
481- GlobalV:: ofs_running << std::string (80 , ' =' ) << " \n " << std::endl;
480+ ofs_running << std::string (80 , ' =' ) << " \n " << std::endl;
482481
483482 // Save initial lambda to restore after scan
484483 std::vector<ModuleBase::Vector3<double >> initial_lambda (nat, 0.0 );
@@ -530,7 +529,7 @@ void spinconstrain::SpinConstrain<std::complex<double>>::run_lambda_linear_scan(
530529 }
531530 }
532531
533- GlobalV:: ofs_running << " [DS-DIAG] === Scan step " << istep << " /" << nsteps
532+ ofs_running << " [DS-DIAG] === Scan step " << istep << " /" << nsteps
534533 << " lambda = " << lambda_val_ev << " eV/uB ===" << std::endl;
535534
536535 // Compute magnetic moments at current lambda
@@ -551,22 +550,22 @@ void spinconstrain::SpinConstrain<std::complex<double>>::run_lambda_linear_scan(
551550 }
552551 ofs_scan << std::endl;
553552
554- GlobalV:: ofs_running << " [DS-DIAG] lambda = " << lambda_val_ev << " eV/uB" << std::endl;
553+ ofs_running << " [DS-DIAG] lambda = " << lambda_val_ev << " eV/uB" << std::endl;
555554 for (int ia = 0 ; ia < nat; ia++) {
556- GlobalV:: ofs_running << " [DS-DIAG] Atom " << ia << " Mi = ("
555+ ofs_running << " [DS-DIAG] Atom " << ia << " Mi = ("
557556 << this ->Mi_ [ia].x << " , "
558557 << this ->Mi_ [ia].y << " , "
559558 << this ->Mi_ [ia].z << " ) uB" << std::endl;
560559 }
561- GlobalV:: ofs_running << std::endl;
560+ ofs_running << std::endl;
562561 }
563562
564563 // =============================================================
565564 // CONSISTENCY CHECK: restore initial lambda and recompute Mi
566565 // to verify that the lambda->Mi mapping is numerically stable
567566 // after multiple lambda updates in the scan loop
568567 // =============================================================
569- GlobalV:: ofs_running << " [DS-DIAG] === Consistency check: restoring initial lambda ===" << std::endl;
568+ ofs_running << " [DS-DIAG] === Consistency check: restoring initial lambda ===" << std::endl;
570569 this ->lambda_ = initial_lambda;
571570 this ->cal_mw_from_lambda (nsteps);
572571
@@ -580,9 +579,9 @@ void spinconstrain::SpinConstrain<std::complex<double>>::run_lambda_linear_scan(
580579 }
581580 ofs_scan << std::endl;
582581
583- GlobalV:: ofs_running << " [DS-DIAG] lambda = " << lambda_start << " eV/uB (restored)" << std::endl;
582+ ofs_running << " [DS-DIAG] lambda = " << lambda_start << " eV/uB (restored)" << std::endl;
584583 for (int ia = 0 ; ia < nat; ia++) {
585- GlobalV:: ofs_running << " [DS-DIAG] Atom " << ia << " Mi = ("
584+ ofs_running << " [DS-DIAG] Atom " << ia << " Mi = ("
586585 << this ->Mi_ [ia].x << " , "
587586 << this ->Mi_ [ia].y << " , "
588587 << this ->Mi_ [ia].z << " ) uB" << std::endl;
@@ -599,11 +598,11 @@ void spinconstrain::SpinConstrain<std::complex<double>>::run_lambda_linear_scan(
599598 if (diff > max_mi_diff) max_mi_diff = diff;
600599 ofs_scan << " # Atom " << ia << " dM = (" << dx << " , " << dy << " , " << dz << " ) uB" << std::endl;
601600 }
602- GlobalV:: ofs_running << " [DS-DIAG] Max Mi difference between step 0 and init_recheck: " << max_mi_diff << " uB" << std::endl;
601+ ofs_running << " [DS-DIAG] Max Mi difference between step 0 and init_recheck: " << max_mi_diff << " uB" << std::endl;
603602 if (max_mi_diff > 1e-8 ) {
604- GlobalV:: ofs_running << " [DS-DIAG] WARNING: Mi mapping may be inconsistent after multiple lambda updates!" << std::endl;
603+ ofs_running << " [DS-DIAG] WARNING: Mi mapping may be inconsistent after multiple lambda updates!" << std::endl;
605604 } else {
606- GlobalV:: ofs_running << " [DS-DIAG] OK: Mi mapping is consistent." << std::endl;
605+ ofs_running << " [DS-DIAG] OK: Mi mapping is consistent." << std::endl;
607606 }
608607 ofs_scan << " # Max Mi difference: " << max_mi_diff << " uB" << std::endl;
609608
@@ -612,10 +611,10 @@ void spinconstrain::SpinConstrain<std::complex<double>>::run_lambda_linear_scan(
612611 // Restore original lambda values (already restored above, but explicit for clarity)
613612 this ->lambda_ = initial_lambda;
614613
615- GlobalV:: ofs_running << std::string (80 , ' =' ) << std::endl;
616- GlobalV:: ofs_running << " [DS-DIAG] === LINEAR LAMBDA SCAN COMPLETE ===" << std::endl;
617- GlobalV:: ofs_running << " [DS-DIAG] Results written to: lambda_scan_results.dat" << std::endl;
618- GlobalV:: ofs_running << std::string (80 , ' =' ) << " \n " << std::endl;
614+ ofs_running << std::string (80 , ' =' ) << std::endl;
615+ ofs_running << " [DS-DIAG] === LINEAR LAMBDA SCAN COMPLETE ===" << std::endl;
616+ ofs_running << " [DS-DIAG] Results written to: lambda_scan_results.dat" << std::endl;
617+ ofs_running << std::string (80 , ' =' ) << " \n " << std::endl;
619618
620619 return ;
621620}
0 commit comments