static int bloch (realtype t, N_Vector y, N_Vector ydot, void *pWorld) {

	World*   pW        = (World*) pWorld;
	BMAux*   m_bmaux   = (BMAux*) pW->auxiliary;

	int      m_nprops  = pW->m_noofspinprops;
	int      m_ncomp   = pW->m_noofspincompartments;
	int 	 m_ncoprops = (m_nprops - 4) / m_ncomp;
	double*  m_exrates = m_bmaux->exrates;
	bool     m_single  = m_bmaux->single;

    // Magnetisation for each poosl
	double*   Mxy    = new double [m_ncomp];
	double*   phi    = new double [m_ncomp];
	double*   Mz     = new double [m_ncomp];
	double*   s      = new double [m_ncomp];
	double*   c      = new double [m_ncomp];
	double*   Mx     = new double [m_ncomp];
	double*   My     = new double [m_ncomp];
	double*   Mx_dot = new double [m_ncomp];
	double*   My_dot = new double [m_ncomp];
	double*   Mz_dot = new double [m_ncomp];

    for (int i = 0; i < m_ncomp; i++) {

    	Mx_dot[i] = 0.0;
    	My_dot[i] = 0.0;
		Mz_dot[i] = 0.0;
		Mxy   [i] = 0.0;
		phi   [i] = 0.0;
		Mx    [i] = 0.0;
		My    [i] = 0.0;
		Mz    [i] = 0.0;
		s     [i] = 0.0;
		c     [i] = 0.0;

    }

    //get current B-field values from the sequence
    if (t<=0.0 || t>pW->pAtom->GetDuration()) {		// Kaveh, hier hab ich gemogelt

    	// this case can happen when searching for step size; in this area no solution is needed
    	// -> set ydot to any defined value.
    	for(int i = 0; i< m_ncomp*NEQ; i+=NEQ) {
    		NV_Ith_S(ydot,XC+i) = 0.0; NV_Ith_S(ydot,YC+i) = 0.0; NV_Ith_S(ydot,ZC+i) = 0.0;
		}

    	return 0;
    }

    double  d_SeqVal[5] = {0.0,0.0,0.0,0.0,0.0};                           // [B1magn,B1phase,Gx,Gy,Gz]
    pW->pAtom->GetValue( d_SeqVal, t );                                    // calculates also pW->NonLinGradField
    if (pW->pStaticAtom != NULL) pW->pStaticAtom->GetValue( d_SeqVal, t ); // calculates also pW->NonLinGradField
    double Bx=0.0, By=0.0, Bz=0.0;
    double* BzPool = new double[m_ncomp];

    //RF field
    Bx = d_SeqVal[RF_AMP]*cos(d_SeqVal[RF_PHS]);
    By = d_SeqVal[RF_AMP]*sin(d_SeqVal[RF_PHS]);


    //Gradient field
    Bz = pW->Values[XC]*d_SeqVal[GRAD_X]+ pW->Values[YC]*d_SeqVal[GRAD_Y]+ pW->Values[ZC]*d_SeqVal[GRAD_Z];

    //other off-resonance contributions (differs for every pool)
    for(int i = 0; i< m_ncomp; i++)
    	BzPool[i] = Bz + pW->Values[i*m_ncoprops+DB] + pW->ConcomitantField(&d_SeqVal[GRAD_X]) + pW->NonLinGradField;


    //NV_Ith_S is the solution magn. vector with components AMPL,PHASE,ZC
    //important: restrict phase to [0, 2*PI]
    int pool =0;
   /* for(int i = 0; i< m_ncomp*NEQ; i+=NEQ){		// loop over pools
    	NV_Ith_S(y,PHASE+i) 				= fmod(NV_Ith_S(y,PHASE+i),6.28318530717958);
    	Mxy[pool] = NV_Ith_S(y,AMPL+i); phi[pool] = NV_Ith_S(y,PHASE+i); Mz[pool] = NV_Ith_S(y,ZC+i);
    	pool++;
    }*/

    for (int i = 0; i< m_ncomp*NEQ; i+=NEQ) {		// loop over pools

       	Mx[pool] = NV_Ith_S(y,XC+i); 
		My[pool] = NV_Ith_S(y,YC+i); 
		Mz[pool] = NV_Ith_S(y,ZC+i);
       	pool++;

    }

    pool = 0;
    
	for (int eqpool = 0; eqpool< ((m_ncomp)*NEQ); eqpool+=NEQ) {		// loop over pools, NEQ steps

    	//avoid CVODE warnings (does not change physics!)
    	if (pW->Values[pool*m_ncoprops + M0] == 0.0) {
    		// this pool is empty, the number of pools reduces
    		NV_Ith_S(y,XC+eqpool)    = 0.0; NV_Ith_S(y,YC+eqpool)    = 0.0;
    		NV_Ith_S(ydot,XC+eqpool) = 0.0; NV_Ith_S(ydot,YC+eqpool) = 0.0;
			NV_Ith_S(y,ZC+eqpool)    = 0.0;
    		NV_Ith_S(ydot,ZC+eqpool) = 0.0;

			
    	} else if ((Mx[pool]*Mx[pool] + My[pool]*My[pool]) < ATOL1 * pW->Values[pool*m_ncoprops+M0] && d_SeqVal[RF_AMP]<BEPS) {
        	//trivial case: no transv. magnetisation AND no excitation
    		NV_Ith_S(y,XC+eqpool)    = 0.0; NV_Ith_S(y,YC+eqpool)    = 0.0;
    		NV_Ith_S(ydot,XC+eqpool) = 0.0; NV_Ith_S(ydot,YC+eqpool) = 0.0;

    		//further, longit. magnetisation already fully relaxed
    		if (fabs(pW->Values[pool*m_ncoprops +M0] - Mz[pool])<ATOL3  *pW->Values[pool*m_ncoprops +M0]) {

    			NV_Ith_S(y,ZC+eqpool)    = pW->Values[pool*m_ncoprops +M0];
    			NV_Ith_S(ydot,ZC+eqpool) = 0.0;

    			if(eqpool == (((m_ncomp)*NEQ)-1))
					return 0;

    		}

    	} else {

    		//compute cartesian components of transverse magnetization

    		/*c[pool] 	= cos(phi[pool]);
    		s[pool] 	= sin(phi[pool]);


    		Mx[pool] 	= c[pool]*Mxy[pool];
    		My[pool] 	= s[pool]*Mxy[pool];*/


    		// Built the n-pool bloch equation, check if each pool exists

    		if (m_ncomp > 1 ){  // do this only if really necessary - time consuming!
    			if (m_single == false) {
    				Mx_dot[pool] = -(pW->Values[pool*m_ncoprops +R2] + exchangeConstants(m_ncomp,pool,m_exrates)) *Mx[pool] 		+ BzPool[pool]*My[pool]    - By*Mz[pool] + exchangeTerms(m_ncomp,pool,m_exrates,Mx);
    				My_dot[pool] = - BzPool[pool]*Mx[pool]  - (pW->Values[pool*m_ncoprops +R2]+exchangeConstants(m_ncomp,pool,m_exrates)) *My[pool]  		   + Bx*Mz[pool] + exchangeTerms(m_ncomp,pool,m_exrates,My);
    				Mz_dot[pool] =   By*Mx[pool]            	 																	   - Bx*My[pool] ;
    			} else {
       				Mx_dot[pool] = -(pW->Values[pool*m_ncoprops +R2]) *Mx[pool] 		+ BzPool[pool]*My[pool]    - By*Mz[pool];
        			My_dot[pool] = - BzPool[pool]*Mx[pool]  - (pW->Values[pool*m_ncoprops +R2]) *My[pool]  	   + Bx*Mz[pool];
        			Mz_dot[pool] =   By*Mx[pool]            	 										   - Bx*My[pool] ;
    			}
    		} else {
    			// use single pool model, much faster
    			Mx_dot[pool] = - pW->Values[pool*m_ncoprops +R2] *Mx[pool] 		+ BzPool[pool]*My[pool]    - By*Mz[pool];
				My_dot[pool] = - BzPool[pool]*Mx[pool]  - pW->Values[pool*m_ncoprops +R2] *My[pool]  		   + Bx*Mz[pool];
				Mz_dot[pool] =   By*Mx[pool]              	 										   - Bx*My[pool] ;
    		}

    		//compute bloch equations old version
    		//      Mx_dot = -pW->Values[R2]*Mx + Bz*My                                              - By*Mz;
    		//      My_dot = -Bz*Mx             - pW->Values[R2]*My                                  + Bx*Mz;
    		//      Mz_dot =  By*Mx             - Bx*My ;

    		//compute derivatives in cylindrical coordinates

    		//NV_Ith_S(ydot,AMPL+eqpool)   = c[pool]*Mx_dot[pool] + s[pool]*My_dot[pool];
    		//NV_Ith_S(ydot,PHASE+eqpool)  = (c[pool]*My_dot[pool] - s[pool]*Mx_dot[pool]) / (Mxy[pool]>BEPS?Mxy[pool]:BEPS); //avoid division by zero
    		NV_Ith_S(ydot,XC+eqpool)  = Mx_dot[pool];
    		NV_Ith_S(ydot,YC+eqpool)  = My_dot[pool];


    	}

    	//longitudinal relaxation
		if (m_ncomp > 1){
			if(m_single == false){
				Mz_dot[pool] 			 +=  pW->Values[pool*m_ncoprops +R1]*(pW->Values[pool*m_ncoprops +M0] - Mz[pool]) - exchangeConstants(m_ncomp,pool,m_exrates)*Mz[pool] + exchangeTerms(m_ncomp,pool,m_exrates,Mz);
			} else{
				Mz_dot[pool] 			 +=  pW->Values[pool*m_ncoprops +R1]*(pW->Values[pool*m_ncoprops +M0] - Mz[pool]);
			}
		} else
			Mz_dot[pool] 			 	 +=  pW->Values[pool*m_ncoprops +R1]*(pW->Values[pool*m_ncoprops +M0] - Mz[pool]);


		NV_Ith_S(ydot,ZC+eqpool) = Mz_dot[pool];

		pool++;
    }

	// Kaveh, hier stehen noch unterschiedliche Zahlen in den verschiedenen Pools
	//cout<<NV_Ith_S(ydot,ZC+0) << "  " <<NV_Ith_S(ydot,ZC+3) 		<<endl;

	delete [] Mxy;
	delete [] phi;
	delete [] Mz;
	delete [] s;
	delete [] c;
	delete [] Mx;
	delete [] My;
	delete [] Mx_dot;
	delete [] My_dot;
	delete [] Mz_dot;
	delete [] BzPool;

    return 0;

}