/* * Copyright (C) 2010 Thorsten Liebig (Thorsten.Liebig@gmx.de) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "AdrOp.h" using namespace std; AdrOp::AdrOp(unsigned int muiImax, unsigned int muiJmax, unsigned int muiKmax, unsigned int muiLmax) { //error-handling... error = new ErrorMsg(9); if (error==NULL) { fprintf(stderr,"Memory allocation failed!! exiting..."); exit(1); } error->SetMsg(1,"Address Operator: Memory allocation failed!! exiting..."); error->SetMsg(2,"Address Operator: Invalid Address requested!! exiting..."); error->SetMsg(3,"Address Operator: Invalid Position set!! exiting..."); error->SetMsg(4,"Address Operator: Invalid jump or passing end of iteration!! exiting..."); error->SetMsg(5,"Address Operator: 4D not yet implemented!! exiting..."); error->SetMsg(6,"Address Operator: Position not set!! exiting..."); error->SetMsg(7,"Address Operator: Cells not added to Address Operator!! exiting..."); error->SetMsg(8,"Address Operator: Invalid Node!! exiting..."); error->SetMsg(9,"Address Operator: Grid invalid!! exiting..."); //if (muiImax<0) muiImax=0; //if (muiJmax<0) muiJmax=0; //if (muiKmax<0) muiKmax=0; //if (muiLmax<0) muiLmax=0; uiDimension=0; if (muiImax>0) uiDimension++; else exit(-1); if (muiJmax>0) uiDimension++; else exit(-2); if (muiKmax>0) uiDimension++; if ( (muiLmax>0) && (muiKmax>0) ) uiDimension++; // cout << "\n-----Address Operator created: Dimension: " << uiDimension << "----" <Error(5); iIshift=iJshift=iKshift=0; reflect=false; uiTypeOffset=0; clCellAdr=NULL; dGrid[0]=NULL; dGrid[1]=NULL; dGrid[2]=NULL; dGrid[3]=NULL; dDeltaUnit=1; bDebug=false; } AdrOp::AdrOp(AdrOp* origOP) { clCellAdr=NULL; error=NULL; // has to be done!!! uiDimension=origOP->uiDimension; uiSize=origOP->uiSize; uiImax=origOP->uiImax; uiJmax=origOP->uiJmax; uiKmax=origOP->uiKmax; uiLmax=origOP->uiLmax; uiIpos=origOP->uiIpos; uiJpos=origOP->uiJpos; uiKpos=origOP->uiKpos; uiLpos=origOP->uiLpos; for (int ii=0; ii<4; ++ii) dGrid[ii]=origOP->dGrid[ii]; dDeltaUnit=origOP->dDeltaUnit; iIshift=origOP->iIshift; iJshift=origOP->iJshift; iKshift=origOP->iKshift; for (int ii=0; ii<3; ++ii) iCellShift[ii]=origOP->iCellShift[ii]; i=origOP->i; j=origOP->j; k=origOP->k; l=origOP->l; reflect=origOP->reflect; uiTypeOffset=origOP->uiTypeOffset; bPosSet=origOP->bPosSet; bDebug=origOP->bDebug; // return; if (origOP->clCellAdr!=NULL) clCellAdr= new AdrOp(origOP->clCellAdr); } AdrOp::~AdrOp() { // cerr << "\n------Address Operator deconstructed-----\n" << endl; delete error; error=NULL; delete clCellAdr; clCellAdr=NULL; } unsigned int AdrOp::SetPos(unsigned int muiIpos, unsigned int muiJpos, unsigned int muiKpos, unsigned int muiLpos) { if (bDebug) fprintf(stderr,"AdrOp Debug:: SetPos(%d,%d,%d,%d) Max(%d,%d,%d,%d) \n",muiIpos,muiJpos,muiKpos,muiLpos,uiImax,uiJmax,uiKmax,uiLmax); bPosSet=false; if (muiIposError(3); if (muiJposError(3); if ((muiKpos>=uiKmax) && (uiDimension>2)) error->Error(3); else if (uiDimension>2) uiKpos=muiKpos; if ((muiLpos>=uiLmax) && (uiDimension>3)) error->Error(3); else if (uiDimension>3) uiLpos=muiLpos; bPosSet=true; // cerr << "Position i:" << uiIpos << " j: " << uiJpos << " k: " << uiKpos << " l: " << 0 << " MAX: i:" << uiImax << " j: " << uiJmax << " k: " << uiKmax << endl; //debug ADRESSEXPENSE(0,0,0,0,uiDimension+1,18) return GetPos(); } bool AdrOp::SetPosChecked(unsigned int muiIpos, unsigned int muiJpos, unsigned int muiKpos, unsigned int muiLpos) { bPosSet=true; if (muiIpos=uiKmax) && (uiDimension>2)) bPosSet=false; else if (uiDimension>2) uiKpos=muiKpos; if ((muiLpos>=uiLmax) && (uiDimension>3)) bPosSet=false; else if (uiDimension>3) uiLpos=muiLpos; ADRESSEXPENSE(0,0,0,0,uiDimension+1,18) return bPosSet; } void AdrOp::SetGrid(double *gridI,double *gridJ,double *gridK,double *gridL) { dGrid[0]=gridI; dGrid[1]=gridJ; dGrid[2]=gridK; dGrid[3]=gridL; ADRESSEXPENSE(0,0,0,0,4,0) } bool AdrOp::CheckPos(unsigned int muiIpos, unsigned int muiJpos, unsigned int muiKpos, unsigned int muiLpos) { bPosSet=true; if ((muiIpos>=uiImax)) bPosSet=false; if ((muiJpos>=uiJmax)) bPosSet=false; if ((muiKpos>=uiKmax) && (uiDimension>2)) bPosSet=false; if ((muiLpos>=uiLmax) && (uiDimension>3)) bPosSet=false; ADRESSEXPENSE(0,0,0,0,uiDimension+1,18) return bPosSet; } bool AdrOp::CheckRelativePos(int muiIrel,int muiJrel,int muiKrel, int muiLrel) { bPosSet=true; if ((muiIrel+(int)uiIpos<0) || (muiIrel+(int)uiIpos>=(int)uiImax)) bPosSet=false; if ((muiJrel+(int)uiJpos<0) || (muiJrel+(int)uiJpos>=(int)uiJmax)) bPosSet=false; if (((muiKrel+(int)uiKpos<0) || (muiKrel+(int)uiKpos>=(int)uiKmax)) && (uiDimension>2)) bPosSet=false; if (((muiLrel+(int)uiLpos<0) || (muiLrel+(int)uiLpos>=(int)uiLmax)) && (uiDimension>3)) bPosSet=false; ADRESSEXPENSE(2*uiDimension,0,0,0,uiDimension+1,18) return bPosSet; } unsigned int AdrOp::GetPos(int muiIrel, int muiJrel, int muiKrel, int /*muiLrel*/) { if (bPosSet==false) error->Error(6); if (reflect) { #if EXPENSE_LOG==1 if (muiIrel+(int)uiIpos<0) ADRESSEXPENSE(2,1,0,0,1,0) if (muiIrel+(int)uiIpos>(int)uiImax-1) ADRESSEXPENSE(4,1,0,0,1,0) if (muiJrel+(int)uiJpos<0) ADRESSEXPENSE(2,1,0,0,1,0) if (muiJrel+(int)uiJpos>(int)uiJmax-1) ADRESSEXPENSE(4,1,0,0,1,0) if (muiKrel+(int)uiKpos<0) ADRESSEXPENSE(2,1,0,0,1,0) if (muiKrel+(int)uiKpos>(int)uiKmax-1) ADRESSEXPENSE(4,1,0,0,1,0) #endif if (muiIrel+(int)uiIpos<0) muiIrel=-2*uiIpos-muiIrel-uiTypeOffset; if (muiIrel+(int)uiIpos>(int)uiImax-1) muiIrel=2*(uiImax-1-uiIpos)-muiIrel+uiTypeOffset; if (muiJrel+(int)uiJpos<0) muiJrel=-2*uiJpos-muiJrel-uiTypeOffset; if (muiJrel+(int)uiJpos>(int)uiJmax-1) muiJrel=2*(uiJmax-1-uiJpos)-muiJrel+uiTypeOffset; if (muiKrel+(int)uiKpos<0) muiKrel=-2*uiKpos-muiKrel-uiTypeOffset; if (muiKrel+(int)uiKpos>(int)uiKmax-1) muiKrel=2*(uiKmax-1-uiKpos)-muiKrel+uiTypeOffset; } if (uiDimension==2) { ADRESSEXPENSE(7,1,0,0,0,7) if ( (muiIrel+uiIposError(2); return 0; } else if (uiDimension==3) { ADRESSEXPENSE(9,3,0,0,0,11) if ( (muiIrel+uiIposError(2); return 0; } else return 0; } unsigned int AdrOp::GetPosFromNode(int ny, unsigned int uiNode) { while (ny<0) ny+=uiDimension; ny=ny%uiDimension; unsigned int help=uiNode,i=0,j=0,k=0,l=0; i=help%uiImax; help=help/uiImax; j=help%uiJmax; help=help/uiJmax; if (uiKmax>0) { k=help%uiKmax; help=help/uiKmax; l=help; } if (!CheckPos(i,j,k,l)) error->Error(8); ADRESSEXPENSE(0,7,0,0,13,4) switch (ny) { case 0: { return i; break; } case 1: { return j; break; } case 2: { return k; break; } case 3: { return l; break; } } return 0; } double AdrOp::GetNodeVolume(unsigned int uiNode) { for (unsigned int n=0; nError(9); double dVol=1; unsigned int uiMax[4]={uiImax,uiJmax,uiKmax,uiLmax}; unsigned int uiPos[4]={GetPosFromNode(0,uiNode),GetPosFromNode(1,uiNode),GetPosFromNode(2,uiNode),GetPosFromNode(3,uiNode)}; for (unsigned int n=0; n0) && (uiPos[n]0) && (uiPos[n]==uiMax[n]-1)) { dVol*=dDeltaUnit*(dGrid[n][uiPos[n]]-dGrid[n][uiPos[n]-1]); ADRESSEXPENSE(3,0,1,2,0,4) } } return dVol; } double AdrOp::GetIndexWidth(int ny, int index) { for (unsigned int n=0; nError(9); double width=0; while (ny<0) ny+=uiDimension; ny=ny%uiDimension; unsigned int uiMax[4]={uiImax,uiJmax,uiKmax,uiLmax}; if ((index>0) && (index<(int)uiMax[ny]-1)) width= (dGrid[ny][index+1]-dGrid[ny][index-1])/2*dDeltaUnit; else if ((index==0) && (index<(int)uiMax[ny]-1)) width=(dGrid[ny][index+1]-dGrid[ny][index])*dDeltaUnit; else if ((index>0) && (index==(int)uiMax[ny]-1)) width=(dGrid[ny][index]-dGrid[ny][index-1])*dDeltaUnit; else width= 0; return width; } double AdrOp::GetIndexCoord(int ny, int index) { for (unsigned int n=0; nError(9); while (ny<0) ny+=uiDimension; ny=ny%uiDimension; unsigned int uiMax[4]={uiImax,uiJmax,uiKmax,uiLmax}; if (index<0) index=0; if (index>=(int)uiMax[ny]) index=uiMax[ny]-1; return dGrid[ny][index]*dDeltaUnit; } double AdrOp::GetIndexDelta(int ny, int index) { if (index<0) return GetIndexCoord(ny, 0) - GetIndexCoord(ny, 1); unsigned int uiMax[4]={uiImax,uiJmax,uiKmax,uiLmax}; if (index>=(int)uiMax[ny]-1) return GetIndexCoord(ny, (int)uiMax[ny]-2) - GetIndexCoord(ny, (int)uiMax[ny]-1); return GetIndexCoord(ny, index+1) - GetIndexCoord(ny, index); } unsigned int AdrOp::Shift(int ny, int step) { if (bPosSet==false) error->Error(6); while (ny<0) ny+=uiDimension; ny=ny%uiDimension; switch (ny) { case 0: { iIshift=step; // if ((int)uiIpos+step<0) iIshift=-2*uiIpos-iIshift; // else if ((int)uiIpos+step>=(int)uiImax) iIshift=-1*iIshift+2*(uiImax-1-uiIpos); break; } case 1: { iJshift=step; // if ((int)uiJpos+iJshift<0) iJshift=-2*uiJpos-iJshift; // else if ((int)uiJpos+iJshift>=(int)uiJmax) iJshift=-1*iJshift+2*(uiJmax-1-uiJpos); break; } case 2: { iKshift=step; // if ((int)uiKpos+iKshift<0) iKshift=-2*uiKpos-iKshift; // else if ((int)uiKpos+iKshift>=(int)uiKmax) iKshift=-1*iKshift+2*(uiKmax-1-uiKpos); break; } } ADRESSEXPENSE(1,1,0,0,2,3) return GetPos(iIshift,iJshift,iKshift); } bool AdrOp::CheckShift(int ny, int step) { while (ny<0) ny+=uiDimension; ny=ny%uiDimension; int shift[3]={0,0,0}; shift[ny]=step; if (this->CheckPos(uiIpos+shift[0],uiJpos+shift[1],uiKpos+shift[2])) { this->Shift(ny,step); return true; } else return false; } unsigned int AdrOp::GetShiftedPos(int ny, int step) { if ((ny<0) || (ny>2)) return GetPos(iIshift,iJshift,iKshift); int pos[3] = {iIshift, iJshift, iKshift}; pos[ny]+=step; return GetPos(pos[0],pos[1],pos[2]); } void AdrOp::ResetShift() { iIshift=iJshift=iKshift=0; } unsigned int AdrOp::Iterate(int jump) { if (abs(jump)>=(int)uiImax) error->Error(4); i=uiIpos+jump; if (i>=uiImax) { i=i-uiImax; j=uiJpos+1; if (j>=uiJmax) { j=0; if (uiDimension==3) { k=uiKpos+1; if (k>=uiKmax) k=0; uiKpos=k; } } uiIpos=i; uiJpos=j; return GetPos(); } else { uiIpos=i; return GetPos(); } } unsigned int AdrOp::GetSize() { return uiSize; } void AdrOp::SetReflection2Node() { reflect=true; uiTypeOffset=0; } void AdrOp::SetReflection2Cell() { reflect=true; uiTypeOffset=1; } void AdrOp::SetReflectionOff() { reflect=false; } AdrOp* AdrOp::AddCellAdrOp() { if (clCellAdr!=NULL) return clCellAdr; if (uiDimension==3) clCellAdr = new AdrOp(uiImax-1,uiJmax-1,uiKmax-1); else if (uiDimension==2) clCellAdr = new AdrOp(uiImax-1,uiJmax-1); else clCellAdr=NULL; if (clCellAdr!=NULL) { clCellAdr->SetPos(0,0,0); clCellAdr->SetReflection2Cell(); } iCellShift[0]=iCellShift[1]=iCellShift[2]=0; return clCellAdr; } AdrOp* AdrOp::DeleteCellAdrOp() { delete clCellAdr; clCellAdr=NULL; return NULL; } unsigned int AdrOp::ShiftCell(int ny, int step) { if (clCellAdr==NULL) error->Error(7); while (ny<0) ny+=uiDimension; ny=ny%uiDimension; iCellShift[ny]=step; ADRESSEXPENSE(3,1,0,0,1,2) return clCellAdr->GetPos(uiIpos+iCellShift[0],uiJpos+iCellShift[1],uiKpos+iCellShift[2]); } bool AdrOp::ShiftCellCheck(int ny, int step) { return clCellAdr->CheckShift(ny,step); } void AdrOp::ResetCellShift() { if (clCellAdr==NULL) error->Error(7); iCellShift[0]=iCellShift[1]=iCellShift[2]=0; } unsigned int AdrOp::GetCellPos(bool incShift) { if (bPosSet==false) error->Error(6); if (clCellAdr==NULL) error->Error(7); #if EXPENSE_LOG==1 if (incShift) ADRESSEXPENSE(3,0,0,0,0,2) #endif if (incShift) return clCellAdr->GetPos(uiIpos+iCellShift[0],uiJpos+iCellShift[1],uiKpos+iCellShift[2]); else return clCellAdr->GetPos(uiIpos,uiJpos,uiKpos); } unsigned int AdrOp::GetCellPos(int i, int j, int k) { if (bPosSet==false) error->Error(6); return clCellAdr->GetPos(uiIpos+i,uiJpos+j,uiKpos+k); } double AdrOp::GetShiftCellVolume(int ny, int step) { for (unsigned int n=0; nError(9); int uiMax[4]={(int)uiImax-1,(int)uiJmax-1,(int)uiKmax-1,(int)uiLmax-1}; while (ny<0) ny+=uiDimension; ny=ny%uiDimension; iCellShift[ny]=step; int uiPos[4]={(int)uiIpos+iCellShift[0],(int)uiJpos+iCellShift[1],(int)uiKpos+iCellShift[2]}; double dVol=1; for (unsigned int n=0; n0) { while ((uiPos[n]<0) || (uiPos[n]>=uiMax[n])) { if (uiPos[n]<0) uiPos[n]=-1*uiPos[n]-1; else if (uiPos[n]>=uiMax[n]) uiPos[n]=uiMax[n]-(uiPos[n]-uiMax[n]+1); } dVol*=(dGrid[n][uiPos[n]+1]-dGrid[n][uiPos[n]])*dDeltaUnit; } } return dVol; } deltaAdrOp::deltaAdrOp(unsigned int max) { uiMax=max; } deltaAdrOp::~deltaAdrOp() { } void deltaAdrOp::SetMax(unsigned int max) { uiMax=max; } unsigned int deltaAdrOp::GetAdr(int pos) { if (uiMax==1) return 0; if (pos<0) pos=pos*-1; else if (pos>(int)uiMax-1) pos=2*(uiMax-1)-pos+1; if ((pos<0) || (pos>(int)uiMax-1)) { fprintf(stderr," Error exiting... "); getchar(); exit(-1); } return pos; }