OOFEM 3.0
Loading...
Searching...
No Matches
floatarray.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 "floatarray.h"
36#include "intarray.h"
37#include "floatmatrix.h"
38#include "mathfem.h"
39#include "error.h"
40#include "datastream.h"
41#include "mathfem.h"
42
43#include <cstdarg>
44#include <cstdlib>
45#include <cstring>
46#include <cmath>
47#include <ostream>
48#include <memory>
49#include <numeric>
50#include <cmath>
51#include <iostream>
52#include <fstream>
53#include <iomanip>
54
55
56namespace oofem {
57// enable this to get text trace of all resize operations (useful to compare eigen and non-eigen version if they diverge)
58// #define _DBG(tag) printYourself(tag)
59#define _DBG(tag)
60
61#ifdef _USE_EIGEN
63 _DBG("ri/BEFORE");
64 if(newsize==size()) /* nothing */;
65 else if(newsize<size()) conservativeResize(newsize);
66 else (*this)=VectorXd::Zero(newsize);
67 _DBG("ri/AFTER");
68 }
69 void FloatArray::resizeWithValues(Index n, /* ignored*/ std::size_t allocChunk){
70 _DBG("rwv/BEFORE");
71 if(n==size()){ _DBG("rwv/AFTER"); return; }
72 Index size0=size();
73 VectorXd::conservativeResize(n);
74 (*this).tail(size()-size0).array()=0.;
75 _DBG("rwv/AFTER");
76 }
78 _DBG("r/BEFORE");
79 Index size0=size();
80 VectorXd::conservativeResize(n);
81 (*this).tail(size()-size0).array()=0.;
82 _DBG("r/AFTER");
83 }
84#else
86 _DBG("ri/BEFORE");
87 if ( (newsize) < this->size() ) {
88 this->values.resize((newsize));
89 } else if ( (newsize) > this->size() ) {
90 this->values.assign((newsize), 0.);
91 }
92 _DBG("ri/AFTER");
93 }
94 void FloatArray :: resize(int n)
95 {
96 _DBG("r/BEFORE");
97 this->values.resize(n);
99 //this->values.assign(n, 0.);
100 _DBG("r/AFTER");
101 }
102
103 void FloatArray :: resizeWithValues(Index n, std::size_t allocChunk)
104 {
105 #ifndef NDEBUG
106 if ( allocChunk < 0 ) {
107 OOFEM_FATAL("allocChunk must be non-negative; %ld", allocChunk);
108 }
109
110 #endif
111 _DBG("rwv/BEFORE");
112 if ( allocChunk > 0 && (Index)this->values.capacity() < n ) {
113 this->values.reserve(n + allocChunk);
114 }
115
116 this->values.resize(n);
117
118 _DBG("rwv/AFTER");
119 }
120#endif
121
122FloatArray FloatArray::fromList(const std::list<double>& lst){
123 FloatArray ret;
124 ret.resize(lst.size());
125 Index i=0;
126 for(const double& x: lst) ret(i++)=x;
127 return ret;
128
129}
130
131FloatArray FloatArray::fromVector(const std::vector<double>& v){
132 FloatArray ret;
133 ret.resize(v.size());
134 for(size_t i=0; i<v.size(); i++) ret(i)=v[i];
135 return ret;
136}
137
138FloatArray FloatArray::fromIniList(std::initializer_list<double> ini) {
139 FloatArray ret;
140 ret.resize(ini.size());
141 Index i=0;
142 for(const double& x: ini) ret(i++)=x;
143 return ret;
144}
145
146FloatArray FloatArray::fromConcatenated(std::initializer_list<FloatArray> ini){
147 int len=0; for(const auto& a: ini) len+=a.size();
148 FloatArray ret(len);
149 int ix=0;
150 for(const auto& a: ini){
151 for(Index i=0; i<a.size(); i++) ret[ix++]=a[i];
152 }
153 return ret;
154}
155
156
157
158#ifdef _USE_EIGEN
159bool FloatArray :: isAllFinite() const { return this->array().isFinite().all(); }
160void FloatArray :: beScaled(double s, const FloatArray &b){ *this=b*s; }
161void FloatArray :: add(const FloatArray &b){ if(b.isEmpty()) return; if(this->isEmpty()){ *this=b; return; } *this+=b; }
162void FloatArray :: add(double offset){ this->array()+=offset; }
163void FloatArray :: add(double factor, const FloatArray &b) { if(this->isEmpty()){ *this=factor*b; return; } *this+=factor*b; }
164void FloatArray :: plusProduct(const FloatMatrix &b, const FloatArray &s, double dV){ if(this->isEmpty()){ *this=b.transpose()*s*dV; return; } *this+=b.transpose()*s*dV; }
165void FloatArray :: subtract(const FloatArray &src){ if(src.isEmpty()) return; if(this->isEmpty()){ *this=-src; return; } *this-=src; }
166void FloatArray :: beMaxOf(const FloatArray &a, const FloatArray &b){ if(a.isEmpty()){ *this=b; return; } if(b.isEmpty()){ *this=a; return; } *this=a.array().max(b.array()).matrix(); }
167void FloatArray :: beMinOf(const FloatArray &a, const FloatArray &b){ if(a.isEmpty()){ *this=b; return; } if(b.isEmpty()){ *this=a; return; } *this=a.array().min(b.array()).matrix(); }
168void FloatArray :: beDifferenceOf(const FloatArray &a, const FloatArray &b){ *this=a-b; }
169void FloatArray :: beDifferenceOf(const FloatArray &a, const FloatArray &b, Index n){ *this=(a-b).head(n); }
170void FloatArray :: beSubArrayOf(const FloatArray &src, const IntArray &indx){ *this=src(indx.minusOne()); }
171void FloatArray :: addSubVector(const FloatArray &src, Index si){ /* grow as needed: tests pass without this */{ int req=(si-1)+src.size(); if(this->size()<req) this->resizeWithValues(req); } this->segment(si-1,src.size())=src; }
172void FloatArray :: beVectorProductOf(const FloatArray &v1, const FloatArray &v2){ Eigen::Ref<const Eigen::Vector3d> v1r(v1), v2r(v2); *this=v1r.cross(v2r); }
173int FloatArray :: giveIndexMinElem(){ Eigen::Index ix; this->minCoeff(&ix); return ix+1; }
174int FloatArray :: giveIndexMaxElem(){ Eigen::Index ix; this->maxCoeff(&ix); return ix+1; }
175/* FIXME: this trips test_sm_NAFEMS_FV12_FreeThinSquarePlate_mitc1.in and test_sm_NAFEMS_FV12_FreeThinSquarePlate_mitc2.in because some FP delta is being accumulated. */
176double FloatArray :: dotProduct(const FloatArray &x) const { return this->dot(x); }
177// double FloatArray :: dotProduct(const FloatArray &x) const { return std::inner_product(this->begin(), this->end(), x.begin(), 0.); /* */ }
178double FloatArray :: dotProduct(const FloatArray &x, Index size) const { return this->head(size).dot(x.head(size)); }
179double FloatArray :: distance_square(const FloatArray &from) const { return (from-(*this)).squaredNorm(); }
180void FloatArray :: checkSizeTowards(const IntArray &loc){ int sz=loc.maximum(); if(this->size()<sz) this->resize(sz); }
181bool FloatArray :: containsOnlyZeroes() const { return (this->array()==0.).all(); }
182void FloatArray :: zero() { this->array()=0.; }
183void FloatArray :: beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray){ *this=aMatrix*anArray; }
184void FloatArray :: beTProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray){ *this=anArray.transpose()*aMatrix; }
185void FloatArray :: negated() { *this*=-1; }
186void FloatArray :: times(double factor){ this->array()*=factor; }
187double FloatArray :: sum() const { return this->array().sum(); }
188double FloatArray :: product() const { return this->array().prod(); }
189void FloatArray :: copySubVector(const FloatArray &src, int si){ this->resizeWithValues(src.size()+si-1); this->tail(src.size())=src; }
190void FloatArray :: power(const double exponent){ *this=this->array().pow(exponent).matrix(); }
191void FloatArray :: beColumnOf(const FloatMatrix &mat, int col){ *this=mat.col(col-1); }
192void FloatArray :: beRowOf(const FloatMatrix &mat, Index row){ *this=mat.row(row-1).transpose(); }
193#else
194
195bool FloatArray :: isAllFinite() const
196{
197 for(Index i=0; i<this->size(); i++){
198 if(!std::isfinite((*this)[i])) {
199 return false;
200 }
201 }
202
203 return true;
204}
205
206
207void
208FloatArray :: beScaled(double s, const FloatArray &b)
209{
211
212 for ( Index i = 0; i < this->size(); ++i ) {
213 (*this) [ i ] = s * b [ i ];
214 }
215}
216
217
218void FloatArray :: add(const FloatArray &b)
219// Performs the operation a=a+b, where a stands for the receiver. If the
220// receiver's size is 0, adjusts its size to that of b. Returns the
221// receiver.
222{
223 if ( b.isEmpty() ) {
224 return;
225 }
226
227 if ( !this->size() ) {
228 * this = b;
229 return;
230 }
231
232# ifndef NDEBUG
233 if ( this->size() != b.size() ) {
234 OOFEM_ERROR("dimension mismatch in a[%d]->add(b[%d])", this->giveSize(), b.giveSize());
235 }
236
237# endif
238
239#ifdef __LAPACK_MODULE
240 int inc = 1;
241 double s = 1.;
242 int size = this->giveSize();
243 daxpy_(& size, & s, b.givePointer(), & inc, this->givePointer(), & inc, b.giveSize(), this->giveSize());
244#else
245 for (Index i = 0; i < this->size(); i++ ) {
246 (*this) [ i ] += b [ i ];
247 }
248#endif
249}
250
251
252void FloatArray :: add(double offset)
253{
254 for ( double &x: *this ) {
255 x += offset;
256 }
257}
258
259
260void FloatArray :: add(double factor, const FloatArray &b)
261// Performs the operation a=a+factor*b, where a stands for the receiver. If the
262// receiver's size is 0, adjusts its size to that of b.
263{
264 if ( this->isEmpty() ) {
265 this->beScaled(factor, b);
266 return;
267 }
268
269# ifndef NDEBUG
270 if ( this->size() != b.size() ) {
271 OOFEM_ERROR("dimension mismatch in a[%d]->add(b[%d])", this->giveSize(), b.giveSize());
272 }
273
274# endif
275
276#ifdef __LAPACK_MODULE
277 int inc = 1;
278 int size = this->giveSize();
279 daxpy_(& size, & factor, b.givePointer(), & inc, this->givePointer(), & inc, b.giveSize(), this->giveSize());
280#else
281 for ( Index i = 0; i < this->size(); ++i ) {
282 (*this) [ i ] += factor * b [ i ];
283 }
284#endif
285}
286
287
288void FloatArray :: plusProduct(const FloatMatrix &b, const FloatArray &s, double dV)
289// Performs the operation a += b^T . s * dV
290{
291 const int nRows = b.giveNumberOfRows();
292 const int nColumns = b.giveNumberOfColumns();
293
294 if ( this->isEmpty() ) {
295 this->resize( nColumns );
296 }
297
298# ifndef NDEBUG
299 if ( this->giveSize() != b.giveNumberOfColumns() ) {
300 OOFEM_ERROR( "dimension mismatch in a[%d] and b[%d, *]", this->giveSize(), b.giveNumberOfColumns() );
301 }
302# endif
303
304#ifdef __LAPACK_MODULE
305 double beta = 1.;
306 int inc = 1;
307 dgemv_("t", & nRows, & nColumns, & dV, b.givePointer(), & nRows, s.givePointer(), & inc, & beta, this->givePointer(), & inc, nColumns, nColumns, nRows);
308#else
309 for ( Index i = 1; i <= nColumns; i++ ) {
310 double sum = 0.;
311 for ( Index j = 1; j <= nRows; j++ ) {
312 sum += b.at(j, i) * s.at(j);
313 }
314 this->at(i) += sum * dV;
315 }
316#endif
317}
318
319
320void FloatArray :: subtract(const FloatArray &src)
321// Performs the operation a=a-src, where a stands for the receiver. If the
322// receiver's size is 0, adjusts its size to that of src.
323{
324 if ( src.isEmpty() ) {
325 return;
326 }
327
328 if ( this->isEmpty() ) {
329 _resize_internal(src.size());
330 for ( Index i = 0; i < this->size(); ++i ) {
331 (*this) [ i ] = -src [ i ];
332 }
333
334 return;
335 }
336
337# ifndef NDEBUG
338 if ( this->size() != src.size() ) {
339 OOFEM_ERROR("dimension mismatch in a[%d]->add(b[%d])", this->giveSize(), src.giveSize());
340 }
341
342# endif
343
344 for ( Index i = 0; i < this->size(); ++i ) {
345 (*this) [ i ] -= src [ i ];
346 }
347}
348
349
350void FloatArray :: beMaxOf(const FloatArray &a, const FloatArray &b)
351{
352 Index n = a.size();
353
354 if ( a.size() == 0 ) {
355 *this = b;
356 return;
357 } else if ( b.size() == 0 ) {
358 *this = a;
359 return;
360 }
361
362# ifndef NDEBUG
363 if ( n != b.size() ) {
364 OOFEM_ERROR("dimension mismatch in beMaxOf(a[%d],b[%d])", n, b.giveSize());
365 }
366
367# endif
368
370
371 for ( Index i = 0; i < n; i++ ) {
372 (*this) [ i ] = max( a [ i ], b [ i ] );
373 }
374}
375
376
377void FloatArray :: beMinOf(const FloatArray &a, const FloatArray &b)
378{
379 Index n = a.size();
380
381 if ( a.size() == 0 ) {
382 *this = b;
383 return;
384 } else if ( b.size() == 0 ) {
385 *this = a;
386 return;
387 }
388
389# ifndef NDEBUG
390 if ( n != b.size() ) {
391 OOFEM_ERROR("dimension mismatch in beMinOf(a[%d],b[%d])", n, b.giveSize());
392 }
393
394# endif
395
397 for ( Index i = 0; i < n; i++ ) {
398 (*this) [ i ] = min( a [ i ], b [ i ] );
399 }
400}
401
402
403void FloatArray :: beDifferenceOf(const FloatArray &a, const FloatArray &b)
404{
405#ifndef NDEBUG
406 if ( a.size() != b.size() ) {
407 OOFEM_ERROR("size mismatch (%d : %d)", a.giveSize(), b.giveSize());
408 }
409
410#endif
411#if 0
413 for ( int i = 0; i < this->giveSize(); ++i ) {
414 (*this) [ i ] = a [ i ] - b [ i ];
415 }
416#else
417 this->resize(a.giveSize());
418 for ( Index i = 0; i < a.size(); ++i ) {
419 (*this)[i]=a[i] - b[i];
420 }
421
422#endif
423}
424
425void FloatArray :: beDifferenceOf(const FloatArray &a, const FloatArray &b, Index n)
426{
427#ifndef NDEBUG
428 if ( a.size() < n || b.size() < n ) {
429 OOFEM_ERROR("wrong size %d vs %d", a.giveSize(), b.giveSize());
430 }
431
432#endif
434 for ( Index i = 0; i < n; ++i ) {
435 (*this) [ i ] = a [ i ] - b [ i ];
436 }
437}
438
439
440void FloatArray :: beSubArrayOf(const FloatArray &src, const IntArray &indx)
441//
442// Returns a subVector of the receiver constructed from an index array.
443// this->at(i) = src.at(indx->at(i))
444//
445{
446#ifndef NDEBUG
447 if ( indx.maximum() > src.giveSize() || indx.minimum() < 1 ) {
448 OOFEM_ERROR("index points outside of source");
449 }
450#endif
451
452 Index n = indx.size();
454 for ( Index i = 1; i <= n; i++ ) {
455 this->at(i) = src.at( indx.at(i) );
456 }
457}
458
459
460void FloatArray :: addSubVector(const FloatArray &src, Index si)
461{
462 Index reqSize, n = src.size();
463
464 si--;
465 reqSize = si + n;
466 if ( this->size() < reqSize ) {
467 this->resizeWithValues(reqSize);
468 }
469
470 for (Index i = 0; i < n; i++ ) {
471 (*this) [si + i] += src [ i ];
472 }
473}
474
475
476void FloatArray :: beVectorProductOf(const FloatArray &v1, const FloatArray &v2)
477{
478# ifndef NDEBUG
479 // check proper bounds
480 if ( ( v1.giveSize() != 3 ) || ( v2.giveSize() != 3 ) ) {
481 OOFEM_ERROR("size mismatch, size is not equal to 3");
482 }
483# endif
484
486
487 this->at(1) = v1.at(2) * v2.at(3) - v1.at(3) * v2.at(2);
488 this->at(2) = v1.at(3) * v2.at(1) - v1.at(1) * v2.at(3);
489 this->at(3) = v1.at(1) * v2.at(2) - v1.at(2) * v2.at(1);
490}
491
492int FloatArray :: giveIndexMinElem()
493{
494 Index index = 1;
495 if ( !this->giveSize() ) {
496 return -1;
497 }
498 double val = (*this) [ 0 ];
499 for (Index i = 1; i < this->size(); i++ ) {
500 if ( val > (*this) [ i ] ) {
501 val = (*this) [ i ];
502 index = i + 1;
503 }
504 }
505 return index;
506}
507
508int FloatArray :: giveIndexMaxElem()
509{
510 Index index = 1;
511 if ( !this->giveSize() ) {
512 return -1;
513 }
514 double val = (*this) [ 0 ];
515 for (Index i = 1; i < this->size(); i++ ) {
516 if ( val < (*this) [ i ] ) {
517 val = (*this) [ i ];
518 index = i + 1;
519 }
520 }
521 return index;
522}
523
524double FloatArray :: dotProduct(const FloatArray &x) const
525{
526# ifndef NDEBUG
527 if ( this->size() != x.size() ) {
528 OOFEM_ERROR("dimension mismatch in a[%d]->dotProduct(b[%d])", this->giveSize(), x.giveSize());
529 }
530
531# endif
532
533 return std::inner_product(this->begin(), this->end(), x.begin(), 0.);
534}
535
536
537double FloatArray :: dotProduct(const FloatArray &x, Index size) const
538{
539# ifndef NDEBUG
540 if ( size > this->size() || size > x.size() ) {
541 OOFEM_ERROR("dimension mismatch in a[%d]->dotProduct(b[%d])", this->giveSize(), x.giveSize());
542 }
543
544# endif
545
546 return std::inner_product(this->begin(), this->begin()+size, x.begin(), 0.);
547}
548
549#endif
550
551double FloatArray :: distance(const FloatArray &x) const
552{
553 return std::sqrt( this->distance_square(x) );
554}
555
556double FloatArray :: distance(const FloatArray &iP1, const FloatArray &iP2, double &oXi, double &oXiUnbounded) const
557{
558 return std::sqrt( distance_square(iP1, iP2, oXi, oXiUnbounded) );
559}
560
561double FloatArray :: distance_square(const FloatArray &iP1, const FloatArray &iP2, double &oXi, double &oXiUnbounded) const
562{
563 const double l2 = iP1.distance_square(iP2);
564
565 if ( l2 > 0.0 ) {
566
567 const double s = (oofem::dot(*this, iP2) - oofem::dot(*this, iP1) ) - ( oofem::dot(iP1, iP2) - oofem::dot(iP1, iP1) );
568
569 if ( s < 0.0 ) {
570 // X is closest to P1
571 oXi = 0.0;
572 oXiUnbounded = s/l2;
573 return this->distance_square(iP1);
574 } else {
575 if ( s > l2 ) {
576 // X is closest to P2
577 oXi = 1.0;
578 oXiUnbounded = s/l2;
579 return this->distance_square(iP2);
580 } else {
581 oXi = s / l2;
582 oXiUnbounded = s/l2;
583 const FloatArray q = ( 1.0 - oXi ) * iP1 + oXi * iP2;
584 return this->distance_square(q);
585 }
586 }
587 } else {
588 // If the points P1 and P2 coincide,
589 // we can compute the distance to any
590 // of these points.
591 oXi = 0.5;
592 oXiUnbounded = 0.5;
593 return this->distance_square(iP1);
594 }
595}
596
597#ifndef _USE_EIGEN
598
599double FloatArray :: distance_square(const FloatArray &from) const
600// returns distance between receiver and from from
601// computed using generalized pythagorean formulae
602{
603 double dist = 0.;
604 Index s = min(this->size(), from.size());
605 for (Index i = 1; i <= s; ++i ) {
606 double dx = this->at(i) - from.at(i);
607 dist += dx * dx;
608 }
609
610 return dist;
611}
612
613#endif
614
615
616void FloatArray :: assemble(const FloatArray &fe, const IntArray &loc)
617// Assembles the array fe (typically, the load vector of a finite
618// element) to the receiver, using loc as location array.
619{
620 Index n = fe.size();
621# ifndef NDEBUG
622 if ( n != (Index) loc.size() ) {
623 OOFEM_ERROR("dimensions of 'fe' (%d) and 'loc' (%d) mismatch", fe.giveSize(), loc.giveSize() );
624 }
625
626# endif
627
628 for (Index i = 1; i <= n; i++ ) {
629 int ii = loc.at(i);
630 if ( ii ) { // if non 0 coefficient,
631 this->at(ii) += fe.at(i);
632 }
633 }
634}
635
636
637void FloatArray :: assembleSquared(const FloatArray &fe, const IntArray &loc)
638// Assembles the array fe (typically, the load vector of a finite
639// element) to the receiver, using loc as location array.
640{
641 Index n = fe.size();
642# ifndef NDEBUG
643 if ( n != (Index) loc.size() ) {
644 OOFEM_ERROR("dimensions of 'fe' (%d) and 'loc' (%d) mismatch", fe.giveSize(), loc.giveSize() );
645 }
646
647# endif
648
649 for (Index i = 1; i <= n; i++ ) {
650 int ii = loc.at(i);
651 if ( ii ) { // if non 0 coefficient,
652 this->at(ii) += fe.at(i) * fe.at(i);
653 }
654 }
655}
656
657#ifndef _USE_EIGEN
658void FloatArray :: checkSizeTowards(const IntArray &loc)
659// Expands the receiver if loc points to coefficients beyond the size of
660// the receiver.
661{
662 int high = loc.maximum();
663 if ( high > this->giveSize() ) { // receiver must be expanded
664 this->resize(high);
665 }
666}
667
668
669
670
671bool FloatArray :: containsOnlyZeroes() const
672{
673 for ( double x : *this ) {
674 if ( x != 0. ) {
675 return false;
676 }
677 }
678
679 return true;
680}
681
682
683void FloatArray :: zero()
684{
685 std::fill(this->begin(), this->end(), 0.);
686}
687
688
689void FloatArray :: beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
690// Stores the product of aMatrix * anArray in to receiver
691{
692 const int nColumns = aMatrix.giveNumberOfColumns();
693 const int nRows = aMatrix.giveNumberOfRows();
694
695 _resize_internal(nRows);
696
697# ifndef NDEBUG
698 if ( aMatrix.giveNumberOfColumns() != anArray.giveSize() ) {
699 OOFEM_ERROR("dimension mismatch (%d, %d) . (%d)",
700 aMatrix.giveNumberOfRows(), aMatrix.giveNumberOfColumns(), anArray.giveSize());
701 }
702# endif
703
704#ifdef __LAPACK_MODULE
705 double alpha = 1., beta = 0.;
706 int inc = 1;
707 dgemv_("n", & nRows, & nColumns, & alpha, aMatrix.givePointer(), & nRows, anArray.givePointer(), & inc, & beta, this->givePointer(), & inc, nColumns, nColumns, nRows);
708#else
709 for (Index i = 1; i <= nRows; i++ ) {
710 double sum = 0.;
711 for (Index j = 1; j <= nColumns; j++ ) {
712 sum += aMatrix.at(i, j) * anArray.at(j);
713 }
714
715 this->at(i) = sum;
716 }
717#endif
718}
719
720
721void FloatArray :: beTProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
722// Stores the product of aMatrix^T * anArray in to receiver
723{
724 const int nRows = aMatrix.giveNumberOfRows();
725 const int nColumns = aMatrix.giveNumberOfColumns();
726
727# ifndef NDEBUG
728 if ( aMatrix.giveNumberOfRows() != anArray.giveSize() ) {
729 OOFEM_ERROR( "dimension mismatch, matrix rows = %d, array size = %d", aMatrix.giveNumberOfRows(), anArray.giveSize() );
730 }
731
732# endif
733 _resize_internal(nColumns);
734
735#ifdef __LAPACK_MODULE
736 double alpha = 1., beta = 0.;
737 int inc = 1;
738 dgemv_("t", & nRows, & nColumns, & alpha, aMatrix.givePointer(), & nRows, anArray.givePointer(), & inc, & beta, this->givePointer(), & inc, nColumns, nColumns, nRows);
739#else
740 for (Index i = 1; i <= nColumns; i++ ) {
741 double sum = 0.;
742 for (Index j = 1; j <= nRows; j++ ) {
743 sum += aMatrix.at(j, i) * anArray.at(j);
744 }
745
746 this->at(i) = sum;
747 }
748#endif
749}
750
751
752void FloatArray :: negated()
753{
754 for ( double &x: *this ) {
755 x = -x;
756 }
757}
758
759#endif /* ifndef _USE_EIGEN */
760
761
762void FloatArray :: printYourself() const
763// Prints the receiver on screen.
764{
765 printf("FloatArray of size : %d \n", (int)this->giveSize());
766 for ( double x: *this ) {
767 printf( "%10.3e ", x );
768 }
769
770 printf("\n");
771}
772
773
774void FloatArray :: printYourself(const std::string &name) const
775// Prints the receiver on screen.
776{
777 printf("%s (%d): \n", name.c_str(), (int)this->giveSize());
778 for ( double x: *this ) {
779 printf( "%10.3e ", x );
780 }
781
782 printf("\n");
783}
784
785void FloatArray :: printYourselfToFile(const std::string filename, const bool showDimensions) const
786// Prints the receiver to file.
787{
788 std :: ofstream arrayfile (filename);
789 if (arrayfile.is_open()) {
790 if (showDimensions)
791 arrayfile << "FloatArray of size : " << this->giveSize() << "\n";
792 arrayfile << std::scientific << std::right << std::setprecision(3);
793 for ( double x: *this ) {
794 arrayfile << std::setw(10) << x << "\t";
795 }
796 arrayfile.close();
797 } else {
798 OOFEM_ERROR("Failed to write to file");
799 }
800}
801
802void FloatArray :: pY() const
803// Prints the receiver on screen with higher accuracy than printYourself.
804{
805 printf("[");
806 for ( double x: *this ) {
807 printf( "%20.14e; ", x );
808 }
809
810 printf("];\n");
811}
812
813
814void FloatArray :: rotatedWith(FloatMatrix &r, char mode)
815// Returns the receiver 'a' rotated according the change-of-base matrix r.
816// If mode = 't', the method performs the operation a = r(transp) * a .
817// If mode = 'n', the method performs the operation a = r * a .
818{
819 FloatArray rta;
820
821 if ( mode == 't' ) {
822 rta.beTProductOf(r, * this);
823 } else if ( mode == 'n' ) {
824 rta.beProductOf(r, * this);
825 } else {
826 OOFEM_ERROR("unsupported mode");
827 }
828
829 * this = rta;
830}
831
832#ifndef _USE_EIGEN
833
834void FloatArray :: times(double factor)
835// Multiplies every coefficient of the receiver by factor.
836{
837 //std::transform(this->begin(), this->end(), this->begin(), std::bind2nd(std::multiplies<double>(), factor));
838 for ( double &x : *this ) {
839 x *= factor;
840 }
841}
842
843#endif
844
845void FloatArray :: normalize(){
846 (void) normalize_giveNorm();
847}
848
849
850double FloatArray :: normalize_giveNorm()
851{
852 double norm = this->computeNorm();
853 if ( norm < 1.e-80 ) {
854 OOFEM_ERROR("cannot norm receiver, norm is too small");
855 }
856 this->times(1. / norm);
857 return norm;
858}
859
860
861double FloatArray :: computeNorm() const
862{
863 return std::sqrt( this->computeSquaredNorm() );
864}
865
866
867double FloatArray :: computeSquaredNorm() const
868{
869 return std::inner_product(this->begin(), this->end(), this->begin(), 0.);
870}
871
872#ifndef _USE_EIGEN
873
874double FloatArray :: sum() const
875{
876 return std::accumulate(this->begin(), this->end(), 0.);
877}
878
879
880double FloatArray :: product() const
881{
882 return std::accumulate(this->begin(), this->end(), 1.0, [](double a, double b) { return a*b; });
883}
884
885
886void FloatArray :: copySubVector(const FloatArray &src, int si)
887{
888 si--;
889 this->resizeWithValues(si + src.giveSize());
890 std :: copy( src.begin(), src.end(), this->begin() + si);
891}
892#endif
893
894contextIOResultType FloatArray :: storeYourself(DataStream &stream) const
895// writes receiver's binary image into stream
896// use id to distinguish some instances
897// return value >0 success
898// =0 file i/o error
899{
900 // write size
901 Index size = this->size();
902 if ( !stream.write(size) ) {
903 return CIO_IOERR;
904 }
905
906 // write raw data
907 if ( size ) {
908 if ( !stream.write(this->givePointer(), size) ) {
909 return CIO_IOERR;
910 }
911 }
912
913 // return result back
914 return CIO_OK;
915}
916
917contextIOResultType FloatArray :: restoreYourself(DataStream &stream)
918// reads receiver from stream
919// warning - overwrites existing data!
920// returns 0 if file i/o error
921// -1 if id od class id is not correct
922{
923 // read size
924 Index size;
925 if ( !stream.read(size) ) {
926 return CIO_IOERR;
927 }
928
929 this->resize(size); // FIXME: useless zero-initialization
930
931 // read raw data
932 if ( size ) {
933 if ( !stream.read(this->givePointer(), size) ) {
934 return CIO_IOERR;
935 }
936 }
937
938 // return result back
939 return CIO_OK;
940}
941
942
943int FloatArray :: givePackSize(DataStream &buff) const
944{
945 return buff.givePackSizeOfSizet(1) + buff.givePackSizeOfDouble(this->giveSize());
946}
947
948
949#ifndef _USE_EIGEN
950// IML compat
951
952FloatArray &FloatArray :: operator = ( const double & val )
953{
954 std::fill(this->begin(), this->begin(), val);
955 return * this;
956}
957
958FloatArray &operator *= ( FloatArray & x, const double & a )
959{
960 x.times(a);
961 return x;
962}
963
964FloatArray operator *( const double & a, const FloatArray & x )
965{
966 FloatArray result;
967 result.beScaled(a, x);
968 return result;
969}
970
971FloatArray operator *( const FloatArray & x, const double & a )
972{
973 FloatArray result;
974 result.beScaled(a, x);
975 return result;
976}
977
979{
980 FloatArray result(x);
981 result.add(y);
982 return result;
983}
984
986{
987 FloatArray result;
988 result.beDifferenceOf(x, y);
989 return result;
990}
991
993{
994 x.add(y);
995 return x;
996}
997
999{
1000 x.subtract(y);
1001 return x;
1002}
1003
1004FloatArray &operator /= ( FloatArray & x, const double & a )
1005{
1006 x.times(1./a);
1007 return x;
1008}
1009#endif
1010
1011double dot(const FloatArray &x, const FloatArray &y)
1012{
1013 return x.dotProduct(y);
1014}
1015
1016double distance(const FloatArray &x, const FloatArray &y)
1017{
1018 return x.distance(y);
1019}
1020
1021double distance_square(const FloatArray &x, const FloatArray &y)
1022{
1023 return x.distance_square(y);
1024}
1025
1026double norm(const FloatArray &x)
1027{
1028 return x.computeNorm();
1029}
1030
1031double norm_square(const FloatArray &x)
1032{
1033 return x.computeSquaredNorm();
1034}
1035
1036bool isfinite(const FloatArray &x)
1037{
1038 return x.isAllFinite();
1039}
1040
1041bool iszero(const FloatArray &x)
1042{
1043 return x.containsOnlyZeroes();
1044}
1045
1046double sum(const FloatArray & x)
1047{
1048 return x.sum();
1049}
1050
1051double product(const FloatArray & x)
1052{
1053 return x.product();
1054}
1055
1056
1057// End of IML compat
1058
1059void FloatArray :: beVectorForm(const FloatMatrix &aMatrix)
1060{
1061 // Rewrites the matrix on vector form, order: 11, 22, 33, 23, 13, 12, 32, 31, 21
1062# ifndef NDEBUG
1063 if ( aMatrix.giveNumberOfColumns() != 3 || aMatrix.giveNumberOfRows() != 3 ) {
1064 OOFEM_ERROR("matrix dimension is not 3x3");
1065 }
1066
1067# endif
1068 *this = {
1069 aMatrix.at(1, 1),
1070 aMatrix.at(2, 2),
1071 aMatrix.at(3, 3),
1072 aMatrix.at(2, 3),
1073 aMatrix.at(1, 3),
1074 aMatrix.at(1, 2),
1075 aMatrix.at(3, 2),
1076 aMatrix.at(3, 1),
1077 aMatrix.at(2, 1)
1078 };
1079}
1080
1081void FloatArray :: beSymVectorFormOfStrain(const FloatMatrix &aMatrix)
1082{
1083 // Revrites a symmetric strain matrix on reduced vector form, order: 11, 22, 33, 23, 13, 12
1084 // shear components are multiplied with a factor 2
1085# ifndef NDEBUG
1086 if ( aMatrix.giveNumberOfColumns() != 3 || aMatrix.giveNumberOfRows() != 3 ) {
1087 OOFEM_ERROR("matrix dimension is not 3x3");
1088 }
1089# endif
1090
1091 *this = {
1092 aMatrix.at(1, 1),
1093 aMatrix.at(2, 2),
1094 aMatrix.at(3, 3),
1095 ( aMatrix.at(2, 3) + aMatrix.at(3, 2) ),
1096 ( aMatrix.at(1, 3) + aMatrix.at(3, 1) ),
1097 ( aMatrix.at(1, 2) + aMatrix.at(2, 1) )
1098 };
1099}
1100
1101
1102void FloatArray :: beSymVectorForm(const FloatMatrix &aMatrix)
1103{
1104 // Revrites the matrix on vector form (symmetrized matrix used), order: 11, 22, 33, 23, 13, 12
1105# ifndef NDEBUG
1106 if ( aMatrix.giveNumberOfColumns() != 3 || aMatrix.giveNumberOfRows() != 3 ) {
1107 OOFEM_ERROR("matrix dimension is not 3x3");
1108 }
1109
1110# endif
1111
1112 *this = {
1113 aMatrix.at(1, 1),
1114 aMatrix.at(2, 2),
1115 aMatrix.at(3, 3),
1116 0.5 * ( aMatrix.at(2, 3) + aMatrix.at(3, 2) ),
1117 0.5 * ( aMatrix.at(1, 3) + aMatrix.at(3, 1) ),
1118 0.5 * ( aMatrix.at(1, 2) + aMatrix.at(2, 1) )
1119 };
1120}
1121
1122void FloatArray :: changeComponentOrder()
1123{
1124 // OOFEM: 11, 22, 33, 23, 13, 12, 32, 31, 21
1125 // UMAT: 11, 22, 33, 12, 13, 23, 32, 21, 31
1126
1127 if ( this->giveSize() == 6 ) {
1128 std :: swap( this->at(4), this->at(6) );
1129 } else if ( this->giveSize() == 9 ) {
1130 // OOFEM: 11, 22, 33, 23, 13, 12, 32, 31, 21
1131 // UMAT: 11, 22, 33, 12, 13, 23, 32, 21, 31
1132 const int abq2oo [ 9 ] = {
1133 1, 2, 3, 6, 5, 4, 7, 9, 8
1134 };
1135
1136 FloatArray tmp(9);
1137 for ( int i = 0; i < 9; i++ ) {
1138 tmp(i) = this->at(abq2oo [ i ]);
1139 }
1140
1141 * this = tmp;
1142 }
1143}
1144
1145
1146std :: ostream &operator << ( std :: ostream & out, const FloatArray & x )
1147{
1148 out << x.giveSize();
1149 for ( double xi : x ) {
1150 out << " " << xi;
1151 }
1152 return out;
1153}
1154
1155//void FloatArray :: beReducedVectorFormOfStrain(const FloatMatrix &aMatrix)
1156//{
1157// // Revrites the matrix on vector form (symmetrized matrix used), order: 11, 22, 33, 23, 13, 12
1158//# ifndef NDEBUG
1159// if ( aMatrix.giveNumberOfColumns() !=3 || aMatrix.giveNumberOfColumns() !=3) {
1160// OOFEM_ERROR("matrix dimension is not 3x3");
1161// }
1162//
1163//# endif
1164//
1165// this->values.resize(6);
1166// this->at(1) = aMatrix.at(1,1); this->at(2) = aMatrix.at(2,2); this->at(3) = aMatrix.at(3,3);
1167// this->at(4) = ( aMatrix.at(2,3) + aMatrix.at(3,2) ); // Shear strains multiplied with a factor of 2
1168// this->at(5) = ( aMatrix.at(1,3) + aMatrix.at(3,1) );
1169// this->at(6) = ( aMatrix.at(1,2) + aMatrix.at(2,1) );
1170//}
1171
1172#ifndef _USE_EIGEN
1173void FloatArray :: power(const double exponent)
1174{
1175 for ( double &x : *this ) {
1176 x = std::pow(x, exponent);
1177 }
1178}
1179
1180
1181
1182void FloatArray :: beColumnOf(const FloatMatrix &mat, int col)
1183{
1185 mat.copyColumn(*this, col);
1186}
1187
1188void FloatArray :: beRowOf(const FloatMatrix &mat, Index row)
1189{
1190 Index nColumns = mat.cols();
1191
1192# ifndef NDEBUG
1193 Index nRows = mat.rows();
1194 if (row>nRows) {
1195 OOFEM_ERROR( "dimension mismatch, matrix rows = %d, wanted row = %d", nRows, row)
1196 }
1197# endif
1198
1199 _resize_internal(nColumns);
1200 for ( Index i = 1; i <= nColumns; i++ ) {
1201 this->at(i) = mat.at(row,i);
1202 }
1203}
1204#endif
1205
1206} // end namespace oofem
virtual int read(int *data, std::size_t count)=0
Reads count integer values into array pointed by data.
virtual int givePackSizeOfDouble(std::size_t count)=0
virtual int givePackSizeOfSizet(std::size_t count)=0
double computeNorm() const
Definition floatarray.C:861
bool containsOnlyZeroes() const
Definition floatarray.C:671
Index size() const
Definition floatarray.h:162
static FloatArray fromIniList(std::initializer_list< double > ini)
Definition floatarray.C:138
void resize(Index s)
Definition floatarray.C:94
double distance(const FloatArray &x) const
Definition floatarray.C:551
double product() const
Definition floatarray.C:880
double & at(Index i)
Definition floatarray.h:202
double computeSquaredNorm() const
Definition floatarray.C:867
std::vector< double > values
Stored values.
Definition floatarray.h:102
double dotProduct(const FloatArray &x) const
Definition floatarray.C:524
bool isAllFinite() const
Returns true if no element is NAN or infinite.
Definition floatarray.C:195
std::vector< double >::iterator begin()
Definition floatarray.h:107
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
double sum() const
Definition floatarray.C:874
void resizeWithValues(Index s, std::size_t allocChunk=0)
Definition floatarray.C:103
static FloatArray fromVector(const std::vector< double > &v)
Definition floatarray.C:131
void _resize_internal(Index newsize)
Definition floatarray.C:85
void beDifferenceOf(const FloatArray &a, const FloatArray &b)
Definition floatarray.C:403
static FloatArray fromConcatenated(std::initializer_list< FloatArray > ini)
Definition floatarray.C:146
double distance_square(const FloatArray &iP1, const FloatArray &iP2, double &oXi, double &oXiUnbounded) const
Definition floatarray.C:561
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Definition floatarray.C:689
double normalize_giveNorm()
Definition floatarray.C:850
void beScaled(double s, const FloatArray &b)
Definition floatarray.C:208
bool isEmpty() const
Returns true if receiver is empty.
Definition floatarray.h:265
friend class FloatMatrix
Definition floatarray.h:551
void beTProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Definition floatarray.C:721
static FloatArray fromList(const std::list< double > &l)
Definition floatarray.C:122
void add(const FloatArray &src)
Definition floatarray.C:218
const double * givePointer() const
Definition floatarray.h:506
void subtract(const FloatArray &src)
Definition floatarray.C:320
std::vector< double >::iterator end()
Definition floatarray.h:108
void times(double s)
Definition floatarray.C:834
FloatArray(int n=0)
Constructor for sized array. Data is zeroed.
Definition floatarray.h:117
const double * givePointer() const
void copyColumn(FloatArray &dest, int c) const
int giveNumberOfColumns() const
Returns number of columns of receiver.
int giveNumberOfRows() const
Returns number of rows of receiver.
double at(std::size_t i, std::size_t j) const
int maximum() const
Definition intarray.C:144
int minimum() const
Definition intarray.C:133
std::size_t size() const
Definition intarray.h:212
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
#define OOFEM_FATAL(...)
Definition error.h:78
#define OOFEM_ERROR(...)
Definition error.h:79
#define _DBG(tag)
Definition floatarray.C:59
FloatArray operator+(const FloatArray &x, const FloatArray &y)
Definition floatarray.C:978
double norm(const FloatArray &x)
FloatArrayF< N > min(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
double norm_square(const FloatArray &x)
bool iszero(const FloatArray &x)
FloatArray operator-(const FloatArray &x, const FloatArray &y)
Definition floatarray.C:985
FloatArrayF< N > max(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
FloatArray & operator/=(FloatArray &x, const double &a)
FloatArray & operator+=(FloatArray &x, const FloatArray &y)
Definition floatarray.C:992
std::ostream & operator<<(std ::ostream &out, const Dictionary &r)
Definition dictionary.C:247
int Index
Definition numerics.h:73
double sum(const FloatArray &x)
double dot(const FloatArray &x, const FloatArray &y)
bool isfinite(const FloatArray &x)
FloatArray & operator-=(FloatArray &x, const FloatArray &y)
Definition floatarray.C:998
double product(const FloatArray &x)
FloatArray operator*(const double &a, const FloatArray &x)
Definition floatarray.C:964
FloatArray & operator*=(FloatArray &x, const double &a)
Vector multiplication by scalar.
Definition floatarray.C:958
double distance(const FloatArray &x, const FloatArray &y)
double distance_square(const FloatArray &x, const FloatArray &y)
@ CIO_IOERR
General IO error.

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