src/MultiSys/MultiExch0.cc
matrix Xnmp(const multi_sys& msys, int p)
  {
  ExchProc Pro = msys.ExProc(p);		// This exchange process
  double   K   = Pro.Kex();			// Process exchange rate (1/sec)
  if(K == 0) 					// We are done if there
    return matrix(msys.LS(),msys.LS(),0);	// is no exchange!

  int    comp0 = Pro.LHSComp(0);		// 0th component on lhs
  double pop0  = msys.pop(comp0);	        // population of 0th component
double pmin  = msys.popmin();			// Smallest component population
  int    dim   = msys.LS();			// Determine overall LS dim
  matrix Xp(dim, dim, 0.0);			// Start with zero superop
  double popI, popJ, kexJo;
  basis Dbs = D_basis(msys);	        	// Default basis

  vector<int> lsds  = msys.LSs();		// Array of component LS dims.
  int         ncmps = msys.NComps();		// No. of components in msys
  int cmpI, cmpJ;				// Liouville basis indices			
  int Jo=0, Jend=0;				// Global Xnmp column indices
  int Io=0, Iend=0, I;				// Global Xnmp row indices
  bool cmpIex=false, cmpJex=false;		// Flag if comps. I/J exchange
  for(cmpI=0,Io=0,Iend=0; cmpI<ncmps; cmpI++)	// Loop Xnmp row components
    {
    Iend += lsds[cmpI];				// Index at end of row block
    cmpIex = Pro.involves(cmpI);		// Flag if comp. exchanging
popI = msys.pop(cmpI);
    for(cmpJ=0,Jo=0,Jend=0; 			// Loop Xnmp colunm components
                  cmpJ<ncmps && cmpIex; cmpJ++)	// if cmpI is exchanging
      {
      Jend   += lsds[cmpJ];			// Index at column end of block
      cmpJex  = Pro.involves(cmpJ);		// Flag if comp. exchanging
      popJ    = msys.pop(cmpJ);			// Population of component 2
//if(cmpI == cmpJ) kexJo = popI*K/pmin;
//else             kexJo = popJ*K/pmin;
      kexJo   = (pop0*K)/popJ;			// Normalized exchange rate
      if(cmpI == cmpJ)				// 1) For "mutual exchange"
        {					//    only diagonal decay terms,
        for(I=Io; I<Iend; I++)			//    the <I|Xp|I> elements,
          Xp.put(kexJo, I, I); 			//    are non-zero
        Jo = Jend;				//    Set J start to next col comp.
        }
      else if(!cmpJex)				// 2) If component J does not
        { Jo = Jend; } 				//    exchange block is zero
      else if(!Pro.mixes(cmpI, cmpJ)) 		// 3) If components I & J don't
        { Jo = Jend; } 				//    exchange block is zero
      else					// 4) Components in I & J are
        {					//    exchanging
        Xnmpblk(msys, Pro, Xp, kexJo, 		//    Generate cross-terms in 
                cmpI, cmpJ, Io, Iend, Jo, Jend);//    block cmpI w/ block cmpJ
        }					//     Next column component
      Jo = Jend;				//     Start of next col comp.
      }						//     Move to next col comp.
    Io = Iend;					//   Start of next row comp.
    }						//   Move  to next row comp.
  return Xp;					// Return process exchange mx
  }
/* This function generates the non-mutual exchange superoperator matrix for a
   specified exchange process p. The calculation is performed in blocks where
   each block corresponds to two components in exchange. Square blocks about
   the diagonal is a component with itself and will be zero unless it is
   involved in the exchange.  If the latter is the case then only diagonal
   elements in the block will may be non-zero. Off-diagonal (maybe rectangular)
   blocks are for two different components in exchange. If the two components
   do not exchange in process p then the block is left empty. If they do 
   exchange the elements in the block are calculated.

   Blocks for component A & B are of dimension LSA x LSB whtere LSA is the
   Liouville space of the component spin system A. Given the base global 
   indices of each component in Liouville space, IAo and JBo respectively, the
   block of elements for A exchanging with B is show below

                     <IAo|Xp|JBo>    ------    <IAo|Xp|JBo+LSB-1>
                          |                           |
                          |                           |
                          |                           |
                 <IAo+LSA-1|Xp|JBo>  ------ <IAo+LSA-1|Xp|JBo+LSB-1>         */
This function generates the non-mutual exchange superoperator matrix for a
specified exchange process p. The calculation is performed in blocks where
each block corresponds to two components in exchange. Square blocks about
the diagonal is a component with itself and will be zero unless it is
involved in the exchange.  If the latter is the case then only diagonal
elements in the block will may be non-zero. Off-diagonal (maybe rectangular)
blocks are for two different components in exchange. If the two components
do not exchange in process p then the block is left empty. If they do
exchange the elements in the block are calculated.

Blocks for component A & B are of dimension LSA x LSB whtere LSA is the
Liouville space of the component spin system A. Given the base global
indices of each component in Liouville space, IAo and JBo respectively, the
block of elements for A exchanging with B is show below


