OOFEM 3.0
Loading...
Searching...
No Matches
skyline.C
Go to the documentation of this file.
1/*
2 *
3 * ##### ##### ###### ###### ### ###
4 * ## ## ## ## ## ## ## ### ##
5 * ## ## ## ## #### #### ## # ##
6 * ## ## ## ## ## ## ## ##
7 * ## ## ## ## ## ## ## ##
8 * ##### ##### ## ###### ## ##
9 *
10 *
11 * OOFEM : Object Oriented Finite Element Code
12 *
13 * Copyright (C) 1993 - 2025 Borek Patzak
14 *
15 *
16 *
17 * Czech Technical University, Faculty of Civil Engineering,
18 * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19 *
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License as published by the Free Software Foundation; either
23 * version 2.1 of the License, or (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * Lesser General Public License for more details.
29 *
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library; if not, write to the Free Software
32 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 */
34
35#include "skyline.h"
36#include "floatmatrix.h"
37#include "intarray.h"
38#include "domain.h"
39#include "engngm.h"
40#include "element.h"
41#include "mathfem.h"
42#include "verbose.h"
43#include "sparsemtrxtype.h"
44#include "classfactory.h"
45#include "activebc.h"
47#ifdef __MPM_MODULE
48#include "../mpm/integral.h"
49#endif
50
51#include <climits>
52#include <cstdlib>
53#include <utility>
54
55#ifdef TIME_REPORT
56 #include "timer.h"
57#endif
58
59namespace oofem {
61
62Skyline :: Skyline(int n) : SparseMtrx(n, n),
63 isFactorized(false)
64{
65}
66
67
68Skyline :: Skyline(const Skyline &s) : SparseMtrx(s.giveNumberOfRows(), s.giveNumberOfColumns()),
69 mtrx(s.mtrx),
70 adr(s.adr),
72{}
73
74
75Skyline :: Skyline(int n, FloatArray mtrx1, IntArray adr1) : SparseMtrx(n, n),
76 mtrx(std::move(mtrx1)),
77 adr(std::move(adr1)),
78 isFactorized(false)
79{}
80
81
82std::unique_ptr<SparseMtrx> Skyline :: clone() const
83{
84 return std::make_unique<Skyline>(*this);
85}
86
87
88double &
89Skyline :: at(int i, int j)
90{
91#ifdef DEBUG
92 // check size
93 if ( ( i > this->giveNumberOfRows() ) || ( j > this->giveNumberOfRows() ) ) {
94 OOFEM_ERROR("dimension mismatch - accessing value at (%d,%d)", i, j);
95 }
96
97#endif
98 // only upper triangular part of skyline is stored
99 if ( j < i ) {
100 std::swap(i, j);
101 }
102
103 int d1 = this->adr.at(j);
104 int ind = d1 + ( j - i );
105
106 if ( ( adr.at(j + 1) - adr.at(j) ) <= ( j - i ) ) {
107 OOFEM_ERROR("request for element which is not in sparse mtrx (%d,%d)", i, j);
108 //
109 // NOTE:
110 //
111 // don't return reference to some zero value; it is true, but possible change
112 // of its value will require rebuilding internal storage structure
113 // of sparse matrix
114 //
115 }
116
117 this->version++;
118 return mtrx [ ind ];
119}
120
121double
122Skyline :: at(int i, int j) const
123{
124#ifdef DEBUG
125 // check size
126 if ( ( i > this->giveNumberOfRows() ) || ( j > this->giveNumberOfRows() ) ) {
127 OOFEM_ERROR("dimension mismatch, when accessing value at (%d,%d)", i, j);
128 }
129
130#endif
131 // only upper triangular part of skyline is stored
132 if ( j < i ) {
133 std::swap(i, j);
134 }
135
136 int d1 = this->adr.at(j);
137 int ind = d1 + ( j - i );
138
139 if ( ( adr.at(j + 1) - adr.at(j) ) <= ( j - i ) ) {
140 return 0.;
141 }
142
143 return mtrx [ ind ];
144}
145
146
147bool
148Skyline :: isAllocatedAt(int i, int j) const
149{
150 if ( j < i ) {
151 std::swap(i, j);
152 }
153
154 if ( ( adr.at(j + 1) - adr.at(j) ) <= ( j - i ) ) {
155 return false;
156 }
157
158 return true;
159}
160
161
162void
163Skyline :: toFloatMatrix(FloatMatrix &answer) const
164{
165 int size = this->giveNumberOfColumns();
166
167# ifdef DEBUG
168 if ( size != this->adr.giveSize() - 1 ) {
169 OOFEM_ERROR("Internal error in skyline matrix: num columns != size(adr)-1: %d != %d", size, this->adr.giveSize() - 1);
170 }
171# endif
172
173 answer.resize(size, size);
174 answer.zero();
175
176 for ( int j = 1; j <= size; j++ ) {
177 int d1 = adr.at(j);
178 int d2 = adr.at(j + 1);
179 int pk = j;
180 for ( int i = d1; i < d2; i++ ) {
181 answer.at(pk, j) = mtrx [ i ];
182 pk--;
183 }
184 }
185 answer.symmetrized();
186}
187
188
189int Skyline :: assemble(const IntArray &loc, const FloatMatrix &mat)
190{
191# ifdef DEBUG
192 int dim = mat.giveNumberOfRows();
193 if ( dim != loc.giveSize() ) {
194 OOFEM_ERROR("dimension of 'mat' and 'loc' mismatch");
195 }
196
197# endif
198
199 int ndofe = mat.giveNumberOfRows();
200
201 for ( int i = 1; i <= ndofe; i++ ) {
202 int ac1 = loc.at(i);
203 if ( ac1 == 0 ) {
204 continue;
205 }
206
207 for ( int j = 1; j <= ndofe; j++ ) {
208 int ac2 = loc.at(j);
209 if ( ac2 == 0 ) {
210 continue;
211 }
212
213 if ( ac1 > ac2 ) {
214 continue;
215 }
216
217 mtrx [ adr.at(ac2) + ac2 - ac1 ] += mat.at(i, j);
218 }
219 }
220
221 this->version++;
222 return 1;
223}
224
225
226int Skyline :: assemble(const IntArray &rloc, const IntArray &cloc, const FloatMatrix &mat)
227{
228 int dim1 = mat.giveNumberOfRows();
229 int dim2 = mat.giveNumberOfColumns();
230 for ( int i = 1; i <= dim1; i++ ) {
231 int ii = rloc.at(i);
232 if ( ii ) {
233 for ( int j = 1; j <= dim2; j++ ) {
234 int jj = cloc.at(j);
235 if ( jj && ii <= jj ) {
236 this->at(ii, jj) += mat.at(i, j);
237 }
238 }
239 }
240 }
241
242 this->version++;
243
244 return 1;
245}
246
247
248FloatArray *Skyline :: backSubstitutionWith(FloatArray &y) const
249{
250 // allocation of answer
251 FloatArray solution( y.giveSize() );
252 int n = this->giveNumberOfRows();
253
254 /************************************/
255 /* modification of right hand side */
256 /************************************/
257 for ( int k = 2; k <= n; k++ ) {
258 int ack = adr.at(k);
259 int ack1 = adr.at(k + 1);
260 double s = 0.0;
261 int acs = k - ( ack1 - ack ) + 1;
262 for ( int i = ack1 - 1; i > ack; i-- ) {
263 s += mtrx [ i ] * y.at(acs);
264 acs++;
265 }
266
267 y.at(k) -= s;
268 }
269
270 /*****************/
271 /* zpetny chod */
272 /*****************/
273 for ( int k = 1; k <= n; k++ ) {
274 y.at(k) /= mtrx [ adr.at(k) ];
275 }
276
277 for ( int k = n; k > 0; k-- ) {
278 int ack = adr.at(k);
279 int ack1 = adr.at(k + 1);
280 solution.at(k) = y.at(k);
281 int acs = k - ( ack1 - ack ) + 1;
282 for ( int i = ack1 - 1; i > ack; i-- ) {
283 y.at(acs) -= mtrx [ i ] * solution.at(k);
284 acs++;
285 }
286 }
287
288 y = solution;
289 return & y;
290}
291
292int Skyline :: setInternalStructure(IntArray a)
293{
294 adr = std::move(a);
295 int n = adr.giveSize();
296 int nwk = adr.at(n);
297 this->mtrx.resize(nwk);
298
299 nRows = nColumns = n - 1;
300
301 this->version++;
302 return true;
303}
304
305
306int Skyline :: buildInternalStructure(EngngModel *eModel, int di, const UnknownNumberingScheme &s)
307{
308 // first create array of
309 // maximal column height for assembled characteristics matrix
310 //
311
312 int maxle;
313 int ac1;
314 int neq;
315 if ( s.isDefault() ) {
316 neq = eModel->giveNumberOfDomainEquations(di, s);
317 } else {
319 }
320 if ( neq == 0 ) {
321 mtrx.clear();
322 adr.clear();
323 return true;
324 }
325
326 IntArray loc;
327 IntArray mht(neq);
328 Domain *domain = eModel->giveDomain(di);
329
330 for ( int j = 1; j <= neq; j++ ) {
331 mht.at(j) = j; // initialize column height, maximum is line number (since it only stores upper triangular)
332 }
333
334 // loop over elements code numbers
335 for ( auto &elem : domain->giveElements() ) {
336 elem->giveLocationArray(loc, s);
337 maxle = INT_MAX;
338 for ( int ieq : loc ) {
339 if ( ieq != 0 ) {
340 maxle = min(maxle, ieq);
341 }
342 }
343
344 for ( int ieq : loc ) {
345 if ( ieq != 0 ) {
346 mht.at(ieq) = min( maxle, mht.at(ieq) );
347 }
348 }
349 }
350
351 // loop over active boundary conditions (e.g. relative kinematic constraints)
352 std :: vector< IntArray >r_locs;
353 std :: vector< IntArray >c_locs;
354
355 for ( auto &gbc : domain->giveBcs() ) {
356 ActiveBoundaryCondition *bc = dynamic_cast< ActiveBoundaryCondition * >( gbc.get() );
357 if ( bc != NULL ) {
358 bc->giveLocationArrays(r_locs, c_locs, UnknownCharType, s, s);
359 for ( std :: size_t k = 0; k < r_locs.size(); k++ ) {
360 IntArray &krloc = r_locs [ k ];
361 IntArray &kcloc = c_locs [ k ];
362 maxle = INT_MAX;
363 for ( int ii : krloc ) {
364 if ( ii > 0 ) {
365 maxle = min(maxle, ii);
366 }
367 }
368 for ( int jj : kcloc ) {
369 if ( jj > 0 ) {
370 mht.at(jj) = min( maxle, mht.at(jj) );
371 }
372 }
373 }
374 }
375 }
376
377#ifdef __MPM_MODULE
378 IntArray locr, locc;
379 // loop over integrals
380 for (auto &in: eModel->giveIntegralList()) {
381 // loop over integral domain
382 for (auto &elem: in->set->giveElementList()) {
383 // get code numbers for integral.term on element
384 in->getElementTermCodeNumbers (locr, locc, domain->giveElement(elem), *in->term, s) ;
385 maxle = INT_MAX;
386 for ( int ii : locr ) {
387 if ( ii > 0 ) {
388 maxle = min(maxle, ii);
389 }
390 }
391 for ( int jj : locc ) {
392 if ( jj > 0 ) {
393 mht.at(jj) = min( maxle, mht.at(jj) );
394 }
395 }
396 }
397 }
398#endif
399
400
401
402 // NOTE
403 // add there call to eModel if any possible additional equation added by
404 // eModel
405 // currently not supported
406
407 // increases number of columns according to size of mht
408 // mht is array containing minimal equation number per column
409 // This method also increases column height.
410
411 adr.resize(neq + 1);
412
413 ac1 = 1;
414 for ( int i = 1; i <= neq; i++ ) {
415 adr.at(i) = ac1;
416 ac1 += ( i - mht.at(i) + 1 );
417 }
418
419 adr.at(neq + 1) = ac1;
420 nRows = nColumns = neq;
421
422 mtrx.resize( ac1 );
423
424 this->version++;
425 return true;
426}
427
428
429SparseMtrx *Skyline :: factorized()
430{
431 // Returns the receiver in U(transp).D.U Crout factorization form.
432
433 if ( isFactorized ) {
434 return this;
435 }
436
437#ifdef TIME_REPORT
438 Timer timer;
439 timer.startTimer();
440#endif
441
442 int n = this->giveNumberOfRows();
443
444 OOFEM_LOG_DEBUG("Skyline info: neq is %d, nwk is %d\n", n, this->giveNumberOfNonZeros());
445
446 for ( int k = 2; k <= n; k++ ) {
447 /* smycka pres sloupce matice */
448 int ack = adr.at(k);
449 int ack1 = adr.at(k + 1);
450 int acrk = k - ( ack1 - ack ) + 1;
451 for ( int i = acrk + 1; i < k; i++ ) {
452 /* smycka pres prvky jednoho sloupce matice */
453 int aci = adr.at(i);
454 int aci1 = adr.at(i + 1);
455 int acri = i - ( aci1 - aci ) + 1;
456 int ac;
457 if ( acri < acrk ) {
458 ac = acrk;
459 } else {
460 ac = acri;
461 }
462
463 int acj = k - ac + ack;
464 int acj1 = k - i + ack;
465 int acs = i - ac + aci;
466 double s = 0.0;
467 for ( int j = acj; j > acj1; j-- ) {
468 s += mtrx [ j ] * mtrx [ acs ];
469 acs--;
470 }
471
472 mtrx [ acj1 ] -= s;
473 }
474
475 /* uprava diagonalniho prvku */
476 double s = 0.0;
477 for ( int i = ack1 - 1; i > ack; i-- ) {
478 double g = mtrx [ i ];
479 int acs = adr.at(acrk);
480 acrk++;
481 mtrx [ i ] /= mtrx [ acs ];
482 s += mtrx [ i ] * g;
483 }
484
485 mtrx [ ack ] -= s;
486 }
487
488 isFactorized = true;
489
490#ifdef TIME_REPORT
491 timer.stopTimer();
492 OOFEM_LOG_DEBUG( "Skyline info: user time consumed by factorization: %.2fs\n", timer.getUtime() );
493#endif
494
495 //this->version++;
496 return this;
497}
498
499
500void Skyline :: times(const FloatArray &x, FloatArray &answer) const
501{
502 // Computes y, the results of the y = U.x, where U is
503 // the receiver. Returns the result.
504
505 int n = x.giveSize();
506
507 //
508 // first check sizes
509 //
510 if ( this->giveNumberOfRows() != n ) {
511 OOFEM_ERROR("size mismatch");
512 }
513
514 answer.resize(n);
515 answer.zero();
516
517 int acc = 1;
518 for ( int i = 1; i <= n; i++ ) {
519 int aci = adr.at(i);
520 int aci1 = adr.at(i + 1);
521 int ac = i - ( aci1 - aci ) + 1;
522 double s = 0.0;
523 int acb = ac;
524 for ( int k = aci1 - 1; k >= aci; k-- ) {
525 s += mtrx [ k ] * x.at(acb);
526 acb++;
527 }
528
529 answer.at(acc) = s;
530 acc++;
531
532 for ( int j = ac; j < i; j++ ) {
533 aci1--;
534 answer.at(j) += mtrx [ aci1 ] * x.at(i);
535 aci++;
536 }
537 }
538}
539
540
541void Skyline :: times(double x)
542{
543 // Multiplies receiver by scalar value.
544 mtrx.times(x);
545
546 this->version++;
547}
548
549
550void Skyline :: add(double x, SparseMtrx &m)
551{
552 Skyline *M = dynamic_cast< Skyline* >( &m );
553
554 mtrx.add(x, M->mtrx);
555
556 this->version++;
557}
558
559
560void Skyline :: printYourself() const
561{
562 // Prints the receiver on screen.
563 FloatMatrix copy;
564 this->toFloatMatrix(copy);
565 copy.printYourself();
566}
567
568
569void Skyline :: writeToFile(const char *fname) const
570{
571 FILE *file = fopen(fname, "w");
572 FloatMatrix copy;
573 this->toFloatMatrix(copy);
574 for ( int i = 1; i <= nRows; ++i ) {
575 for ( int j = 1; j <= nColumns; ++j ) {
576 fprintf( file, "%10.3e ", copy.at(i, j) );
577 }
578 fprintf(file, "\n");
579 }
580 fclose(file);
581}
582
583
584void Skyline :: zero()
585{
586 mtrx.zero();
587 isFactorized = false;
588
589 this->version++;
590}
591
592
593std::unique_ptr<SparseMtrx> Skyline :: giveSubMatrix(const IntArray &rows, const IntArray &cols)
594{
595 IntArray positions( cols.giveSize() + 1 );
596
597 FloatArray values( this->giveNumberOfNonZeros() ); //TODO choose a better initial size?
598 int diagPos = 1;
599 int nnz = 0; // number of nonzeros
600
601 for ( int j = 1; j <= cols.giveSize(); j++ ) {
602 for ( int i = rows.giveSize(); i >= 1; i-- ) { // start from the "bottom of the matrix"
603 if( j < i ){
604 continue;
605 }
606
607 bool hasValue = this->isAllocatedAt( rows.at(i), cols.at(j) );
608
609 if ( hasValue && i == j ) { // allocated diagonal element
610 values.at(++nnz) = this->at( rows.at(i), cols.at(j) );
611 positions.at(diagPos++) = nnz;
612 } else if ( i == j ) { // empty diagonal element
613 values.at(++nnz) = 0.0;
614 positions.at(diagPos++) = nnz;
615 } else if ( hasValue ) {
616 values.at(++nnz) = this->at( rows.at(i), cols.at(j) );
617 }
618 }
619 }
620
621 positions.at(diagPos++) = ++nnz;
622
623 FloatArray mtrxValues(nnz);
624
625 for ( int i = 0; i < nnz-1; i++ ) {
626 mtrxValues [ i + 1] = values [ i ];
627 }
628 int neq = rows.giveSize();
629
630 return std::make_unique<Skyline>(neq, mtrxValues, positions);
631}
632
633
634void Skyline :: rbmodes(FloatMatrix &r, int &nse, IntArray &se,
635 double limit, int tc)
636{
637 /*
638 * funkce rozlozi matici A na LDL tvar, pak vypocte
639 * bazove vektory prostoru Ker A
640 */
641 int neq = this->giveNumberOfRows();
642 IntArray adrb(7);
643 FloatArray b(6 *neq);
644
645 /**********************/
646 /* rozklad matice A */
647 /**********************/
648
649 // report skyline statistics
650 OOFEM_LOG_INFO("Skyline info: neq is %d, nwk is %d\n", neq, this->giveNumberOfNonZeros());
651
652 if ( tc == 1 || tc == 3 ) {
653 /* pocitadlo singularnich rovnic */
654 int ise = 1;
655 /* pocitadlo v poli singularnich radku */
656 int ib = 1;
657 adrb.at(1) = 1;
658
659 /* cyklus pres radky, ktere maji byt odkondezovany */
660 for ( int i = 2; i <= neq; i++ ) {
661 int lj = adr.at(i);
662 int uj = adr.at(i + 1) - 2;
663
664 /* minimalni radkovy index v i tem sloupci */
665 int mi = i - ( uj - lj ) - 1;
666 int j = mi + 1;
667
668 /* cyklus pres mimodiagonalni prvky zpracovavaneho radku */
669 for ( int jj = uj; jj > lj; jj-- ) {
670 int li = adr.at(j);
671 int ui = adr.at(j + 1) - 1;
672 int k = j - ( ui - li );
673
674 /* vyber nizsiho sloupce a tim urceni rozsahu cyklu */
675 int uk, ii;
676 if ( k < mi ) {
677 uk = uj + 1;
678 ii = li + j - mi;
679 } else {
680 uk = lj + i - k;
681 ii = ui;
682 }
683
684 /* cyklus pres prvky nad zpracovavanym prvkem */
685 double s = 0.0;
686 for ( int kk = uk; kk > jj; kk-- ) {
687 s += mtrx [ kk ] * mtrx [ ii ];
688 ii--;
689 }
690
691 mtrx [ jj ] -= s;
692 j++;
693 }
694
695 /* uprava diagonalniho prvku */
696 double s = 0.0;
697 j = mi;
698 for ( int jj = uj + 1; jj > lj; jj-- ) {
699 double g = mtrx [ jj ];
700 mtrx [ jj ] /= mtrx [ adr.at(j) ];
701 s += mtrx [ jj ] * g;
702 j++;
703 }
704
705 mtrx [ lj ] -= s;
706
707 /* kontrola diagonalniho prvku */
708 if ( fabs(mtrx [ lj ]) < limit ) {
709 /* pole cisel singularnich rovnic */
710 se.at(ise) = i;
711 ise++;
712
713 /* vynulovani prvku sloupce v poli a a jejich uchovani v poli b */
714 for ( int jj = uj + 1; jj > lj; jj-- ) {
715 b.at(ib) = mtrx [ jj ];
716 ib++;
717 mtrx [ jj ] = 0.0;
718 }
719
720 mtrx [ lj ] = 1.0;
721 /* pole adres zacatku v poli obsahujicim singularni radky */
722 adrb.at(ise) = ib;
723
724 /* vynulovani prvku radku v poli a */
725 for ( int jj = i + 1; jj <= neq; jj++ ) {
726 if ( jj - ( adr.at(jj + 1) - adr.at(jj) ) < i ) {
727 mtrx [ adr.at(jj) + jj - i ] = 0.0;
728 }
729 }
730 }
731 }
732
733 nse = ise - 1;
734 }
735
736 if ( tc == 2 || tc == 3 ) {
737 /* navrat puvodne vynulovanych slozek */
738 int ise = nse;
739 for ( int i = 1; i <= ise; i++ ) {
740 int uj = adr.at(se.at(i) + 1) - 1;
741 int lj = adr.at( se.at(i) );
742 int ib = adrb.at(i);
743 for ( int jj = uj; jj > lj; jj-- ) {
744 mtrx [ jj ] = b.at(ib);
745 ib++;
746 }
747 }
748
749 /* sestaveni baze ker A */
750 if ( ise ) {
751 r.resize(neq, ise);
752 r.zero();
753 } else {
754 r.clear();
755 }
756
757 for ( int i = 1; i <= ise; i++ ) {
758 for ( int j = neq; j > 0; j-- ) {
759 r.at(se.at(i), i) = 1.0;
760 int uk = adr.at(j + 1) - 1;
761 int lk = adr.at(j);
762 int k = j - ( uk - lk );
763 for ( int kk = uk; kk > lk; kk-- ) {
764 r.at(k, i) -= mtrx [ kk ] * r.at(j, i);
765 k++;
766 }
767 }
768 }
769 }
770
771 //this->version++;
772}
773
774
775void Skyline :: ldl_feti_sky(FloatArray &x, FloatArray &y,
776 int nse, double limit, IntArray &se)
777/*
778 * funkce resi cast soustavy rovnic v metode FETI
779 * matice soustavy a je ulozena ve skyline
780 * matice soustavy muze byt singularni
781 * matice soustavy musi byt jiz rozlozena na tvar LDL
782 *
783 * vstupy
784 * y - vektor prave strany
785 * adr - pole adres diagonalnich prvku
786 * n - pocet neznamych
787 * m - pocet neznamych redukovaneho problemu
788 * nse - pocet linearne zavislych rovnic
789 * limit - promenna urcujici linearni zavislost
790 * se - pole cisel singularnich rovnic
791 *
792 * vystupy
793 * x - vektor reseni
794 */
795{
796 int neq = this->giveNumberOfRows();
797
798 /*******************************************************/
799 /* vypocet pomocneho vektoru z */
800 /* vektor prave strany ma na prvnich m pozicich nuly */
801 /* pro vektor z se nealokuje nove pole */
802 /* slozky vektoru y se prepisuji na slozky vektoru z */
803 /*******************************************************/
804 //k = 0;
805 for ( int i = 1; i <= neq; i++ ) {
806 int lj = adr.at(i);
807 int uj = adr.at(i + 1) - 1;
808 int ii = i - uj + lj;
809 double s = 0.0;
810 for ( int j = uj; j > lj; j-- ) {
811 s += mtrx [ j ] * y.at(ii);
812 ii++;
813 }
814
815 /*
816 * if (se[k]==i){
817 * y[i]=0.0; k++;
818 * }
819 * else{
820 */
821
822 y.at(i) -= s;
823
824 /* }*/
825 }
826
827 /********************************************************/
828 /* kontrola zeliminovaneho vektoru prave strany */
829 /* pokud na nektere pozici se[i] bude nenulove cislo, */
830 /* je soustava neresitelna, protoze se lisi hodnosti */
831 /* matice soustavy a rozsirene matice soustavy */
832 /********************************************************/
833
834 /*
835 * fprintf (s2,"\n");
836 * for (i=1;i<=nse;i++){
837 * fprintf (s2,"\n eliminovana prava strana singularni rovnice %ld %le",se->at(i),y->at(se->at(i)));
838 */
839 /*
840 * if (fabs(y[se[i]])>limit){
841 * fprintf (s2,"\n\n v %ld. linearne zavisle rovnici je nenulovy prvek",se[i]);
842 * fprintf (s2,"\n ve vektoru zeliminovane prave strany.");
843 * }
844 */
845 /*
846 * }
847 */
848
849 /**********************************************************/
850 /* deleni prvku vektoru prave strany diagonalnimi prvky */
851 /**********************************************************/
852 for ( int i = 1; i <= neq; i++ ) {
853 y.at(i) /= mtrx [ adr.at(i) ];
854 }
855
856 /*****************************************************/
857 /* vypocet vektoru x z vektoru z */
858 /* vypocet se provadi pro m redukovanych neznamych */
859 /*****************************************************/
860 int k = nse;
861 for ( int i = neq; i > 0; i-- ) {
862 int lj = adr.at(i);
863 int uj = adr.at(i + 1);
864 if ( k > 0 ) {
865 if ( se.at(k) == i ) {
866 y.at(i) = 1.0;
867 k--;
868 }
869 }
870
871 x.at(i) = y.at(i);
872 double s = x.at(i);
873 int ii = i - 1;
874 for ( int j = lj + 1; j < uj; j++ ) {
875 y.at(ii) -= s * mtrx [ j ];
876 ii--;
877 }
878 }
879
880 //this->version++;
881}
882} // end namespace oofem
#define REGISTER_SparseMtrx(class, type)
virtual void giveLocationArrays(std ::vector< IntArray > &rows, std ::vector< IntArray > &cols, CharType type, const UnknownNumberingScheme &r_s, const UnknownNumberingScheme &c_s)
Definition activebc.h:137
std ::vector< std ::unique_ptr< GeneralBoundaryCondition > > & giveBcs()
Definition domain.h:349
Element * giveElement(int n)
Definition domain.C:165
std ::vector< std ::unique_ptr< Element > > & giveElements()
Definition domain.h:294
virtual int giveNumberOfDomainEquations(int di, const UnknownNumberingScheme &num)
Definition engngm.C:452
Domain * giveDomain(int n)
Definition engngm.C:1936
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
*Sets size of receiver to be an empty matrix It will have zero rows and zero columns size void clear()
int giveNumberOfColumns() const
Returns number of columns of receiver.
void zero()
Zeroes all coefficient of receiver.
*Prints matrix to stdout Useful for debugging void printYourself() const
int giveNumberOfRows() const
Returns number of rows of receiver.
double at(std::size_t i, std::size_t j) const
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
void toFloatMatrix(FloatMatrix &answer) const override
Converts receiving sparse matrix to a dense float matrix.
Definition skyline.C:163
IntArray adr
Integer array holding addresses of diagonal members.
Definition skyline.h:74
Skyline(int n=0)
Definition skyline.C:62
bool isAllocatedAt(int i, int j) const override
Checks whether memory is allocated at position (i,j).
Definition skyline.C:148
int giveNumberOfNonZeros() const
Definition skyline.h:138
FloatArray mtrx
Vector of stored coefficients.
Definition skyline.h:72
double & at(int, int) override
Returns coefficient at position (i,j).
Definition skyline.C:89
int isFactorized
Flag indicating whether factorized.
Definition skyline.h:76
int nColumns
Number of columns.
Definition sparsemtrx.h:71
SparseMtrxVersionType version
Definition sparsemtrx.h:82
int giveNumberOfRows() const
Returns number of rows of receiver.
Definition sparsemtrx.h:114
int giveNumberOfColumns() const
Returns number of columns of receiver.
Definition sparsemtrx.h:116
SparseMtrx(int n=0, int m=0)
Definition sparsemtrx.h:89
int nRows
Number of rows.
Definition sparsemtrx.h:69
double getUtime()
Returns total user time elapsed in seconds.
Definition timer.C:105
void startTimer()
Definition timer.C:69
void stopTimer()
Definition timer.C:77
virtual int giveRequiredNumberOfDomainEquation() const
#define OOFEM_ERROR(...)
Definition error.h:79
#define OOFEM_LOG_INFO(...)
Definition logger.h:143
#define OOFEM_LOG_DEBUG(...)
Definition logger.h:144
FloatArrayF< N > min(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
@ SMT_Skyline
Symmetric skyline.

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011