OOFEM 3.0
Loading...
Searching...
No Matches
compcol.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// inspired by
36/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
37/* ******** *** SparseLib++ */
38/* ******* ** *** *** *** v. 1.5c */
39/* ***** *** ******** ******** */
40/* ***** *** ******** ******** R. Pozo */
41/* ** ******* *** ** *** *** K. Remington */
42/* ******** ******** A. Lumsdaine */
43/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
44/* */
45/* */
46/* SparseLib++ : Sparse Matrix Library */
47/* */
48/* National Institute of Standards and Technology */
49/* University of Notre Dame */
50/* Authors: R. Pozo, K. Remington, A. Lumsdaine */
51/* */
52/* NOTICE */
53/* */
54/* Permission to use, copy, modify, and distribute this software and */
55/* its documentation for any purpose and without fee is hereby granted */
56/* provided that the above notice appear in all copies and supporting */
57/* documentation. */
58/* */
59/* Neither the Institutions (National Institute of Standards and Technology, */
60/* University of Notre Dame) nor the Authors make any representations about */
61/* the suitability of this software for any purpose. This software is */
62/* provided ``as is'' without expressed or implied warranty. */
63/* */
64/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
65
66/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
67/* Compressed column sparse matrix (0-based) */
68/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
69
70#include "compcol.h"
71#include "floatarray.h"
72#include "engngm.h"
73#include "domain.h"
74#include "element.h"
75#include "sparsemtrxtype.h"
76#include "activebc.h"
77#include "classfactory.h"
78#ifdef __MPM_MODULE
79#include "../mpm/integral.h"
80#endif
81
82#include <set>
83
84namespace oofem {
86
87
88CompCol :: CompCol(int n) : SparseMtrx(n, n),
89 val(0),
90 rowind(0),
91 colptr(n),
92 base(0),
93 nz(0)
94{}
95
96
97CompCol :: CompCol(const CompCol &S) : SparseMtrx(S.nRows, S.nColumns),
98 val(S.val),
100 colptr(S.colptr),
101 base(S.base),
102 nz(S.nz)
103{}
104
105
106CompCol &CompCol :: operator = ( const CompCol & C )
107{
108 nRows = C.nRows;
109 nColumns = C.nColumns;
110
111 base = C.base;
112 nz = C.nz;
113 val = C.val;
114 rowind = C.rowind;
115 colptr = C.colptr;
116 this->version = C.version;
117
118 return * this;
119}
120
121
122std::unique_ptr<SparseMtrx> CompCol :: clone() const
123{
124 return std::make_unique<CompCol>(*this);
125}
126
127
128void CompCol :: times(const FloatArray &x, FloatArray &answer) const
129{
130 if ( x.giveSize() != this->giveNumberOfColumns() ) {
131 OOFEM_ERROR("incompatible dimensions");
132 }
133
134 answer.resize(this->giveNumberOfRows());
135 answer.zero();
136
137 for ( int j = 0; j < this->giveNumberOfColumns(); j++ ) {
138 double rhs = x[j];
139 for ( int t = colptr[j]; t < colptr[j + 1]; t++ ) {
140 answer[ rowind[t] ] += val[t] * rhs;
141 }
142 }
143}
144
145
146void CompCol :: timesT(const FloatArray &x, FloatArray &answer) const
147{
148 if ( x.giveSize() != this->giveNumberOfRows() ) {
149 OOFEM_ERROR("Error in CompCol -- incompatible dimensions");
150 }
151
152 answer.resize(this->giveNumberOfColumns());
153 answer.zero();
154
155 for ( int i = 0; i < this->giveNumberOfColumns(); i++ ) {
156 double r = 0.0;
157 for ( int t = colptr[i]; t < colptr[i + 1]; t++ ) {
158 r += val[t] * x[ rowind[t] ];
159 }
160
161 answer[i] = r;
162 }
163}
164
165
166void CompCol :: times(double x)
167{
168 val.times(x);
169
170 this->version++;
171}
172
173
174int CompCol :: buildInternalStructure(EngngModel *eModel, int di, const UnknownNumberingScheme &s)
175{
176 IntArray loc;
177 Domain *domain = eModel->giveDomain(di);
178 int neq = eModel->giveNumberOfDomainEquations(di, s);
179 // allocation map
180 std :: vector< std :: set< int > > columns(neq);
181
182 this->nz = 0;
183
184 for ( auto &elem : domain->giveElements() ) {
185 elem->giveLocationArray(loc, s);
186
187 for ( int ii : loc ) {
188 if ( ii > 0 ) {
189 for ( int jj : loc ) {
190 if ( jj > 0 ) {
191 columns [ jj - 1 ].insert(ii - 1);
192 }
193 }
194 }
195 }
196 }
197
198
199 // loop over active boundary conditions
200 std :: vector< IntArray >r_locs;
201 std :: vector< IntArray >c_locs;
202
203 for ( auto &gbc : domain->giveBcs() ) {
204 ActiveBoundaryCondition *bc = dynamic_cast< ActiveBoundaryCondition * >( gbc.get() );
205 if ( bc != NULL ) {
206 bc->giveLocationArrays(r_locs, c_locs, UnknownCharType, s, s);
207 for ( std :: size_t k = 0; k < r_locs.size(); k++ ) {
208 IntArray &krloc = r_locs [ k ];
209 IntArray &kcloc = c_locs [ k ];
210 for ( int ii : krloc ) {
211 if ( ii ) {
212 for ( int jj : kcloc ) {
213 if ( jj ) {
214 columns [ jj - 1 ].insert(ii - 1);
215 }
216 }
217 }
218 }
219 }
220 }
221 }
222
223#ifdef __MPM_MODULE
224 IntArray locr, locc;
225 // loop over integrals
226 for (auto &in: eModel->giveIntegralList()) {
227 // loop over integral domain
228 for (auto &elem: in->set->giveElementList()) {
229 // get code numbers for integral.term on element
230 in->getElementTermCodeNumbers (locr, locc, domain->giveElement(elem), *in->term, s) ;
231 for ( int ii : locr ) {
232 if ( ii ) {
233 for ( int jj : locc ) {
234 if ( jj ) {
235 columns [ jj - 1 ].insert(ii - 1);
236 }
237 }
238 }
239 }
240 }
241 }
242#endif
243
244 for ( int i = 0; i < neq; i++ ) {
245 this->nz += columns [ i ].size();
246 }
247
248 rowind.resize(nz);
249 colptr.resize(neq + 1);
250 int indx = 0;
251
252 for ( int j = 0; j < neq; j++ ) { // column loop
253 colptr[j] = indx;
254 for ( int row: columns [ j ] ) { // row loop
255 rowind[indx++] = row;
256 }
257 }
258
259 colptr[neq] = indx;
260
261 // allocate value array
262 val.resize(nz);
263 val.zero();
264
265 OOFEM_LOG_DEBUG("CompCol info: neq is %d, nwk is %d\n", neq, nz);
266
267 nColumns = nRows = neq;
268
269 this->version++;
270
271 return true;
272}
273
274
275int CompCol :: assemble(const IntArray &loc, const FloatMatrix &mat)
276{
277 int dim = mat.giveNumberOfRows();
278
279# ifdef DEBUG
280 if ( dim != loc.giveSize() ) {
281 OOFEM_ERROR("dimension of 'k' and 'loc' mismatch");
282 }
283# endif
284
285 for ( int j = 0; j < dim; j++ ) {
286 int jj = loc[j];
287 if ( jj ) {
288 int cstart = colptr[jj - 1];
289 int t = cstart;
290 int last_ii = this->nRows + 1; // Ensures that t is set correctly the first time.
291 for ( int i = 0; i < dim; i++ ) {
292 int ii = loc[i];
293 if ( ii ) {
294 // Some heuristics that speed up most cases ( benifits are large for incremental sub-blocks, e.g. locs = [123, 124, 125, 245, 246, 247] ):
295 if ( ii < last_ii )
296 t = cstart;
297 else if ( ii > last_ii )
298 t++;
299 for ( ; rowind[t] < ii - 1; t++ ) {
300# ifdef DEBUG
301 if ( t >= colptr[jj] )
302 OOFEM_ERROR("Couldn't find row %d in the sparse structure", ii);
303# endif
304 }
305 val[t] += mat(i, j);
306 last_ii = ii;
307 }
308 }
309 }
310 }
311
312 // increment version
313 this->version++;
314
315 return 1;
316}
317
318int CompCol :: assemble(const IntArray &rloc, const IntArray &cloc, const FloatMatrix &mat)
319{
320 int dim1, dim2;
321
322 dim1 = mat.giveNumberOfRows();
323 dim2 = mat.giveNumberOfColumns();
324
325 for ( int j = 0; j < dim2; j++ ) {
326 int jj = cloc[j];
327 if ( jj ) {
328 int cstart = colptr[jj - 1];
329 int t = cstart;
330 int last_ii = this->nRows + 1; // Ensures that t is set correctly the first time.
331 for ( int i = 0; i < dim1; i++ ) {
332 int ii = rloc[i];
333 if ( ii ) {
334 // Some heuristics that speed up most cases ( benifits are large for incremental sub-blocks, e.g. locs = [123, 124, 125, 245, 246, 247] ):
335 if ( ii < last_ii )
336 t = cstart;
337 else if ( ii > last_ii )
338 t++;
339 for ( ; rowind[t] < ii - 1; t++ ) {
340# ifdef DEBUG
341 if ( t >= colptr[jj] )
342 OOFEM_ERROR("Couldn't find row %d in the sparse structure", ii);
343# endif
344 }
345 val[t] += mat(i, j);
346 last_ii = ii;
347 }
348 }
349 }
350 }
351
352 this->version++;
353
354 return 1;
355}
356
357void CompCol :: zero()
358{
359 val.zero();
360
361 this->version++;
362}
363
364
365void CompCol :: toFloatMatrix(FloatMatrix &answer) const
366{ }
367
368void CompCol :: printYourself() const
369{ }
370
371
372double &CompCol :: at(int i, int j)
373{
374 this->version++;
375
376 for ( int t = colptr[j - 1]; t < colptr[j]; t++ ) {
377 if ( rowind[t] == i - 1 ) {
378 return val[t];
379 }
380 }
381
382 OOFEM_ERROR("Array accessing exception -- (%d,%d) out of bounds", i, j);
383}
384
385
386double CompCol :: at(int i, int j) const
387{
388 for ( int t = colptr[j - 1]; t < colptr[j]; t++ ) {
389 if ( rowind[t] == i - 1 ) {
390 return val[t];
391 }
392 }
393
394 if ( i <= this->giveNumberOfRows() && j <= this->giveNumberOfColumns() ) {
395 return 0.0;
396 } else {
397 OOFEM_ERROR("Array accessing exception -- (%d,%d) out of bounds", i, j);
398 }
399 // return 0.; // return to suppress compiler warning message
400}
401
402double CompCol :: operator() (int i, int j) const
403{
404 for ( int t = colptr[j]; t < colptr[j + 1]; t++ ) {
405 if ( rowind[t] == i ) {
406 return val[t];
407 }
408 }
409
410 if ( i < this->giveNumberOfRows() && j < this->giveNumberOfColumns() ) {
411 return 0.0;
412 } else {
413 OOFEM_ERROR("Array accessing exception -- (%d,%d) out of bounds", i, j);
414 }
415 // return 0.; // return to suppress compiler warning message
416}
417
418double &CompCol :: operator() (int i, int j)
419{
420 this->version++;
421
422 for ( int t = colptr[j]; t < colptr[j + 1]; t++ ) {
423 if ( rowind[t] == i ) {
424 return val[t];
425 }
426 }
427
428 OOFEM_ERROR("Array element (%d,%d) not in sparse structure -- cannot assign", i, j);
429}
430
431} // 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
FloatArray val
Definition compcol.h:88
CompCol(int n=0)
Definition compcol.C:88
IntArray colptr
Definition compcol.h:90
IntArray rowind
Definition compcol.h:89
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
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
int giveNumberOfColumns() const
Returns number of columns of receiver.
int giveNumberOfRows() const
Returns number of rows of receiver.
int giveSize() const
Definition intarray.h:211
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
#define OOFEM_ERROR(...)
Definition error.h:79
#define OOFEM_LOG_DEBUG(...)
Definition logger.h:144
#define S(p)
Definition mdm.C:469
@ SMT_CompCol
Compressed column.

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