This function generates the non - mutual exchange superoperator matrix for a specified exchange process p . The calculation is performed in blocks where each block corresponds to two components in exchange . Square blocks about the diagonal is a component with itself and will be zero unless it is involved in the exchange . If the latter is the case then only diagonal elements in the block will may be non - zero . Off - diagonal ( maybe rectangular ) blocks are for two different components in exchange . If the two components do not exchange in process p then the block is left empty . If they do exchange the elements in the block are calculated . Blocks for component A & B are of dimension LSA x LSB whtere LSA is the Liouville space of the component spin system A . Given the base global indices of each component in Liouville space IAo and JBo respectively the block of elements for A exchanging with B is show below
matrix Xnmp(const multi_sys& msys, int p)
  {
  ExchProc Pro = msys.ExProc(p);		
  double   K   = Pro.Kex();			
  if(K == 0) 					
    return matrix(msys.LS(),msys.LS(),0);	
  int    comp0 = Pro.LHSComp(0);		
  double pop0  = msys.pop(comp0);	        
double pmin  = msys.popmin();			
  int    dim   = msys.LS();			
  matrix Xp(dim, dim, 0.0);			
  double popI, popJ, kexJo;
  basis Dbs = D_basis(msys);	        	
  vector<int> lsds  = msys.LSs();		
  int         ncmps = msys.NComps();		
  int cmpI, cmpJ;				
  int Jo=0, Jend=0;				
  int Io=0, Iend=0, I;				
  bool cmpIex=false, cmpJex=false;		
  for(cmpI=0,Io=0,Iend=0; cmpI<ncmps; cmpI++)	
    {
    Iend += lsds[cmpI];				
    cmpIex = Pro.involves(cmpI);		
popI = msys.pop(cmpI);
    for(cmpJ=0,Jo=0,Jend=0; 			
                  cmpJ<ncmps && cmpIex; cmpJ++)	
      {
      Jend   += lsds[cmpJ];			
      cmpJex  = Pro.involves(cmpJ);		
      popJ    = msys.pop(cmpJ);			
      kexJo   = (pop0*K)/popJ;			
      if(cmpI == cmpJ)				
        {					
        for(I=Io; I<Iend; I++)			
          Xp.put(kexJo, I, I); 			
        Jo = Jend;				
        }
      else if(!cmpJex)				
        { Jo = Jend; } 				
      else if(!Pro.mixes(cmpI, cmpJ)) 		
        { Jo = Jend; } 				
      else					
        {					
        Xnmpblk(msys, Pro, Xp, kexJo, 		
                cmpI, cmpJ, Io, Iend, Jo, Jend);
        }					
      Jo = Jend;				
      }						
    Io = Iend;					
    }						
  return Xp;					
  }
matrix Xnmp ( const multi_sys & msys , int p ) { ExchProc Pro = msys . ExProc ( p ) ; double K = Pro . Kex ( ) ; if ( K == 0 ) return matrix ( msys . LS ( ) , msys . LS ( ) , 0 ) ; int comp0 = Pro . LHSComp ( 0 ) ; double pop0 = msys . pop ( comp0 ) ; double pmin = msys . popmin ( ) ; int dim = msys . LS ( ) ; matrix Xp ( dim , dim , 0.0 ) ; double popI , popJ , kexJo ; basis Dbs = D_basis ( msys ) ; vector < int > lsds = msys . LSs ( ) ; int ncmps = msys . NComps ( ) ; int cmpI , cmpJ ; int Jo = 0 , Jend = 0 ; int Io = 0 , Iend = 0 , I ; bool cmpIex = false , cmpJex = false ; for ( cmpI = 0 , Io = 0 , Iend = 0 ; cmpI < ncmps ; cmpI ++ ) { Iend += lsds [ cmpI ] ; cmpIex = Pro . involves ( cmpI ) ; popI = msys . pop ( cmpI ) ; for ( cmpJ = 0 , Jo = 0 , Jend = 0 ; cmpJ < ncmps && cmpIex ; cmpJ ++ ) { Jend += lsds [ cmpJ ] ; cmpJex = Pro . involves ( cmpJ ) ; popJ = msys . pop ( cmpJ ) ; kexJo = ( pop0 * K ) / popJ ; if ( cmpI == cmpJ ) { for ( I = Io ; I < Iend ; I ++ ) Xp . put ( kexJo , I , I ) ; Jo = Jend ; } else if ( ! cmpJex ) { Jo = Jend ; } else if ( ! Pro . mixes ( cmpI , cmpJ ) ) { Jo = Jend ; } else { Xnmpblk ( msys , Pro , Xp , kexJo , cmpI , cmpJ , Io , Iend , Jo , Jend ) ; } Jo = Jend ; } Io = Iend ; } return Xp ; }
This function generates the non-mutual exchange superoperator matrix for a
specified exchange process p. The calculation is performed in blocks where
each block corresponds to two components in exchange.
This function generates the non - mutual exchange superoperator matrix for a specified exchange process p . The calculation is performed in blocks where each block corresponds to two components in exchange .
// This exchange process // Process exchange rate (1/sec) // We are done if there // is no exchange! // 0th component on lhs // population of 0th component // Smallest component population // Determine overall LS dim // Start with zero superop // Default basis // Array of component LS dims. // No. of components in msys // Liouville basis indices			 // Global Xnmp column indices // Global Xnmp row indices // Flag if comps. I/J exchange // Loop Xnmp row components // Index at end of row block // Flag if comp. exchanging // Loop Xnmp colunm components // if cmpI is exchanging // Index at column end of block // Flag if comp. exchanging // Population of component 2 //if(cmpI == cmpJ) kexJo = popI*K/pmin; //else             kexJo = popJ*K/pmin; // Normalized exchange rate // 1) For "mutual exchange" //    only diagonal decay terms, //    the <I|Xp|I> elements, //    are non-zero //    Set J start to next col comp. // 2) If component J does not //    exchange block is zero // 3) If components I & J don't //    exchange block is zero // 4) Components in I & J are //    exchanging //    Generate cross-terms in  //    block cmpI w/ block cmpJ //     Next column component //     Start of next col comp. //     Move to next col comp. //   Start of next row comp. //   Move  to next row comp. // Return process exchange mx