Gems3k  3.1
GEMS3K standalone solver for geochemical equilibria
 All Classes Files Functions Variables Enumerations Enumerator
/Users/kulik/DevGEMS/trunk/standalone/GEMS3K/nodearray.h
Go to the documentation of this file.
00001 //-------------------------------------------------------------------
00002 // $Id: nodearray.h 760 2012-11-27 16:33:44Z dmitrieva $
00006 //
00011 //
00012 // Copyright (C) 2006-2012 S.Dmytriyeva, D.Kulik
00013 // <GEMS Development Team, mailto:gems2.support@psi.ch>
00014 //
00015 // This file is part of the GEMS3K code for thermodynamic modelling
00016 // by Gibbs energy minimization <http://gems.web.psi.ch/GEMS3K/>
00017 //
00018 // GEMS3K is free software: you can redistribute it and/or modify
00019 // it under the terms of the GNU Lesser General Public License as
00020 // published by the Free Software Foundation, either version 3 of
00021 // the License, or (at your option) any later version.
00022 
00023 // GEMS3K is distributed in the hope that it will be useful,
00024 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00025 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00026 // GNU Lesser General Public License for more details.
00027 
00028 // You should have received a copy of the GNU General Public License
00029 // along with GEMS3K code. If not, see <http://www.gnu.org/licenses/>.
00030 //-------------------------------------------------------------------
00031 //
00032 
00033 #ifndef _nodearray_h_
00034 #define _nodearray_h_
00035 
00036 #include "node.h"
00037 
00038 // These structures are needed for implementation of Random Walk and
00039 // similar particle-based transport algorithms
00040 enum  PTCODE 
00041 {
00042    DISSOLVED = 20,
00043    ADVECTIVE = 21,
00044    DIFFUSIVE = 22,
00045    COLLOID = 23
00046 };
00047 
00048 struct  LOCATION 
00049 
00050 {  double x,
00051         y,
00052         z;
00053 
00054   LOCATION():
00055    x(0.), y (0.), z(0.) {}
00056 
00057   LOCATION( float ax, float ay=0., float az=0. ):
00058      x(ax), y (ay), z(az) {}
00059 
00060   LOCATION( const LOCATION& loc ):
00061         x(loc.x), y (loc.y), z(loc.z) {}
00062 
00063 //   const LOCATION& operator= (const LOCATION& loc);
00064 //   {
00065 //      x = loc.x;
00066 //      y = loc.y;
00067 //      z = loc.z;
00068 //    }
00069 };
00070 
00071 // Definition of TNodeArray class
00072 class TNodeArray : public TNode
00073 {
00074 protected:
00075 
00076     DATABR* (*NodT0);  
00077     DATABR* (*NodT1);  
00078 
00079     long int anNodes;  
00080     long int sizeN;        
00081     long int sizeM;    
00082     long int sizeK;    
00083 
00084     LOCATION size;     
00085 
00086 
00087     LOCATION* grid;    
00088 
00089     char* tcNode;      
00090     bool* iaNode;      
00091     
00092     void allocMemory();
00093     void freeMemory();
00094 
00097    LOCATION getGrid( long int iN, long int jN, long int kN ) const;
00098 
00100    bool isLocationInNode( long int ii, long int jj, long int kk, LOCATION cxyz ) const;
00102    bool isLocationInNode( long int iNode, LOCATION cxyz ) const;
00103 
00104 public:
00105 
00106   static TNodeArray* na;   
00107 
00108 #ifndef IPMGEMPLUGIN
00109 // These calls are used only inside of GEMS-PSI GEM2MT module
00110 
00112    TNodeArray( long int nNodes, MULTI *apm );
00113 
00115    TNodeArray( long int asizeN, long int asizeM, long int asizeK, MULTI *apm );
00116 
00125   gstring PutGEM2MTFiles(  QWidget* par, long int nIV,
00126        bool bin_mode = false, bool brief_mode = false, bool with_comments = true,
00127        bool putNodT1=false, bool addMui=false );
00128 
00132    void  setNodeArray( gstring& dbr_file, long int ndx, bool binary_f );
00133 
00134 #else
00135 // Used in GEMIPM2 standalone module only
00136    TNodeArray( long int nNod );   
00137    TNodeArray( long int asizeN, long int asizeM, long int asizeK );
00139 #endif
00140 
00142    inline long int iNode( long int indN, long int indM, long int indK ) const
00143      { return  (( indK * sizeM + indM  ) * sizeN + indN);  }
00144 
00146    inline long int indN( long int ndx ) const
00147     { return  (ndx % sizeN);  }
00148 
00150    inline long int indM( long int ndx ) const
00151     {
00152            long int j = (ndx - ndx % sizeN);
00153          j /=  sizeN;
00154      return  (j % sizeM);
00155     }
00156 
00158    inline long int indK( long int ndx ) const
00159     {
00160            long int k = ndx - ndx % sizeN;
00161           k /= sizeN;
00162           k = k - k % sizeM;
00163       return  k/sizeM;
00164     }
00165 
00166     ~TNodeArray();      
00167 
00168     long int nNodes() const  
00169     { return anNodes; }
00170 
00171     long int SizeN() const  
00172     { return sizeN; }
00173 
00174     long int SizeM() const  
00175     { return sizeM; }
00176 
00177     long int SizeK() const  
00178     { return sizeK; }
00179 
00180     DATABRPTR* pNodT0() const 
00181     { return NodT0; }
00182 
00183     DATABRPTR* pNodT1() const 
00184     { return NodT1; }
00185 
00186     bool* piaNode() const 
00187     { return iaNode; }
00188     
00189     char* ptcNode() const 
00190     { return tcNode; }
00191     
00193     long int RunGEM( long int ndx, long int Mode );
00194 
00196     long int  RunGEM( long int indN, long int indM, long int indK, long int Mode )
00197     { return RunGEM( iNode( indN, indM, indK ), Mode); }
00198         // (both calls clean the work node DATABR structure)
00199 
00209     void  InitNodeArray( const char *dbrfiles_lst_name, long int *nodeTypes, bool getNodT1, bool binary_f  );
00210 
00213     void  setNodeArray( long int ndx, long int* nodeTypes  );
00214 
00216     void  checkNodeArray( long int i, long int* nodeTypes, const char*  datachbr_file );
00217 
00218    //---------------------------------------------------------
00219    // Methods for working with node arrays (access to data from DBR)
00221    double get_mPH( long int ia, long int nodex, long int PHx );
00223    double get_vPH( long int ia, long int nodex, long int PHx );
00225    double get_bPH( long int ia, long int nodex, long int PHx, long int IC );
00226 
00227 
00228    //---------------------------------------------------------
00229    // Methods for working with node arrays
00230 
00233     void CopyWorkNodeFromArray( long int ndx, long int nNodes, DATABRPTR* anyNodeArray );
00234 
00238     void MoveWorkNodeToArray( long int ndx, long int nNodes, DATABRPTR* anyNodeArray );
00239 
00244     void CopyNodeFromTo( long int ndx, long int nNodes, DATABRPTR* arr_From,
00245          DATABRPTR* arr_To );
00246 
00247     //---------------------------------------------------------
00248     // Data collection for monitoring differences
00249     // formatted writing into text file that must be already open 
00250     //
00252     void logDiffsIC( FILE* diffile, long int t, double at, long int nx, long int every_t );
00253 
00255     void logProfileAqIC( FILE* logfile, long int t, double at, long int nx, long int every_t );
00256 
00258     void logProfileTotIC( FILE* logfile, long int t, double at, long int nx, long int every_t );
00259 
00261     void logProfilePhMol( FILE* logfile, long int t, double at, long int nx, long int every_t );
00262     
00264     void logProfilePhVol( FILE* logfile, long int t, double at, long int nx, long int every_t );
00265     
00267     void logProfileAqDC( FILE* logfile, long int t, double at, long int nx, long int every_t );
00268 
00269     //---------------------------------------------------------
00270     // Working with the node grid (mainly used in Random Walk algorithms)
00271 
00274      void SetGrid( double aSize[3], double (*aGrid)[3] = 0 );
00275 
00279      long int FindNodeFromLocation( LOCATION cxyz, long int old_node = -1 ) const;
00280 
00282      void GetNodeSizes( long int ndx, LOCATION cxyz[2] );
00283 
00285      LOCATION& GetNodeLocation( long int ndx )
00286      { return grid[ndx]; }
00287 
00289      LOCATION& GetSize()
00290      { return size; }
00291 
00293      double GetNodeMass( long int ndx, char type, char tcode, unsigned char ips );
00294 
00296      void MoveParticleMass( long int ndx_from, long int ind_to, char type, char ComponentMode, 
00297                  char tcode, unsigned char ips, double m_v );
00298 
00300      void databr_to_vtk( fstream& ff, const char*name, double time, long cycle,
00301                                long int nFields=0, long int (*Flds)[2]=0);
00302 
00303 };
00304 
00305 //IC node data access macroses
00306 #define node0_bIC( nodex, ICx ) (TNodeArray::na->pNodT0()[(nodex)]->bIC[(ICx)])
00307 #define node1_bIC( nodex, ICx ) (TNodeArray::na->pNodT1()[(nodex)]->bIC[(ICx)])
00308 #define node0_rMB( nodex, ICx ) (TNodeArray::na->pNodT0()[(nodex)]->rMB[(ICx)])
00309 #define node1_rMB( nodex, ICx ) (TNodeArray::na->pNodT1()[(nodex)]->rMB[(ICx)])
00310 #define node0_uIC( nodex, ICx ) (TNodeArray::na->pNodT0()[(nodex)]->uIC[(ICx)])
00311 #define node1_uIC( nodex, ICx ) (TNodeArray::na->pNodT1()[(nodex)]->uIC[(ICx)])
00312 
00313 //DC node data access macroses
00314 
00315   // amount of DC with index DCx from T0 node with index nodex
00316 #define node0_xDC( nodex, DCx ) (TNodeArray::na->pNodT0()[(nodex)]->xDC[(DCx)])
00317   // amount of DC with index DCx from T1 node with index nodex
00318 #define node1_xDC( nodex, DCx ) (TNodeArray::na->pNodT1()[(nodex)]->xDC[(DCx)])
00319 
00320   // activity coefficient of DC with index DCx from T0 node with index nodex
00321 #define node0_gam( nodex, DCx ) (TNodeArray::na->pNodT0()[(nodex)]->gam[(DCx)])
00322   // activity coefficient of DC with index DCx from T1 node with index nodex
00323 #define node1_gam( nodex, DCx ) (TNodeArray::na->pNodT1()[(nodex)]->gam[(DCx)])
00324 
00325   // upper constraint on amount of DC with index DCx from T0 node with index nodex
00326 #define node0_dul( nodex, DCx ) (TNodeArray::na->pNodT0()[(nodex)]->dul[(DCx)])
00327   // upper constraint on amount of DC with index DCx from T1 node with index nodex
00328 #define node1_dul( nodex, DCx ) (TNodeArray::na->pNodT1()[(nodex)]->dul[(DCx)])
00329 
00330   // lower constraint on amount of DC with index DCx from T0 node with index nodex
00331 #define node0_dll( nodex, DCx ) (TNodeArray::na->pNodT0()[(nodex)]->dll[(DCx)])
00332   // lower constraint on amount of DC with index DCx from T1 node with index nodex
00333 #define node1_dll( nodex, DCx ) (TNodeArray::na->pNodT1()[(nodex)]->dll[(DCx)])
00334 
00335 //Phase node data access macroses
00336   // amount of phase with index PHx from T0 node with index nodex
00337 #define node0_xPH( nodex, PHx ) (TNodeArray::na->pNodT0()[(nodex)]->xPH[(PHx)])
00338   // amount of phase with index PHx from T1 node with index nodex
00339 #define node1_xPH( nodex, PHx ) (TNodeArray::na->pNodT1()[(nodex)]->xPH[(PHx)])
00340 
00341   // volume of multicomponent phase with index PHx from T0 node with index nodex
00342 #define node0_vPS( nodex, PHx ) (TNodeArray::na->pNodT0()[(nodex)]->vPS[(PHx)])
00343   // volume of multicomponent phase with index PHx from T1 node with index nodex
00344 #define node1_vPS( nodex, PHx ) (TNodeArray::na->pNodT1()[(nodex)]->vPS[(PHx)])
00345 
00346   // volume of single-component phase with index PHx from T0 node with index nodex
00347 #define node0_vPH( nodex, PHx ) (TNodeArray::na->get_vPH( 0, (nodex), (PHx)))
00348   // volume of single-component phase with index PHx from T1 node with index nodex
00349 #define node1_vPH( nodex, PHx ) (TNodeArray::na->get_vPH( 1, (nodex), (PHx)))
00350 
00351   // mass of multicomponent phase with index PHx from T0 node with index nodex
00352 #define node0_mPS( nodex, PHx ) (TNodeArray::na->pNodT0()[(nodex)]->mPS[(PHx)])
00353   // mass of multicomponent phase with index PHx from T1 node with index nodex
00354 #define node1_mPS( nodex, PHx ) (TNodeArray::na->pNodT1()[(nodex)]->mPS[(PHx)])
00355 
00356   // mass of single-component phase with index PHx from T0 node with index nodex
00357 #define node0_mPH( nodex, PHx )  (TNodeArray::na->get_mPH( 0, (nodex), (PHx)))
00358   // mass of single-component phase with index PHx from T1 node with index nodex
00359 #define node1_mPH( nodex, PHx )  (TNodeArray::na->get_mPH( 1, (nodex), (PHx)))
00360 
00361 
00362   // amount of solvent/sorbent in phase with index PHx from T0 node with index nodex
00363 #define node0_xPA( nodex, PHx ) (TNodeArray::na->pNodT0()[(nodex)]->xPA[(PHx)])
00364   // amount of solvent/sorbent in phase with index PHx from T1 node with index nodex
00365 #define node1_xPA( nodex, PHx ) (TNodeArray::na->pNodT1()[(nodex)]->xPA[(PHx)])
00366 
00367 // equilibrium bulk composition of solid part of the system, moles from T0 node
00368 #define node0_bSP( nodex, ICx ) (TNodeArray::na->pNodT0()[(nodex)]->bSP[(ICx)])
00369 // equilibrium bulk composition of solid part of the system, moles from T1 node
00370 #define node1_bSP( nodex, ICx ) (TNodeArray::na->pNodT1()[(nodex)]->bSP[(ICx)])
00371 
00372 
00373 // Phase compositions node data access macroses
00374 // amount of independent component ICx in multi-component phase PHx in T0 node nodex
00375 #define node0_bPS( nodex, PHx, ICx ) ( TNodeArray::na->pNodT0()[(nodex)]->bPS[ \
00376                                        (PHx)*TNodeArray::na->pCSD()->nICb+(ICx)])
00377 // amount of independent component ICx in multi-component phase PHx in T1 node nodex
00378 #define node1_bPS( nodex, PHx, ICx ) ( TNodeArray::na->pNodT1()[(nodex)]->bPS[ \
00379                                        (PHx)*TNodeArray::na->pCSD()->nICb+(ICx)])
00380 
00381 // amount of independent component ICx in single-component phase PHx in T0 node nodex
00382 #define node0_bPH( nodex, PHx, ICx )  (TNodeArray::na->get_bPH( 0, (nodex), (PHx), (ICx)))
00383 // amount of independent component ICx in single-component phase PHx in T1 node nodex
00384 #define node1_bPH( nodex, PHx, ICx )  (TNodeArray::na->get_bPH( 1, (nodex), (PHx), (ICx)))
00385 
00386 #endif   // _nodearray_h_
00387 
00388 // end nodearray.h