58 iMaxSize(iWorkSpaceSize),
59 iCurSize(iWorkSpaceSize),
65 bDuplicateIndices(bDupInd),
71 (void)pdSetResVec(pdTmpRhs);
72 (void)pdSetSolVec(pdTmpRhs);
77 if (bDuplicateIndices) {
81 iRow.reserve(iCurSize);
82 iCol.reserve(iCurSize);
89 for (
integer iCnt = 0; iCnt < 11*iN; iCnt++) {
93 for (
integer iCnt = 0; iCnt < iN; iCnt++) {
100 iIFLAG[I_3] = iPivotParam;
111 Y12Solver::~Y12Solver(
void)
113 if (pdPIVOT != NULL) {
123 Y12Solver::IsValid(
void)
const
134 #ifdef DEBUG_MEMMANAGER
143 Y12Solver::Factor(
void)
161 if (bDuplicateIndices) {
167 iRow.resize(iCurSize);
168 iCol.resize(iCurSize);
174 memmove(pir, piRow,
sizeof(
integer)*iNonZeroes);
175 memmove(pic, piCol,
sizeof(
integer)*iNonZeroes);
177 for (
unsigned i = 0; i < iNonZeroes; i++) {
192 dAFLAG, iIFLAG, &iIFAIL);
195 silent_cerr(
"Y12Solver (y12prefactor): "
196 "error during pre-factorization, code "
197 << iIFAIL <<
":" << std::endl);
208 dAFLAG, iIFLAG, &iIFAIL);
211 silent_cerr(
"Y12Solver (y12factor): "
212 "error during factorization, code "
213 << iIFAIL <<
":" << std::endl);
218 if (dAFLAG[7] < 1.e-12) {
219 silent_cerr(
"Y12Solver (y12factor):"
220 " warning, possible bad conditioning of matrix"
227 Y12Solver::Solve(
void)
const
234 const_cast<Y12Solver *
>(
this)->
Factor();
245 silent_cerr(
"Y12Solver (y12solve): "
246 "error during back substitution, code "
247 << iIFAIL <<
":" << std::endl);
254 bHasBeenReset =
false;
261 std::vector<doublereal>& Ax,
262 std::vector<integer>& Ar, std::vector<integer>& Ac,
263 std::vector<integer>& Ap)
const
265 if (!bHasBeenReset) {
277 if (iCurSize > 5*iNonZeroes) {
278 iCurSize = 5*iNonZeroes;
280 }
else if (iCurSize < 3*iNonZeroes) {
281 if (iMaxSize < 5*iNonZeroes) {
284 iCurSize = 5*iNonZeroes;
290 Y12Solver::PutError(
integer rc)
const
292 silent_cerr(std::endl);
296 silent_cerr(
"\tThe coefficient matrix A is not" << std::endl
297 <<
"\tfactorized, i.e. the call of subroutine" << std::endl
298 <<
"\tY12MD was not preceded by a call of Y12MC" << std::endl
299 <<
"\tduring the solution of Ax=b or during" << std::endl
300 <<
"\tthe solution of the first system in a" << std::endl
301 <<
"\tsequence ( Ax1 = b1 , Ax2 = b2,.....,Axp =" << std::endl
302 <<
"\tbp) of systems with the same coefficient" << std::endl
303 <<
"\tmatrix. This will work in all cases only" << std::endl
304 <<
"\tif the user sets IFLAG(1) .ge. 0 before" << std::endl
305 <<
"\tthe call of package Y12M (i.e. before the" << std::endl
306 <<
"\tfirst call of a subroutine of this" << std::endl
307 <<
"\tpackage)." << std::endl);
311 silent_cerr(
"\tThe coefficient matrix A is not ordered," << std::endl
312 <<
"\ti.e. the call of subroutine Y12MC was not" << std::endl
313 <<
"\tpreceded by a call of Y12MB. This will" << std::endl
314 <<
"\twork in all cases only if the user sets" << std::endl
315 <<
"\tIFLAG(1) .ge. 0 before the call of package" << std::endl
316 <<
"\tY12M (i.e. before the first call of a" << std::endl
317 <<
"\tsubroutine of this package)." << std::endl);
321 silent_cerr(
"\tA pivotal element abs(a(i,i;j)) < AFLAG(4)" << std::endl
322 <<
"\t* AFLAG(6) is selected. When AFLAG(4) is" << std::endl
323 <<
"\tsufficiently small this is an indication" << std::endl
324 <<
"\tthat the coefficient matrix is numerically" << std::endl
325 <<
"\tsingular." << std::endl);
329 silent_cerr(
"\tAFLAG(5), the growth factor, is larger" << std::endl
330 <<
"\tthan AFLAG(3). When AFLAG(3) is" << std::endl
331 <<
"\tsufficiently large this indicates that the" << std::endl
332 <<
"\telements of the coefficient matrix A grow" << std::endl
333 <<
"\tso quickly during the factorization that" << std::endl
334 <<
"\tthe continuation of the computation is not" << std::endl
335 <<
"\tjustified. The choice of a smaller" << std::endl
336 <<
"\tstability factor, AFLAG(1), may give" << std::endl
337 <<
"\tbetter results in this case." << std::endl);
341 silent_cerr(
"\tThe length NN of arrays A and SNR is not" << std::endl
342 <<
"\tsufficient. Larger values of NN (and" << std::endl
343 <<
"\tpossibly of NN1) should be used." << std::endl);
347 silent_cerr(
"\tThe length NN1 of array RNR is not" << std::endl
348 <<
"\tsufficient. Larger values of NN1 (and" << std::endl
349 <<
"\tpossibly of NN) should be used." << std::endl);
353 silent_cerr(
"\tA row without non-zero elements in its" << std::endl
354 <<
"\tactive part is found during the" << std::endl
355 <<
"\tdecomposition. If the drop-tolerance," << std::endl
356 <<
"\tAFLAG(2), is sufficiently small, then" << std::endl
357 <<
"\tIFAIL = 7 indicates that the matrix is" << std::endl
358 <<
"\tnumerically singular. If a large value of" << std::endl
359 <<
"\tthe drop-tolerance AFLAG(2) is used and if" << std::endl
360 <<
"\tIFAIL = 7 on exit, this is not certain. A" << std::endl
361 <<
"\trun with a smaller value of AFLAG(2)" << std::endl
362 <<
"\tand/or a careful check of the parameters" << std::endl
363 <<
"\tAFLAG(8) and AFLAG(5) is recommended in" << std::endl
364 <<
"\tthe latter case." << std::endl);
368 silent_cerr(
"\tA column without non-zero elements in its" << std::endl
369 <<
"\tactive part is found during the" << std::endl
370 <<
"\tdecomposition. If the drop-tolerance," << std::endl
371 <<
"\tAFLAG(2), is sufficiently small, then" << std::endl
372 <<
"\tIFAIL = 8 indicates that the matrix is" << std::endl
373 <<
"\tnumerically singular. If a large value of" << std::endl
374 <<
"\tthe drop-tolerance AFLAG(2) is used and if" << std::endl
375 <<
"\tIFAIL = 8 on exit, this is not certain. A" << std::endl
376 <<
"\trun with a smaller value of AFLAG(2)" << std::endl
377 <<
"\tand/or a careful check of the parameters" << std::endl
378 <<
"\tAFLAG(8) and AFLAG(5) is recommended in" << std::endl
379 <<
"\tthe latter case." << std::endl);
383 silent_cerr(
"\tA pivotal element is missing. This may" << std::endl
384 <<
"\toccur if AFLAG(2) > 0 and IFLAG(4) = 2" << std::endl
385 <<
"\t(i.e. some system after the first one in a" << std::endl
386 <<
"\tsequence of systems with the same" << std::endl
387 <<
"\tstructure is solved using a positive value" << std::endl
388 <<
"\tfor the drop-tolerance). The value of the" << std::endl
389 <<
"\tdrop-tolerance AFLAG(2), should be" << std::endl
390 <<
"\tdecreased and the coefficient matrix of" << std::endl
391 <<
"\tthe system refactorized. This error may" << std::endl
392 <<
"\talso occur when one of the special pivotal" << std::endl
393 <<
"\tstrategies (IFLAG(3)=0 or IFLAG(3)=2) is" << std::endl
394 <<
"\tused and the matrix is not suitable for" << std::endl
395 <<
"\tsuch a strategy." << std::endl);
399 silent_cerr(
"\tSubroutine Y12MF is called with IFLAG(5) =" << std::endl
400 <<
"\t1 (i.e. with a request to remove the" << std::endl
401 <<
"\tnon-zero elements of the lower triangular" << std::endl
402 <<
"\tmatrix L). IFLAG(5)=2 must be" << std::endl
403 <<
"\tinitialized instead of IFLAG(5)=1." << std::endl);
407 silent_cerr(
"\tThe coefficient matrix A contains at least" << std::endl
408 <<
"\ttwo elements in the same position (i,j)." << std::endl
409 <<
"\tThe input data should be examined" << std::endl
410 <<
"\tcarefully in this case." << std::endl);
414 silent_cerr(
"\tThe number of equations in the system Ax=b" << std::endl
415 <<
"\tis smaller than 2 (i.e. N<2). The value" << std::endl
416 <<
"\tof N should be checked." << std::endl);
420 silent_cerr(
"\tThe number of non-zero elements of the" << std::endl
421 <<
"\tcoefficient matrix is non-positive (i.e." << std::endl
422 <<
"\tZ.le.0 ). The value of the parameter Z" << std::endl
423 <<
"\t(renamed NZ in Y12MF) should be checked." << std::endl);
427 silent_cerr(
"\tThe number of non-zero elements in the" << std::endl
428 <<
"\tcoefficient matrix is smaller than the" << std::endl
429 <<
"\tnumber of equations (i.e. Z < N ). If" << std::endl
430 <<
"\tthere is no mistake (i.e. if parameter Z," << std::endl
431 <<
"\trenamed NZ in Y12MF, is correctly assigned" << std::endl
432 <<
"\ton entry) then the coefficient matrix is" << std::endl
433 <<
"\tstructurally singular in this case." << std::endl);
437 silent_cerr(
"\tThe length IHA of the first dimension of" << std::endl
438 <<
"\tarray HA is smaller than N. IHA.ge.N" << std::endl
439 <<
"\tshould be assigned." << std::endl);
443 silent_cerr(
"\tThe value of parameter IFLAG(4) is not" << std::endl
444 <<
"\tassigned correctly. IFLAG(4) should be" << std::endl
445 <<
"\tequal to 0, 1 or 2. See more details in" << std::endl
446 <<
"\tthe description of this parameter." << std::endl);
450 silent_cerr(
"\tA row without non-zero elements has been" << std::endl
451 <<
"\tfound in the coefficient matrix A of the" << std::endl
452 <<
"\tsystem before the Gaussian elimination is" << std::endl
453 <<
"\tinitiated. Matrix A is structurally" << std::endl
454 <<
"\tsingular." << std::endl);
458 silent_cerr(
"\tA column without non-zero elements has" << std::endl
459 <<
"\tbeen found in the coefficient matrix A of" << std::endl
460 <<
"\tthe system before the Gaussian elimination" << std::endl
461 <<
"\tis initiated. Matrix A is structurally" << std::endl
462 <<
"\tsingular." << std::endl);
466 silent_cerr(
"\tParameter IFLAG(2) is smaller than 1. The" << std::endl
467 <<
"\tvalue of IFLAG(2) should be a positive" << std::endl
468 <<
"\tinteger (IFLAG(2) = 3 is recommended)." << std::endl);
472 silent_cerr(
"\tParameter IFLAG(3) is out of range." << std::endl
473 <<
"\tIFLAG(3) should be equal to 0, 1 or 2." << std::endl);
477 silent_cerr(
"\tParameter IFLAG(5) is out of range." << std::endl
478 <<
"\tIFLAG(5) should be equal to 1, 2 or 3 (but" << std::endl
479 <<
"\twhen IFLAG(5) = 3 Y12MB and Y12MC should" << std::endl
480 <<
"\tnot be called; see also the message for" << std::endl
481 <<
"\tIFAIL = 22 below)." << std::endl);
485 silent_cerr(
"\tEither subroutine Y12MB or subroutine" << std::endl
486 <<
"\tY12MC is called with IFLAG(5) = 3. Each of" << std::endl
487 <<
"\tthese subroutines should be called with" << std::endl
488 <<
"\tIFLAG(5) equal to 1 or 2." << std::endl);
492 silent_cerr(
"\tThe number of allowed iterations" << std::endl
493 <<
"\t(parameter IFLAG(11) when Y12MF is used)" << std::endl
494 <<
"\tis smaller than 2. IFLAG(11) .ge. 2" << std::endl
495 <<
"\tshould be assigned." << std::endl);
499 silent_cerr(
"\tAt least one element whose column number" << std::endl
500 <<
"\tis either larger than N or smaller than 1" << std::endl
501 <<
"\tis found." << std::endl);
505 silent_cerr(
"\tAt least one element whose row number is" << std::endl
506 <<
"\teither larger than N or smaller than 1 is" << std::endl
507 <<
"\tfound." << std::endl);
511 silent_cerr(
"\t Unhandled code." << std::endl);
515 silent_cerr(std::endl);
524 Y12SparseSolutionManager::Y12SparseSolutionManager(
integer iSize,
528 iColStart(iSize + 1),
534 ASSERT(((dPivotFactor >= 0.0) && (dPivotFactor <= 1.0)) || dPivotFactor == -1.0);
538 if (iWorkSpaceSize == 0) {
543 iWorkSpaceSize = 3*iSize*iSize;
547 if (dPivotFactor == 0.) {
554 iRow.reserve(iWorkSpaceSize);
555 iCol.reserve(iWorkSpaceSize);
556 dMat.reserve(iWorkSpaceSize);
560 Y12Solver(iMatSize, iWorkSpaceSize,
561 &dVec[0], iPivot, bDupInd));
563 pLS->SetSolutionManager(
this);
572 Y12SparseSolutionManager::~Y12SparseSolutionManager(
void)
584 Y12SparseSolutionManager::IsValid(
void)
const
588 #ifdef DEBUG_MEMMANAGER
596 Y12SparseSolutionManager::MatrReset(
void)
602 Y12SparseSolutionManager::MakeIndexForm(
void)
609 pLS->MakeCompactForm(MH, dMat, iRow, iCol, iColStart);
614 Y12SparseSolutionManager::Solve(
void)
624 std::cerr <<
"### after MakeIndexForm:" << std::endl
625 <<
"{col Ap[col]}={" << std::endl;
626 for (
unsigned i = 0; i < iColStart.size(); i++) {
627 std::cerr << i <<
" " << iColStart[i] << std::endl;
629 std::cerr <<
"}" << std::endl;
631 std::cerr <<
"{idx Ai[idx] col Ax[idx]}={" << std::endl;
633 for (
unsigned i = 0; i < dMat.size(); i++) {
634 std::cerr << i <<
" " << iRow[i] <<
" " << c <<
" " << dMat[i] << std::endl;
635 if (i == iColStart[c]) {
639 std::cerr <<
"}" << std::endl;
645 std::cerr <<
"### after Solve:" << std::endl
646 <<
"{col Ap[col]}={" << std::endl;
647 for (
unsigned i = 0; i < iColStart.size(); i++) {
648 std::cerr << i <<
" " << iColStart[i] << std::endl;
650 std::cerr <<
"}" << std::endl;
652 std::cerr <<
"{idx Ai[idx] col Ax[idx]}={" << std::endl;
654 for (
unsigned i = 0; i < dMat.size(); i++) {
655 std::cerr << i <<
" " << iRow[i] <<
" " << c <<
" " << dMat[i] << std::endl;
656 if (i == iColStart[c]) {
660 std::cerr <<
"}" << std::endl;
669 Y12SparseCCSolutionManager<CC>::Y12SparseCCSolutionManager(
integer Dim,
671 : Y12SparseSolutionManager(Dim, dummy, dPivot,
true),
679 Y12SparseCCSolutionManager<CC>::~Y12SparseCCSolutionManager(
void)
688 Y12SparseCCSolutionManager<CC>::MatrReset(
void)
696 Y12SparseCCSolutionManager<CC>::MakeIndexForm(
void)
699 pLS->MakeCompactForm(MH, dMat, iRow, iCol, iColStart);
703 CC(dMat, iRow, iColStart));
713 Y12SparseCCSolutionManager<CC>::MatrInitialize(
void)
723 Y12SparseCCSolutionManager<CC>::pMatHdl(
void)
const
733 template class Y12SparseCCSolutionManager<CColMatrixHandler<1> >;
734 template class Y12SparseCCSolutionManager<DirCColMatrixHandler<1> >;
virtual integer MakeIndexForm(doublereal *const Ax, integer *const Arow, integer *const Acol, integer *const AcolSt, int offset=0) const =0
#define MBDYN_EXCEPT_ARGS
#define SAFEDELETEARR(pnt)
#define ASSERT(expression)
#define SAFENEWWITHCONSTRUCTOR(pnt, item, constructor)
#define defaultMemoryManager
static std::stack< cleanup * > c
#define SAFENEWARR(pnt, item, sz)