OOFEM  2.1
flotarry.C
Go to the documentation of this file.
00001 /*
00002  *
00003  *                 #####    #####   ######  ######  ###   ###
00004  *               ##   ##  ##   ##  ##      ##      ## ### ##
00005  *              ##   ##  ##   ##  ####    ####    ##  #  ##
00006  *             ##   ##  ##   ##  ##      ##      ##     ##
00007  *            ##   ##  ##   ##  ##      ##      ##     ##
00008  *            #####    #####   ##      ######  ##     ##
00009  *
00010  *
00011  *             OOFEM : Object Oriented Finite Element Code
00012  *
00013  *               Copyright (C) 1993 - 2013   Borek Patzak
00014  *
00015  *
00016  *
00017  *       Czech Technical University, Faculty of Civil Engineering,
00018  *   Department of Structural Mechanics, 166 29 Prague, Czech Republic
00019  *
00020  *  This program is free software; you can redistribute it and/or modify
00021  *  it under the terms of the GNU General Public License as published by
00022  *  the Free Software Foundation; either version 2 of the License, or
00023  *  (at your option) any later version.
00024  *
00025  *  This program is distributed in the hope that it will be useful,
00026  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00027  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00028  *  GNU General Public License for more details.
00029  *
00030  *  You should have received a copy of the GNU General Public License
00031  *  along with this program; if not, write to the Free Software
00032  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00033  */
00034 /*
00035  * The original idea for this class comes from
00036  * Dubois-Pelerin, Y.: "Object-Oriented  Finite Elements: Programming concepts and Implementation",
00037  * PhD Thesis, EPFL, Lausanne, 1992.
00038  */
00039 
00040 #include "flotarry.h"
00041 #include "intarray.h"
00042 #include "flotmtrx.h"
00043 #include "mathfem.h"
00044 #include "error.h"
00045 #include "datastream.h"
00046 #include "classtype.h"
00047 #include "mathfem.h"
00048 #include "freestor.h"
00049 
00050 #include <cstdarg>
00051 
00052 #ifdef __PARALLEL_MODE
00053  #include "combuff.h"
00054 #endif
00055 
00056 namespace oofem {
00057 FloatArray :: FloatArray(int n)
00058 // Constructor : creates an array of size n (filled with garbage).
00059 {
00060     allocatedSize = size = n;
00061     if ( size ) {
00062         values = allocDouble(size);
00063 #ifdef DEBUG
00064         if ( !values ) {
00065             OOFEM_FATAL2("FloatArray :: FloatArray - Failed in allocating %d doubles", n);
00066         }
00067 
00068 #endif
00069     } else {
00070         values = NULL;
00071     }
00072 }
00073 
00074 FloatArray :: FloatArray(const FloatArray &src)
00075 {
00076     // copy constructor
00077 
00078     double *srcVal;
00079 
00080     allocatedSize = size = src.size;
00081     if ( size ) {
00082         values = allocDouble(size);
00083 #ifdef DEBUG
00084         if ( !values ) {
00085             OOFEM_FATAL2("FloatArray :: FloatArray - Failed in allocating %d doubles", size);
00086         }
00087 
00088 #endif
00089     } else {
00090         values = NULL;
00091     }
00092 
00093     srcVal = src.values;
00094     for ( int i = 0; i < size; i++ ) {
00095         this->values [ i ] = srcVal [ i ];
00096     }
00097 }
00098 
00099 FloatArray :: ~FloatArray()
00100 {
00101     if ( values ) {
00102         freeDouble(values);
00103     }
00104 }
00105 
00106 FloatArray &
00107 FloatArray :: operator = ( const FloatArray & src )
00108 {
00109     if ( this != & src ) { // beware of s=s;
00110         this->resize(src.size);
00111         for ( int i = 0; i < this->size; i++ ) {
00112             this->values [ i ] = src.values [ i ];
00113         }
00114     }
00115 
00116     return * this;
00117 }
00118 
00119 #ifdef DEBUG
00120 double &
00121 FloatArray :: operator()(int i)
00122 {
00123     if ( i >= size ) {
00124         OOFEM_ERROR2("FloatArray :: operator() : array error on index : %d <= 0 \n", i);
00125     }
00126     return values [ i ];
00127 }
00128 
00129 const double &
00130 FloatArray :: operator()(int i) const
00131 {
00132     if ( i >= size ) {
00133         OOFEM_ERROR2("FloatArray :: operator() : array error on index : %d <= 0 \n", i);
00134     }
00135     return values [ i ];
00136 }
00137 #endif
00138 
00139 
00140 void
00141 FloatArray :: setValues(int n, ...)
00142 {
00143     va_list vl;
00144     va_start(vl,n);
00145     this->resize(n);
00146     for (int i = 0; i < n; i++ ) {
00147         this->values [ i ] = va_arg(vl, double);
00148     }
00149     va_end(vl);
00150 }
00151 
00152 
00153 void
00154 FloatArray :: beScaled(double s, const FloatArray &b)
00155 {
00156     this->resize(b.size);
00157     for ( int i = 0; i < this->size; ++i ) {
00158         this->values [ i ] = s * b.values [ i ];
00159     }
00160 }
00161 
00162 
00163 void FloatArray :: add(const FloatArray &b)
00164 // Performs the operation a=a+b, where a stands for the receiver. If the
00165 // receiver's size is 0, adjusts its size to that of b. Returns the
00166 // receiver.
00167 {
00168     if ( b.size == 0 ) {
00169         return;
00170     }
00171 
00172     if ( !size ) {
00173         * this = b;
00174         return;
00175     }
00176 
00177     if ( size != b.size ) {
00178         OOFEM_ERROR3("FloatArray :: add :  dimension mismatch in a[%d]->add(b[%d])\n", size, b.size);
00179     }
00180 
00181     for ( int i = 0; i < this->size; i++ ) {
00182         this->values [ i ] += b.values [ i ];
00183     }
00184 }
00185 
00186 
00187 void FloatArray :: add(double offset)
00188 {
00189     for ( int i = 0; i < this->size; i++ ) {
00190         this->values [ i ] += offset;
00191     }
00192 }
00193 
00194 
00195 void FloatArray :: add(const double factor, const FloatArray &b)
00196 // Performs the operation a=a+factor*b, where a stands for the receiver. If the
00197 // receiver's size is 0, adjusts its size to that of b.
00198 {
00199     if ( this->size == 0 ) {
00200         this->beScaled(factor, b);
00201         return;
00202     }
00203 
00204 #  ifdef DEBUG
00205     if ( size != b.size ) {
00206         OOFEM_ERROR3("FloatArray :: add :  dimension mismatch in a[%d]->add(b[%d])\n", size, b.size);
00207     }
00208 
00209 #  endif
00210 
00211     for ( int i = 0; i < this->size; ++i ) {
00212         this->values [ i ] += factor * b.values [ i ];
00213     }
00214 }
00215 
00216 void FloatArray :: subtract(const FloatArray &src)
00217 // Performs the operation a=a-src, where a stands for the receiver. If the
00218 // receiver's size is 0, adjusts its size to that of src.
00219 {
00220     if ( src.giveSize() == 0 ) {
00221         return;
00222     }
00223 
00224     if ( !size ) {
00225         this->resize(src.size);
00226         for ( int i = 0; i < this->size; ++i ) {
00227             this->values [ i ] = -src.values [ i ];
00228         }
00229 
00230         return;
00231     }
00232 
00233 #  ifdef DEBUG
00234     if ( this->size != src.size ) {
00235         OOFEM_ERROR3("FloatArray dimension mismatch in a[%d]->add(b[%d])\n", size, src.size);
00236     }
00237 
00238 #  endif
00239 
00240     for ( int i = 0; i < this->size; ++i ) {
00241         this->values [ i ] -= src.values [ i ];
00242     }
00243 }
00244 
00245 
00246 void FloatArray :: beMaxOf(const FloatArray &a, const FloatArray &b)
00247 {
00248     int n = a.giveSize();
00249 
00250 #  ifdef DEBUG
00251     if ( n != b.size ) {
00252         OOFEM_ERROR3("FloatArray dimension mismatch in beMaxOf(a[%d],b[%d])\n", n, b.size);
00253     }
00254 
00255 #  endif
00256 
00257     this->resize(n);
00258     for ( int i = 0; i < n; i++ ) {
00259         this->values [ i ] = max( a(i), b(i) );
00260     }
00261 }
00262 
00263 
00264 void FloatArray :: beMinOf(const FloatArray &a, const FloatArray &b)
00265 {
00266     int n = a.giveSize();
00267 
00268 #  ifdef DEBUG
00269     if ( n != b.size ) {
00270         OOFEM_ERROR3("FloatArray dimension mismatch in beMinOf(a[%d],b[%d])\n", n, b.size);
00271     }
00272 
00273 #  endif
00274 
00275     this->resize(n);
00276     for ( int i = 0; i < n; i++ ) {
00277         this->values [ i ] = min( a(i), b(i) );
00278     }
00279 }
00280 
00281 
00282 void FloatArray :: beDifferenceOf(const FloatArray &a, const FloatArray &b)
00283 {
00284 #ifdef DEBUG
00285     if ( a.size != b.size ) {
00286         OOFEM_ERROR3("FloatArray :: beDifferenceOf - size mismatch (%d : %d)", a.size, b.size);
00287     }
00288 
00289 #endif
00290     this->resize(a.size);
00291     for ( int i = 0; i < this->size; ++i ) {
00292         this->values [ i ] = a.values [ i ] - b.values [ i ];
00293     }
00294 }
00295 
00296 void FloatArray :: beDifferenceOf(const FloatArray &a, const FloatArray &b, int n)
00297 {
00298 #ifdef DEBUG
00299     if ( a.size < n || b.size < n ) {
00300         OOFEM_ERROR3("FloatArray :: beDifferenceOf - wrong size ", a.size, b.size);
00301     }
00302 
00303 #endif
00304     this->resize(n);
00305     for ( int i = 0; i < n; ++i ) {
00306         this->values [ i ] = a.values [ i ] - b.values [ i ];
00307     }
00308 }
00309 
00310 
00311 void FloatArray :: beSubArrayOf(const FloatArray &src, const IntArray &indx)
00312 //
00313 // returns subVector from receiver
00314 // subVector size will be indx max val size
00315 // and on i-th position of subVector will be this->at(indx->at(i))
00316 //
00317 {
00318     int i, ii, n, isize;
00319 
00320     n = indx.giveSize();
00321 
00322 #ifdef DEBUG
00323     if ( src.size != n ) {
00324         OOFEM_ERROR("FloatArray :: beSubArrayOf - size mismatch");
00325     }
00326 
00327 #endif
00328 
00329     for ( isize = 0, i = 0; i < n; i++ ) {
00330         if ( indx(i) > isize ) {
00331             isize = indx(i);
00332         }
00333     }
00334 
00335     this->resize(isize);
00336     for ( i = 0; i < n; i++ ) {
00337         ii = indx(i);
00338         if ( ii > 0 ) {
00339             this->values [ ii-1 ] = src.values [ i ];
00340         }
00341     }
00342 }
00343 
00344 
00345 void FloatArray :: addSubVector(const FloatArray &src, int si)
00346 {
00347     int i, reqSize, n = src.giveSize();
00348 
00349     si--;
00350     reqSize = si + n;
00351     if ( this->giveSize() < reqSize ) {
00352         this->resize(reqSize);
00353     }
00354 
00355     for ( i = 1; i <= n; i++ ) {
00356         this->at(si + i) += src.at(i);
00357     }
00358 }
00359 
00360 
00361 void FloatArray :: beVectorProductOf(const FloatArray &v1, const FloatArray &v2)
00362 {
00363     // check proper bounds
00364     if ( ( v1.giveSize() != 3 ) || ( v2.giveSize() != 3 ) ) {
00365         OOFEM_ERROR(" FloatArray::VectorProduct : size mismatch, size is not equal to 3");
00366     }
00367 
00368     this->resize(3);
00369 
00370     this->at(1) = v1.at(2) * v2.at(3) - v1.at(3) * v2.at(2);
00371     this->at(2) = v1.at(3) * v2.at(1) - v1.at(1) * v2.at(3);
00372     this->at(3) = v1.at(1) * v2.at(2) - v1.at(2) * v2.at(1);
00373 }
00374 
00375 
00376 double FloatArray :: dotProduct(const FloatArray &x) const
00377 {
00378 #  ifdef DEBUG
00379     if ( this->size != x.size ) {
00380         OOFEM_ERROR3("FloatArray :: dotProduct :  dimension mismatch in a[%d]->dotProduct(b[%d])\n", this->size, x.size);
00381     }
00382 
00383 #  endif
00384 
00385     double dp = 0;
00386     for ( int i = 0; i < this->size; i++ ) {
00387         dp += this->values [ i ] * x.values [ i ];
00388     }
00389 
00390     return dp;
00391 }
00392 
00393 
00394 double FloatArray :: dotProduct(const FloatArray &x, int size) const
00395 {
00396 #  ifdef DEBUG
00397     if ( size > this->size || size > x.size ) {
00398         OOFEM_ERROR3("FloatArray :: dotProduct :  dimension mismatch in a[%d]->dotProduct(b[%d])\n", this->size, x.size);
00399     }
00400 
00401 #  endif
00402 
00403     double dp = 0.;
00404     for ( int i = 0; i < size; i++ ) {
00405         dp += this->values [ i ] * x.values [ i ];
00406     }
00407 
00408     return dp;
00409 }
00410 
00411 
00412 double FloatArray :: distance(const FloatArray &x) const
00413 {
00414     return sqrt( this->distance_square(x) );
00415 }
00416 
00417 
00418 double FloatArray :: distance_square(const FloatArray &from) const
00419 // returns distance between receiver and from from
00420 // computed using generalized pythagorean formulae
00421 {
00422     double *p1, *p2, dx, dist = 0.;
00423 
00424     p1 = this->values;
00425     p2 = from.values;
00426     int s = min(size, from.size);
00427     while ( s-- ) {
00428         dx = ( * p1 ) - ( * p2 );
00429         dist += dx * dx;
00430         p1++;
00431         p2++;
00432     }
00433 
00434     return dist;
00435 }
00436 
00437 
00438 void FloatArray :: assemble(const FloatArray &fe, const IntArray &loc)
00439 // Assembles the array fe (typically, the load vector of a finite
00440 // element) to the receiver, using loc as location array.
00441 {
00442     int n = fe.giveSize();
00443 #  ifdef DEBUG
00444     if ( n != loc.giveSize() ) {
00445         OOFEM_ERROR3("FloatArray::assemble : dimensions of 'fe' (%d) and 'loc' (%d) mismatch",fe.giveSize(), loc.giveSize());
00446     }
00447     
00448 #  endif
00449 
00450     for ( int i = 1; i <= n; i++ ) {
00451         int ii = loc.at(i);
00452         if ( ii ) { // if non 0 coefficient,
00453             this->at(ii) += fe.at(i);
00454         }
00455     }
00456 
00457 }
00458 
00459 
00460 #ifdef DEBUG
00461 double &FloatArray :: at(int i)
00462 // Returns the i-th coefficient of the receiver. Slow but safe.
00463 {
00464     this->checkBounds(i);
00465     return values [ i - 1 ];
00466 }
00467 
00468 double FloatArray :: at(int i) const
00469 // Returns the i-th coefficient of the receiver. Slow but safe.
00470 {
00471     this->checkBounds(i);
00472     return values [ i - 1 ];
00473 }
00474 #endif
00475 
00476 
00477 #ifdef DEBUG
00478 void FloatArray :: checkBounds(int i) const
00479 // Checks that the receiver's size is not smaller than 'i'.
00480 {
00481     if ( i <= 0 ) {
00482         OOFEM_ERROR2("FloatArray :: checkBounds : array error on index : %d <= 0 \n", i);
00483     }
00484 
00485     if ( i > size ) {
00486         OOFEM_ERROR3("FloatArray :: checkBounds : array error on index : %d > %d \n", i, size);
00487     }
00488 }
00489 #endif
00490 
00491 
00492 void FloatArray :: checkSizeTowards(const IntArray &loc)
00493 // Expands the receiver if loc points to coefficients beyond the size of
00494 // the receiver.
00495 {
00496     int n, high;
00497 
00498     high = 0;
00499     n = loc.giveSize();
00500     for ( int i = 1; i <= n; i++ ) {
00501         high = max( high, ( loc.at(i) ) );
00502     }
00503 
00504     if ( high > size ) {   // receiver must be expanded
00505         this->resize(high);
00506     }
00507 }
00508 
00509 
00510 void FloatArray :: resize(int n, int allocChunk)
00511 {
00512     int i;
00513     double *newValues, *p1, *p2;
00514 
00515 #ifdef DEBUG
00516     if ( allocChunk < 0 ) {
00517         OOFEM_FATAL2("FloatArray :: resize - allocChunk must be non-negative; %d", allocChunk);
00518     }
00519 
00520 #endif
00521 
00522     if ( n <= allocatedSize ) {
00523         size = n;
00524         return;
00525     }
00526 
00527     newValues = allocDouble(n + allocChunk);
00528 #ifdef DEBUG
00529     if ( !newValues ) {
00530         OOFEM_FATAL2("FloatArray :: resize - Failed in allocating %d doubles", n + allocChunk);
00531     }
00532 
00533 #endif
00534     p1 = values;
00535     p2 = newValues;
00536     i  = size;
00537     while ( i-- ) {
00538         * p2++ = * p1++;
00539     }
00540 
00541     if ( values ) {
00542         freeDouble(values);
00543     }
00544 
00545     values = newValues;
00546     allocatedSize = n + allocChunk;
00547     size = n;
00548 }
00549 
00550 
00551 void FloatArray :: hardResize(int n)
00552 // Reallocates the receiver with new size.
00553 {
00554     int i;
00555     double *newValues, *p1, *p2;
00556 
00557     // if (n <= allocatedSize) {size = n; return;}
00558 
00559     newValues = allocDouble(n);
00560 #ifdef DEBUG
00561     if ( !newValues ) {
00562         OOFEM_FATAL2("FloatArray :: hardResize - Failed in allocating %d doubles", n);
00563     }
00564 
00565 #endif
00566     p1 = values;
00567     p2 = newValues;
00568     i  = min(size, n);
00569     while ( i-- ) {
00570         * p2++ = * p1++;
00571     }
00572 
00573     if ( values ) {
00574         freeDouble(values);
00575     }
00576 
00577     values = newValues;
00578     allocatedSize = size = n;
00579 }
00580 
00581 
00582 
00583 bool FloatArray :: containsOnlyZeroes() const
00584 {
00585     for ( int i = 0; i < this->size; i++ ) {
00586         if ( this->values [ i ] != 0. ) {
00587             return false;
00588         }
00589     }
00590 
00591     return true;
00592 }
00593 
00594 
00595 void FloatArray :: zero()
00596 {
00597     for ( int i = 0; i < this->size; i++ ) {
00598         this->values [ i ] = 0.;
00599     }
00600 }
00601 
00602 
00603 void FloatArray :: beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
00604 // Stores the product of aMatrix * anArray in to receiver
00605 {
00606     int nColumns, nRows;
00607     double sum;
00608 
00609 #  ifdef DEBUG
00610     if ( ( nColumns = aMatrix.giveNumberOfColumns() ) - anArray.giveSize() ) {
00611         OOFEM_ERROR("FloatArray :: beProductOf : dimension mismatch");
00612     }
00613 
00614 #  endif
00615 
00616     nColumns = aMatrix.giveNumberOfColumns();
00617     this->resize( nRows = aMatrix.giveNumberOfRows() );
00618     for ( int i = 1; i <= nRows; i++ ) {
00619         sum = 0.;
00620         for ( int j = 1; j <= nColumns; j++ ) {
00621             sum += aMatrix.at(i, j) * anArray.at(j);
00622         }
00623 
00624         this->at(i) = sum;
00625     }
00626 }
00627 
00628 
00629 void FloatArray :: beTProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
00630 // Stores the product of aMatrix^T * anArray in to receiver
00631 {
00632     int nColumns, nRows;
00633     double sum;
00634 
00635 #  ifdef DEBUG
00636     if ( ( nColumns = aMatrix.giveNumberOfRows() ) - anArray.giveSize() ) {
00637         OOFEM_ERROR("FloatArray :: beTProductOf : dimension mismatch");
00638     }
00639 
00640 #  endif
00641 
00642     nColumns = aMatrix.giveNumberOfRows();
00643     this->resize( nRows = aMatrix.giveNumberOfColumns() );
00644     for ( int i = 1; i <= nRows; i++ ) {
00645         sum = 0.;
00646         for ( int j = 1; j <= nColumns; j++ ) {
00647             sum += aMatrix.at(j, i) * anArray.at(j);
00648         }
00649 
00650         this->at(i) = sum;
00651     }
00652 }
00653 
00654 
00655 void FloatArray :: negated()
00656 {
00657     for ( int i = 0; i < this->size; i++ ) {
00658         this->values [ i ] = -this->values [ i ];
00659     }
00660 }
00661 
00662 
00663 void FloatArray :: printYourself() const
00664 // Prints the receiver on screen.
00665 {
00666     printf("FloatArray of size : %d \n", size);
00667     for ( int i = 1; i <= size; ++i ) {
00668         printf( "%10.3e  ", this->at(i) );
00669     }
00670 
00671     printf("\n");
00672 }
00673 
00674 
00675 void FloatArray :: pY() const
00676 // Prints the receiver on screen with higher accuracy than printYourself.
00677 {
00678     printf("[");
00679     for ( int i = 1; i <= size; ++i ) {
00680         printf( "%20.14e; ", this->at(i) );
00681     }
00682 
00683     printf("];\n");
00684 }
00685 
00686 
00687 void FloatArray :: rotatedWith(FloatMatrix &r, char mode)
00688 // Returns the receiver 'a' rotated according the change-of-base matrix r.
00689 // If mode = 't', the method performs the operation  a = r(transp) * a .
00690 // If mode = 'n', the method performs the operation  a = r * a .
00691 {
00692     FloatArray rta;
00693 
00694     if ( mode == 't' ) {
00695         rta.beTProductOf(r, * this);
00696     } else if ( mode == 'n' ) {
00697         rta.beProductOf(r, * this);
00698     } else {
00699         OOFEM_ERROR("FloatArray :: rotatedWith: unsupported mode");
00700     }
00701 
00702     * this = rta;
00703 }
00704 
00705 
00706 void FloatArray :: times(double factor)
00707 // Multiplies every coefficient of the receiver by factor.
00708 {
00709     for ( int i = 0; i < this->size; i++ ) {
00710         this->values [ i ] *= factor;
00711     }
00712 }
00713 
00714 
00715 double FloatArray :: normalize()
00716 {
00717     double norm = this->computeNorm();
00718     if ( norm < 1.e-80 ) {
00719         OOFEM_ERROR("FloatArray::normalize : cannot norm receiver, norm is too small");
00720     }
00721 
00722     this->times(1. / norm);
00723     return norm;
00724 }
00725 
00726 
00727 double FloatArray :: computeNorm() const
00728 {
00729     return sqrt( this->computeSquaredNorm() );
00730 }
00731 
00732 
00733 double FloatArray :: computeSquaredNorm() const
00734 {
00735     int i;
00736     double *p, norm2 = 0.;
00737 
00738     p = this->values;
00739     i = this->size;
00740     while ( i-- ) {
00741         norm2 += ( * p ) * ( * p );
00742         p++;
00743     }
00744 
00745     return norm2;
00746 }
00747 
00748 
00749 double FloatArray :: sum() const
00750 {
00751     int i;
00752     double *p, sum = 0;
00753 
00754     p = this->values;
00755     i = this->size;
00756     while ( i-- ) {
00757         sum += * ( p++ );
00758     }
00759 
00760     return sum;
00761 }
00762 
00763 void FloatArray :: copySubVector(const FloatArray &src, int si)
00764 {
00765     int i, reqSize, n = src.giveSize();
00766 
00767     si--;
00768     reqSize = si + n;
00769     if ( this->giveSize() < reqSize ) {
00770         this->resize(reqSize);
00771     }
00772 
00773     for ( i = 1; i <= n; i++ ) {
00774         this->at(si + i) = src.at(i);
00775     }
00776 }
00777 
00778 
00779 contextIOResultType FloatArray :: storeYourself(DataStream *stream, ContextMode mode)
00780 // writes receiver's binary image into stream
00781 // use id to distinguish some instances
00782 // return value >0 success
00783 //              =0 file i/o error
00784 {
00785     // write size
00786     if ( !stream->write(& size, 1) ) {
00787         return CIO_IOERR;
00788     }
00789 
00790     // write raw data
00791     if ( size ) {
00792         if ( !stream->write(values, size) ) {
00793             return CIO_IOERR;
00794         }
00795     }
00796 
00797     // return result back
00798     return CIO_OK;
00799 }
00800 
00801 contextIOResultType FloatArray :: restoreYourself(DataStream *stream, ContextMode mode)
00802 // reads receiver from stream
00803 // warning - overwrites existing data!
00804 // returns 0 if file i/o error
00805 //        -1 if id od class id is not correct
00806 {
00807     // read size
00808     if ( !stream->read(& size, 1) ) {
00809         return CIO_IOERR;
00810     }
00811 
00812     if ( size > allocatedSize ) {
00813         if ( values != NULL ) {
00814             freeDouble(values);
00815         }
00816 
00817         values = allocDouble(size);
00818 #ifdef DEBUG
00819         if ( !values ) {
00820             OOFEM_FATAL2("FloatArray :: restoreYourself - Failed in allocating %d doubles", size);
00821         }
00822 
00823 #endif
00824         allocatedSize = size;
00825     }
00826 
00827     // read raw data
00828     if ( size ) {
00829         if ( !stream->read(values, size) ) {
00830             return CIO_IOERR;
00831         }
00832     }
00833 
00834     // return result back
00835     return CIO_OK;
00836 }
00837 
00838 
00839 #ifdef __PARALLEL_MODE
00840 int FloatArray :: packToCommBuffer(CommunicationBuffer &buff) const
00841 {
00842     int result = 1;
00843     // pack size
00844     result &= buff.packInt(size);
00845     // pack data
00846     result &= buff.packArray(this->values, size);
00847 
00848     return result;
00849 }
00850 
00851 int FloatArray :: unpackFromCommBuffer(CommunicationBuffer &buff)
00852 {
00853     int newSize, result = 1;
00854     // unpack size
00855     result &= buff.unpackInt(newSize);
00856     // resize yourself
00857     this->resize(newSize);
00858     result &= buff.unpackArray(this->values, newSize);
00859 
00860     return result;
00861 }
00862 
00863 int FloatArray :: givePackSize(CommunicationBuffer &buff) const
00864 {
00865     return buff.givePackSize(MPI_INT, 1) + buff.givePackSize(MPI_DOUBLE, this->size);
00866 }
00867 
00868 #endif
00869 
00870 #ifdef IML_COMPAT
00871 
00872 FloatArray &FloatArray :: operator = ( const double & val )
00873 {
00874     for ( int i = 0; i < size; i++ ) {
00875         values [ i ] = val;
00876     }
00877 
00878     return * this;
00879 }
00880 
00881 FloatArray &operator *= ( FloatArray & x, const double & a )
00882 {
00883     int N = x.giveSize();
00884     for ( int i = 0; i < N; i++ ) {
00885         x(i) *= a;
00886     }
00887 
00888     return x;
00889 }
00890 
00891 
00892 FloatArray operator *( const double & a, const FloatArray & x )
00893 {
00894     int N = x.giveSize();
00895     FloatArray result(N);
00896     for ( int i = 0; i < N; i++ ) {
00897         result(i) = x(i) * a;
00898     }
00899 
00900     return result;
00901 }
00902 
00903 FloatArray operator *( const FloatArray & x, const double & a )
00904 {
00905     // This is the other commutative case of vector*scalar.
00906     // It should be just defined to be
00907     // "return operator*(a,x);"
00908     // but some compilers (e.g. Turbo C++ v.3.0) have trouble
00909     // determining the proper template match.  For the moment,
00910     // we'll just duplicate the code in the scalar * vector
00911     // case above.
00912 
00913     int N = x.giveSize();
00914     FloatArray result(N);
00915     for ( int i = 0; i < N; i++ ) {
00916         result(i) = x(i) * a;
00917     }
00918 
00919     return result;
00920 }
00921 
00922 FloatArray operator + ( const FloatArray & x, const FloatArray & y )
00923 {
00924     int N = x.giveSize();
00925 #if DEBUG
00926     if ( N != y.giveSize() ) {
00927         OOFEM_ERROR("loatArray operator+ : incompatible vector lengths");
00928     }
00929 #endif
00930 
00931     FloatArray result(N);
00932     for ( int i = 0; i < N; i++ ) {
00933         result(i) = x(i) + y(i);
00934     }
00935 
00936     return result;
00937 }
00938 
00939 FloatArray operator - ( const FloatArray & x, const FloatArray & y )
00940 {
00941     int N = x.giveSize();
00942 #if DEBUG
00943     if ( N != y.giveSize() ) {
00944         OOFEM_ERROR("FloatArray operator- : incompatible vector lengths");
00945     }
00946 #endif
00947 
00948     FloatArray result(N);
00949     for ( int i = 0; i < N; i++ ) {
00950         result(i) = x(i) - y(i);
00951     }
00952 
00953     return result;
00954 }
00955 
00956 
00957 FloatArray &operator += ( FloatArray & x, const FloatArray & y )
00958 {
00959     int N = x.giveSize();
00960 #if DEBUG
00961     if ( N != y.giveSize() ) {
00962         OOFEM_ERROR("FloatArray& operator+= : incompatible vector lengths");
00963     }
00964 #endif
00965 
00966     for ( int i = 0; i < N; i++ ) {
00967         x(i) += y(i);
00968     }
00969 
00970     return x;
00971 }
00972 
00973 
00974 FloatArray &operator -= ( FloatArray & x, const FloatArray & y )
00975 {
00976     int N = x.giveSize();
00977 #if DEBUG
00978     if ( N != y.giveSize() ) {
00979         OOFEM_ERROR("FloatArray& operator-= : incompatible vector lengths");
00980     }
00981 #endif
00982 
00983     for ( int i = 0; i < N; i++ ) {
00984         x(i) -= y(i);
00985     }
00986 
00987     return x;
00988 }
00989 
00990 
00991 double dot(const FloatArray &x, const FloatArray &y)
00992 {
00993     //  Check for compatible dimensions:
00994 #if DEBUG
00995     if ( x.giveSize() != y.giveSize() ) {
00996         OOFEM_ERROR("dot : incompatible dimensions");
00997     }
00998 #endif
00999 
01000     double temp =  0;
01001     for ( int i = 0; i < x.giveSize(); i++ ) {
01002         temp += x(i) * y(i);
01003     }
01004 
01005     return temp;
01006 }
01007 
01008 double norm(const FloatArray &x)
01009 {
01010     double temp = oofem :: dot(x, x);
01011     return sqrt(temp);
01012 }
01013 
01014 #endif
01015 
01016 void FloatArray :: beFullVectorForm(const FloatMatrix &aMatrix)
01017 {
01018     // Revrites the matrix on vector form, order: 11, 22, 33, 23, 13, 12, 32, 31, 21
01019 #  ifdef DEBUG
01020     if (  aMatrix.giveNumberOfColumns() || aMatrix.giveNumberOfColumns() !=3) {
01021         OOFEM_ERROR("FloatArray :: beFullVectorForm : matrix dimension is not 3x3");
01022     }
01023 
01024 #  endif
01025     this->resize(9);
01026     this->at(1) = aMatrix.at(1,1); this->at(2) = aMatrix.at(2,2); this->at(3) = aMatrix.at(3,3);
01027     this->at(4) = aMatrix.at(2,3); this->at(5) = aMatrix.at(1,3); this->at(6) = aMatrix.at(1,2);
01028     this->at(7) = aMatrix.at(3,2); this->at(8) = aMatrix.at(3,1); this->at(9) = aMatrix.at(2,1);
01029 }
01030 
01031 void FloatArray :: beReducedVectorForm(const FloatMatrix &aMatrix)
01032 {
01033     // Revrites the  matrix on vector form (symmetrized matrix used), order: 11, 22, 33, 23, 13, 12
01034 #  ifdef DEBUG
01035     if (  aMatrix.giveNumberOfColumns() !=3 || aMatrix.giveNumberOfColumns() !=3) {
01036         OOFEM_ERROR("FloatArray :: beReducedVectorForm : matrix dimension is not 3x3");
01037     }
01038 
01039 #  endif
01040     
01041     this->resize(6);
01042     this->at(1) = aMatrix.at(1,1); this->at(2) = aMatrix.at(2,2); this->at(3) = aMatrix.at(3,3);
01043     this->at(4) = 0.5*( aMatrix.at(2,3) + aMatrix.at(3,2) );
01044     this->at(5) = 0.5*( aMatrix.at(1,3) + aMatrix.at(3,1) );
01045     this->at(6) = 0.5*( aMatrix.at(1,2) + aMatrix.at(2,1) );
01046 }
01047 
01048 
01049 } // end namespace oofem

This page is part of the OOFEM documentation. Copyright (c) 2011 Borek Patzak
Project e-mail: info@oofem.org
Generated at Sun Mar 10 2013 18:16:53 for OOFEM by doxygen 1.7.6.1 written by Dimitri van Heesch, © 1997-2011