BJtensor.cpp

Go to the documentation of this file.
00001 //############################################################################
00002 //#                                                                          #
00003 //#             /~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/~~\              #
00004 //#            |                                          |____|             #
00005 //#            |                                          |                  #
00006 //#            |                                          |                  #
00007 //#            |                 B A S E                  |                  #
00008 //#            |                                          |                  #
00009 //#            |                                          |                  #
00010 //#            |              C L A S S E S               |                  #
00011 //#            |                                          |                  #
00012 //#            |                                          |                  #
00013 //#            |          C + +     S O U R C E           |                  #
00014 //#            |                                          |                  #
00015 //#            |                                          |                  #
00016 //#            |                                          |                  #
00017 //#            |                                          |                  #
00018 //#            |                                          |                  #
00019 //#         /~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/   |                  #
00020 //#        |                                         |    |                  #
00021 //#         \_________________________________________\__/                   #
00022 //#                                                                          #
00023 //#                                                                          #
00024 //############################################################################
00025 //
00026 //   "C makes it easy to shoot yourself in the foot, C++ makes it harder,
00027 //   but when you do, it blows away your whole leg" -- Bjarne Stroustrup
00028 //
00030 //################################################################################
00031 //# COPY-YES  (C):     :-))                                                      #
00032 //# PROJECT:           Object Oriented Finite Element Program                    #
00033 //# PURPOSE:                                                                     #
00034 //# CLASS:             BJtensor                                                    #
00035 //#                                                                              #
00036 //# VERSION:                                                                     #
00037 //# LANGUAGE:          C++.ver >= 2.0 ( Borland C++ ver=3.00, SUN C++ ver=2.1 )  #
00038 //# TARGET OS:         DOS || UNIX || . . .                                      #
00039 //# DESIGNER(S):       Boris Jeremic                                             #
00040 //# PROGRAMMER(S):     Boris Jeremic                                             #
00041 //#                                                                              #
00042 //#                                                                              #
00043 //# DATE:              May 28. - July 21 '93                                     #
00044 //# UPDATE HISTORY:    july 8. '93. BJtensor02 - BJtensor multiplication             #
00045 //#                                 inner and outer products                     #
00046 //#                    august 17-19 '93 fixed default constructor that wasted    #
00047 //#                                     memory ###                               #
00048 //#                    october 11 '93 added transpose0110, transpose0101,        #
00049 //#                                   transpose0111 so the creation of           #
00050 //#                                   isotropic BJtensor is much easer and         #
00051 //#                                   understandable !                           #
00052 //#                    januar 06 '93  added BJtensor2BJmatrix_1, BJtensor2BJmatrix_2     #
00053 //#                                   inverse_1, inverse_2, inverse_3            #
00054 //#                    januar 20 '93  added inverse  TRUE ONE                    #
00055 //#                    August 22-29 '94 choped to separate files and worked on   #
00056 //#                                   const and & issues                         #
00057 //#                    August 30-31 '94 added use_def_dim to full the CC         #
00058 //#                                   resolved problem with temoraries for       #
00059 //#                                   operators + and - ( +=, -= )               #
00060 //#                    28June2004     added val4 for efficiency still            #
00061 //#                                   to be worked on                            #
00062 //#                                                                              #
00063 //#                                                                              #
00064 //#                                                                              #
00065 //################################################################################
00066 //*/
00067 //
00068 #ifndef TENSOR_CC
00069 #define TENSOR_CC
00070 
00071 #include "BJtensor.h"
00072 
00073 // just send appropriate arguments to the base constructor
00074 //##############################################################################
00075 BJtensor::BJtensor(int rank_of_BJtensor, double initval):
00076   nDarray(rank_of_BJtensor, initval)  // default constructor
00077     {
00078       indices1 = (char *) NULL; //since NULL is (void *)  02june98
00079       indices2 = (char *) NULL; //since NULL is (void *)  02june98 
00080     }
00081 
00082 
00083 //##############################################################################
00084 BJtensor::BJtensor(int rank_of_BJtensor, const int *pdim, double *values):
00085   nDarray(rank_of_BJtensor, pdim, values)
00086     {
00087       indices1 = (char *) NULL; //since NULL is (void *)  02june98 
00088       indices2 = (char *) NULL; //since NULL is (void *)  02june98 
00089     }
00090 
00091 
00092 //##############################################################################
00093 BJtensor::BJtensor(int rank_of_BJtensor, const int *pdim, double initvalue):
00094   nDarray(rank_of_BJtensor, pdim, initvalue)
00095     {
00096       indices1 = (char *) NULL; //since NULL is (void *)  02june98 
00097       indices2 = (char *) NULL; //since NULL is (void *)  02june98 
00098     }
00099 
00100 
00101 //##############################################################################
00102 BJtensor::BJtensor(char *flag, int rank_of_BJtensor, const int *pdim):
00103   nDarray( flag, rank_of_BJtensor, pdim) // create a unit nDarray
00104     {
00105       indices1 = (char *) NULL; //since NULL is (void *)  02june98 
00106       indices2 = (char *) NULL; //since NULL is (void *)  02june98 
00107     }
00108 
00109 
00110 //##############################################################################
00111 BJtensor::BJtensor(char *flag):
00112   nDarray(flag) { } //this one used to send "NO" message
00113 
00114 
00115 
00116 //##############################################################################
00117 BJtensor::BJtensor(const BJtensor & x):   // copy initializer
00118   nDarray("NO")           // with base class constructor cancelation
00119   {
00120     x.pc_nDarray_rep->n++;  // we're adding another reference.
00121 //    x.reference_count(+1); // we're adding another reference.
00122     pc_nDarray_rep = x.pc_nDarray_rep;  // point to the new BJtensor_rep.
00123 // add the indices
00124     indices1 = x.indices1;
00125     indices2 = x.indices2;
00126  }
00127 
00128 
00129 
00130 //##############################################################################
00131 BJtensor::BJtensor(const nDarray & x):
00132   nDarray( x ) {  } // copy-initializer
00133                      // DO NOT delete ( NULL ) indices because return
00134                      // from operator*( BJtensor & arg ) this one
00135                      // is invoked and so I need this indices.
00136 
00137 
00138 
00139 
00140  // IT IS NOT INHERITED so must be defined in all derived classes
00141  // See ARM page 277.
00142  //##############################################################################
00143 // BJtensor::~BJtensor()
00144 // {
00145 //   if (reference_count(-1) == 0)  // if reference count  goes to 0
00146 //     {
00147 // // DEallocate memory of the actual nDarray
00148 // // delete [pc_nDarray_rep->pc_nDarray_rep->total_numb] pc_nDarray_rep->pd_nDdata;
00149 // // nema potrebe za brojem clanova koji se brisu!! see ELLIS & STROUSTRUP $18.3
00150 // //                                                and note on the p.65($5.3.4)
00151 // //  and the page 276 ($12.4)
00152 //     delete data();
00153 //     delete dim();
00154 //     delete pc_nDarray_rep;
00155 //   }
00156 // }
00157 
00158 
00159 
00160 
00161 // IT IS NOT INHERITED so must be defined in all derived classes
00162 // See ARM page 306.
00163 //##############################################################################
00164 BJtensor& BJtensor::operator=( const BJtensor & rval)
00165   {
00166     rval.pc_nDarray_rep->n++; // we're adding another reference.
00167 //    rval.reference_count(+1);  // tell the rval it has another reference
00168 //   /*  It is important to increment the reference_counter in the new
00169 //       BJtensor before decrementing the reference_counter in the
00170 //       old BJtensor_rep to ensure proper operation when assigning a
00171 //       BJtensor_rep to itself ( after ARKoenig JOOP May/June '90 )  */
00172 // clean up current value;
00173     if( reference_count(-1) == 0)  // if nobody else is referencing us.
00174       {
00175         delete [] data();
00176         delete [] dim();
00177         delete pc_nDarray_rep;
00178       }
00179 // connect to new value
00180     pc_nDarray_rep = rval.pc_nDarray_rep;  // point at the rval BJtensor_rep
00181 // null indices in the rval AND in the this
00182 // because rval is temporary anyway and I need *this
00183 //    rval.null_indices();
00184     this->null_indices();
00185     return *this;
00186   }
00187 
00188 
00189 
00190 
00191 //##############################################################################
00192 // this is supposed to fill in the char * indices1 or the char * indices2
00193 // array in BJtensor object
00194 // so that they can be checked for matching later on when operations like
00195 // single contraction (.), double contraction (:), dyadic product (otimes)
00196 // are performed the object can choose the right operator.
00197 // Also when multiplying BJtensor by itself ( like for example:
00198 //               D("ij")*D("kl")
00199 // the other char * indices2 is defined to take the other array of
00200 // indices
00201 // so that mulitplication will be O.K.
00202 // Since only two BJtensors can be multiplied at the time ( binary operation )
00203 // only indices1 and indices2 are needed #
00204 // WATCH OUT THIS IS NOT STANDRAD AS YOU CANNOT QUARANTY THE ORDER OF EXECUTION!!!!
00205 BJtensor & BJtensor::operator()(char *indices_from_user)
00206   {
00207     if ( this->indices1 == NULL )
00208       {
00209         this->indices1 = indices_from_user;
00210         return *this;
00211       }
00212     else
00213       {
00214         this->indices2 = indices_from_user;
00215         return *this;
00216       }
00217   }
00218 
00219 
00220 
00221 //##############################################################################
00222 void BJtensor::null_indices()
00223   {
00224     this->indices1 = (char *) NULL; //since NULL is (void *)  02june98 
00225     this->indices2 = (char *) NULL; //since NULL is (void *)  02june98 
00226   }
00227 
00228 
00229 
00230 
00231 //++//##############################################################################
00232 //++// BJtensor addition
00233 //++BJtensor BJtensor::operator+( BJtensor & rval)
00234 //++  {
00235 //++    int this_rank_of_BJtensor = this->rank();  //pc_nDarray_rep->nDarray_rank;
00236 //++    int rval_rank_of_BJtensor =  rval.rank();  //pc_nDarray_rep->nDarray_rank;
00237 //++
00238 //++    if(this_rank_of_BJtensor != rval_rank_of_BJtensor)
00239 //++      {
00240 //++        ::printf("\a\nTensors of different ranks: addition not possible\n");
00241 //++        ::exit ( 1 );
00242 //++      }
00243 //++
00244 //++    for ( int i=0 ; i<this_rank_of_BJtensor ; i++ )
00245 //++      if (this->dim()[i] != rval.dim()[i] )
00246 //++//      if (this->dim(i) != rval.dim(i) )
00247 //++        {
00248 //++          ::fprintf(stderr,"\a\nDimension discrepancy in operator+\n",
00249 //++                   "this->dim()[%d]=%d\n",
00250 //++                   "arg.dim()[%d]=%d\n",
00251 //++                    i,this->dim()[i],
00252 //++                    i,rval.dim()[i] );
00253 //++          ::exit(1);
00254 //++        }
00255 //++// construct BJtensor using the same control numbers as for the
00256 //++// original one .
00257 //++//      BJtensor add(pc_nDarray_rep->nDarray_rank, pc_nDarray_rep->dim, 0.0);
00258 //++      BJtensor add( this->rank(), dim(), 0.0);
00259 //++
00260 //++      add.indices1 = this->indices1;
00261 //++
00262 //++//      switch(pc_nDarray_rep->nDarray_rank)
00263 //++      switch(this->rank())
00264 //++        {
00265 //++          case 0:
00266 //++            {
00267 //++              add.val(1) = val(1) + rval.val(1);
00268 //++              break;
00269 //++            }
00270 //++
00271 //++          case 1:
00272 //++            {
00273 //++              for ( int i1=1 ; i1<=3 ; i1++ )
00274 //++                add.val(i1) = val(i1) + rval.val(i1);
00275 //++              break;
00276 //++            }
00277 //++
00278 //++          case 2:
00279 //++            {
00280 //++              for ( int i2=1 ; i2<=3 ; i2++ )
00281 //++                for ( int j2=1 ; j2<=3 ; j2++ )
00282 //++                  add.val(i2, j2) = val(i2, j2) + rval.val(i2, j2);
00283 //++              break;
00284 //++            }
00285 //++
00286 //++          case 3:
00287 //++            {
00288 //++              for ( int i3=1 ; i3<=3 ; i3++ )
00289 //++                for ( int j3=1 ; j3<=3 ; j3++ )
00290 //++                  for ( int k3=1 ; k3<=3 ; k3++ )
00291 //++                    add.val(i3, j3, k3) = val(i3, j3, k3) +
00292 //++                                                 rval.val(i3, j3, k3);
00293 //++              break;
00294 //++            }
00295 //++
00296 //++          case 4:
00297 //++            {
00298 //++              for ( int i4=1 ; i4<=3 ; i4++ )
00299 //++                for ( int j4=1 ; j4<=3 ; j4++ )
00300 //++                  for ( int k4=1 ; k4<=3 ; k4++ )
00301 //++                    for ( int l4=1 ; l4<=3 ; l4++ )
00302 //++                      add.val(i4,j4,k4,l4)=val(i4,j4,k4,l4)+
00303 //++                                                  rval.val(i4,j4,k4,l4);
00304 //++              break;
00305 //++            }
00306 //++        }
00307 //++
00308 //++    null_indices();
00309 //++    rval.null_indices();
00310 //++
00311 //++    return add;
00312 //++  }
00313 //++
00314 //````````//##############################################################################
00315 //````````// BJtensor addition
00316 //````````BJtensor& BJtensor::operator+=(const BJtensor & rval)
00317 //````````  {
00318 //````````    int this_rank_of_BJtensor = this->rank();  //pc_nDarray_rep->nDarray_rank;
00319 //````````    int rval_rank_of_BJtensor =  rval.rank();  //pc_nDarray_rep->nDarray_rank;
00320 //````````
00321 //````````    if(this_rank_of_BJtensor != rval_rank_of_BJtensor)
00322 //````````      {
00323 //````````        ::printf("\a\nTensors of different ranks: += not possible\n");
00324 //````````        ::exit ( 1 );
00325 //````````      }
00326 //````````
00327 //````````    for ( int i=0 ; i<this_rank_of_BJtensor ; i++ )
00328 //````````      if (this->dim()[i] != rval.dim()[i] )
00329 //````````//      if (this->dim(i) != rval.dim(i) )
00330 //````````        {
00331 //````````::fprintf(stderr,"\a\nDimension discrepancy in operator+=\n this->dim()[%d]=%d\n arg.dim()[%d]=%d\n",
00332 //````````i,this->dim()[i],
00333 //````````i,rval.dim()[i] );
00334 //````````::exit(1);
00335 //````````        }
00336 //````````// Copy *this if necessary
00337 //````````    if ( this->pc_nDarray_rep->n > 1 )// see ARK in JOOP may/june '90
00338 //````````      {                               // "Letter From a Newcomer"
00339 //````````//..............................................................................
00340 //````````      // create the structure:
00341 //````````        nDarray_rep * New_pc_nDarray_rep = new nDarray_rep; // this 'new' is overloaded
00342 //````````        New_pc_nDarray_rep->nDarray_rank = this->pc_nDarray_rep->nDarray_rank;
00343 //````````// in the case of nDarray_rank=0 add one to get right thing from the
00344 //````````// operator new
00345 //````````        int one_or0 = 0;
00346 //````````        if(!New_pc_nDarray_rep->nDarray_rank) one_or0 = 1;
00347 //````````        New_pc_nDarray_rep->dim = new int[New_pc_nDarray_rep->nDarray_rank+one_or0];
00348 //````````                                  // array for dimensions
00349 //````````        New_pc_nDarray_rep->total_numb = 1;
00350 //````````        for( int idim = 0 ; idim < New_pc_nDarray_rep->nDarray_rank ; idim++ )
00351 //````````          {
00352 //````````            New_pc_nDarray_rep->dim[idim] = this->pc_nDarray_rep->dim[idim];
00353 //````````            New_pc_nDarray_rep->total_numb *= New_pc_nDarray_rep->dim[idim];
00354 //````````          }
00355 //````````// allocate memory for the actual nDarray as nDarray
00356 //````````        New_pc_nDarray_rep->pd_nDdata = new double [(size_t)New_pc_nDarray_rep->total_numb];
00357 //````````          if (!New_pc_nDarray_rep->pd_nDdata)
00358 //````````            {
00359 //````````              ::fprintf(stderr,"\a\nInsufficient memory for array\n");
00360 //````````              ::exit(1);
00361 //````````            }
00362 //````````         New_pc_nDarray_rep->n = 1;  // so far, there's one reference
00363 //````````         for ( i=0 ; i<New_pc_nDarray_rep->total_numb ; i++ )
00364 //````````           New_pc_nDarray_rep->pd_nDdata[i] = this->pc_nDarray_rep->pd_nDdata[i];
00365 //````````//.........
00366 //````````         this->pc_nDarray_rep->total_numb--;
00367 //````````         this->pc_nDarray_rep = New_pc_nDarray_rep;
00368 //````````//..............................................................................
00369 //````````      }
00370 //````````// it appears that I can add this two BJtensors just as a simple BJvectors:
00371 //````````    for (int j=0 ; j<this->pc_nDarray_rep->total_numb ; j++)
00372 //````````      this->pc_nDarray_rep->pd_nDdata[j] += rval.pc_nDarray_rep->pd_nDdata[j];
00373 //````````
00374 //````````    this->indices1 = rval.indices1;
00375 //````````    return *this;
00376 //````````  }
00377 //````````
00378 
00379 //##############################################################################
00380 // BJtensor addition
00381 #ifndef _VC6
00382 BJtensor operator+(const BJtensor & lval, const BJtensor & rval)
00383   {
00384     BJtensor result(lval);
00385     result += rval;
00386     return result;
00387   }
00388 #else
00389 BJtensor BJtensor::operator+(const BJtensor & rval) const
00390   {
00391     BJtensor result(*this);
00392     result += rval;
00393     return result;
00394   }
00395 #endif
00396 
00397 
00398 
00399 
00402 //BJtensor  BJtensor::operator+(double rval)
00403 // {
00406 //      BJtensor add(this->rank(), dim(), 0.0);
00407 //
00408 //      add.indices1 = this->indices1;
00409 //
00410 //      switch(this->rank())
00411 //        {
00412 //          case 0:
00413 //            {
00414 //              add.val(1) = val(1) + rval;
00415 //              break;
00416 //            }
00417 //
00418 //          case 1:
00419 //            {
00420 //              for ( int i1=1 ; i1<=this->dim()[0] ; i1++ )
00421 //                add.val(i1) = val(i1) + rval;
00422 //              break;
00423 //            }
00424 //
00425 //          case 2:
00426 //            {
00427 //              for ( int i2=1 ; i2<=this->dim()[0] ; i2++ )
00428 //                for ( int j2=1 ; j2<=this->dim()[1] ; j2++ )
00429 //                  add.val(i2, j2) = val(i2, j2) + rval;
00430 //              break;
00431 //            }
00432 //
00433 //          case 3:
00434 //            {
00435 //              for ( int i3=1 ; i3<=this->dim()[0] ; i3++ )
00436 //                for ( int j3=1 ; j3<=this->dim()[1] ; j3++ )
00437 //                  for ( int k3=1 ; k3<=this->dim()[2] ; k3++ )
00438 //                    add.val(i3, j3, k3) = val(i3, j3, k3) + rval;
00439 //              break;
00440 //            }
00441 //
00442 //          case 4:
00443 //            {
00444 //              for ( int i4=1 ; i4<=this->dim()[0] ; i4++ )
00445 //                for ( int j4=1 ; j4<=this->dim()[1] ; j4++ )
00446 //                  for ( int k4=1 ; k4<=this->dim()[2] ; k4++ )
00447 //                    for ( int l4=1 ; l4<=this->dim()[3] ; l4++ )
00448 //                      add.val(i4,j4,k4,l4)=val(i4,j4,k4,l4)+rval;
00449 //              break;
00450 //            }
00451 //        }
00452 //
00453 //    null_indices();
00454 //
00455 //    return add;
00456 // }
00457 
00458 
00459 
00460 //..//++//##############################################################################
00461 //..//++// BJtensor substraction
00462 //..//++BJtensor BJtensor::operator-(BJtensor & rval)
00463 //++ {
00464 //++    int this_rank_of_BJtensor = this->rank();  //pc_nDarray_rep->nDarray_rank;
00465 //++    int rval_rank_of_BJtensor = rval.rank();   //pc_nDarray_rep->nDarray_rank;
00466 //++
00467 //++    if(this_rank_of_BJtensor != rval_rank_of_BJtensor)
00468 //++      {
00469 //++        ::printf("\a\nTensors of different ranks:",
00470 //++                 " substraction not possible\n");
00471 //++        ::exit ( 1 );
00472 //++      }
00473 //++
00474 //++    for ( int i=0 ; i<this_rank_of_BJtensor ; i++ )
00475 //++      if (this->dim()[i] != rval.dim()[i] )
00476 //++        {
00477 //++          ::fprintf(stderr,"\a\nDimension discrepancy in operator  -  \n",
00478 //++                   "this->dim()[%d]=%d\n",
00479 //++                   "arg.dim()[%d]=%d\n",
00480 //++                    i,this->dim()[i],
00481 //++                    i,rval.dim()[i]);
00482 //++          ::exit(1);
00483 //++        }
00484 //++// construct BJtensor using the same control numbers as for the
00485 //++// original one.
00486 //++      BJtensor sub(this->rank(), dim(), 0.0);
00487 //++
00488 //++      sub.indices1 = this->indices1;
00489 //++
00490 //++      switch(this->rank())
00491 //++        {
00492 //++          case 0:
00493 //++            {
00494 //++              sub.val(1) = val(1) - rval.val(1);
00495 //++              break;
00496 //++            }
00497 //++
00498 //++          case 1:
00499 //++            {
00500 //++              for ( int i1=1 ; i1<=3 ; i1++ )
00501 //++                sub.val(i1) = val(i1) - rval.val(i1);
00502 //++              break;
00503 //++            }
00504 //++
00505 //++          case 2:
00506 //++            {
00507 //++              for ( int i2=1 ; i2<=3 ; i2++ )
00508 //++                for ( int j2=1 ; j2<=3 ; j2++ )
00509 //++                  sub.val(i2, j2) = val(i2, j2) -
00510 //++                                           rval.val(i2, j2);
00511 //++              break;
00512 //++            }
00513 //++
00514 //++          case 3:
00515 //++            {
00516 //++              for ( int i3=1 ; i3<=3 ; i3++ )
00517 //++                for ( int j3=1 ; j3<=3 ; j3++ )
00518 //++                  for ( int k3=1 ; k3<=3 ; k3++ )
00519 //++                    sub.val(i3, j3, k3) = val(i3, j3, k3) -
00520 //++                                                 rval.val(i3, j3, k3);
00521 //++              break;
00522 //++            }
00523 //++
00524 //++          case 4:
00525 //++            {
00526 //++              for ( int i4=1 ; i4<=3 ; i4++ )
00527 //++                for ( int j4=1 ; j4<=3 ; j4++ )
00528 //++                  for ( int k4=1 ; k4<=3 ; k4++ )
00529 //++                    for ( int l4=1 ; l4<=3 ; l4++ )
00530 //++                      sub.val(i4,j4,k4,l4)=val(i4,j4,k4,l4)-
00531 //++                                                  rval.val(i4,j4,k4,l4);
00532 //++              break;
00533 //++            }
00534 //++        }
00535 //++
00536 //++    null_indices();
00537 //++    rval.null_indices();
00538 //++
00539 //++    return sub;
00540 //++ }
00541 
00542 //````````//##############################################################################
00543 //````````// BJtensor substraction
00544 //````````BJtensor& BJtensor::operator-=(const BJtensor & rval)
00545 //````````  {
00546 //````````    int this_rank_of_BJtensor = this->rank();  //pc_nDarray_rep->nDarray_rank;
00547 //````````    int rval_rank_of_BJtensor =  rval.rank();  //pc_nDarray_rep->nDarray_rank;
00548 //````````
00549 //````````    if(this_rank_of_BJtensor != rval_rank_of_BJtensor)
00550 //````````      {
00551 //````````        ::printf("\a\nTensors of different ranks: -= not possible\n");
00552 //````````        ::exit ( 1 );
00553 //````````      }
00554 //````````
00555 //````````    for ( int i=0 ; i<this_rank_of_BJtensor ; i++ )
00556 //````````      if (this->dim()[i] != rval.dim()[i] )
00557 //````````//      if (this->dim(i) != rval.dim(i) )
00558 //````````        {
00559 //````````::fprintf(stderr,"\a\nDimension discrepancy in operator-=\n this->dim()[%d]=%d\n arg.dim()[%d]=%d\n",
00560 //````````i,this->dim()[i],
00561 //````````i,rval.dim()[i] );
00562 //````````::exit(1);
00563 //````````        }
00564 //````````// Copy *this if necessary
00565 //````````    if ( this->pc_nDarray_rep->n > 1 )// see ARK in JOOP may/june '90
00566 //````````      {                               // "Letter From a Newcomer"
00567 //````````//..............................................................................
00568 //````````      // create the structure:
00569 //````````        nDarray_rep * New_pc_nDarray_rep = new nDarray_rep; // this 'new' is overloaded
00570 //````````        New_pc_nDarray_rep->nDarray_rank = this->pc_nDarray_rep->nDarray_rank;
00571 //````````// in the case of nDarray_rank=0 add one to get right thing from the
00572 //````````// operator new
00573 //````````        int one_or0 = 0;
00574 //````````        if(!New_pc_nDarray_rep->nDarray_rank) one_or0 = 1;
00575 //````````        New_pc_nDarray_rep->dim = new int[New_pc_nDarray_rep->nDarray_rank+one_or0];
00576 //````````                                  // array for dimensions
00577 //````````        New_pc_nDarray_rep->total_numb = 1;
00578 //````````        for( int idim = 0 ; idim < New_pc_nDarray_rep->nDarray_rank ; idim++ )
00579 //````````          {
00580 //````````            New_pc_nDarray_rep->dim[idim] = this->pc_nDarray_rep->dim[idim];
00581 //````````            New_pc_nDarray_rep->total_numb *= New_pc_nDarray_rep->dim[idim];
00582 //````````          }
00583 //````````// allocate memory for the actual nDarray as nDarray
00584 //````````        New_pc_nDarray_rep->pd_nDdata = new double [(size_t)New_pc_nDarray_rep->total_numb];
00585 //````````          if (!New_pc_nDarray_rep->pd_nDdata)
00586 //````````            {
00587 //````````              ::fprintf(stderr,"\a\nInsufficient memory for array\n");
00588 //````````              ::exit(1);
00589 //````````            }
00590 //````````         New_pc_nDarray_rep->n = 1;  // so far, there's one reference
00591 //````````         for ( i=0 ; i<New_pc_nDarray_rep->total_numb ; i++ )
00592 //````````           New_pc_nDarray_rep->pd_nDdata[i] = this->pc_nDarray_rep->pd_nDdata[i];
00593 //````````//.........
00594 //````````         this->pc_nDarray_rep->total_numb--;
00595 //````````         this->pc_nDarray_rep = New_pc_nDarray_rep;
00596 //````````//..............................................................................
00597 //````````      }
00598 //````````// it appears that I can add this two BJtensors just as a simple BJvectors:
00599 //````````    for (int j=0 ; j<this->pc_nDarray_rep->total_numb ; j++)
00600 //````````      this->pc_nDarray_rep->pd_nDdata[j] -= rval.pc_nDarray_rep->pd_nDdata[j];
00601 //````````
00602 //````````    this->indices1 = rval.indices1;
00603 //````````    return *this;
00604 //````````  }
00605 //````````
00606 
00607 //##############################################################################
00608 // BJtensor substraction
00609 #ifndef _VC6
00610 BJtensor operator-(const BJtensor & lval, const BJtensor & rval)
00611   {
00612     BJtensor result(lval);
00613     result -= rval;
00614     return result;
00615   }
00616 #else
00617 BJtensor BJtensor::operator-(const BJtensor & rval) const
00618   {
00619     BJtensor result(*this);
00620     result -= rval;
00621     return result;
00622   }
00623 #endif
00624 
00625 
00626 
00627 
00630 //BJtensor  BJtensor::operator-( double rval)
00631 //  {
00634 //    BJtensor sub(this->rank(), dim(), 0.0);
00635 //
00636 //    sub.indices1 = this->indices1;
00637 //
00638 //    switch(this->rank())
00639 //      {
00640 //        case 0:
00641 //          {
00642 //            sub.val(1) = val(1) - rval;
00643 //            break;
00644 //          }
00645 //
00646 //        case 1:
00647 //          {
00648 //            for ( int i1=1 ; i1<=this->dim()[0] ; i1++ )
00649 //              sub.val(i1) = val(i1) - rval;
00650 //            break;
00651 //          }
00652 //
00653 //        case 2:
00654 //          {
00655 //            for ( int i2=1 ; i2<=this->dim()[0] ; i2++ )
00656 //              for ( int j2=1 ; j2<=this->dim()[1] ; j2++ )
00657 //                sub.val(i2, j2) = val(i2, j2) - rval;
00658 //            break;
00659 //          }
00660 //
00661 //        case 3:
00662 //          {
00663 //            for ( int i3=1 ; i3<=this->dim()[0] ; i3++ )
00664 //              for ( int j3=1 ; j3<=this->dim()[1] ; j3++ )
00665 //                for ( int k3=1 ; k3<=this->dim()[2] ; k3++ )
00666 //                  sub.val(i3, j3, k3) = val(i3, j3, k3) - rval;
00667 //            break;
00668 //          }
00669 //
00670 //        case 4:
00671 //          {
00672 //            for ( int i4=1 ; i4<=this->dim()[0] ; i4++ )
00673 //              for ( int j4=1 ; j4<=this->dim()[1] ; j4++ )
00674 //                for ( int k4=1 ; k4<=this->dim()[2] ; k4++ )
00675 //                  for ( int l4=1 ; l4<=this->dim()[3] ; l4++ )
00676 //                    sub.val(i4,j4,k4,l4)=val(i4,j4,k4,l4)-rval;
00677 //            break;
00678 //          }
00679 //      }
00680 //
00681 //    null_indices();
00682 //
00683 //    return sub;
00684 //  }
00685 //
00686 
00687 //##############################################################################
00689 //check what happens if you are have tenosr A=B and then you do B*5.13
00690 // does it change A as well !!!!!!!!!!!!!!!!!!!!!!!!!!
00691 // TS KR!!!!
00692 //
00693 BJtensor BJtensor::operator*( const double rval) const //Guanzhou added const
00694  {
00695 // construct BJtensor using the same control numbers as for the
00696 // original one.
00697     
00698     //Guanzhou changed!!! taking const values from cval instead of val
00699     
00700     BJtensor mult(this->rank(), dim(), 0.0);
00701     
00702     mult.indices1 = this->indices1;
00703 
00704     switch(this->rank())
00705       {
00706         case 0:
00707           {
00708             mult.val(1) = cval(1) * rval;
00709             break;
00710           }
00711 
00712         case 1:
00713           {
00714             for ( int i1=1 ; i1<=this->dim()[0] ; i1++ )
00715               mult.val(i1) = cval(i1) * rval;
00716             break;
00717           }
00718 
00719         case 2:
00720           {
00721             for ( int i2=1 ; i2<=this->dim()[0] ; i2++ )
00722               for ( int j2=1 ; j2<=this->dim()[1] ; j2++ )
00723                 mult.val(i2, j2) = cval(i2, j2) * rval;
00724             break;
00725           }
00726 
00727         case 3:
00728           {
00729             for ( int i3=1 ; i3<=this->dim()[0] ; i3++ )
00730               for ( int j3=1 ; j3<=this->dim()[1] ; j3++ )
00731                 for ( int k3=1 ; k3<=this->dim()[2] ; k3++ )
00732                   mult.val(i3, j3, k3) = cval(i3, j3, k3) * rval;
00733             break;
00734           }
00735 
00736         case 4:
00737           {
00738             for ( int i4=1 ; i4<=this->dim()[0] ; i4++ )
00739               for ( int j4=1 ; j4<=this->dim()[1] ; j4++ )
00740                 for ( int k4=1 ; k4<=this->dim()[2] ; k4++ )
00741                   for ( int l4=1 ; l4<=this->dim()[3] ; l4++ )
00742                     mult.val(i4,j4,k4,l4) = cval(i4,j4,k4,l4)*rval;
00743             break;
00744           }
00745       }
00746 
00747     mult.null_indices();
00748 
00749     return mult;
00750  }
00751 
00752 //    BJtensor operator*( double lval, nDarray & rval);  // REVIEWER global
00753 //##############################################################################
00754 // scalar multiplication
00755 BJtensor  operator*( const double lval, BJtensor & rval)
00756   {
00757     return rval*lval;
00758   }
00759 
00760 //##############################################################################
00761 //##############################################################################
00762 //##############################################################################
00763 //##############################################################################
00764 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
00765 //
00766 //
00767 //                                _____..---========+^+=========---.._____
00768 //   ______________________ __,_='=====____  ================== _____=====`=
00769 //  (._____________________I__) _ __=_/    `--------=+=--------'
00770 //      /      /--...---===='---+----'
00771 //     '------'---.--- _  _ =   _._'    "Make it so..."
00772 //                    `--------'                  Captain Jean-Luc Picard
00773 //                                                USS Enterprise, NCC-1701D
00774 //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
00775 BJtensor BJtensor::operator*( BJtensor & arg)
00776   {
00777 //DEBUGprint::printf("before block in operator* coreleft is: %lu bytes\n", (unsigned long) ::coreleft());
00778 //   const int MAX_TENS_ORD = 8;
00779    const int MAX_TENS_ORD = 4;
00780 //....   int results_rank = 0;
00781 
00782 //DEBUGprint::printf("this->rank()=%d\n",
00783 //DEBUGprint          this->rank());
00784 //DEBUGprint::printf("arg.rank()=%d\n",
00785 //DEBUGprint          arg.rank());
00786 
00787 // space for CONTRACTED indices
00788    int *this_contr = new int[MAX_TENS_ORD];
00789    int *arg_contr  = new int[MAX_TENS_ORD];
00790 
00791 // space for UN-CONTRACTED indices
00792    int *this_uncontr = new int[MAX_TENS_ORD];
00793    int *arg_uncontr  = new int[MAX_TENS_ORD];
00794 
00795    for(int this_ic=0 ; this_ic<MAX_TENS_ORD ; this_ic++ )
00796      {
00797        this_contr[this_ic] = 0;
00798        this_uncontr[this_ic] = 0;
00799      }
00800    for( int arg_ic=0 ; arg_ic<MAX_TENS_ORD ; arg_ic++ )
00801      {
00802        arg_contr[arg_ic]  = 0;
00803        arg_uncontr[arg_ic]  = 0;
00804      }
00805 
00806 // now make the right choice for indices for this and arg BJtensor !!!
00807 //
00808 //                  |||~          |||~          |||~
00809 //                 (0 0)         (0 0)         (0 0)
00810 //--------------ooO-(_)-Ooo---ooO-(_)-Ooo---ooO-(_)-Ooo----------------------
00811 //
00812 // WATCH OUT THIS IS NOT STANDRAD AS YOU CANNOT QUARANTY THE ORDER OF EXECUTION!!!!
00813 
00814    char * this_indices = this->indices1;
00815    char * arg_indices  = arg.indices1;
00816 
00817 //fprintf(stdout,"\n\n\n\n  this->indices1 = %s   ; this->indices2 = %s\n", this->indices1,this->indices2);
00818 // if the BJtensors are same then split indices :-)
00819    if ( this->pc_nDarray_rep == arg.pc_nDarray_rep )
00820      {
00821 // WATCH OUT THIS IS NOT STANDRAD AS YOU CANNOT QUARANTY THE ORDER OF EXECUTION!!!!
00822        this_indices = this->indices2; // this is changed because
00823        arg_indices  = arg.indices1;  // it reads indices from
00824                                     // right so "in" indices1 are
00825                                    // the right ( arg ) and "in"
00826                                   // indices2 are the
00827                                  // left indices
00828 // WATCH OUT THIS IS NOT STANDRAD AS YOU CANNOT QUARANTY THE ORDER OF EXECUTION!!!!
00829 //       this_indices = this->indices1; // Now it turns out that it is 
00830 //       arg_indices  = arg.indices2;  // reading indices from left!!!!!!
00831 //                                    // Not any more as per g++ (12 may 2000
00832 //                                   // 
00833 //                                  // 
00834 //                                 //  
00835 // WATCH OUT THIS IS NOT STANDRAD AS YOU CANNOT QUARANTY THE ORDER OF EXECUTION!!!!
00836      }
00837 //DEBUGprint::printf("this_indices=%s\n", this_indices);
00838 //DEBUGprint::printf("arg_indices=%s\n",  arg_indices);
00839 
00840 
00841 //   int this_indices_number = ::strlen(this->pc_nDarray_rep->indices1);
00842 //   int  arg_indices_number = ::strlen(arg.pc_nDarray_rep->indices1);
00843 
00844    int this_indices_number = ::strlen(this_indices);
00845    int  arg_indices_number = ::strlen(arg_indices);
00846 
00847 //DEBUGprint::printf("this_indices_number=%d\n",
00848 //DEBUGprint          this_indices_number);
00849 //DEBUGprint::printf("arg_indices_number=%d\n",
00850 //DEBUGprint          arg_indices_number);
00851 
00852 // check for indices number: should be EQUAL than rank of BJtensor
00853    if ( this_indices_number != this->rank() )
00854      {
00855 ::fprintf(stderr,"\a\n 'this' has more/less indices than expected:\n \
00856 this_indices_number = %d\n \
00857 this_indices = %s\n \
00858 this->rank() = %d\n",
00859 this_indices_number,
00860 this_indices,
00861 this->rank());
00862 ::exit(1);
00863      }
00864 
00865    if ( arg_indices_number != arg.rank() )
00866      {
00867 ::fprintf(stderr,"\a\n 'arg' has more/less indices than expected:\n \
00868 arg_indices_number = %d\n \
00869 arg_indices = %s\n \
00870 arg.rank() = %d\n",
00871 arg_indices_number,
00872 arg_indices,
00873 arg.rank());
00874 ::exit(1);
00875      }
00876 
00877 // counter for contracted indices
00878    int contr_counter = contracted_ind(this_indices,
00879                                       arg_indices,
00880                                       this_contr,
00881                                       arg_contr,
00882                                       this_indices_number,
00883                                       arg_indices_number  );
00884 
00885    int this_uni_count = uncontracted_ind( this_uncontr,
00886                                           this_contr,
00887                                           this_indices_number);
00888 
00889    int arg_uni_count = uncontracted_ind( arg_uncontr,
00890                                          arg_contr,
00891                                          arg_indices_number);
00892 
00893 //number of UNcontractions
00894    int uncontr_counter = this_uni_count + arg_uni_count;
00895 
00896 //TEMP  this is just the test because right now only up to order = 4
00897    if ( uncontr_counter > MAX_TENS_ORD )
00898      {
00899        ::fprintf(stderr,"\a\a\n\n  OOOPS product of multiplication has order %d\n",
00900                            uncontr_counter);
00901        ::exit(1);
00902      }
00903 
00904 //DEBUGprint ::printf("..... this_uni_count = %d, arg_uni_count = %d\n",
00905 //DEBUGprint                 this_uni_count,      arg_uni_count);
00906 //DEBUGprint ::printf(" uncontr_counter %d\n",uncontr_counter);
00907 //DEBUGprint for( int pthis_ic=0 ;
00908 //DEBUGprint      pthis_ic<(this->rank()+1) ;
00909 //DEBUGprint      pthis_ic++ )
00910 //DEBUGprint   ::printf("this_uncontr[%d]=%d\n",pthis_ic,this_uncontr[pthis_ic]);
00911 //DEBUGprint for( int parg_ic=0 ;
00912 //DEBUGprint      parg_ic<(arg.rank()+1) ;
00913 //DEBUGprint      parg_ic++ )
00914 //DEBUGprint   ::printf("             arg_uncontr[%d]=%d\n",parg_ic,arg_uncontr[parg_ic]);
00915 
00917 // let's make result BJtensor
00918 
00919    int t = 0;
00920    int a = 0;
00921    static int results_dims[MAX_TENS_ORD];
00922    for( t=0 ; t < this_uni_count ; t++ )
00923      results_dims[t]=this->dim()[this_uncontr[t]-1];
00924    for( a=0 ; a < arg_uni_count ; a++ )
00925      results_dims[a+t]=arg.dim()[arg_uncontr[a]-1];
00926 // do kraja (till the end) . . .
00927    for( ; a < MAX_TENS_ORD-t ; a++ )
00928      results_dims[a+t]=1;
00929 
00930 
00931 // Indices  pa sada indeksi ( index )
00932    static char results_indices[MAX_TENS_ORD+1];
00933    for( t=0 ; t < this_uni_count ; t++ )
00934      results_indices[t]=this_indices[this_uncontr[t]-1];
00935    for( a=0 ; a < arg_uni_count ; a++ )
00936      results_indices[a+t]=arg_indices[arg_uncontr[a]-1];
00937 // the last one . . .
00938    results_indices[uncontr_counter] = '\0';
00939 
00940 
00941 //DEBUGprint  ::printf("\n\n......  uncontr_counter+1=%d\n", uncontr_counter+1);
00942 //DEBUGprintfor( int pa=0 ; pa < MAX_TENS_ORD ; pa++ )
00943 //DEBUGprint  ::printf("   results_dims[%d]=%d\n",pa,results_dims[pa]);
00944 
00945    BJtensor result(uncontr_counter, results_dims, 0.0);
00946    result(results_indices);  // initialize indices in result
00947 //DEBUGprint  ::printf("\n\n..................   results_indices=%s\n",results_indices);
00948 
00950 // check dimensions in each BJtensor order
00951    for( t=0 ; t<contr_counter ; t++ )
00952      if ( this->dim()[this_contr[t]-1] !=
00953           arg.dim()[arg_contr[t]-1] )
00954        {
00955          ::fprintf(stderr,"\a\a\n t = %d \n"
00956                   "this_contr[t]-1  = %d\n"
00957                   "this->dim()[%d] = %d\n"
00958                   "arg_contr[t]-1  = %d\n"
00959                   "arg.dim()[%d] = %d\n",
00960                    t,
00961                    this_contr[t]-1,
00962                    this_contr[t]-1,this->dim()[this_contr[t]-1],
00963                    arg_contr[t]-1,
00964                    arg_contr[t]-1,arg.dim()[arg_contr[t]-1]);
00965          ::exit(1);
00966        }
00967 
00985 //#*%
00986 
00987    int *inerr_dims = new int[MAX_TENS_ORD];
00988    for( t=0 ; t<contr_counter ; t++ )
00989      {
00990        inerr_dims[t] = this->dim()[this_contr[t]-1];
00991 //DEBUGprint       ::printf("    inerr_dims[%d] = %d\n",t,inerr_dims[t]);
00992      }
00993    for( ; t<MAX_TENS_ORD ; t++ )
00994      {
00995        inerr_dims[t] = 1;
00996 //DEBUGprint       ::printf("          the rest of inerr_dims[%d] = %d\n",t,inerr_dims[t]);
00997      }
00998 
00999 
01000    int *lid = new int[MAX_TENS_ORD];
01001    for( t=0 ; t<MAX_TENS_ORD ; t++ )
01002      {
01003        lid[t] = 1;
01004 //DEBUGprint       ::printf("    lid[%d] = %d\n",t,lid[t]);
01005      }
01006 
01007    int *rid = new int[MAX_TENS_ORD];
01008    for( t=0 ;  t<MAX_TENS_ORD ; t++ )
01009      {
01010        rid[t] = 1;
01011 //DEBUGprint       ::printf("    rid[%d] = %d\n",t,rid[t]);
01012      }
01013 
01014    int *cd = new int[MAX_TENS_ORD];
01015    int *rd = new int[MAX_TENS_ORD];
01016 
01017    int *resd = new int[MAX_TENS_ORD];
01018    for( t=0 ;  t<MAX_TENS_ORD ; t++ )
01019      {
01020        resd[t] = 1;
01021 //DEBUGprint       ::printf("    resd[%d] = %d\n",t,resd[t]);
01022      }
01023 
01024   double inerr=0.0;
01025 
01026 // obrnuti red zbog brzeg izvrsenja ( rd[0] ide do najveceg broja . . . )
01027 //  for ( rd[7]=1 ; rd[7]<=results_dims[7] ; rd[7]++ )
01028 //   for ( rd[6]=1 ; rd[6]<=results_dims[6] ; rd[6]++ )
01029 //    for ( rd[5]=1 ; rd[5]<=results_dims[5] ; rd[5]++ )
01030 //     for ( rd[4]=1 ; rd[4]<=results_dims[4] ; rd[4]++ )
01031       for ( rd[3]=1 ; rd[3]<=results_dims[3] ; rd[3]++ )
01032        for ( rd[2]=1 ; rd[2]<=results_dims[2] ; rd[2]++ )
01033         for ( rd[1]=1 ; rd[1]<=results_dims[1] ; rd[1]++ )
01034          for ( rd[0]=1 ; rd[0]<=results_dims[0] ; rd[0]++ )
01035           {
01036             inerr = 0.0;
01037 
01038 //            for ( cd[7]=1 ; cd[7]<=inerr_dims[7] ; cd[7]++ )
01039 //             for ( cd[6]=1 ; cd[6]<=inerr_dims[6] ; cd[6]++ )
01040 //              for ( cd[5]=1 ; cd[5]<=inerr_dims[5] ; cd[5]++ )
01041 //               for ( cd[4]=1 ; cd[4]<=inerr_dims[4] ; cd[4]++ )
01042                 for ( cd[3]=1 ; cd[3]<=inerr_dims[3] ; cd[3]++ )
01043                  for ( cd[2]=1 ; cd[2]<=inerr_dims[2] ; cd[2]++ )
01044                   for ( cd[1]=1 ; cd[1]<=inerr_dims[1] ; cd[1]++ )
01045                    for ( cd[0]=1 ; cd[0]<=inerr_dims[0] ; cd[0]++ )
01046                     {
01047 
01048 // contracted indices
01049                       for ( t=0 ; t<contr_counter ; t++ )
01050                         {
01051                           lid[ this_contr[t]-1 ]  = cd[t];
01052 //DEBUGprint                          ::printf("this contracted  t=%d  lid[%d]=%d     ",
01053 //DEBUGprint                                    t,this_contr[t]-1,lid[this_contr[t]-1]);
01054                         }
01055 //DEBUGprint                      ::printf("\n");
01056                       for ( t=0 ; t<contr_counter ; t++ )
01057                         {
01058                           rid[ arg_contr[t]-1 ]  = cd[t];
01059 //DEBUGprint                          ::printf("arg contracted  t=%d  rid[%d]=%d    ",
01060 //DEBUGprint                                    t,arg_contr[t]-1,rid[arg_contr[t]-1]);
01061                         }
01062 //DEBUGprint                      ::printf("\n");
01063 
01064 
01065 // uncontracted indices
01066                       for ( t=0 ; t<this_uni_count ; t++ )
01067                         {
01068                           lid[ this_uncontr[t]-1 ]  = rd[t];
01069 //DEBUGprint                          ::printf("this uncontracted ----- t=%d lid[%d]=%d  ",
01070 //DEBUGprint                                    t,this_uncontr[t]-1,lid[this_uncontr[t]-1]);
01071                         }
01072 //DEBUGprint                      ::printf("\n");
01073 
01074 //                      for ( t=0 ; t<arg_uni_count ; t++ )
01075                       for ( ; t<(this_uni_count+arg_uni_count) ; t++ )
01076                         {
01077                           rid[ arg_uncontr[t-this_uni_count]-1 ] = rd[t];
01078 //DEBUGprint                          ::printf("arg uncontracted ----- t=%d  rid[%d]=%d  ",
01079 //DEBUGprint                                    t,
01080 //DEBUGprint                                    arg_uncontr[t-this_uni_count]-1,
01081 //DEBUGprint                                    rid[arg_uncontr[t-this_uni_count]-1]);
01082                         }
01083 //DEBUGprint                      ::printf("\n");
01084 
01085 
01086 
01087 //                      inerr =
01088 //                      this->val(lid[0],lid[1],lid[2],lid[3],
01089 //                                       lid[4],lid[5],lid[6],lid[7]) *
01090 //                      arg.val(rid[0],rid[1],rid[2],rid[3],
01091 //                                     rid[4],rid[5],rid[6],rid[7]);
01092 
01093                       inerr = inerr +
01094                       this->val(lid[0],lid[1],lid[2],lid[3]) *
01095                       arg.val(rid[0],rid[1],rid[2],rid[3]);
01096 //::printf(" inerr = %12.4lf \n   this[%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d] = %12.4lf arg[%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d] = %12.4lf\n",
01097 //      inerr,lid[0],lid[1],lid[2],lid[3],lid[4],lid[5],lid[6],lid[7],
01098 //      this->val(lid[0],lid[1],lid[2],lid[3],lid[4],lid[5],lid[6],lid[7]),
01099 //      rid[0],rid[1],rid[2],rid[3],rid[4],rid[5],rid[6],rid[7],
01100 //      arg.val(rid[0],rid[1],rid[2],rid[3],rid[4],rid[5],rid[6],rid[7]));
01101 
01102 //DEBUGprint::printf("inerr=%6.2lf this[%1d,%1d,%1d,%1d]=%6.2lf arg[%1d,%1d,%1d,%1d]=%6.2lf\n",
01103 //DEBUGprint      inerr,lid[0],lid[1],lid[2],lid[3],
01104 //DEBUGprint      this->val(lid[0],lid[1],lid[2],lid[3]),
01105 //DEBUGprint      rid[0],rid[1],rid[2],rid[3],
01106 //DEBUGprint      arg.val(rid[0],rid[1],rid[2],rid[3]));
01107 
01108                     }
01109 
01110                                                            // might be optimized 
01111             for ( t=0 ; t<this_uni_count ; t++ )           // put first on in second
01112               {                                            // loop TS
01113 //..                resd[ this_uncontr[t]-1 ] = rd[t];
01114                 resd[t] = rd[t];
01115 //DEBUGprint                ::printf("##### t=%d  resd[%d]=%d\n",
01116 //DEBUGprint                          t,this_uncontr[t]-1,resd[t]);
01117 //DEBUGprint                          t,t,resd[t]);
01118               }
01119             for ( ; t<(this_uni_count+arg_uni_count) ; t++ )
01120               {
01121 //..                resd[ arg_uncontr[t]-1 ] = rd[t];
01122                 resd[t] = rd[t];
01123 //DEBUGprint                ::printf("##### t=%d  resd[%d]=%d\n",
01124 //DEBUGprint                          t,arg_uncontr[t]-1,resd[t]);
01125 //DEBUGprint                          t,t,resd[t]);
01126               }
01127 
01128 //          result(resd[0],resd[1],resd[2],resd[3],
01129 //                 resd[4],resd[5],resd[6],resd[7]) = inerr ;
01130 //::printf(" -----------result[%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d] = %lf\n",
01131 
01132 
01133 
01134 //      resd[0],resd[1],resd[2],resd[3],resd[4],resd[5],resd[6],resd[7],
01135 //      result(resd[0],resd[1],resd[2],resd[3],resd[4],resd[5],resd[6],resd[7]));
01136 
01137           result.val(resd[0],resd[1],resd[2],resd[3]) = inerr ;
01138 //DEBUGprint::printf("##################################### result[%1d,%1d,%1d,%1d]=%8.2lf\n",
01139 //DEBUGprint             resd[0],resd[1],resd[2],resd[3],
01140 //DEBUGprint      result(resd[0],resd[1],resd[2],resd[3]));
01141 
01142 
01143           }
01144 
01145 // deleting dinamically allocated arrays
01146                              
01147     delete  [] this_contr;   
01148     delete  [] arg_contr;    
01149                              
01150     delete  [] this_uncontr; 
01151     delete  [] arg_uncontr ; 
01152                              
01153     delete  [] inerr_dims;   
01154                              
01155     delete  [] lid;          
01156     delete  [] rid;          
01157                              
01158     delete  [] cd;           
01159     delete  [] rd;           
01160                              
01161     delete  [] resd;         
01162 
01163 // NULLification of indices
01164 
01165     null_indices();
01166     arg.null_indices();
01167 
01168 //DEBUGprint::printf("     after delete in operator* coreleft is: %lu bytes\n", (unsigned long) ::coreleft());
01169 
01170     return result; // Returning a local variable ??
01171                    // copy-initializer happens before the destructor,
01172                    // so reference count is 2 when destructor is called,
01173                    // thus destructor doesn't free the memory.
01174   }
01175 
01176 
01177 
01178 //......//##############################################################################
01179 //......//##############################################################################
01180 //......//##############################################################################
01181 //......//##############################################################################
01182 //......//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
01183 //......//
01184 //......//
01185 //......//                                _____..---========+^+=========---.._____
01186 //......//   ______________________ __,_='=====____  ================== _____=====`=
01187 //......//  (._____________________I__) _ __=_/    `--------=+=--------'
01188 //......//      /      /--...---===='---+----'
01189 //......//     '------'---.--- _  _ =   _._'    "Make it so..."
01190 //......//                    `--------'                  Captain Jean-Luc Picard
01191 //......//                                                USS Enterprise, NCC-1701D
01192 //......//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
01193 //......BJtensor operator*(BJtensor& lval, BJtensor& rval)
01194 //......  {
01195 //......//DEBUGprint::printf("before block in operator* coreleft is: %lu bytes\n", (unsigned long) ::coreleft());
01196 //......//   const int MAX_TENS_ORD = 8;
01197 //......   const int MAX_TENS_ORD = 4;
01198 //......//....   int results_rank = 0;
01199 //......
01200 //......//DEBUGprint::printf("lval.rank()=%d\n",
01201 //......//DEBUGprint          lval.rank());
01202 //......//DEBUGprint::printf("rval.rank()=%d\n",
01203 //......//DEBUGprint          rval.rank());
01204 //......
01205 //......// space for CONTRACTED indices
01206 //......   int *lval_contr = new int[MAX_TENS_ORD];
01207 //......   int *rval_contr  = new int[MAX_TENS_ORD];
01208 //......
01209 //......// space for UN-CONTRACTED indices
01210 //......   int *lval_uncontr = new int[MAX_TENS_ORD];
01211 //......   int *rval_uncontr = new int[MAX_TENS_ORD];
01212 //......
01213 //......   for(int lval_ic=0 ; lval_ic<MAX_TENS_ORD ; lval_ic++ )
01214 //......     {
01215 //......       lval_contr[lval_ic] = 0;
01216 //......       lval_uncontr[lval_ic] = 0;
01217 //......     }
01218 //......   for( int rval_ic=0 ; rval_ic<MAX_TENS_ORD ; rval_ic++ )
01219 //......     {
01220 //......       rval_contr[rval_ic]  = 0;
01221 //......       rval_uncontr[rval_ic]  = 0;
01222 //......     }
01223 //......
01224 //......
01225 //......
01226 //......// now make the right choice for indices for this and rval BJtensor !!!
01227 //......//
01228 //......//                  |||~          |||~          |||~
01229 //......//                 (0 0)         (0 0)         (0 0)
01230 //......//--------------ooO-(_)-Ooo---ooO-(_)-Ooo---ooO-(_)-Ooo----------------------
01231 //......//
01232 //......
01233 //......   char * lval_indices = lval.indices1;
01234 //......   char * rval_indices = rval.indices1;
01235 //......
01236 //......// if the BJtensors are same then split indices :-)
01237 //......   if ( lval.pc_nDarray_rep == rval.pc_nDarray_rep )
01238 //......     {
01239 //......       lval_indices = lval.indices2; // this is changed because
01240 //......       rval_indices  = rval.indices1;  // it reads indices from
01241 //......                                    // right so "in" indices1 are
01242 //......                                   // the right ( rval ) and "in"
01243 //......                                  // indices2 are the
01244 //......                                 // left indices
01245 //......     }
01246 //......//DEBUGprint::printf("lval_indices=%s\n", lval_indices);
01247 //......//DEBUGprint::printf("rval_indices=%s\n",  rval_indices);
01248 //......
01249 //......
01250 //......
01251 //......//   int lval_indices_number = ::strlen(lval.pc_nDarray_rep->indices1);
01252 //......//   int  rval_indices_number = ::strlen(rval.pc_nDarray_rep->indices1);
01253 //......
01254 //......   int lval_indices_number = ::strlen(lval_indices);
01255 //......   int rval_indices_number = ::strlen(rval_indices);
01256 //......
01257 //......//DEBUGprint::printf("lval_indices_number=%d\n",
01258 //......//DEBUGprint          lval_indices_number);
01259 //......//DEBUGprint::printf("rval_indices_number=%d\n",
01260 //......//DEBUGprint          rval_indices_number);
01261 //......
01262 //......// check for indices number: should be EQUAL than rank of BJtensor
01263 //......   if ( lval_indices_number != lval.rank() )
01264 //......     {
01265 //......       ::fprintf(stderr,"\a\n 'this' has more/less indices than expected:\n",
01266 //......                " lval_indices_number = %d\n",
01267 //......                " lval.rank() = %d\n",
01268 //......                  lval_indices_number,
01269 //......                  lval.rank());
01270 //......       ::exit(1);
01271 //......     }
01272 //......
01273 //......   if ( rval_indices_number != rval.rank() )
01274 //......     {
01275 //......       ::fprintf(stderr,"\a\n 'rval' has more/less indices than expected:\n",
01276 //......                " rval_indices_number = %d\n",
01277 //......                " rval.rank() = %d\n",
01278 //......                  rval_indices_number,
01279 //......                  rval.rank());
01280 //......       ::exit(1);
01281 //......     }
01282 //......
01283 //......// counter for contracted indices
01284 //......   int contr_counter = lval.contracted_ind(lval_indices,
01285 //......                                           rval_indices,
01286 //......                                           lval_contr,
01287 //......                                           rval_contr,
01288 //......                                           lval_indices_number,
01289 //......                                           rval_indices_number  );
01290 //......
01291 //......   int lval_uni_count = lval.uncontracted_ind( lval_uncontr,
01292 //......                                               lval_contr,
01293 //......                                               lval_indices_number);
01294 //......
01295 //......   int rval_uni_count = rval.uncontracted_ind( rval_uncontr,
01296 //......                                               rval_contr,
01297 //......                                               rval_indices_number);
01298 //......
01299 //......//number of UNcontractions
01300 //......   int uncontr_counter = lval_uni_count + rval_uni_count;
01301 //......
01302 //......//TEMP  this is just the test because right now only up to order = 4
01303 //......   if ( uncontr_counter > 4 )
01304 //......     {
01305 //......       ::fprintf(stderr,"\a\a\n\n  OOOPS product of multiplication has order %d\n",
01306 //......                           uncontr_counter);
01307 //......       ::exit(1);
01308 //......     }
01309 //......
01310 //......
01311 //......//DEBUGprint ::printf("..... lval_uni_count = %d, rval_uni_count = %d\n",
01312 //......//DEBUGprint                 lval_uni_count,      rval_uni_count);
01313 //......//DEBUGprint ::printf(" uncontr_counter %d\n",uncontr_counter);
01314 //......//DEBUGprint for( int plval_ic=0 ;
01315 //......//DEBUGprint      plval_ic<(lval.rank()+1) ;
01316 //......//DEBUGprint      plval_ic++ )
01317 //......//DEBUGprint   ::printf("lval_uncontr[%d]=%d\n",plval_ic,lval_uncontr[plval_ic]);
01318 //......//DEBUGprint for( int prval_ic=0 ;
01319 //......//DEBUGprint      prval_ic<(rval.rank()+1) ;
01320 //......//DEBUGprint      prval_ic++ )
01321 //......//DEBUGprint   ::printf("             rval_uncontr[%d]=%d\n",prval_ic,rval_uncontr[prval_ic]);
01322 //......
01323 //....../////////////////////////////////////////////////////
01324 //......// let's make result BJtensor
01325 //......
01326 //......   static int results_dims[MAX_TENS_ORD];
01327 //......   for( int t=0 ; t < lval_uni_count ; t++ )
01328 //......     results_dims[t]=lval.dim()[lval_uncontr[t]-1];
01329 //......   for( int a=0 ; a < rval_uni_count ; a++ )
01330 //......     results_dims[a+t]=rval.dim()[rval_uncontr[a]-1];
01331 //......// do kraja . . .
01332 //......   for( ; a < MAX_TENS_ORD-t ; a++ )
01333 //......     results_dims[a+t]=1;
01334 //......
01335 //......
01336 //......
01337 //......
01338 //......
01339 //......
01340 //......// pa sada indeksi
01341 //......   static char results_indices[MAX_TENS_ORD];
01342 //......   for( t=0 ; t < lval_uni_count ; t++ )
01343 //......     results_indices[t]=lval_indices[lval_uncontr[t]-1];
01344 //......   for( a=0 ; a < rval_uni_count ; a++ )
01345 //......     results_indices[a+t]=rval_indices[rval_uncontr[a]-1];
01346 //......// the last one . . .
01347 //......   results_indices[uncontr_counter] = '\0';
01348 //......
01349 //......
01350 //......//DEBUGprint  ::printf("\n\n......  uncontr_counter+1=%d\n", uncontr_counter+1);
01351 //......//DEBUGprintfor( int pa=0 ; pa < MAX_TENS_ORD ; pa++ )
01352 //......//DEBUGprint  ::printf("   results_dims[%d]=%d\n",pa,results_dims[pa]);
01353 //......
01354 //......   BJtensor result(uncontr_counter, results_dims, 0.0);
01355 //......   result(results_indices);  // initialize indices in result
01356 //......//DEBUGprint  ::printf("\n\n..................   results_indices=%s\n",results_indices);
01357 //......
01358 //......//////////////////////////////////////////////////
01359 //......// check dimensions in each tesnor order
01360 //......   for( t=0 ; t<contr_counter ; t++ )
01361 //......     if ( lval.dim()[lval_contr[t]-1] !=
01362 //......          rval.dim()[rval_contr[t]-1] )
01363 //......       {
01364 //......         ::fprintf(stderr,"\a\a\n t = %d \n"
01365 //......                  "lval_contr[t]-1  = %d\n"
01366 //......                  "lval.dim()[%d] = %d\n"
01367 //......                  "rval_contr[t]-1  = %d\n"
01368 //......                  "rval.dim()[%d] = %d\n",
01369 //......                   t,
01370 //......                   lval_contr[t]-1,
01371 //......                   lval_contr[t]-1,lval.dim()[lval_contr[t]-1],
01372 //......                   rval_contr[t]-1,
01373 //......                   rval_contr[t]-1,rval.dim()[rval_contr[t]-1]);
01374 //......         ::exit(1);
01375 //......       }
01376 //......
01377 //....../////////////////////////////////////////////////////#*%
01378 //......//////////////////////////////////////////////////#*%
01379 //......///////////////////////////////////////////////#*%
01380 //......////////////////////////////////////////////#*%
01381 //....../////////////////////////////////////////#*%
01382 //......//////////////////////////////////////#*%
01383 //......///////////////////////////////////#*%
01384 //......////////////////////////////////#*%
01385 //....../////////////////////////////#*%
01386 //......//////////////////////////#*%
01387 //......///////////////////////#*%
01388 //......////////////////////#*%
01389 //....../////////////////#*%
01390 //......//////////////#*%
01391 //......///////////#*%
01392 //......////////#*%
01393 //....../////#*%
01394 //......//#*%
01395 //......
01396 //......   int *inerr_dims = new int[MAX_TENS_ORD];
01397 //......   for( t=0 ; t<contr_counter ; t++ )
01398 //......     {
01399 //......       inerr_dims[t] = lval.dim()[lval_contr[t]-1];
01400 //......//DEBUGprint       ::printf("    inerr_dims[%d] = %d\n",t,inerr_dims[t]);
01401 //......     }
01402 //......   for( ; t<MAX_TENS_ORD ; t++ )
01403 //......     {
01404 //......       inerr_dims[t] = 1;
01405 //......//DEBUGprint       ::printf("          the rest of inerr_dims[%d] = %d\n",t,inerr_dims[t]);
01406 //......     }
01407 //......
01408 //......
01409 //......   int *lid = new int[MAX_TENS_ORD];
01410 //......   for( t=0 ; t<MAX_TENS_ORD ; t++ )
01411 //......     {
01412 //......       lid[t] = 1;
01413 //......//DEBUGprint       ::printf("    lid[%d] = %d\n",t,lid[t]);
01414 //......     }
01415 //......
01416 //......   int *rid = new int[MAX_TENS_ORD];
01417 //......   for( t=0 ;  t<MAX_TENS_ORD ; t++ )
01418 //......     {
01419 //......       rid[t] = 1;
01420 //......//DEBUGprint       ::printf("    rid[%d] = %d\n",t,rid[t]);
01421 //......     }
01422 //......
01423 //......   int *cd = new int[MAX_TENS_ORD];
01424 //......   int *rd = new int[MAX_TENS_ORD];
01425 //......
01426 //......   int *resd = new int[MAX_TENS_ORD];
01427 //......   for( t=0 ;  t<MAX_TENS_ORD ; t++ )
01428 //......     {
01429 //......       resd[t] = 1;
01430 //......//DEBUGprint       ::printf("    resd[%d] = %d\n",t,resd[t]);
01431 //......     }
01432 //......
01433 //......  double inerr=0.0;
01434 //......
01435 //......// obrnuti red zbog brzeg izvrsenja ( rd[0] ide do najveceg broja . . . )
01436 //......//  for ( rd[7]=1 ; rd[7]<=results_dims[7] ; rd[7]++ )
01437 //......//   for ( rd[6]=1 ; rd[6]<=results_dims[6] ; rd[6]++ )
01438 //......//    for ( rd[5]=1 ; rd[5]<=results_dims[5] ; rd[5]++ )
01439 //......//     for ( rd[4]=1 ; rd[4]<=results_dims[4] ; rd[4]++ )
01440 //......      for ( rd[3]=1 ; rd[3]<=results_dims[3] ; rd[3]++ )
01441 //......       for ( rd[2]=1 ; rd[2]<=results_dims[2] ; rd[2]++ )
01442 //......        for ( rd[1]=1 ; rd[1]<=results_dims[1] ; rd[1]++ )
01443 //......         for ( rd[0]=1 ; rd[0]<=results_dims[0] ; rd[0]++ )
01444 //......          {
01445 //......            inerr = 0.0;
01446 //......
01447 //......//            for ( cd[7]=1 ; cd[7]<=inerr_dims[7] ; cd[7]++ )
01448 //......//             for ( cd[6]=1 ; cd[6]<=inerr_dims[6] ; cd[6]++ )
01449 //......//              for ( cd[5]=1 ; cd[5]<=inerr_dims[5] ; cd[5]++ )
01450 //......//               for ( cd[4]=1 ; cd[4]<=inerr_dims[4] ; cd[4]++ )
01451 //......                for ( cd[3]=1 ; cd[3]<=inerr_dims[3] ; cd[3]++ )
01452 //......                 for ( cd[2]=1 ; cd[2]<=inerr_dims[2] ; cd[2]++ )
01453 //......                  for ( cd[1]=1 ; cd[1]<=inerr_dims[1] ; cd[1]++ )
01454 //......                   for ( cd[0]=1 ; cd[0]<=inerr_dims[0] ; cd[0]++ )
01455 //......
01456 //......
01457 //......
01458 //......
01459 //......
01460 //......                    {
01461 //......
01462 //......// contracted indices
01463 //......                      for ( t=0 ; t<contr_counter ; t++ )
01464 //......                        {
01465 //......                          lid[ lval_contr[t]-1 ]  = cd[t];
01466 //......//DEBUGprint                          ::printf("this contracted  t=%d  lid[%d]=%d     ",
01467 //......//DEBUGprint                                    t,lval_contr[t]-1,lid[lval_contr[t]-1]);
01468 //......                        }
01469 //......//DEBUGprint                      ::printf("\n");
01470 //......                      for ( t=0 ; t<contr_counter ; t++ )
01471 //......                        {
01472 //......                          rid[ rval_contr[t]-1 ]  = cd[t];
01473 //......//DEBUGprint                          ::printf("rval contracted  t=%d  rid[%d]=%d    ",
01474 //......//DEBUGprint                                    t,rval_contr[t]-1,rid[rval_contr[t]-1]);
01475 //......                        }
01476 //......//DEBUGprint                      ::printf("\n");
01477 //......
01478 //......
01479 //......// uncontracted indices
01480 //......                      for ( t=0 ; t<lval_uni_count ; t++ )
01481 //......                        {
01482 //......                          lid[ lval_uncontr[t]-1 ]  = rd[t];
01483 //......//DEBUGprint                          ::printf("this uncontracted ----- t=%d lid[%d]=%d  ",
01484 //......//DEBUGprint                                    t,lval_uncontr[t]-1,lid[lval_uncontr[t]-1]);
01485 //......                        }
01486 //......//DEBUGprint                      ::printf("\n");
01487 //......
01488 //......//                      for ( t=0 ; t<rval_uni_count ; t++ )
01489 //......                      for ( ; t<(lval_uni_count+rval_uni_count) ; t++ )
01490 //......                        {
01491 //......                          rid[ rval_uncontr[t-lval_uni_count]-1 ] = rd[t];
01492 //......//DEBUGprint                          ::printf("rval uncontracted ----- t=%d  rid[%d]=%d  ",
01493 //......//DEBUGprint                                    t,
01494 //......//DEBUGprint                                    rval_uncontr[t-lval_uni_count]-1,
01495 //......//DEBUGprint                                    rid[rval_uncontr[t-lval_uni_count]-1]);
01496 //......                        }
01497 //......//DEBUGprint                      ::printf("\n");
01498 //......
01499 //......
01500 //......
01501 //......//                      inerr =
01502 //......//                      lval.val(lid[0],lid[1],lid[2],lid[3],
01503 //......//                                       lid[4],lid[5],lid[6],lid[7]) *
01504 //......//                      rval.val(rid[0],rid[1],rid[2],rid[3],
01505 //......//                                     rid[4],rid[5],rid[6],rid[7]);
01506 //......
01507 //......                      inerr = inerr +
01508 //......                      lval.val(lid[0],lid[1],lid[2],lid[3]) *
01509 //......                      rval.val(rid[0],rid[1],rid[2],rid[3]);
01510 //......//::printf(" inerr = %12.4lf \n   this[%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d] = %12.4lf rval[%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d] = %12.4lf\n",
01511 //......//      inerr,lid[0],lid[1],lid[2],lid[3],lid[4],lid[5],lid[6],lid[7],
01512 //......//      lval.val(lid[0],lid[1],lid[2],lid[3],lid[4],lid[5],lid[6],lid[7]),
01513 //......//      rid[0],rid[1],rid[2],rid[3],rid[4],rid[5],rid[6],rid[7],
01514 //......//      rval.val(rid[0],rid[1],rid[2],rid[3],rid[4],rid[5],rid[6],rid[7]));
01515 //......
01516 //......//DEBUGprint::printf("inerr=%6.2lf this[%1d,%1d,%1d,%1d]=%6.2lf rval[%1d,%1d,%1d,%1d]=%6.2lf\n",
01517 //......//DEBUGprint      inerr,lid[0],lid[1],lid[2],lid[3],
01518 //......//DEBUGprint      lval.val(lid[0],lid[1],lid[2],lid[3]),
01519 //......//DEBUGprint      rid[0],rid[1],rid[2],rid[3],
01520 //......//DEBUGprint      rval.val(rid[0],rid[1],rid[2],rid[3]));
01521 //......
01522 //......                    }
01523 //......
01524 //......
01525 //......            for ( t=0 ; t<lval_uni_count ; t++ )
01526 //......              {
01527 //......//..                resd[ lval_uncontr[t]-1 ] = rd[t];
01528 //......                resd[t] = rd[t];
01529 //......//DEBUGprint                ::printf("##### t=%d  resd[%d]=%d\n",
01530 //......//DEBUGprint                          t,lval_uncontr[t]-1,resd[t]);
01531 //......//DEBUGprint                          t,t,resd[t]);
01532 //......              }
01533 //......            for ( ; t<(lval_uni_count+rval_uni_count) ; t++ )
01534 //......              {
01535 //......//..                resd[ rval_uncontr[t]-1 ] = rd[t];
01536 //......                resd[t] = rd[t];
01537 //......//DEBUGprint                ::printf("##### t=%d  resd[%d]=%d\n",
01538 //......//DEBUGprint                          t,rval_uncontr[t]-1,resd[t]);
01539 //......//DEBUGprint                          t,t,resd[t]);
01540 //......              }
01541 //......
01542 //......//          result(resd[0],resd[1],resd[2],resd[3],
01543 //......//                 resd[4],resd[5],resd[6],resd[7]) = inerr ;
01544 //......//::printf(" -----------result[%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d] = %lf\n",
01545 //......
01546 //......
01547 //......
01548 //......//      resd[0],resd[1],resd[2],resd[3],resd[4],resd[5],resd[6],resd[7],
01549 //......//      result(resd[0],resd[1],resd[2],resd[3],resd[4],resd[5],resd[6],resd[7]));
01550 //......
01551 //......          result.val(resd[0],resd[1],resd[2],resd[3]) = inerr ;
01552 //......//DEBUGprint::printf("##################################### result[%1d,%1d,%1d,%1d]=%8.2lf\n",
01553 //......//DEBUGprint             resd[0],resd[1],resd[2],resd[3],
01554 //......//DEBUGprint      result(resd[0],resd[1],resd[2],resd[3]));
01555 //......
01556 //......
01557 //......          }
01558 //......
01559 //......// deleting dinamically allocated arrays
01560 //......
01561 //......    delete [] lval_contr;
01562 //......    delete [] rval_contr;
01563 //......
01564 //......    delete [] lval_uncontr;
01565 //......    delete [] rval_uncontr ;
01566 //......
01567 //......    delete [] inerr_dims;
01568 //......
01569 //......    delete [] lid;
01570 //......    delete [] rid;
01571 //......
01572 //......    delete [] cd;
01573 //......    delete [] rd;
01574 //......
01575 //......    delete [] resd;
01576 //......
01577 //......// NULLification of indices
01578 //......
01579 //......    lval.null_indices();
01580 //......    rval.null_indices();
01581 //......
01582 //......//DEBUGprint::printf("     after delete in operator* coreleft is: %lu bytes\n", (unsigned long) ::coreleft());
01583 //......
01584 //......    return BJtensor(result); // Returning a local variable ??
01585 //......                   // copy-initializer happens before the destructor,
01586 //......                   // so reference count is 2 when destructor is called,
01587 //......                   // thus destructor doesn't free the memory.
01588 //......  }
01589 //......
01590 
01591 
01592 
01593 //##############################################################################
01594 // counter for contracted indices
01595 int BJtensor::contracted_ind(char  * argleft_indices,
01596                            char  * argright_indices,
01597                            int   * argleft_contr,
01598                            int   * argright_contr,
01599                            int     argleft_ind_numb,
01600                            int     argright_ind_numb)
01601   {
01602     int contr_counter = 0;
01603     int argleft_i_count = 0;
01604     int argright_i_count  = 0;
01605 
01606     for ( int argleft_indices_counter = 1 ;
01607           argleft_indices_counter<=argleft_ind_numb ;
01608           argleft_indices_counter++ )
01609       {
01610         int t_i_c = argleft_indices_counter - 1;
01611         for ( int argright_indices_counter = 1 ;
01612               argright_indices_counter<= argright_ind_numb ;
01613               argright_indices_counter++ )
01614           {
01615             int a_i_c = argright_indices_counter - 1;
01616             if ( argleft_indices[t_i_c] ==
01617                  argright_indices[a_i_c] )
01618               {
01619                 argleft_contr[argleft_i_count] = argleft_indices_counter;
01620                 argright_contr[argright_i_count] = argright_indices_counter;
01621 
01622                 argleft_i_count++;
01623                 argright_i_count++;
01624 
01625                 contr_counter++;
01626               }
01627           }
01628       }
01629 
01630 
01631 //DEBUGprint ::printf("..... argleft_i_count = %d, argright_i_count = %d\n",
01632 //DEBUGprint                 argleft_i_count,      argright_i_count);
01633 //DEBUGprint ::printf(" contr_counter %d\n",contr_counter);
01634 //DEBUGprint for(int pthis_ic=0 ;
01635 //DEBUGprint     pthis_ic<(argleft->rank()+1) ;
01636 //DEBUGprint     pthis_ic++ )
01637 //DEBUGprint   ::printf("argleft_contr[%d]=%d\n",pthis_ic,argleft_contr[pthis_ic]);
01638 //DEBUGprint for( int parg_ic=0 ;
01639 //DEBUGprint      parg_ic<(argright->rank()+1) ;
01640 //DEBUGprint      parg_ic++ )
01641 //DEBUGprint   ::printf("                 argright_contr[%d]=%d\n",
01642 //DEBUGprint                              parg_ic,argright_contr[parg_ic]);
01643 
01644 
01645     return contr_counter;
01646   }
01647 
01648 //##############################################################################
01649 // counter for UNcontracted indices
01650 int BJtensor::uncontracted_ind(int *tens_uncontr,
01651                              int *tens_contr,
01652                              int tens_ind_numb)
01653   {
01654 // counter for UNcontracted indices
01655     int tens_uni_count = 0;
01656 
01657     for ( int tens_unindices_counter = 1 ;
01658           tens_unindices_counter<=tens_ind_numb ;
01659           tens_unindices_counter++ )
01660       {
01661         tens_uncontr[tens_uni_count] = tens_unindices_counter;
01662         for ( int tens_indices_counter = 1 ;
01663               tens_indices_counter<=tens_ind_numb ;
01664               tens_indices_counter++ )
01665           {
01666             int t_i_c = tens_indices_counter - 1;
01667 //DEBUGprint::printf("CHECK tens_uncontr[%d]=%d",tens_uni_count, tens_uncontr[tens_uni_count]);
01668 //DEBUGprint::printf("  WITH tens_contr[%d]=%d\n", t_i_c,tens_contr[t_i_c]);
01669             if ( tens_uncontr[tens_uni_count] == tens_contr[t_i_c] )
01670               {
01671                 tens_uncontr[tens_uni_count] = 0;
01672                 tens_uni_count--;
01673                 tens_indices_counter=tens_ind_numb;//out of inner for loop
01674               }
01675           }
01676         tens_uni_count++;
01677       }
01678     return tens_uni_count;
01679   }
01680 
01681 //##############################################################################
01682 // BJtensorial division THE rval MUST BE 0 ORDER BJtensor
01683 BJtensor BJtensor::operator/( BJtensor & rval)
01684  {
01685 // construct BJtensor using the same control numbers as for the
01686 // original one.
01687     BJtensor div(this->rank(), dim(), 0.0);
01688     double rvalDouble = rval.trace();
01689     if ( rval.rank() != 1 ) ::printf("rval.rank() != 1 for BJtensor BJtensor::operator/( BJtensor & rval)\n");
01690 
01691     div.indices1 = this->indices1;
01692 
01693     switch(this->rank())
01694       {
01695         case 0:
01696           {
01697             div.val(1) = val(1)/rvalDouble;
01698             break;
01699           }
01700 
01701         case 1:
01702           {
01703             for ( int i1=1 ; i1<=3 ; i1++ )
01704               div.val(i1) = val(i1)/rvalDouble;
01705             break;
01706           }
01707 
01708         case 2:
01709           {
01710             for ( int i2=1 ; i2<=3 ; i2++ )
01711               for ( int j2=1 ; j2<=3 ; j2++ )
01712                 div.val(i2, j2) = val(i2, j2)/rvalDouble;
01713             break;
01714           }
01715 
01716         case 3:
01717           {
01718             for ( int i3=1 ; i3<=3 ; i3++ )
01719               for ( int j3=1 ; j3<=3 ; j3++ )
01720                 for ( int k3=1 ; k3<=3 ; k3++ )
01721                   div.val(i3, j3, k3) = val(i3, j3, k3)/rvalDouble;
01722             break;
01723           }
01724 
01725         case 4:
01726           {
01727             for ( int i4=1 ; i4<=3 ; i4++ )
01728               for ( int j4=1 ; j4<=3 ; j4++ )
01729                 for ( int k4=1 ; k4<=3 ; k4++ )
01730                   for ( int l4=1 ; l4<=3 ; l4++ )
01731                     div.val(i4,j4,k4,l4)=val(i4,j4,k4,l4)/rvalDouble;
01732             break;
01733           }
01734       }
01735 
01736     null_indices();
01737 
01738     return div;
01739  }
01740 
01741 
01742 
01743 //##############################################################################
01745 //     ijkl  -->> ikjl    */
01746 BJtensor BJtensor::transpose0110() const
01747   {
01748 // construct BJtensor using the same control numbers as for the
01749 // original one and than transpose it.
01750    BJtensor trans1(this->rank(), dim(), 0.0);
01751 
01752    for ( int i=1 ; i<=dim()[0] ; i++ )
01753      for ( int j=1 ; j<=dim()[1] ; j++ )
01754        for ( int k=1 ; k<=dim()[2] ; k++ )
01755          for ( int l=1 ; l<=dim()[3] ; l++ )
01756            trans1.val(i, j, k, l) = cval(i, k, j, l);
01757 
01758     trans1.null_indices();
01759 //    null_indices();
01760     return trans1;
01761  }
01762 
01763 //##############################################################################
01765 //     ijkl  -->> ikjl    */
01766 BJtensor BJtensor::transposeoverbar() const // same as transpose0110
01767   {
01768 // construct BJtensor using the same control numbers as for the
01769 // original one and than transpose it.
01770    BJtensor trans1(this->rank(), dim(), 0.0);
01771 
01772    for ( int i=1 ; i<=dim()[0] ; i++ )
01773      for ( int j=1 ; j<=dim()[1] ; j++ )
01774        for ( int k=1 ; k<=dim()[2] ; k++ )
01775          for ( int l=1 ; l<=dim()[3] ; l++ )
01776            trans1.val(i, j, k, l) = cval(i, k, j, l);
01777 
01778     trans1.null_indices();
01779 //    null_indices();
01780     return trans1;
01781  }
01782 //##############################################################################
01784 //     ijkl  -->> ilkj    */
01785 BJtensor BJtensor::transpose0101() const
01786   {
01787 // construct BJtensor using the same control numbers as for the
01788 // original one and than transpose it.
01789    BJtensor trans1(this->rank(), dim(), 0.0);
01790 
01791    for ( int i=1 ; i<=dim()[0] ; i++ )
01792      for ( int j=1 ; j<=dim()[1] ; j++ )
01793        for ( int k=1 ; k<=dim()[2] ; k++ )
01794          for ( int l=1 ; l<=dim()[3] ; l++ )
01795            trans1.val(i, j, k, l) = cval(i, l, k, j);
01796 
01797     trans1.null_indices();
01798 //    null_indices();
01799     return trans1;
01800  }
01801 
01802 //##############################################################################
01804 //     ijkl  -->> iljk    */
01805 BJtensor BJtensor::transpose0111() const
01806   {
01807 // construct BJtensor using the same control numbers as for the
01808 // original one and than transpose it.
01809    BJtensor trans1(this->rank(), dim(), 0.0);
01810 
01811    for ( int i=1 ; i<=dim()[0] ; i++ )
01812      for ( int j=1 ; j<=dim()[1] ; j++ )
01813        for ( int k=1 ; k<=dim()[2] ; k++ )
01814          for ( int l=1 ; l<=dim()[3] ; l++ )
01815            trans1.val(i, j, k, l) = cval(i, l, j, k);
01816 
01817     trans1.null_indices();
01818 //    null_indices();
01819     return trans1;
01820  }
01821 //##############################################################################
01823 //     ijkl  -->> iljk    */
01824 BJtensor BJtensor::transposeunderbar() const   // transpose0111() 
01825   {
01826 // construct BJtensor using the same control numbers as for the
01827 // original one and than transpose it.
01828    BJtensor trans1(this->rank(), dim(), 0.0);
01829 
01830    for ( int i=1 ; i<=dim()[0] ; i++ )
01831      for ( int j=1 ; j<=dim()[1] ; j++ )
01832        for ( int k=1 ; k<=dim()[2] ; k++ )
01833          for ( int l=1 ; l<=dim()[3] ; l++ )
01834            trans1.val(i, j, k, l) = cval(i, l, j, k);
01835 
01836     trans1.null_indices();
01837 //    null_indices();
01838     return trans1;
01839  }
01840 
01841 //##############################################################################
01843 //     ijkl  -->> jikl
01844 BJtensor BJtensor::transpose1100() const
01845   {
01846 // construct BJtensor using the same control numbers as for the
01847 // original one and than transpose it.
01848    BJtensor trans1(this->rank(), dim(), 0.0);
01849 
01850    for ( int i=1 ; i<=dim()[0] ; i++ )
01851      for ( int j=1 ; j<=dim()[1] ; j++ )
01852        for ( int k=1 ; k<=dim()[2] ; k++ )
01853          for ( int l=1 ; l<=dim()[3] ; l++ )
01854            trans1.val(i, j, k, l) = cval(j, i, k, l);
01855 
01856     trans1.null_indices();
01857 //    null_indices();
01858     return trans1;
01859  }
01860 
01861 //##############################################################################
01863 //     ijkl  -->> ijlk
01864 BJtensor BJtensor::transpose0011() const
01865   {
01866 // construct BJtensor using the same control numbers as for the
01867 // original one and than transpose it.
01868    BJtensor trans1(this->rank(), dim(), 0.0);
01869 
01870    for ( int i=1 ; i<=dim()[0] ; i++ )
01871      for ( int j=1 ; j<=dim()[1] ; j++ )
01872        for ( int k=1 ; k<=dim()[2] ; k++ )
01873          for ( int l=1 ; l<=dim()[3] ; l++ )
01874            trans1.val(i, j, k, l) = cval(i, j, l, k);
01875 
01876     trans1.null_indices();
01877 //    null_indices();
01878     return trans1;
01879  }
01880 
01881 //##############################################################################
01883 //     ijkl  -->> iilk
01884 BJtensor BJtensor::transpose1001() const
01885   {
01886 // construct BJtensor using the same control numbers as for the
01887 // original one and than transpose it.
01888    BJtensor trans1(this->rank(), dim(), 0.0);
01889 
01890    for ( int i=1 ; i<=dim()[0] ; i++ )
01891      for ( int j=1 ; j<=dim()[1] ; j++ )
01892        for ( int k=1 ; k<=dim()[2] ; k++ )
01893          for ( int l=1 ; l<=dim()[3] ; l++ )
01894            trans1.val(i, j, k, l) = cval(l, j, k, i);
01895 
01896     trans1.null_indices();
01897 //    null_indices();
01898     return trans1;
01899  }
01900 
01901 
01902 
01903 
01904 //##############################################################################
01906 //     ij  -->> ji    */
01907 BJtensor BJtensor::transpose11() const
01908   {
01909 // construct BJtensor using the same control numbers as for the
01910 // original one and than transpose it.
01911    BJtensor trans1(this->rank(), dim(), 0.0);
01912 
01913    for ( int i=1 ; i<=dim()[0] ; i++ )
01914      for ( int j=1 ; j<=dim()[1] ; j++ )
01915        trans1.val(i, j) = cval(j, i);
01916 
01917     trans1.null_indices();
01918 //    null_indices();
01919     return trans1;
01920  }
01921 
01922 //##############################################################################
01924 //     ij  
01925 BJtensor BJtensor::symmetrize11() const
01926   {
01927 // construct BJtensor using the same control numbers as for the
01928 // original one and than symmetrize it.
01929 //   BJtensor sym(this->rank(), dim(), 0.0);
01930 
01931 
01932    BJtensor temp(*this);
01933 
01934    BJtensor sym = (temp + temp.transpose11())*0.5;
01935 
01936    sym.null_indices();
01937    return sym;
01938  }
01939 
01940 //..//##############################################################################
01941 //..///* symmterize function for 2th rank BJtensors:
01942 //..//     ij  
01943 //..BJtensor BJtensor::symmetrize11() const
01944 //..  {
01945 //..// construct BJtensor using the same control numbers as for the
01946 //..// original one and than symmetrize it.
01947 //..//   BJtensor sym(this->rank(), dim(), 0.0);
01948 //..
01949 //..
01950 //..   BJtensor temp(*this);
01951 //..
01952 //..   BJtensor sym = (temp + temp.transpose11())*0.5;
01953 //..
01954 //..   sym.null_indices();
01955 //..   return sym;
01956 //.. }
01957 //..
01958 
01959 
01960 // moved to ndarray april 3 1995
01961 //--//##############################################################################
01962 //--// trace function: trace of a second rank BJtensor
01963 //--// what about fourth ( 4th ) rank BJtensor trace or any other rank ??
01964 //--double BJtensor::trace() const 
01965 //--  {
01966 //--    double tr = 0.0;
01967 //--// ovaj case ne treba vec moze sve do 4-tog reda ( ili kasnije osmog # )
01968 //--    switch(this->rank())
01969 //--      {
01970 //--        case 0:
01971 //--          {
01972 //--//            ::printf(" trace=%.4e  ", val(1));
01973 //--//            ::printf("\n");
01974 //--            tr = cval(1);
01975 //--            break;
01976 //--          }
01977 //--
01978 //--        case 1:
01979 //--          {
01980 //--            if(dim()[0] != 1)
01981 //--              {
01982 //--::printf("\a\nERROR in trace function : not a squared 1-st rank BJtensor\n");
01983 //--::exit( 1 );
01984 //--              }
01985 //--            tr = cval(1);
01986 //--            break;
01987 //--          }
01988 //--
01989 //--        case 2:
01990 //--          {
01991 //--            if(dim()[0] != dim()[1])
01992 //--              {
01993 //--::printf("\a\nERROR in trace function : not a sqared 2nd-rank BJtensor\n");
01994 //--::exit( 1 );
01995 //--              }
01996 //--            for ( int i2=1 ; i2<=dim()[0] ; i2++ )
01997 //--              tr += cval(i2, i2);
01998 //--            break;
01999 //--          }
02000 //--
02001 //--        case 3:
02002 //--          {
02003 //--            if( dim()[0] != dim()[1] ||
02004 //--                dim()[1] != dim()[2] ||
02005 //--                dim()[2] != dim()[0]    )
02006 //--              {
02007 //--::printf("\a\nERROR in trace function : not a sqared 3nd-rank BJtensor\n");
02008 //--::exit( 1 );
02009 //--              }
02010 //--            for ( int i3=1 ; i3<=dim()[0] ; i3++ )
02011 //--              tr += cval(i3, i3, i3);
02012 //--            break;
02013 //--          }
02014 //--
02015 //--        case 4:
02016 //--          {
02017 //--            if( dim()[0] != dim()[1] ||
02018 //--                dim()[1] != dim()[2] ||
02019 //--                dim()[2] != dim()[3] ||
02020 //--                dim()[3] != dim()[0]    )
02021 //--              {
02022 //--::printf("\a\nERROR in trace function : not a sqared 4nd-rank BJtensor\n");
02023 //--::exit( 1 );
02024 //--              }
02025 //--            for ( int i4=1 ; i4<=dim()[0] ; i4++ )
02026 //--              tr += cval(i4, i4, i4, i4);
02027 //--            break;
02028 //--          }
02029 //--      }
02030 //--
02031 //..........    null_indices();
02032 //--
02033 //--    return tr;
02034 //--  }
02035 
02036 
02037 //##############################################################################
02038 // determinant function
02039 double BJtensor::determinant() const
02040   {
02041     double det = 0.0;
02042 //    switch(pc_nDarray_rep->nDarray_rank)
02043     switch(this->rank())
02044       {
02045         case 0:
02046           {
02047             det = cval(1);
02048             break;
02049           }
02050 
02051         case 1:
02052           {
02053             if(dim()[0] != 1)
02054               {
02055                 ::fprintf(stderr,"\a\n ERROR: only for square BJvector (1) \n");
02056                 ::exit(1);
02057               }
02058             det = cval(1);
02059             break;
02060           }
02061 
02062         case 2:
02063           {
02064             BJmatrix converted = this->BJtensor2BJmatrix_2();
02065             det = converted.determinant();
02066             break;
02067           }
02068 
02069         case 3:
02070           {
02071             ::fprintf(stderr,"\a\n SORRY: not implemented \n");
02072             ::exit(1);
02073             break;
02074           }
02075 
02076         case 4:
02077           {
02078             ::fprintf(stderr,"\a\n SORRY: not implemented \n");
02079             ::exit(1);
02080             break;
02081           }
02082       }
02083 
02084 //..........    null_indices();
02085 
02086     return det;
02087   }
02088 
02089 
02090 //##############################################################################
02091 BJmatrix BJtensor::BJtensor2BJmatrix_1() const // convert BJtensor of even order to BJmatrix
02092                                 // to be used in inversion process
02093                                 // in the begining only BJtensor of
02094                                 // 2 and 4 order
02095                                 // I_ijkl scheme
02096   {
02097     int BJtensor_order = this->rank();
02098     static int BJmatrix_dims[] = {0,0};
02099 
02100     if ( BJtensor_order == 2 )
02101       {
02102         BJmatrix_dims[0] = this->dim(1);
02103         BJmatrix_dims[1] = this->dim(2);
02104       }
02105     else if ( BJtensor_order == 4 )
02106       {
02107         BJmatrix_dims[0] = (this->dim(1))*(this->dim(3));
02108         BJmatrix_dims[1] = (this->dim(2))*(this->dim(4));
02109       }
02110     else
02111       {
02112         ::fprintf(stderr,"\a\n only BJtensor rank 2 and 4 #\n");
02113         ::exit(1);
02114       }
02115 
02116     BJmatrix converted(BJmatrix_dims[0], BJmatrix_dims[1], 0.0);
02117 
02118 
02119    int m41 = 0;
02120    int m42 = 0;
02121 // filling out the converted BJmatrix
02122     if ( BJtensor_order == 2 )
02123       {
02124         for ( int c22=1 ; c22<=this->dim(2) ; c22++ )
02125           for ( int c21=1 ; c21<=this->dim(1) ; c21++ )
02126             converted.val(c21,c22)=this->cval(c21,c22);
02127       }
02128     else if ( BJtensor_order == 4 )
02129       {
02130         for ( int c44=1 ; c44<=this->dim(4) ; c44++ )
02131           for ( int c43=1 ; c43<=this->dim(3) ; c43++ )
02132             for ( int c42=1 ; c42<=this->dim(2) ; c42++ )
02133               for ( int c41=1 ; c41<=this->dim(1) ; c41++ )
02134                 {
02135                   m41 = this->dim(1)*(c41-1)+c43;
02136                   m42 = this->dim(2)*(c42-1)+c44;
02137 
02138                   converted.val( m41, m42 ) = this->cval( c41, c42, c43, c44 );
02139 
02140                 }
02141       }
02142     else
02143       {
02144         ::fprintf(stderr,"\a\n only BJtensor rank 2 and 4 #\n");
02145         ::exit(1);
02146       }
02147 //    converted.print("t","\n\n converted \n");
02148     return converted;
02149   }
02150 
02151 
02152 //##############################################################################
02153 BJmatrix BJtensor::BJtensor2BJmatrix_2() const // convert BJtensor of even order to BJmatrix
02154                                 // to be used in inversion process
02155                                 // in the begining only BJtensor of
02156                                 // 2 and 4 order
02157                                 // I_ikjl scheme
02158   {
02159     int BJtensor_order = this->rank();
02160     static int BJmatrix_dims[] = {0,0};
02161 
02162     if ( BJtensor_order == 2 )
02163       {
02164         BJmatrix_dims[0] = this->dim(1);
02165         BJmatrix_dims[1] = this->dim(2);
02166       }
02167     else if ( BJtensor_order == 4 )
02168       {
02169         BJmatrix_dims[0] = (this->dim(1))*(this->dim(2));
02170         BJmatrix_dims[1] = (this->dim(3))*(this->dim(4));
02171       }
02172     else
02173       {
02174         ::fprintf(stderr,"\a\n only BJtensor rank 2 and 4 #\n");
02175         ::exit(1);
02176       }
02177 
02178     BJmatrix converted(BJmatrix_dims[0], BJmatrix_dims[1], 0.0);
02179 
02180 
02181    int m41 = 0;
02182    int m42 = 0;
02183 // filling out the converted BJmatrix
02184     if ( BJtensor_order == 2 )
02185       {
02186         for ( int c22=1 ; c22<=this->dim(2) ; c22++ )
02187           for ( int c21=1 ; c21<=this->dim(1) ; c21++ )
02188             converted.val(c21,c22)=this->cval(c21,c22);
02189       }
02190     else if ( BJtensor_order == 4 )
02191       {
02192         for ( int c44=1 ; c44<=this->dim(4) ; c44++ )
02193           for ( int c43=1 ; c43<=this->dim(3) ; c43++ )
02194             for ( int c42=1 ; c42<=this->dim(2) ; c42++ )
02195               for ( int c41=1 ; c41<=this->dim(1) ; c41++ )
02196                 {
02197                   m41 = this->dim(1)*(c41-1)+c42;
02198                   m42 = this->dim(3)*(c43-1)+c44;
02199 
02200                   converted.val( m41, m42 ) = this->cval( c41, c42, c43, c44 );
02201 
02202                 }
02203       }
02204     else
02205       {
02206         ::fprintf(stderr,"\a\n only BJtensor rank 2 and 4 #\n");
02207         ::exit(1);
02208       }
02209 
02210 //    converted.print("t","\n\n converted \n");
02211 
02212     return converted;
02213   }
02214 
02215 
02216 //~~~~//##############################################################################
02217 //~~~~BJmatrix BJtensor::BJtensor2BJmatrix_3()  // convert BJtensor of even order to BJmatrix
02218 //~~~~                                // to be used in inversion process
02219 //~~~~                                // in the begining only BJtensor of
02220 //~~~~                                // 2 and 4 order
02221 //~~~~                                // I_iljk scheme
02222 //~~~~  {
02223 //~~~~    int BJtensor_order = this->rank();
02224 //~~~~    static int BJmatrix_dims[] = {0,0};
02225 //~~~~
02226 //~~~~    if ( BJtensor_order == 2 )
02227 //~~~~      {
02228 //~~~~        BJmatrix_dims[0] = this->dim(1);
02229 //~~~~        BJmatrix_dims[1] = this->dim(2);
02230 //~~~~      }
02231 //~~~~    else if ( BJtensor_order == 4 )
02232 //~~~~      {
02233 //~~~~        BJmatrix_dims[0] = (this->dim(1))*(this->dim(4));
02234 //~~~~        BJmatrix_dims[1] = (this->dim(2))*(this->dim(3));
02235 //~~~~      }
02236 //~~~~    else
02237 //~~~~      {
02238 //~~~~        ::fprintf(stderr,"\a\n only BJtensor rank 2 and 4 #\n");
02239 //~~~~        ::exit(1);
02240 //~~~~      }
02241 //~~~~
02242 //~~~~    BJmatrix converted(BJmatrix_dims[0], BJmatrix_dims[1], 0.0);
02243 //~~~~
02244 //~~~~
02245 //~~~~   int m41 = 0;
02246 //~~~~   int m42 = 0;
02247 //~~~~// filling out the converted BJmatrix
02248 //~~~~    if ( BJtensor_order == 2 )
02249 //~~~~      {
02250 //~~~~        for ( int c22=1 ; c22<=this->dim(2) ; c22++ )
02251 //~~~~          for ( int c21=1 ; c21<=this->dim(1) ; c21++ )
02252 //~~~~            converted.val(c21,c22)=this->val(c21,c22);
02253 //~~~~      }
02254 //~~~~    else if ( BJtensor_order == 4 )
02255 //~~~~      {
02256 //~~~~        for ( int c44=1 ; c44<=this->dim(4) ; c44++ )
02257 //~~~~          for ( int c43=1 ; c43<=this->dim(3) ; c43++ )
02258 //~~~~            for ( int c42=1 ; c42<=this->dim(2) ; c42++ )
02259 //~~~~              for ( int c41=1 ; c41<=this->dim(1) ; c41++ )
02260 //~~~~                {
02261 //~~~~                  m41 = this->dim(1)*(c41-1)+c44;
02262 //~~~~                  m42 = this->dim(2)*(c42-1)+c43;
02263 //~~~~
02264 //~~~~                  converted.val( m41, m42 ) = this->val( c41, c42, c43, c44 );
02265 //~~~~
02266 //~~~~                }
02267 //~~~~      }
02268 //~~~~    else
02269 //~~~~      {
02270 //~~~~        ::fprintf(stderr,"\a\n only BJtensor rank 2 and 4 #\n");
02271 //~~~~        ::exit(1);
02272 //~~~~      }
02273 //~~~~
02274 //~~~~//    converted.print("t","\n\n converted \n");
02275 //~~~~
02276 //~~~~    return converted;
02277 //~~~~  }
02278 //~~~~
02279 //~~~~
02280 //~~~~
02281 
02282 //..//##############################################################################
02283 //..BJtensor BJtensor::inverse()  // invert BJtensor of even rank by
02284 //..                          // converting it to BJmatrix
02285 //..                          // and than inverting the BJmatrix
02286 //..                          // and at the end puting it back
02287 //..                          // again ( back conversion )
02288 //..  {
02289 //..    static int BJmatrix_dims[] = {0,0};
02290 //..    if ( this->rank() == 2 )
02291 //..      {
02292 //..        BJmatrix_dims[0] = this->dim(1);
02293 //..        BJmatrix_dims[1] = this->dim(2);
02294 //..      }
02295 //..    else if ( this->rank() == 4 )
02296 //..      {
02297 //..        BJmatrix_dims[0] = (this->dim(1))*(this->dim(2));
02298 //..        BJmatrix_dims[1] = (this->dim(3))*(this->dim(4));
02299 //..      }
02300 //..    else
02301 //..      {
02302 //..        ::fprintf(stderr,"\a\n only BJtensor rank 2 and 4 #\n");
02303 //..        ::exit(1);
02304 //..      }
02305 //..    BJmatrix converted(BJmatrix_dims[0], BJmatrix_dims[1], 0.0);
02306 //..
02307 //..   int m41 = 0;
02308 //..   int m42 = 0;
02309 //..
02310 //..// filling out the converted BJmatrix
02311 //..    if ( this->rank() == 2 )
02312 //..      {
02313 //..        for ( int c22=1 ; c22<=this->dim(2) ; c22++ )
02314 //..          for ( int c21=1 ; c21<=this->dim(1) ; c21++ )
02315 //..            converted.val(c21,c22)=this->val(c21,c22);
02316 //..      }
02317 //..    else if ( this->rank() == 4 )
02318 //..      {
02319 //..        for ( int c44=1 ; c44<=this->dim(4) ; c44++ )
02320 //..          for ( int c43=1 ; c43<=this->dim(3) ; c43++ )
02321 //..            for ( int c42=1 ; c42<=this->dim(2) ; c42++ )
02322 //..              for ( int c41=1 ; c41<=this->dim(1) ; c41++ )
02323 //..                {
02324 //..                  m41 = this->dim(1)*(c41-1)+c42;
02325 //..                  m42 = this->dim(3)*(c43-1)+c44;
02326 //..
02327 //..                  converted.val( m41, m42 ) = this->val( c41, c42, c43, c44 );
02328 //..                }
02329 //..      }
02330 //..    else
02331 //..      {
02332 //..        ::fprintf(stderr,"\a\n only BJtensor rank 2 and 4 #\n");
02333 //..        ::exit(1);
02334 //..      }
02335 //..
02336 //..//  converted.print("c","\n Converted:\n");
02337 //..  BJmatrix converted_inverse = converted.inverse();
02338 //..
02339 //..// building up a BJtensor result
02340 //..  BJtensor result(this->rank(), this->dim(), 0.0);
02341 //..
02342 //..// filling back the inverted BJmatrix to BJtensor
02343 //..    if ( this->rank() == 2 )
02344 //..      {
02345 //..        for ( int c22=1 ; c22<=this->dim(2) ; c22++ )
02346 //..          for ( int c21=1 ; c21<=this->dim(1) ; c21++ )
02347 //..            result.val(c21,c22)=converted_inverse.val(c21,c22);
02348 //..      }
02349 //..    else if ( this->rank() == 4 )
02350 //..      {
02351 //..        for ( int c44=1 ; c44<=this->dim(4) ; c44++ )
02352 //..          for ( int c43=1 ; c43<=this->dim(3) ; c43++ )
02353 //..            for ( int c42=1 ; c42<=this->dim(2) ; c42++ )
02354 //..              for ( int c41=1 ; c41<=this->dim(1) ; c41++ )
02355 //..                {
02356 //..                  m41 = this->dim(1)*(c41-1)+c42;
02357 //..                  m42 = this->dim(3)*(c43-1)+c44;
02358 //..
02359 //..                  result.val(c41,c42,c43,c44) = converted_inverse.val(m41,m42);
02360 //..                }
02361 //..      }
02362 //..//    result.print("t","back to BJtensor result");
02363 //..    return result;
02364 //..  }
02365 //..
02366 
02367 //~~~~//##############################################################################
02368 //~~~~BJtensor BJtensor::inverse_1()  // invert BJtensor of even rank by
02369 //~~~~                            // converting it to BJmatrix
02370 //~~~~                            // and than inverting the BJmatrix
02371 //~~~~                            // and at the end puting it back
02372 //~~~~                            // again ( back conversion )
02373 //~~~~                            // I_ijkl scheme
02374 //~~~~
02375 //~~~~  {
02376 //~~~~
02377 //~~~~  BJmatrix converted = this->BJtensor2BJmatrix_1();
02378 //~~~~
02379 //~~~~//  converted.print("c","\n Converted:\n");
02380 //~~~~
02381 //~~~~  BJmatrix converted_inverse = converted.inverse();
02382 //~~~~
02383 //~~~~//  converted_inverse.print("t","\n\n converted \n");
02384 //~~~~
02385 //~~~~  BJtensor result = converted_inverse.BJmatrix2BJtensor_1();
02386 //~~~~
02387 //~~~~//    result.print("t","back to BJtensor result");
02388 //~~~~
02389 //~~~~    return result;
02390 //~~~~  }
02391 
02392 
02393 //##############################################################################
02394 BJtensor BJtensor::inverse_2()  const // invert BJtensor of even rank by
02395                             // converting it to BJmatrix
02396                             // and than inverting the BJmatrix
02397                             // and at the end puting it back
02398                             // again ( back conversion )
02399                             // I_ikjl scheme
02400 
02401 {
02402 
02403   BJmatrix converted = this->BJtensor2BJmatrix_2();
02404 
02405 //  converted.print("c","\n Converted:\n");
02406 
02407   BJmatrix converted_inverse = converted.inverse();
02408 
02409 //  converted_inverse.print("t","\n\n converted_inverse \n");
02410 
02411   BJtensor result = converted_inverse.BJmatrix2BJtensor_2();
02412 
02413 //  result.print("t","back to BJtensor result");
02414 
02415   return result;
02416 }
02417 
02418 
02419 //##############################################################################
02420 BJtensor BJtensor::inverse()  const // invert BJtensor of even rank by
02421                           // converting it to BJmatrix
02422                           // and than inverting the BJmatrix
02423                           // and at the end puting it back
02424                           // again ( back conversion )
02425                           // I_ikjl scheme   TRUE ONE
02426 
02427   {
02428 
02429   int BJmatrix_or_BJtensor4 = this->rank();
02430 
02431   BJmatrix converted = this->BJtensor2BJmatrix_2();
02432 
02433   BJtensor result;
02434 
02435 //converted.print("c","\n Converted:\n");
02436 
02437   BJmatrix converted_inverse = converted.inverse();
02438 
02439 //converted_inverse.print("t","\n\n Converted_inverse \n");
02440 
02441   if ( BJmatrix_or_BJtensor4 == 4 ) 
02442     {
02443       result = converted_inverse.BJmatrix2BJtensor_2();
02444     }
02445   else if ( BJmatrix_or_BJtensor4 == 2 ) 
02446     {
02447       result = converted_inverse.BJmatrix2BJtensor_22();
02448 //result.print("r","\n\n result  = converted_inverse.BJmatrix2BJtensor_2();\n");
02449     }
02450   else 
02451     {
02452       ::fprintf(stderr,"only 2 and 4 BJtensors \n");
02453       ::exit(1);
02454     }
02455 
02456 //    result.print("t","back to BJtensor result");
02457 #ifdef SASA
02458 //***** Dodao Sasa
02459 //  result.pc_nDarray_rep->dim=this->dim();
02460 //************** Dosta prljavo ( ako se ubije treba videti da se
02461 // iskopira niz a ne pointer jer ovako moze da bude problema ako 
02462 // se unisti jedan od nizova !!!
02463 // Takodje ako su dimenzije tenzora razlicite bi ce problema
02464  if(BJmatrix_or_BJtensor4==4){
02465   result.pc_nDarray_rep->dim[0]=this->dim()[2];
02466   result.pc_nDarray_rep->dim[1]=this->dim()[3];
02467   result.pc_nDarray_rep->dim[2]=this->dim()[0];
02468   result.pc_nDarray_rep->dim[3]=this->dim()[1];
02469   }
02470  else {
02471   result.pc_nDarray_rep->dim[0]=this->dim()[1];
02472   result.pc_nDarray_rep->dim[1]=this->dim()[0];
02473   }
02474 #endif
02475 // ***************** Kraj izmena koje je dodao Sasa
02476     return result;
02477   }
02478 
02479 
02480 //~~~~//##############################################################################
02481 //~~~~BJtensor BJtensor::inverse_3()  // invert BJtensor of even rank by
02482 //~~~~                            // converting it to BJmatrix
02483 //~~~~                            // and than inverting the BJmatrix
02484 //~~~~                            // and at the end puting it back
02485 //~~~~                            // again ( back conversion )
02486 //~~~~                            // I_ilkj scheme
02487 //~~~~
02488 //~~~~  {
02489 //~~~~
02490 //~~~~  BJmatrix converted = this->BJtensor2BJmatrix_3();
02491 //~~~~
02492 //~~~~//  converted.print("c","\n Converted:\n");
02493 //~~~~
02494 //~~~~  BJmatrix converted_inverse = converted.inverse();
02495 //~~~~
02496 //~~~~//  converted_inverse.print("t","\n\n converted \n");
02497 //~~~~
02498 //~~~~  BJtensor result = converted_inverse.BJmatrix2BJtensor_3();
02499 //~~~~
02500 //~~~~//    result.print("t","back to BJtensor result");
02501 //~~~~
02502 //~~~~    return result;
02503 //~~~~  }
02504 //~~~~
02505 
02506 
02507 //.~~~~      //##############################################################################
02508 //.~~~~      // use "from" and initialize already allocated BJtensor from "from" values
02509 //.~~~~      void BJtensor::Initialize( const BJtensor & from )
02510 //.~~~~        {
02511 //.~~~~      // copy only data because everything else has already been defined
02512 //.~~~~      // WATCH OUT IT HAS TO BE DEFINED BEFORE THIS FUNCTIONS IS CALLED
02513 //.~~~~          for ( int i=0 ; i<pc_nDarray_rep->total_numb ; i++ )
02514 //.~~~~            this->pc_nDarray_rep->pd_nDdata[i] = from.pc_nDarray_rep->pd_nDdata[i] ;
02515 //.~~~~        }
02516 
02517 
02518 //##############################################################################
02519 char * BJtensor::f_indices1( void ) const
02520   {
02521     return( this->indices1 );
02522   }
02523 //##############################################################################
02524 char * BJtensor::f_indices2( void ) const
02525   {
02526     return( this->indices2 );
02527   }
02528 
02529 
02530 #endif
02531 
02532 

Generated on Mon Oct 23 15:05:24 2006 for OpenSees by doxygen 1.5.0