OOFEM 3.0
Loading...
Searching...
No Matches
floatarrayf.h
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#ifndef floatarrayf_h
36#define floatarrayf_h
37
38#include "oofemenv.h"
39#include "contextioresulttype.h"
40#include "contextmode.h"
41#include "datastream.h"
42#include "error.h"
43#include "floatarray.h"
44
45#include <array>
46#include <initializer_list>
47#include <cmath>
48#include <algorithm>
49#include <numeric>
50
51namespace oofem {
52
57template<std::size_t N>
59#ifdef _USE_EIGEN
60 : public VectorNd<N>
61#endif
62{
63#ifdef _USE_EIGEN
64public:
65 OOFEM_EIGEN_DERIVED(FloatArrayF,VectorNd<N>);
66 Index size() const { return VectorNd<N>::size(); }
67 const double *data() const { return VectorNd<N>::data(); }
68 double *data() { return VectorNd<N>::data(); }
69
70 template<
71 typename... Args,
72 class = typename std::enable_if_t<sizeof...(Args) == N>,
73 class = std::enable_if_t<(std::conjunction_v<std::is_same<double, Args>...>)>
74 >
75 FloatArrayF(Args... args){
76 std::initializer_list<double> ini{ args ... };
77 int i=0; for(const double& x: ini){ (*this)[i++]=x; }
78 }
79
80
81 // since we re-declare operator[ {...} ] below, we need to include those as well for overload resolution
82 double &operator[] (Index i){ return VectorNd<N>::operator[](i); }
83 const double &operator[] (Index i) const { return VectorNd<N>::operator[](i); }
84#else
85protected:
87 std::array< double, N > values;
88
89public:
91
92 auto begin() { return this->values.begin(); }
93 auto end() { return this->values.end(); }
94 auto begin() const { return this->values.begin(); }
95 auto end() const { return this->values.end(); }
97
102 {
103#ifndef NDEBUG
104 if ( x.giveSize() != N ) {
105 OOFEM_ERROR("Can't convert dynamic float array of size %d to fixed size %ld\n", x.giveSize(), N);
106 }
107#endif
108 std::copy_n(x.begin(), N, values.begin());
109 }
110
111 template<typename... V, class = typename std::enable_if_t<sizeof...(V) == N>>
112 FloatArrayF(V... x) : values{x...} { }
115
117 void operator = (const FloatArrayF<N> &src) { values = src.values; }
118
119
125 inline double &operator[] (std::size_t i)
126 {
127 #ifndef NDEBUG
128 return values.at( i );
129 #else
130 return values [ i ];
131 #endif
132 }
133
138 inline const double &operator[] (std::size_t i) const {
139 #ifndef NDEBUG
140 return values.at( i );
141 #else
142 return values [ i ];
143 #endif
144 }
145
146 int size() const { return N; }
147 const double *data() const { return values.data(); }
148 double *data() { return values.data(); }
149
150#endif
151
157 inline double &at(std::size_t i) { return (*this)[i-1]; }
163 inline double at(std::size_t i) const { return (*this)[i-1]; }
164
165 #ifdef _USE_EIGEN
166 template<std::size_t M> inline FloatArrayF<M> operator[] (std::size_t const (&c)[M]) const { return (*this)(c).eval(); }
167 template<size_t M> inline void assign(const FloatArrayF<M> &x, int const (&c)[M] ){ (*this)(c)=x; }
168 template<size_t M> inline void assemble(const FloatArrayF<M> &x, int const (&c)[M] ){ (*this)(c)+=x; }
169 #else
174 template<std::size_t M>
175 inline FloatArrayF<M> operator[] (std::size_t const (&c)[M]) const
176 {
178 for ( std::size_t i = 0; i < M; ++i ) {
179 x[i] = (*this)[ c[i] ];
180 }
181 return x;
182 }
183
185 template<size_t M>
186 inline void assign(const FloatArrayF<M> &x, int const (&c)[M] )
187 {
188 for ( std::size_t i = 0; i < M; ++i ) {
189 (*this)[c[i]] = x[i];
190 }
191 }
192
194 template<size_t M>
195 inline void assemble(const FloatArrayF<M> &x, int const (&c)[M] )
196 {
197 for ( std::size_t i = 0; i < M; ++i ) {
198 (*this)[c[i]] += x[i];
199 }
200 }
201 #endif
203 int giveSize() const { return size(); }
208 void printYourself(const std::string &name="FloatArrayF") const
209 {
210 printf("%s (%d): \n", name.c_str(), this->size());
211 for ( double x: *this ) {
212 printf( "%10.3e ", x );
213 }
214 printf("\n");
215 }
216
220 const double *givePointer() const { return data(); }
221 double *givePointer() { return data(); }
222
224 {
225 if ( !stream.write(this->givePointer(), this->size()) ) {
226 return CIO_IOERR;
227 }
228 return CIO_OK;
229 }
230
232 {
233 if ( !stream.read(this->givePointer(), this->size()) ) {
234 return CIO_IOERR;
235 }
236 return CIO_OK;
237 }
238
239 int givePackSize(DataStream &buff) const
240 {
241 return buff.givePackSizeOfDouble(this->size());
242 }
243
244 //friend class FloatMatrixF;
245};
246
247
249template<std::size_t N>
250std::ostream & operator << ( std::ostream & out, const FloatArrayF<N> & x )
251{
252 out << x.size();
253 for ( double xi : x ) {
254 out << " " << xi;
255 }
256 return out;
257}
258
259
260#ifdef _USE_EIGEN
261// cast args to VectorNd<N> to avoid the operator calling itself; it also prevents Eigen from returning expression template, which would fail where the result is fed into a function arg (is this a limitation of derived class in Eigen?)
262template<size_t N, size_t M> inline FloatArrayF<N> assemble(const FloatArrayF<M> &x, int const (&c)[M] ){ FloatArrayF<N> out=VectorNd<N>::Zero(); out(c)=x; return out; }
263template<std::size_t N> FloatArrayF<N> operator * ( double a, const FloatArrayF<N> & x ){ return a*(VectorNd<N>)x; }
264template<std::size_t N> FloatArrayF<N> operator * ( const FloatArrayF<N> & x, double a ){ return a*(VectorNd<N>)x; }
265template<std::size_t N> FloatArrayF<N> mult ( const FloatArrayF<N> & x, const FloatArrayF<N> & y ){ return (x.array()*y.array()).matrix(); }
266template<std::size_t N> FloatArrayF<N> operator / ( const FloatArrayF<N> & x, double a ){ return ((VectorNd<N>)x)/a; }
267template<std::size_t N> FloatArrayF<N> operator ^ ( const FloatArrayF<N> & x, double a){ return x.array().pow(a); }
268template<std::size_t N> FloatArrayF<N> operator + ( const FloatArrayF<N> & x, const FloatArrayF<N> & y ){ return ((VectorNd<N>)x)+((VectorNd<N>)y); }
269template<std::size_t N> FloatArrayF<N> operator - ( const FloatArrayF<N> & x, const FloatArrayF<N> & y ){ return ((VectorNd<N>)x)-((VectorNd<N>)y); }
270template<std::size_t N> FloatArrayF<N> operator - ( const FloatArrayF<N> & x ){ return -((VectorNd<N>)x); };
271//template<std::size_t N> FloatArrayF<N> &operator += ( FloatArrayF<N> & x, const FloatArrayF<N> & y ){ (VectorNd<N>)x+=y; return x; }
272//template<std::size_t N> FloatArrayF<N> &operator -= ( FloatArrayF<N> & x, const FloatArrayF<N> & y ){ (VectorNd<N>)x-=y; return x; }
273//template<std::size_t N> FloatArrayF<N> &operator *= ( FloatArrayF<N> & x, double a ){ (VectorNd<N>)x*=a; return x; }
274//template<std::size_t N> FloatArrayF<N> &operator /= ( FloatArrayF<N> & x, double a ){ (VectorNd<N>)x/=a; return x; }
275//template<std::size_t N> FloatArrayF<N> operator ^= ( FloatArrayF<N> & x, double a){ x=x.array().pow(a); return x; }
276template<std::size_t N> bool iszero(const FloatArrayF<N> &x){ return (x.array()==0).all(); }
277template<std::size_t N> bool isfinite( const FloatArrayF<N> &x ){ return x.isfinite().all(); }
278template<std::size_t N> double norm_squared( const FloatArrayF<N> & x ){ return x.squaredNorm(); }
279template<std::size_t N> double norm( const FloatArrayF<N> & x ){ return x.norm(); }
280template<std::size_t N> FloatArrayF<N> normalize( const FloatArrayF<N> & x ){ return x/x.norm(); }
281template<std::size_t N> double sum( const FloatArrayF<N> & x ){ return x.array().sum(); }
282template<std::size_t N> double product( const FloatArrayF<N> & x ){ return x.array().prod(); }
283inline FloatArrayF<3> cross( const FloatArrayF<3> & x, const FloatArrayF<3> & y ){ return x.cross(y); }
284template<std::size_t N> double dot( const FloatArrayF<N> & x, const FloatArrayF<N> & y ){ return x.dot(y); }
285template<std::size_t N> FloatArrayF<N> max(const FloatArrayF<N> &a, const FloatArrayF<N> &b){ return a.array().max(b); }
286template<std::size_t N> FloatArrayF<N> min(const FloatArrayF<N> &a, const FloatArrayF<N> &b){ return a.array().min(b); }
287template<std::size_t N> FloatArrayF<N> zeros() { return FloatArrayF<N>::Zero(); }
288#else
289
291template<size_t N, size_t M>
292inline FloatArrayF<N> assemble(const FloatArrayF<M> &x, int const (&c)[M] )
293{
294 FloatArrayF<N> out;
295 for ( std::size_t i = 0; i < M; ++i ) {
296 out[c[i]] = x[i];
297 }
298 return out;
299}
300
301
302
304template<std::size_t N>
306{
307 FloatArrayF<N> out;
308 for ( std::size_t i = 0; i < N; ++i ) {
309 out[i] = x[i] * a;
310 }
311 return out;
312}
313
314template<std::size_t N>
316{
317 return a*x;
318}
319
321template<std::size_t N>
323{
324 FloatArrayF<N> out;
325 for ( std::size_t i = 0; i < N; ++i ) {
326 out[i] = x[i] * y[i];
327 }
328 return out;
329}
330
331
332template<std::size_t N>
334{
335 FloatArrayF<N> out;
336 for ( std::size_t i = 0; i < N; ++i ) {
337 out[i] = x[i] / a;
338 }
339 return out;
340}
341
342template<std::size_t N>
344{
345 FloatArrayF<N> out;
346 for ( std::size_t i = 0; i < N; ++i ) {
347 out[i] = std::pow(x[i], a);
348 }
349 return out;
350}
351
352template<std::size_t N>
354{
355 FloatArrayF<N> out;
356 for ( std::size_t i = 0; i < N; ++i ) {
357 out[i] = x[i] + y[i];
358 }
359 return out;
360}
361
362template<std::size_t N>
364{
365 FloatArrayF<N> out;
366 for ( std::size_t i = 0; i < N; ++i ) {
367 out[i] = x[i] - y[i];
368 }
369 return out;
370}
371
372template<std::size_t N>
374{
375 FloatArrayF<N> out;
376 for ( std::size_t i = 0; i < N; ++i ) {
377 out[i] = - x[i];
378 }
379 return out;
380}
381
382template<std::size_t N>
384{
385 for ( std::size_t i = 0; i < N; ++i ) {
386 x[i] += y[i];
387 }
388 return x;
389}
390
391template<std::size_t N>
393{
394 for ( std::size_t i = 0; i < N; ++i ) {
395 x[i] -= y[i];
396 }
397 return x;
398}
399
400template<std::size_t N>
402{
403 for ( auto &v : x ) {
404 v *= a;
405 }
406 return x;
407}
408
409template<std::size_t N>
411{
412 for ( auto &v : x ) {
413 v /= a;
414 }
415 return x;
416}
417
418template<std::size_t N>
420{
421 for ( auto &v : x ) {
422 v = std::pow(v, a);
423 }
424}
425
426
428template<std::size_t N>
429bool iszero(const FloatArrayF<N> &x)
430{
431 for ( auto &v : x ) {
432 if ( v != 0. ) {
433 return false;
434 }
435 }
436 return true;
437}
438
440template<std::size_t N>
441bool isfinite( const FloatArrayF<N> &x )
442{
443 for ( auto &val : x ) {
444 if ( !std::isfinite(val) ) {
445 return false;
446 }
447 }
448 return true;
449}
450
452template<std::size_t N>
453double norm_squared( const FloatArrayF<N> & x )
454{
455 double ans = 0.;
456 for ( auto &val : x ) {
457 ans += val * val;
458 }
459 return ans;
460}
461
463template<std::size_t N>
464double norm( const FloatArrayF<N> & x )
465{
466 return std::sqrt(norm_squared(x));
467}
468
470template<std::size_t N>
472{
473 return x / norm(x);
474}
475
477template<std::size_t N>
478double sum( const FloatArrayF<N> & x )
479{
480 return std::accumulate(x.begin(), x.end(), 0.);
481}
482
484template<std::size_t N>
485double product( const FloatArrayF<N> & x )
486{
487 return std::accumulate(x.begin(), x.end(), 1.0, [](double a, double b) { return a*b; });
488}
489
491inline FloatArrayF<3> cross( const FloatArrayF<3> & x, const FloatArrayF<3> & y )
492{
493 return {
494 x[1] * y[2] - x[2] * y[1],
495 x[2] * y[0] - x[0] * y[2],
496 x[0] * y[1] - x[1] * y[0],
497 };
498}
499
501template<std::size_t N>
502double dot( const FloatArrayF<N> & x, const FloatArrayF<N> & y )
503{
504 double ans = 0.;
505 for ( std::size_t i = 0; i < N; ++i ) {
506 ans += x[i] * y[i];
507 }
508 return ans;
509}
510
511template<std::size_t N>
513{
514 FloatArrayF<N> out;
515 for (std::size_t i = 0; i < N; ++i) {
516 out[i] = std::max(a[i], b[i]);
517 }
518 return out;
519}
520
521template<std::size_t N>
523{
524 FloatArrayF<N> out;
525 for (std::size_t i = 0; i < N; ++i) {
526 out[i] = std::min(a[i], b[i]);
527 }
528 return out;
529}
530
532template<std::size_t N>
534 return FloatArrayF<N>();
535}
536
537
538
539#endif
540
541
543template<std::size_t N>
545{
546 return norm_squared(a-b);
547}
548
550template<std::size_t N>
552{
553 return norm(a-b);
554}
555
556
557
562inline void swap_46(FloatArrayF<6> &t)
563{
564 std::swap( t[3], t[5] );
565}
566
567inline void swap_46(FloatArrayF<9> &t)
568{
569 // OOFEM: 11, 22, 33, 23, 13, 12, 32, 31, 21
570 // UMAT: 11, 22, 33, 12, 13, 23, 32, 21, 31
571 std::swap( t[3], t[5] );
572 std::swap( t[7], t[8] );
573}
574
575
577const FloatArrayF<6> I6 {1., 1., 1., 0., 0., 0.};
578
581{
582 return {s[0], s[1], s[2], 0.5*s[3], 0.5*s[4], 0.5*s[5]};
583}
584
587{
588 return {e[0], e[1], e[2], 2*e[3], 2*e[4], 2*e[5]};
589}
590
591
592} // end namespace oofem
593#endif // floatarrayf_h
#define N(a, b)
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 write(const int *data, std::size_t count)=0
Writes count integer values from array pointed by data.
void printYourself(const std::string &name="FloatArrayF") const
auto end() const
Definition floatarrayf.h:95
auto begin() const
Definition floatarrayf.h:94
double & at(std::size_t i)
const double * data() const
FloatArrayF(const FloatArray &x)
Ctor from dynamic array (size must match).
const double * givePointer() const
std::array< double, N > values
Stored values.
Definition floatarrayf.h:87
FloatArrayF()
Empty Ctor (zeroes).
contextIOResultType storeYourself(DataStream &stream) const
int giveSize() const
Returns the size of receiver.
void assemble(const FloatArrayF< M > &x, int const (&c)[M])
Assemble x into self.
double at(std::size_t i) const
contextIOResultType restoreYourself(DataStream &stream)
void assign(const FloatArrayF< M > &x, int const (&c)[M])
Assign x into self.
FloatArrayF(V... x)
Direct value ctor.
int size() const
Returns the size of receiver.
FloatArrayF(const FloatArrayF< N > &x)
Copy ctor.
Definition floatarrayf.h:99
int givePackSize(DataStream &buff) const
double * givePointer()
std::vector< double >::iterator begin()
Definition floatarray.h:107
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
#define OOFEM_ERROR(...)
Definition error.h:79
FloatArray operator+(const FloatArray &x, const FloatArray &y)
Definition floatarray.C:978
double norm(const FloatArray &x)
OOFEM_EXPORT FloatArray operator/(const FloatArray &x, const double &a)
FloatArrayF< N > min(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
FloatArrayF< 6 > to_voigt_strain_6(const FloatArrayF< 6 > &s)
Convert stress to strain Voigt form.
bool iszero(const FloatArray &x)
FloatArray operator-(const FloatArray &x, const FloatArray &y)
Definition floatarray.C:985
FloatArrayF< N > assemble(const FloatArrayF< M > &x, int const (&c)[M])
Assemble components into zero matrix.
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
FloatArrayF< N > operator^=(FloatArrayF< N > &x, double a)
int Index
Definition numerics.h:73
FloatArrayF< 3 > cross(const FloatArrayF< 3 > &x, const FloatArrayF< 3 > &y)
Computes $ x \cross y $.
double sum(const FloatArray &x)
FloatArrayF< N > operator^(const FloatArrayF< N > &x, double a)
double dot(const FloatArray &x, const FloatArray &y)
FloatArrayF< N > mult(const FloatArrayF< N > &x, const FloatArrayF< N > &y)
Element-wise multiplication.
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
void swap_46(FloatArrayF< 6 > &t)
FloatArrayF< N > normalize(const FloatArrayF< N > &x)
Normalizes vector (L2 norm).
FloatArrayF< N > zeros()
For more readable code.
FloatArray & operator*=(FloatArray &x, const double &a)
Vector multiplication by scalar.
Definition floatarray.C:958
double distance(const FloatArray &x, const FloatArray &y)
@ CIO_IOERR
General IO error.
FloatArrayF< 6 > to_voigt_stress_6(const FloatArrayF< 6 > &e)
Convert strain to stress Voigt form.
double norm_squared(const FloatArrayF< N > &x)
Computes the L2 norm of x.
const FloatArrayF< 6 > I6
I expressed in Voigt form.
FloatArrayF< N > distance_squared(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
Computes the norm(a-b)^2.
#define OOFEM_EXPORT
Definition oofemcfg.h:7

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