PSCF v1.3.2
AmIteratorTmpl.tpp
1#ifndef PSCF_AM_ITERATOR_TMPL_TPP
2#define PSCF_AM_ITERATOR_TMPL_TPP
3
4/*
5* PSCF - Polymer Self-Consistent Field
6*
7* Copyright 2015 - 2025, The Regents of the University of Minnesota
8* Distributed under the terms of the GNU General Public License.
9*/
10
11#include "NanException.h"
12#include <pscf/inter/Interaction.h>
13#include <pscf/math/LuSolver.h>
14#include <util/format/Dbl.h>
15#include <util/format/Int.h>
16#include <util/misc/Timer.h>
17#include <util/misc/FileMaster.h>
18
19#include <cmath>
20
21namespace Pscf
22{
23
24 using namespace Util;
25
26 // Public member functions
27
28 /*
29 * Constructor
30 */
31 template <typename Iterator, typename T>
33 : epsilon_(0),
34 maxItr_(200),
35 maxHist_(50),
36 verbose_(1),
37 errorType_("relNormResid"),
38 error_(0.0),
39 nBasis_(0),
40 itr_(0),
41 totalItr_(0),
42 nElem_(0),
43 lambda_(1.0),
44 r_(0.9),
45 useLambdaRamp_(true),
46 isAllocatedAM_(false)
47 { ParamComposite::setClassName("AmIteratorTmpl"); }
48
49 /*
50 * Destructor
51 */
52 template <typename Iterator, typename T>
55
56 /*
57 * Read parameter file block.
58 */
59 template <typename Iterator, typename T>
61 {
62
63 // Error tolerance for scalar error. Stop when error < epsilon.
64 read(in, "epsilon", epsilon_);
65
66 // Maximum number of iterations (optional)
67 // Default set in constructor (200)
68 readOptional(in, "maxItr", maxItr_);
69
70 // Maximum number of previous vectors in history (optional)
71 // Default set in constructor (50)
72 readOptional(in, "maxHist", maxHist_);
73
74 // Verbosity level of error reporting, values 0-3 (optional)
75 // Initialized to 1 by default in constructor
76 // verbose_ = 0 => FTS
77 // verbose_ = 1 => concise
78 // verbose_ = 2 => report all error measures at end
79 // verbose_ = 3 => report all error measures every iteration
80 readOptional(in, "verbose", verbose_);
82 #if 0
83 // Ramping parameter for correction step
84 // Default set to 0.9. lambda = 1 - r_^nBasis for nBasis < maxHist
85 readOptional(in, "r", r_);
86 #endif
87
88 #ifdef PSCF_AM_TEST
89 // Default set to be false
90 readOptional(in, "hasAmTest", hasAmTest_);
91 #endif
92 }
93
94 /*
95 * Iteratively solve a fixed-point problem.
96 */
97 template <typename Iterator, typename T>
98 int AmIteratorTmpl<Iterator,T>::solve(bool isContinuation)
99 {
100 // Initialization and allocate operations on entry to loop.
101 setup(isContinuation);
102
103 // Preconditions for generic Anderson-mixing (AM) algorithm.
104 UTIL_CHECK(hasInitialGuess());
105 UTIL_CHECK(isAllocatedAM_);
106
107 // Start overall timer
108 timerTotal_.start();
109
110 // Solve MDE for initial state
111 timerMDE_.start();
112 evaluate();
113 timerMDE_.stop();
114
115 // Iterative loop
116 nBasis_ = stateBasis_.size();
117 for (itr_ = 0; itr_ < maxItr_; ++itr_) {
118
119 // Append current state to stateHistory_ ringbuffer
120 getCurrent(temp_);
121 stateHistory_.append(temp_);
123 timerAM_.start();
124
125 if (verbose_ > 2) {
126 Log::file() << "------------------------------- \n";
127 }
128
129 if (verbose_ > 0){
130 Log::file() << " Iteration " << Int(itr_,5);
132
133 // Compute current residual vector, store in temp_
134 timerResid_.start();
135 getResidual(temp_);
136
137 // Append current residual to residualHistory_ ring buffer
138 residualHistory_.append(temp_);
139 timerResid_.stop();
140
141 // Compute scalar error used to test convergence
142 timerError_.start();
143 try {
144 error_ = computeError(verbose_);
145 } catch (const NanException&) {
146 Log::file() << ", error = NaN" << std::endl;
147 break; // Exit loop if a NanException is caught
148 }
149 if (verbose_ > 0 && verbose_ < 3) {
150 Log::file() << ", error = " << Dbl(error_, 15)
151 << std::endl;
152 }
153 timerError_.stop();
155 // Output additional details of this iteration to the log file
156 outputToLog();
157
158 #ifdef PSCF_AM_TEST
159 // Compute errors and ratios used for algorithm testing
160 if (hasAmTest_){
161 // Compute errors and ratios used for algorithm testing
162 correctionError_ = computeError(0);
163 if (itr_ > 0) {
164 projectionRatio_ += projectionError_/preError_;
165 correctionRatio_ += correctionError_/preError_;
166 testCounter ++;
167 }
168 preError_ = correctionError_;
169 }
170 #endif
171
172 // Check for convergence
173 if (error_ < epsilon_) {
174
175 // Stop timers
176 timerAM_.stop();
177 timerTotal_.stop();
178
179 if (verbose_ > 2) {
180 Log::file() << "-------------------------------\n";
181 }
182
183 if (verbose_ > 0) {
184 Log::file() << " Converged\n";
185 }
186
187 // Output error report if not done previously
188 if (verbose_ == 2) {
189 Log::file() << "\n";
190 computeError(2);
191 }
193 totalItr_ += itr_;
194
195 // Successful completion (i.e., converged within tolerance)
196 return 0;
197
198 } else {
199
200 // Compute optimal coefficients for basis vectors
201 timerCoeff_.start();
202 computeTrialCoeff();
203 timerCoeff_.stop();
204
205 // Compute updated trial state and residual vectors
206 timerOmega_.start();
207 updateTrial();
208
209 // Correction (or "mixing") step
210 addCorrection(stateTrial_, residualTrial_);
211
212 // Update the parent system using new trial state
213 update(stateTrial_);
214
215 timerOmega_.stop();
216 timerAM_.stop();
217
218 // Perform the main calculation of the parent system -
219 // Solve MDEs, compute phi's, compute stress if needed
220 timerMDE_.start();
221 evaluate();
222 timerMDE_.stop();
223 }
224
225 }
226
227 // Failure: Counter itr_ reached maxItr_ without converging
228 timerTotal_.stop();
229 Log::file() << "Iterator failed to converge.\n";
230 return 1;
231
232 }
233
234 template <typename Iterator, typename T>
235 void AmIteratorTmpl<Iterator,T>::outputTimers(std::ostream& out) const
236 {
237 // Output timing results, if requested.
238 double total = timerTotal_.time();
239 out << "\n";
240 out << " ";
241 out << "Total" << std::setw(22)<< "Per Iteration"
242 << std::setw(9) << "Fraction" << "\n";
243 out << "MDE solution: "
244 << Dbl(timerMDE_.time(), 9, 3) << " s, "
245 << Dbl(timerMDE_.time()/totalItr_, 9, 3) << " s, "
246 << Dbl(timerMDE_.time()/total, 9, 3) << "\n";
247 out << "residual computation: "
248 << Dbl(timerResid_.time(), 9, 3) << " s, "
249 << Dbl(timerResid_.time()/totalItr_, 9, 3) << " s, "
250 << Dbl(timerResid_.time()/total, 9, 3) << "\n";
251 out << "mixing coefficients: "
252 << Dbl(timerCoeff_.time(), 9, 3) << " s, "
253 << Dbl(timerCoeff_.time()/totalItr_, 9, 3) << " s, "
254 << Dbl(timerCoeff_.time()/total, 9, 3) << "\n";
255 out << "checking convergence: "
256 << Dbl(timerError_.time(), 9, 3) << " s, "
257 << Dbl(timerError_.time()/totalItr_, 9, 3) << " s, "
258 << Dbl(timerError_.time()/total, 9, 3) << "\n";
259 out << "updating guess: "
260 << Dbl(timerOmega_.time(), 9, 3) << " s, "
261 << Dbl(timerOmega_.time()/totalItr_, 9, 3) << " s, "
262 << Dbl(timerOmega_.time()/total, 9, 3)<< "\n";
263 out << "total time: "
264 << Dbl(total, 9, 3) << " s, "
265 << Dbl(total/totalItr_, 9, 3) << " s \n";
266 out << "\n";
267
268 #ifdef PSCF_AM_TEST
269 if (hasAmTest_){
270 out << "Average Projection Step Reduction Ratio: "
271 << Dbl(projectionRatio_/testCounter, 3, 3)<< "\n";
272 out << "Average Correction Step Reduction Ratio: "
273 << Dbl(correctionRatio_/testCounter, 3, 3)<< "\n";
274 }
275 #endif
276 }
277
278 template <typename Iterator, typename T>
280 {
281 timerMDE_.clear();
282 timerResid_.clear();
283 timerError_.clear();
284 timerCoeff_.clear();
285 timerOmega_.clear();
286 timerAM_.clear();
287 timerTotal_.clear();
288 totalItr_ = 0;
289 }
290
291 // Protected member functions - Initialization
292
293 /*
294 * Read and validate optional errorType string parameter.
295 */
296 template <typename Iterator, typename T>
298 {
299 // Note: errorType_ is initialized to "relNormResid" in constructor
300
301 // Read optional errorType_ string if present
302 readOptional(in, "errorType", errorType_);
303
304 // Check validity, normalize to standard form
305 bool isValid = isValidErrorType();
306
307 // If not valid, throw Exception with error message
308 if (!isValid) {
309 std::string msg = "Invalid iterator error type [";
310 msg += errorType_;
311 msg += "] in parameter file";
312 UTIL_THROW(msg.c_str());
313 }
314 }
315
316 /*
317 * Check validity of errorType_ string and normalize if valid.
318 */
319 template <typename Iterator, typename T>
321 {
322 // Process possible synonyms
323 if (errorType_ == "norm") errorType_ = "normResid";
324 if (errorType_ == "rms") errorType_ = "rmsResid";
325 if (errorType_ == "max") errorType_ = "maxResid";
326 if (errorType_ == "relNorm") errorType_ = "relNormResid";
327
328 // Check value
329 bool valid;
330 valid = (errorType_ == "normResid"
331 || errorType_ == "rmsResid"
332 || errorType_ == "maxResid"
333 || errorType_ == "relNormResid");
334 return valid;
335
336 }
337
338 /*
339 * Read and validate optional errorType string parameter.
340 */
341 template <typename Iterator, typename T>
342 void
344 bool useLambdaRamp)
345 {
346 // Set default parameter for useLambdaRamp_
347 useLambdaRamp_ = useLambdaRamp;
348
349 // Optionally read mixing parameters
350 readOptional(in, "lambda", lambda_);
351 readOptional(in, "useLambdaRamp", useLambdaRamp_);
352 if (useLambdaRamp_) {
353 readOptional(in, "r", r_);
354 }
355 }
356
357 /*
358 * Allocate memory required by the AM algorithm, if needed.
359 * (protected, non-virtual)
360 */
361 template <typename Iterator, typename T>
363 {
364 // If already allocated, do nothing and return
365 if (isAllocatedAM_) return;
366
367 // Compute and set number of elements in a residual vector
368 nElem_ = nElements();
369
370 // Allocate ring buffers
371 stateHistory_.allocate(maxHist_+1);
372 residualHistory_.allocate(maxHist_+1);
373 stateBasis_.allocate(maxHist_);
374 residualBasis_.allocate(maxHist_);
375
376 // Allocate arrays used in iteration
377 stateTrial_.allocate(nElem_);
378 residualTrial_.allocate(nElem_);
379 temp_.allocate(nElem_);
380
381 // Allocate arrays/matrices used in coefficient calculation
382 U_.allocate(maxHist_, maxHist_);
383 v_.allocate(maxHist_);
384 coeffs_.allocate(maxHist_);
385
386 isAllocatedAM_ = true;
387 }
388
389 /*
390 * Initialize just before entry to iterative loop.
391 * (virtual)
392 */
393 template <typename Iterator, typename T>
394 void AmIteratorTmpl<Iterator,T>::setup(bool isContinuation)
395 {
396 if (!isAllocatedAM()) {
397 allocateAM();
398 } else {
399 // Clear residual and state history buffers
400 residualHistory_.clear();
401 stateHistory_.clear();
402 if (!isContinuation) {
403 // Clear bases iff not a continuation
404 residualBasis_.clear();
405 stateBasis_.clear();
406 }
407 }
408 }
409
410 /*
411 * Clear all history and basis vector data.
412 */
413 template <typename Iterator, typename T>
415 {
416 UTIL_CHECK(isAllocatedAM_);
417 residualHistory_.clear();
418 stateHistory_.clear();
419 residualBasis_.clear();
420 stateBasis_.clear();
421 }
422
423 // Private non-virtual member functions
424
425 /*
426 * Compute optimal coefficients of basis vectors.
427 */
428 template <typename Iterator, typename T>
429 void AmIteratorTmpl<Iterator,T>::computeTrialCoeff()
430 {
431 // If first iteration and bases are empty
432 // then initialize U, v and coeff arrays
433 if (itr_ == 0 && nBasis_ == 0) {
434 int m, n;
435 for (m = 0; m < maxHist_; ++m) {
436 v_[m] = 0.0;
437 coeffs_[m] = 0.0;
438 for (n = 0; n < maxHist_; ++n) {
439 U_(m, n) = 0.0;
440 }
441 }
442 return;
443 }
444
445 // Do nothing else on first iteration
446 if (itr_ == 0) return;
447
448 // Update stateBasis_, residualBasis_, U_ matrix and v_ vector
449 if (stateHistory_.size() > 1) {
450
451 // Update basis spanning differences of past state vectors
452 updateBasis(stateBasis_, stateHistory_);
453
454 // Update basis spanning differences of past residual vectors
455 updateBasis(residualBasis_, residualHistory_);
456
457 // Update the U matrix and v vector.
458 updateU(U_, residualBasis_);
459
460 }
461
462 // Update nBasis_
463 nBasis_ = residualBasis_.size();
464 UTIL_CHECK(nBasis_ > 0);
465 UTIL_CHECK(stateBasis_.size() == nBasis_);
466
467 // Update v_ vector (dot product of basis vectors and residual)
468 computeV(v_, residualHistory_[0], residualBasis_);
469
470 // Solution of the matrix problem U coeffs_ = -v yields a coeff
471 // vector that minimizes the norm of the residual. Below, we:
472 // 1. Solve matrix equation: U coeffs_ = v
473 // 2. Flip the sign of the resulting coeffs_ vector
474
475 if (nBasis_ == 1) {
476 // Solve explicitly for coefficient
477 coeffs_[0] = v_[0] / U_(0,0);
478 } else
479 if (nBasis_ < maxHist_) {
480
481 // Create temporary smaller version of U_, v_, coeffs_ .
482 // This avoids reallocation of U_ with each iteration.
483 DMatrix<double> tempU;
484 DArray<double> tempv, tempcoeffs;
485 tempU.allocate(nBasis_,nBasis_);
486 tempv.allocate(nBasis_);
487 tempcoeffs.allocate(nBasis_);
488 for (int i = 0; i < nBasis_; ++i) {
489 tempv[i] = v_[i];
490 for (int j = 0; j < nBasis_; ++j) {
491 tempU(i,j) = U_(i,j);
492 }
493 }
494
495 // Solve matrix equation
496 LuSolver solver;
497 solver.allocate(nBasis_);
498 solver.computeLU(tempU);
499 solver.solve(tempv, tempcoeffs);
500
501 // Transfer solution to full-sized member variable
502 for (int i = 0; i < nBasis_; ++i) {
503 coeffs_[i] = tempcoeffs[i];
504 }
505
506 } else
507 if (nBasis_ == maxHist_) {
508
509 LuSolver solver;
510 solver.allocate(maxHist_);
511 solver.computeLU(U_);
512 solver.solve(v_, coeffs_);
513
514 }
515
516 // Flip the sign of the coeffs_ vector (see comment above)
517 for (int i = 0; i < nBasis_; ++i) {
518 coeffs_[i] *= -1.0;
519 }
520
521 return;
522 }
523
524 template <typename Iterator, typename T>
525 void AmIteratorTmpl<Iterator,T>::updateTrial()
526 {
527
528 // Set state and residual trial vectors to current values
529 setEqual(stateTrial_, stateHistory_[0]);
530 setEqual(residualTrial_, residualHistory_[0]);
531
532 // Add linear combinations of state and residual basis vectors
533 if (nBasis_ > 0) {
534
535 // Combine basis vectors into trial guess and predicted residual
536 addEqVectors(stateTrial_, stateBasis_, coeffs_);
537 addEqVectors(residualTrial_, residualBasis_, coeffs_);
538
539 }
540
541 #ifdef PSCF_AM_TEST
542 // Additional direct computation of error after projection step
543 if (hasAmTest_){
544 timerOmega_.stop();
545
546 // Additional MDE solution
547 timerMDE_.start();
548 update(stateTrial_);
549 evaluate();
550 timerMDE_.stop();
551
552 // Residual computation
553 timerResid_.start();
554 getResidual(temp_);
555 timerResid_.stop();
556
557 // Compute error after projection
558 timerError_.start();
559 projectionError_ = computeError(temp_, stateTrial_, errorType_, 0);
560 timerError_.stop();
561 timerOmega_.start();
562 }
563 #endif
564
565 }
566
567 // Private virtual member functions
568
569 /*
570 * Compute ramped mixing parameter for Anderson mixing algorithm.
571 */
572 template <typename Iterator, typename T>
574 {
575 if (useLambdaRamp_ && (nBasis_ < maxHist_)) {
576 double factor = 1.0 - pow(r_, nBasis_ + 1);
577 return factor*lambda_;
578 } else {
579 return lambda_;
580 }
581 }
582
583 /*
584 * Update entire U matrix.
585 */
586 template <typename Iterator, typename T>
587 void
589 DMatrix<double> & U,
590 RingBuffer<T> const & residualBasis)
591 {
592 int nBasis = residualBasis.size();
593 int maxHist = U.capacity1();
594 UTIL_CHECK(maxHist >= nBasis);
595
596 // Update matrix U by shifting elements diagonally
597 for (int m = maxHist - 1; m > 0; --m) {
598 for (int n = maxHist-1; n > 0; --n) {
599 U(m,n) = U(m-1,n-1);
600 }
601 }
602
603 // Compute U matrix's new row 0 and col 0
604 for (int m = 0; m < nBasis; ++m) {
605 double dotprod = dotProduct(residualBasis[0],residualBasis[m]);
606 if (m == 0) {
607 U(0,0) = dotprod;
608 } else {
609 U(m,0) = dotprod;
610 U(0,m) = dotprod;
611 }
612 }
613
614 }
615
616 /*
617 * Compute v vector (dot products of residual and basis vectors).
618 */
619 template <typename Iterator, typename T>
620 void AmIteratorTmpl<Iterator, T>::computeV(
621 DArray<double> & v,
622 T const & resCurrent,
623 RingBuffer<T> const & residualBasis)
624 {
625 int nBasis = residualBasis.size();
626 UTIL_CHECK(v.capacity() >= nBasis);
627 for (int m = 0; m < nBasis; ++m) {
628 v[m] = dotProduct(resCurrent, residualBasis[m]);
629 }
630 }
631
632 /*
633 * Compute scalar error, possibly output to log.
634 */
635 template <typename Iterator, typename T>
636 double
638 T&stateTrial,
639 std::string errorType,
640 int verbose)
641 {
642 double error = 0.0;
643
644 // Find max residual vector element
645 double maxRes = maxAbs(residTrial);
646
647 // Find norm of residual vector
648 double normRes = norm(residTrial);
649
650 // Check if calculation has diverged (normRes will be NaN)
651 UTIL_CHECK(!std::isnan(normRes));
652
653 // Find root-mean-squared residual element value
654 double rmsRes = normRes/sqrt(nElements());
655
656 // Find norm of residual vector relative to state
657 double normField = norm(stateTrial);
658 double relNormRes = normRes/normField;
659
660 // Set error value
661 if (errorType == "maxResid") {
662 error = maxRes;
663 } else if (errorType == "normResid") {
664 error = normRes;
665 } else if (errorType == "rmsResid") {
666 error = rmsRes;
667 } else if (errorType == "relNormResid") {
668 error = relNormRes;
669 } else {
670 UTIL_THROW("Invalid iterator error type in parameter file.");
671 }
672
673 if (verbose > 1) {
674 Log::file() << "\n";
675 Log::file() << "Max Residual = " << Dbl(maxRes,15) << "\n";
676 Log::file() << "Residual Norm = " << Dbl(normRes,15) << "\n";
677 Log::file() << "RMS Residual = " << Dbl(rmsRes,15) << "\n";
678 Log::file() << "Relative Norm = " << Dbl(relNormRes,15)
679 << std::endl;
680 }
681
682 return error;
683 }
684
685 /*
686 * Compute error (use current residual, errorType).
687 */
688 template <typename Iterator, typename T>
690 {
691 return computeError(residualHistory_[0], stateHistory_[0],
693 }
694
695
696 /*
697 * Update a list of basis vectors.
698 */
699 template <typename Iterator, typename T>
700 void
701 AmIteratorTmpl<Iterator,T>::updateBasis(RingBuffer<T> & basis,
702 RingBuffer<T> const & history)
703 {
704 // Make sure at least two histories are stored
705 UTIL_CHECK(history.size() >= 2);
706
707 // Set up array to store new basis
708 basis.advance();
709 if (basis[0].isAllocated()) {
710 UTIL_CHECK(basis[0].capacity() == history[0].capacity());
711 } else {
712 basis[0].allocate(history[0].capacity());
713 }
714
715 // New basis vector is difference between two most recent vectors
716 subVV(basis[0], history[0], history[1]);
717 }
718
719 /*
720 * Add a linear combination of basis vectors to a vector v.
721 */
722 template <typename Iterator, typename T>
723 void
724 AmIteratorTmpl<Iterator,T>::addEqVectors(T& v,
725 RingBuffer<T> const & basis,
726 DArray<double> coeffs)
727 {
728 int nBasis = basis.size();
729 UTIL_CHECK(coeffs.capacity() >= nBasis);
730 for (int i = 0; i < nBasis; i++) {
731 addEqVc(v, basis[i], coeffs[i]);
732 }
733 }
734
735 /*
736 * Add a correction based on the predicted remaining residual.
737 */
738 template <typename Iterator, typename T>
739 void
740 AmIteratorTmpl<Iterator,T>::addCorrection(T& stateTrial,
741 T const & residualTrial)
742 {
743 double lambda = computeLambda();
744 addEqVc(stateTrial, residualTrial, lambda);
745 }
746
747 // Private virtual vector math functions
748
749 /*
750 * Compute L2 norm of a vector.
751 */
752 template <typename Iterator, typename T>
753 double AmIteratorTmpl<Iterator,T>::norm(T const & a)
754 {
755 double normSq = dotProduct(a, a);
756 return sqrt(normSq);
757 }
758
759}
760#endif
Template for Anderson mixing iterator algorithm.
virtual void setup(bool isContinuation)
Initialize just before entry to iterative loop.
ScalarParam< Type > & read(std::istream &in, const char *label, Type &value)
Add and read a new required ScalarParam < Type > object.
void readMixingParameters(std::istream &in, bool useLambdaRamp=true)
Read optional parameters used in default correction algorithm.
void allocateAM()
Allocate memory required by AM algorithm, if necessary.
bool isAllocatedAM() const
Have data structures required by the AM algorithm been allocated?
virtual void clear()
Clear information about history.
void outputTimers(std::ostream &out) const
Log output timing results.
std::string errorType() const
Get error type string.
ScalarParam< Type > & readOptional(std::istream &in, const char *label, Type &value)
void clearTimers()
Clear timers.
int verbose() const
Verbosity level, allowed values 0, 1, or 2.
~AmIteratorTmpl()
Destructor.
void readErrorType(std::istream &in)
Read and validate the optional errorType string parameter.
int verbose_
Verbosity level.
double epsilon_
Error tolerance.
AmIteratorTmpl()
Constructor.
virtual double computeLambda()
Compute mixing parameter for correction step of Anderson mixing.
virtual bool isValidErrorType()
Checks if a string is a valid error type.
int maxItr_
Maximum number of iterations to attempt.
virtual double computeError(DeviceArray< cudaReal > &residTrial, DeviceArray< cudaReal > &stateTrial, std::string errorType, int verbose)
std::string errorType_
Type of error criterion used to test convergence.
virtual void readParameters(std::istream &in)
Read all parameters and initialize.
int maxHist_
Maximum number of basis vectors in AM algorithm.
int solve(bool isContinuation=false)
Iterate to a solution.
Solve Ax=b by LU decomposition of A.
Definition LuSolver.h:31
void allocate(int n)
Allocate memory.
Definition LuSolver.cpp:46
Exception thrown when not-a-number (NaN) is encountered.
int capacity() const
Return allocated size.
Definition Array.h:159
Dynamically allocatable contiguous array template.
Definition DArray.h:32
void allocate(int capacity)
Allocate the underlying C array.
Definition DArray.h:199
Dynamically allocated Matrix.
Definition DMatrix.h:25
void allocate(int capacity1, int capacity2)
Allocate memory for a matrix.
Definition DMatrix.h:170
Wrapper for a double precision number, for formatted ostream output.
Definition Dbl.h:40
Wrapper for an int, for formatted ostream output.
Definition Int.h:37
static std::ostream & file()
Get log ostream by reference.
Definition Log.cpp:59
int capacity1() const
Get number of rows (range of the first array index).
Definition Matrix.h:136
void setClassName(const char *className)
Set class name string.
Class for storing history of previous values in an array.
Definition RingBuffer.h:27
void allocate(int capacity)
Allocate a new empty buffer.
Definition RingBuffer.h:257
void advance()
Advances the pointer to an added element without assigning a value.
Definition RingBuffer.h:306
int size() const
Return number of values currently in the buffer.
Definition RingBuffer.h:325
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Definition global.h:68
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition global.h:49
void subVV(Array< double > &a, Array< double > const &b, Array< double > const &c)
Vector subtraction, a[i] = b[i] - c[i].
Definition VecOp.cpp:81
void addEqVc(DeviceArray< cudaReal > &a, DeviceArray< cudaReal > const &b, cudaReal const c)
Vector addition in-place w/ coefficient, a[i] += b[i] * c, kernel wrapper.
Definition VecOpMisc.cu:343
PSCF package top-level namespace.