src/expde/indices/index.cc

Go to the documentation of this file.
00001 //    expde: expression templates for partial differential equations.
00002 //    Copyright (C) 2001  Christoph Pflaum
00003 //    This program is free software; you can redistribute it and/or modify
00004 //    it under the terms of the GNU General Public License as published by
00005 //    the Free Software Foundation; either version 2 of the License, or
00006 //    (at your option) any later version.
00007 //
00008 //    This program is distributed in the hope that it will be useful,
00009 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 //    GNU General Public License for more details.
00012 //
00013 //                 SEE  Notice1.doc made by 
00014 //                 LAWRENCE LIVERMORE NATIONAL LABORATORY
00015 //
00016 
00017 // ------------------------------------------------------------
00018 // variable.cc
00019 //
00020 // ------------------------------------------------------------
00021 
00022 // Include level 0:
00023 #ifdef COMP_GNUOLD
00024  #include <iostream.h>
00025  #include <fstream.h>
00026  #include <time.h>
00027  #include <math.h>
00028 #else
00029  #include <iostream>
00030  #include <fstream>
00031  #include <ctime>
00032  #include <cmath>
00033 #endif 
00034 
00035 
00036 
00037 // Include level 0:
00038 #include "../parser.h"
00039 
00040 // Include level 1:
00041 #include "../paramete.h"
00042 #include "../abbrevi.h"
00043 #include "../math_lib/math_lib.h"
00044 
00045 // Include level 2:
00046 #include "../basic/basic.h"
00047 
00048 // Include level 3:
00049 #include "../domain/domain.h"
00050 
00051 // Include level 4:
00052 #include "../formulas/boundy.h"
00053 #include "../formulas/loc_sten.h"
00054 
00055 // Include level 5:
00056 #include "../grid/gpar.h"
00057 #include "../grid/parallel.h"
00058 #include "../grid/mgcoeff.h"
00059 #include "../grid/sto_man.h"
00060 #include "../grid/gridbase.h"
00061 #include "../grid/grid.h"
00062 #include "../grid/input.h"
00063 
00064 
00065 // Include level 5.1
00066 #include "../evpar/evpar.h"
00067 
00068 // Include level 6:
00069 #include "../extemp/variable.h"  
00070 #include "../extemp/eleme.h"
00071      
00072 // Include level 7:
00073 #include "index.h"
00074 
00075 
00077                // 1. Index_set
00078                // 2. ExpdeIndex
00079                // 3. from variable.h
00081 
00083 // 1. Index_set
00085 Index_set::Index_set(Grid* gr) {
00086   int max_size;
00087 
00088   // -1.
00089   hashtable_initialized = false;
00090   nicht_implementiert   = false;
00091 
00092   // 0. 
00093   grid = gr;
00094 
00095   // 2. construct elements
00096   used_P_interior = 0;
00097   used_P_nearb    = 0;
00098   used_P_cellpoi  = 0;
00099   used_P_Bo2p     = 0;
00100 
00101   length_P_interior =  minimal_length_P_interior;
00102   length_P_nearb    =  minimal_length_P_nearb;
00103   length_P_cellpoi  =  minimal_length_P_cellpoi;
00104   length_P_Bo2p     =  minimal_length_P_Bo2p;
00105 
00106   start_P_interior  = new P_interior*[length_P_interior];
00107   start_P_nearb     = new P_nearb*[length_P_nearb];
00108   start_P_cellpoi   = new P_cellpoi*[length_P_cellpoi];
00109   start_P_Bo2p      = new P_Bo2p*[length_P_Bo2p];
00110 
00111   size     = used_P_interior + used_P_nearb + used_P_cellpoi + used_P_Bo2p;
00112   max_size = 
00113     length_P_interior + length_P_nearb + 
00114     length_P_cellpoi  + length_P_Bo2p;
00115 
00116   // sorted numbers
00117   sorted_number = new int[max_size];
00118   sorted_number_back = new int[max_size];
00119   int ii;
00120   for(ii=0;ii<max_size;++ii) {
00121     sorted_number[ii] = ii;
00122     sorted_number_back[ii] = ii;
00123   }
00124 }
00125 
00126 
00127 
00128 Index_set::Index_set(Subgrid subgrid, Grid* gr) {
00129   int color;
00130   int lev;
00131   int run_bo;
00132   int number;
00133  
00134   // -1.
00135   hashtable_initialized = false;
00136   nicht_implementiert   = false;
00137 
00138   sorted_number = NULL;
00139 
00140   // 0. 
00141   P_interior *iter_i;
00142   P_nearb    *iter_n;
00143   P_Bo2p     *iter_b;
00144   P_cellpoi  *iter_cf;
00145 
00146 
00147   grid = gr;
00148   lev = grid->Max_level();
00149 
00150   // 1. count
00151   used_P_interior = 0;
00152   if(subgrid.run_interior()) {
00153     // innere Punkte
00154     for(color=0;color<8;++color)
00155       for(iter_i=grid->Start_P_interior(lev,color);
00156           iter_i!=NULL;iter_i=iter_i->Next()) {
00157         ++used_P_interior;
00158       }
00159   }
00160   used_P_nearb = 0;
00161   used_P_cellpoi = 0;
00162   if(subgrid.run_nearb()) {
00163     // Randzellfreiheitsgrade
00164     for(iter_cf=grid->Start_P_cellpoi(lev);
00165         iter_cf!=NULL;iter_cf=iter_cf->Next()) {
00166       ++used_P_cellpoi;
00167     }
00168     // randnahe Punkte
00169     for(color=0;color<8;++color)
00170       for(iter_n=grid->Start_P_nearb(lev,color);
00171             iter_n!=NULL;iter_n=iter_n->Next()) {
00172         ++used_P_nearb;
00173       }
00174   }
00175   used_P_Bo2p = 0;
00176   run_bo = subgrid.run_boundary();
00177   if(run_bo==true) {
00178     // Randpunkte
00179     for(color=0;color<8;++color) {
00180       for(iter_b=grid->Start_P_Bo2p(lev,color);
00181           iter_b!=NULL;iter_b=iter_b->Next()) {
00182         ++used_P_Bo2p;
00183       }
00184     }
00185   }
00186   else if(run_bo<false) {
00187     // Randpunkte
00188     for(color=0;color<8;++color)
00189       for(iter_b=grid->Start_P_Bo2p(lev,color);
00190           iter_b!=NULL;iter_b=iter_b->Next()) {
00191         if(iter_b->Give_Label(-run_bo,grid)) {
00192           ++used_P_Bo2p;
00193         }
00194       }
00195   }
00196   
00197   // 2. construct elements
00198   length_P_interior = used_P_interior;
00199   length_P_nearb    = used_P_nearb;
00200   length_P_cellpoi  = used_P_cellpoi;
00201   length_P_Bo2p     = used_P_Bo2p;
00202 
00203   if(length_P_interior < minimal_length_P_interior) 
00204     length_P_interior =  minimal_length_P_interior;
00205   if(length_P_nearb    < minimal_length_P_nearb)    
00206     length_P_nearb    =  minimal_length_P_nearb;
00207   if(length_P_cellpoi  < minimal_length_P_cellpoi)
00208     length_P_cellpoi  =  minimal_length_P_cellpoi;
00209   if(length_P_Bo2p     < minimal_length_P_Bo2p)     
00210     length_P_Bo2p     =  minimal_length_P_Bo2p;
00211 
00212   start_P_interior = new P_interior*[length_P_interior];
00213   start_P_nearb    = new P_nearb*[length_P_nearb];
00214   start_P_cellpoi  = new P_cellpoi*[length_P_cellpoi];
00215   start_P_Bo2p     = new P_Bo2p*[length_P_Bo2p];
00216 
00217 
00218   size = used_P_interior + used_P_nearb + used_P_cellpoi + used_P_Bo2p;
00219 
00220   // 3. set pointers
00221   if(subgrid.run_interior()) {
00222     number = 0;
00223     // innere Punkte
00224     for(color=0;color<8;++color)
00225       for(iter_i=grid->Start_P_interior(lev,color);
00226           iter_i!=NULL;iter_i=iter_i->Next()) {
00227         start_P_interior[number] = iter_i;
00228         ++number;
00229       }
00230   }
00231 
00232   if(subgrid.run_nearb()) {
00233     number=0;
00234     // Randzellfreiheitsgrade
00235     for(iter_cf=grid->Start_P_cellpoi(lev);
00236         iter_cf!=NULL;iter_cf=iter_cf->Next()) {
00237         start_P_cellpoi[number] = iter_cf;
00238         ++number;
00239     }
00240     number=0;
00241     // randnahe Punkte
00242     for(color=0;color<8;++color)
00243       for(iter_n=grid->Start_P_nearb(lev,color);
00244             iter_n!=NULL;iter_n=iter_n->Next()) {
00245         start_P_nearb[number] = iter_n;
00246         ++number;
00247       }
00248   }
00249 
00250   run_bo = subgrid.run_boundary();
00251   if(run_bo==true) {
00252     number = 0;
00253     // Randpunkte
00254     for(color=0;color<8;++color) {
00255       for(iter_b=grid->Start_P_Bo2p(lev,color);
00256           iter_b!=NULL;iter_b=iter_b->Next()) {
00257         start_P_Bo2p[number] = iter_b;
00258         ++number;
00259       }
00260     }
00261   }
00262   else if(run_bo<false) {
00263     number = 0;
00264     // Randpunkte
00265     for(color=0;color<8;++color)
00266       for(iter_b=grid->Start_P_Bo2p(lev,color);
00267           iter_b!=NULL;iter_b=iter_b->Next()) {
00268         if(iter_b->Give_Label(-run_bo,grid)) {
00269         start_P_Bo2p[number] = iter_b;
00270         ++number;
00271         }
00272       }
00273   }
00274 
00275   // sorted numbers
00276   sorted_number = new int[size];
00277   sorted_number_back = new int[size];
00278   int ii;
00279   for(ii=0;ii<size;++ii) {
00280     sorted_number[ii] = ii;
00281     sorted_number_back[ii] = ii;
00282   }
00283 };
00284 
00285 // for sort_planes
00286 int Index_set::integer_m(int ii,
00287                          double coordz_min, 
00288                          int num_points_z,
00289                          int zwei_po_lev) {
00290   typ_of_general_points typ;
00291   Index3D I;
00292   dir_3D d;
00293 
00294   typ = type(ii);
00295   if(typ==type_P_Bo2p) {
00296     // Bo2p
00297     d = pointer_P_Bo2p(ii)->d();
00298     if(d==Ddir) return 0;
00299     if(d==Tdir) return num_points_z-1;
00300 
00301     I = pointer_P_Bo2p(ii)->Ind();
00302     return (int)((I.coordinate_z()-coordz_min) * zwei_po_lev) + 1;
00303   }
00304   else {
00305     if(typ==type_P_interior) {
00306       // interior
00307       I = pointer_P_interior(ii)->Ind();
00308     }
00309     if(typ==type_P_nearb) {
00310       // nearb
00311       I = pointer_P_nearb(ii)->Ind();
00312     }
00313     return (int)((I.coordinate_z()-coordz_min) * zwei_po_lev) + 1;
00314   }
00315 };
00316 
00317 
00318 void Index_set::Sort_by(sorting_types sort_typ) {
00319   int m;
00320   int zwei_po_lev;
00321 
00322   Index3D I;
00323   double coordz_max, coordz_min;
00324   ExpdeIndex i;
00325   int ii;
00326   int num_points_z;
00327   int *anz_in_plane;
00328 
00329   Index1D Iz_min;
00330   Index1D Iz_max;
00331 
00332   typ_of_general_points typ;
00333   
00334   if(sort_typ != z_plane_sort) {
00335     cout << " Dieser Sortierungstyp ist in Index_set::Index_set " 
00336          << " nicht implementiert! " << endl;
00337   }
00338 
00339   zwei_po_lev = Zweipotenz(grid->Max_level());
00340 
00341   // 1. count and look for small and large index3D
00342   coordz_max = 0.0;
00343   coordz_min = 1.0;
00344  
00345   for(ii=0;ii<size;++ii) {
00346     typ = type(ii);
00347     if(typ==type_P_interior) {
00348       // interior
00349       I = pointer_P_interior(ii)->Ind();
00350     }
00351     if(typ==type_P_nearb) {
00352       // nearb
00353       I = pointer_P_nearb(ii)->Ind();
00354     }
00355     if(typ==type_P_cellpoi) {
00356       cout << " Noch nicht implementiert in diesem Index Konstruktor! "
00357            << endl;
00358     }
00359     if(typ==type_P_Bo2p) {
00360       // Bo2p
00361       I = pointer_P_Bo2p(ii)->Ind();
00362     }
00363     // maximal and minimal point in z-direction
00364     if(coordz_max < I.coordinate_z()) {
00365       Iz_max     = I.I_z();
00366       coordz_max = I.coordinate_z();
00367     }
00368     if(coordz_min > I.coordinate_z()) {
00369       Iz_min     = I.I_z();
00370       coordz_min = I.coordinate_z();
00371     }
00372   }
00373 
00374   // 3. count number of points in z direction
00375   num_points_z = (int)((coordz_max-coordz_min) *
00376                        zwei_po_lev) + 3;
00377   anz_in_plane = new int[num_points_z];
00378   for(m=0; m<num_points_z; ++m) {
00379     anz_in_plane[m] = 0;
00380   }
00381 
00382   // 4. count anz_in_plane[m]
00383   for(ii=0;ii<size;++ii) {
00384     m  = integer_m(ii,coordz_min,num_points_z,zwei_po_lev);
00385     anz_in_plane[m] = anz_in_plane[m] + 1;
00386   }
00387 
00388   for(m=1; m<num_points_z; ++m) {
00389     anz_in_plane[m] = anz_in_plane[m] + anz_in_plane[m-1];
00390   }
00391 
00392   for(m=num_points_z-1; m>0; --m) {
00393     anz_in_plane[m] = anz_in_plane[m-1];
00394   }
00395   anz_in_plane[0] = 0;
00396 
00397   /*
00398   for(m=0; m<num_points_z; ++m) {
00399     cout << " anz_in_plane[" << m << "] = " 
00400          << anz_in_plane[m] << endl;
00401   }
00402   */
00403 
00404   // 5. sorted numbers 
00405   for(ii=0;ii<size;++ii) {
00406     m  = integer_m(ii,coordz_min,num_points_z,zwei_po_lev);
00407     sorted_number[anz_in_plane[m]] = ii;
00408     sorted_number_back[ii] = anz_in_plane[m];
00409     anz_in_plane[m]++;
00410   }
00411 
00412   /*
00413   for(ii=0;ii<size;++ii) {
00414     cout << " sorted_number[" << ii << "] = " 
00415          << sorted_number[ii] << endl;
00416   }
00417   */
00418 
00419   /*
00420   int sum, sumback, sumtest;
00421   sum     = 0;
00422   sumback = 0;
00423   sumtest = 0;
00424 
00425   for(ii=0;ii<size;++ii) {
00426     sum     = sum     + sorted_number[ii];
00427     sumtest = sumtest + ii;
00428     sumback = sumback + sorted_number_back[ii];
00429   }
00430 
00431   cout << " sum: "     << sum 
00432        << " sumtest: " << sumtest 
00433        << " sumback: " << sumback << endl;
00434   */
00435 };
00436 
00437 void Index_set::initialize_hashtable() {
00438   int i;
00439 
00440   if(nicht_implementiert) 
00441     cout << " error in Index_set::initialize_hashtable() nicht implementiert"
00442          << endl;
00443 
00444   if(hashtable_initialized==false) {
00445     hashtable_initialized = true;
00446     // hashtable initialisieren
00447     hashtable_indices_leng  = 
00448       Find_next_prime(Factor_hashtable_indices_lenght*size);
00449     hashtable_indices_start = 
00450       new Point_hashtable_indices*[hashtable_indices_leng];
00451     for(i=0;i<hashtable_indices_leng;++i)
00452       hashtable_indices_start[i] = NULL;
00453     hashtable_indices_occ=0;
00454     // Werte setzen
00455     for(i=0;i<used_P_interior;++i) {
00456       Add_point(start_P_interior[i]->Ind(),6,i);
00457     }
00458     for(i=0;i<used_P_nearb;++i) {
00459       Add_point(start_P_nearb[i]->Ind(),6,i+used_P_interior);
00460     }
00461     for(i=0;i<used_P_cellpoi;++i) {
00462       Add_point(start_P_cellpoi[i]->Ind(),7,
00463                 i+used_P_interior+used_P_nearb);
00464     }
00465     for(i=0;i<used_P_Bo2p;++i) {
00466 
00467       Add_point(start_P_Bo2p[i]->Ind(),(int)start_P_Bo2p[i]->d(),
00468                 i+used_P_interior+used_P_nearb+used_P_cellpoi);
00469     }
00470   }
00471 }
00472 
00473 
00474 void Index_set::Add_point(Index3D I, int Gedir, int value) {
00475   int Nx, Ny, Nz;
00476   Nx = I.I_x().get();
00477   Ny = I.I_y().get();
00478   Nz = I.I_z().get();
00479 
00480   Point_hashtable_indices* point;
00481 
00482   point = hashtable_indices_start
00483     [hashtable_indices_function(Nx,Ny,Nz,Gedir,hashtable_indices_leng)];
00484   if(point==NULL) {
00485     hashtable_indices_occ++;
00486     point = new Point_hashtable_indices(Nx,Ny,Nz,Gedir,value);
00487     hashtable_indices_start[hashtable_indices_function(Nx,Ny,Nz,Gedir,
00488                                                    hashtable_indices_leng)] = 
00489       point;
00490   }
00491   else {
00492     while(point->next!=NULL && 
00493           (point->nx!=Nx || point->ny!=Ny || point->nz!=Nz
00494            || point->gedir!=Gedir))
00495       point = point->next;
00496     if(point->nx!=Nx || point->ny!=Ny || point->nz!=Nz
00497        || point->gedir!=Gedir) {
00498       hashtable_indices_occ++;
00499       point->next = new Point_hashtable_indices(Nx,Ny,Nz,Gedir,value);
00500     }
00501   }
00502 }
00503 
00504 
00505 int Index_set::Give_value(Index3D I, int Gedir) {
00506   int Nx, Ny, Nz;
00507   Nx = I.I_x().get();
00508   Ny = I.I_y().get();
00509   Nz = I.I_z().get();
00510 
00511   Point_hashtable_indices* point;
00512 
00513   point = 
00514     hashtable_indices_start[hashtable_indices_function(
00515                             Nx,Ny,Nz,Gedir,hashtable_indices_leng)];
00516   
00517   while(point!=NULL) {
00518     if(point->nx==Nx && point->ny==Ny && point->nz==Nz
00519        && point->gedir==Gedir) return point->wert;
00520     point = point->next;
00521   }
00522   cout << " Error in Index_set::Give_value(Index3D I, int Gedir) " << endl;
00523   return 0;      
00524 }
00525 
00526 bool Index_set::Exists_index(Index3D I, int Gedir) {
00527   int Nx, Ny, Nz;
00528   Nx = I.I_x().get();
00529   Ny = I.I_y().get();
00530   Nz = I.I_z().get();
00531 
00532   Point_hashtable_indices* point;
00533 
00534   point = 
00535     hashtable_indices_start[hashtable_indices_function(
00536                             Nx,Ny,Nz,Gedir,hashtable_indices_leng)];
00537   
00538   while(point!=NULL) {
00539     if(point->nx==Nx && point->ny==Ny && point->nz==Nz
00540        && point->gedir==Gedir) return true;
00541     point = point->next;
00542   }
00543   return false;      
00544 }
00545 
00546 
00548 // 2. ExpdeIndex
00550 
00551 ExpdeIndex::ExpdeIndex() {
00552   set = NULL;
00553   i = 0;
00554   counter = 0;
00555 }
00556 
00557 ExpdeIndex::ExpdeIndex(int co, Index_set* s) {
00558   set     = s;
00559   counter = co;
00560   i       = set->Sorted_number(counter);
00561 }
00562 
00563 
00564 void ExpdeIndex::Test_correct() {
00565   if(set == NULL) cout << " Error: set == NULL in ExpdeIndex! " << endl;
00566   else {
00567     if(i < 0) cout << " Error: i < 0 in ExpdeIndex! " << endl;
00568     if(i >= set->Size()) cout << " Error: i >= Size in ExpdeIndex! " << endl;
00569   }
00570 }
00571 
00572 int ExpdeIndex::integer(Index_set& M) {
00573   int gedir;
00574   Index3D I;
00575   typ_of_general_points typ;
00576   
00577   // 0. short cut?
00578   if(&M == set) {
00579     //    return i;
00580     return counter;
00581   }
00582   // 1. calc type 
00583   typ = set->type(i);
00584 
00585   // calc Index 3D and gedir;
00586   if(typ==type_P_interior) {
00587     I = set->pointer_P_interior(i)->Ind();
00588     gedir = 6;
00589   }
00590   else if(typ==type_P_nearb){
00591     I = set->pointer_P_nearb(i)->Ind();
00592     gedir = 6;
00593   } 
00594   else if(typ==type_P_Bo2p){
00595     I = set->pointer_P_Bo2p(i)->Ind();
00596     gedir = set->pointer_P_Bo2p(i)->d();
00597   }
00598   else if(typ==type_P_cellpoi){
00599     I = set->pointer_P_cellpoi(i)->Ind();
00600     gedir = 7;
00601   }
00602 
00603   return M.Sorted_number_back(M.Give_value(I,gedir));
00604   //  return M.Give_value(I,gedir);
00605 }
00606 
00607 
00609 // 3. from variable.h
00611 
00612 assignable_vector Variable::operator[] (ExpdeIndex& i) {
00613   return assignable_vector(i.index_set()->varM(i.i_integer()),
00614                            number_variable);
00615 }
00616 
00617 
00618 
00619 
00620 
00621 
00622 
00623 
00624 

Generated on Mon Jan 16 13:23:41 2006 for IPPL by  doxygen 1.4.6