public void Update()
    {
        if (m_bSimulating)
        {
            switch (m_eSimType)
            {
                #region Fixed
            case ESimulateType.Fixed:
            {
                CmpShader.SetFloat("fRandomSeed", Random.Range(0.0f, 1.0f));
                CmpShader.SetInt("iLatticeStartX", Random.Range(0, m_iSiteNumber[2] - 1));
                CmpShader.SetInt("iLatticeStartY", Random.Range(0, m_iSiteNumber[2] - 1));

                CmpShader.Dispatch(m_iKernelCalcUsing, m_iSiteNumber[2] / m_iCalcDiv, m_iSiteNumber[2] / m_iCalcDiv, 1);
                CmpShader.Dispatch(m_iKernelEnergyUsing, m_iSiteNumber[2] / m_iEnergyDiv, m_iSiteNumber[2] / m_iEnergyDiv, 1);

                if ((m_iStep % m_iEnergyStep) != 0)
                {
                    //accumulate energy and calculate average
                    if (-1 != m_iKernelSumUsing)
                    {
                        CmpShader.Dispatch(m_iKernelSumUsing, m_iSiteNumber[2] / m_iSumDiv, m_iSiteNumber[2] / m_iSumDiv, 1);
                    }
                    CmpShader.Dispatch(m_iKernelGetEnergyOut, 1, 1, 1);
                }

                ++m_iStep;

                if (null != m_txStep)
                {
                    m_txStep.text = m_iStep.ToString();
                }

                if (m_iStep != 0 && (m_iStep % m_iEnergyStep) == 0)
                {
                    CmpShader.Dispatch(m_iKernelDispUsing, m_iSiteNumber[2] / m_iDispDiv, m_iSiteNumber[2] / m_iDispDiv, 1);

                    m_pFloatBuffer = new ComputeBuffer(2, 4);
                    m_pFloatBuffer.SetData(new [] { 0.0f, 0.0f });
                    CmpShader.SetBuffer(m_iKernelGetEnergyOut, "FloatDataBuffer", m_pFloatBuffer);

                    if (-1 != m_iKernelSumUsing)
                    {
                        CmpShader.Dispatch(m_iKernelSumUsing, m_iSiteNumber[2] / m_iSumDiv, m_iSiteNumber[2] / m_iSumDiv, 1);
                    }
                    CmpShader.Dispatch(m_iKernelGetEnergyOut, 1, 1, 1);
                    float[] dataOut = { 0.0f, 0.0f };
                    m_pFloatBuffer.GetData(dataOut);
                    m_lstEnergyStepList.Add(m_iStep);
                    m_lstEnergyList.Add(dataOut[1]);
                    m_lstEnergyList.Add(dataOut[0]);
                    if (null != m_pManager)
                    {
                        m_pManager.LogData(string.Format("step:{0} e:{1}", m_iStep, dataOut[0]));
                    }
                    if (null != m_txEnergy)
                    {
                        m_txEnergy.text = string.Format("Energy: {0}", dataOut[0]);
                    }

                    m_pFloatBuffer.Release();
                    m_pFloatBuffer = null;

                    CmpShader.Dispatch(m_iKernelResetEnergyHistory, 1, 1, 1);
                }

                if (m_iStopStep > 1 && 0 == (m_iStep % m_iStopStep))
                {
                    PauseSimulate();
                    if (null != m_pManager)
                    {
                        m_pManager.OnStopSimulation();
                        string sStp = "\nStep=\n{";
                        string sE   = "\nE=\n{";
                        string sEav = "\nEav=\n{";
                        for (int i = 0; i < m_lstEnergyStepList.Count; ++i)
                        {
                            sStp += m_lstEnergyStepList[i].ToString();
                            sE   += m_lstEnergyList[2 * i].ToString(CultureInfo.InvariantCulture);
                            sEav += m_lstEnergyList[2 * i + 1].ToString(CultureInfo.InvariantCulture);
                            if (i != m_lstEnergyStepList.Count - 1)
                            {
                                sStp += ",";
                                sE   += ",";
                                sEav += ",";
                            }
                            else
                            {
                                sStp += "}\n";
                                sE   += "}\n";
                                sEav += "}\n";
                            }
                        }

                        string sFileName = m_pManager.SaveTextResult(string.Format("Fixed Run at:{0}, with group:{1}\n, size:{6}**4, iteration:{2}, beta:{3}, stop step:{4}, estep:{5}\n"
                                                                                   , DateTime.Now
                                                                                   , m_sGroupName
                                                                                   , m_iIter
                                                                                   , m_fBeta
                                                                                   , m_iStopStep
                                                                                   , m_iEnergyStep
                                                                                   , m_iSiteNumber[1])
                                                                     + sStp + sE + sEav);
                        CManager.ShowMessage("Data save to:" + sFileName);
                        m_pManager.LogData("Stopped. Data save to:" + sFileName);
                    }
                }
            }
            break;
                #endregion

                #region cycle
            case ESimulateType.Cycle:
            {
                if (m_iStepNow == m_iSkipStep && 0 == m_iStableTick)
                {
                    //just enter the cycle
                    //clear energy history and set buffer
                    CmpShader.Dispatch(m_iKernelResetEnergyHistory, 1, 1, 1);
                    m_lstEnergyList.Clear();

                    //only the first time in here, will have m_iStableTick = 0
                    //all others will have m_iStableTick = 1 -> m_iStableStep
                    m_iStableTick = m_iStableStep + 1;
                }

                //we are waiting for it to stable
                if (m_iStableTick > 1)
                {
                    //if (null != m_pManager)
                    //{
                    //    m_pManager.LogData(string.Format("step:{0} stable", m_iStableStep + 2 - m_iStableTick));
                    //}
                    CmpShader.SetFloat("fRandomSeed", Random.Range(0.0f, 1.0f));

                    CmpShader.SetInt("iLatticeStartX", Random.Range(0, m_iSiteNumber[2] - 1));
                    CmpShader.SetInt("iLatticeStartY", Random.Range(0, m_iSiteNumber[2] - 1));
                    CmpShader.Dispatch(m_iKernelCalcUsing, m_iSiteNumber[2] / m_iCalcDiv, m_iSiteNumber[2] / m_iCalcDiv, 1);
                    CmpShader.Dispatch(m_iKernelEnergyUsing, m_iSiteNumber[2] / m_iEnergyDiv, m_iSiteNumber[2] / m_iEnergyDiv, 1);
                    if (-1 != m_iKernelSumUsing)
                    {
                        CmpShader.Dispatch(m_iKernelSumUsing, m_iSiteNumber[2] / m_iSumDiv, m_iSiteNumber[2] / m_iSumDiv, 1);
                    }
                    CmpShader.Dispatch(m_iKernelGetEnergyOut, 1, 1, 1);
                    --m_iStableTick;
                    break;
                }

                //now m_iStableTick = 0 or 1
                //either m_iStepNow < m_iSkipStep
                //or we finish skip
                int iStepNow = m_iStepNow >= m_iSkipStep ? (m_iStepNow - m_iSkipStep) : 0;
                //for example, totalstep = 3490, beta from 0.01 to 3.5
                //stepnow go from 0,1,...,3490,3491,3492,...,(2*3490)
                //when stepnow <= 3490, it is 0.01 + (3.49 / 3490) * stepnow
                //when stepnow > 3490, it is 2*3490 - stepnow.  for example, stepnow = 3491, it is 3490-1, stepnow = 2*3490, it is 0

                //above is give up. we now run for only grow, so iStepNow <= m_iTargetStep
                if (null != m_txStep)
                {
                    m_txStep.text = iStepNow.ToString();
                }
                float fCurrentBetaX = m_v3Beta.x + m_v3Beta.z * iStepNow;

                CmpShader.SetFloat("fBeta", fCurrentBetaX);

                CmpShader.SetFloat("fRandomSeed", Random.Range(0.0f, 1.0f));
                CmpShader.SetInt("iLatticeStartX", Random.Range(0, m_iSiteNumber[2] - 1));
                CmpShader.SetInt("iLatticeStartY", Random.Range(0, m_iSiteNumber[2] - 1));

                //Note for L = 16, m_iSiteNumber[0] = 4, m_iSiteNumber[1] = 16, m_iSiteNumber[2] =  256 for 4D(256x256 texture) and 64 for 3D(64x64 texture)
                CmpShader.Dispatch(m_iKernelCalcUsing, m_iSiteNumber[2] / m_iCalcDiv, m_iSiteNumber[2] / m_iCalcDiv, 1);
                CmpShader.Dispatch(m_iKernelDispUsing, m_iSiteNumber[2] / m_iDispDiv, m_iSiteNumber[2] / m_iDispDiv, 1);

                //when first time in here, we already run for stable
                if (m_iStepNow >= m_iSkipStep && 1 == m_iStableTick)
                {
                    CmpShader.Dispatch(m_iKernelEnergyUsing, m_iSiteNumber[2] / m_iEnergyDiv, m_iSiteNumber[2] / m_iEnergyDiv, 1);
                    m_pFloatBuffer = new ComputeBuffer(2, 4);
                    m_pFloatBuffer.SetData(new [] { 0.0f, 0.0f });
                    CmpShader.SetBuffer(m_iKernelGetEnergyOut, "FloatDataBuffer", m_pFloatBuffer);
                    if (-1 != m_iKernelSumUsing)
                    {
                        CmpShader.Dispatch(m_iKernelSumUsing, m_iSiteNumber[2] / m_iSumDiv, m_iSiteNumber[2] / m_iSumDiv, 1);
                    }
                    CmpShader.Dispatch(m_iKernelGetEnergyOut, 1, 1, 1);
                    float[] dataOut = { 0.0f, 0.0f };
                    m_pFloatBuffer.GetData(dataOut);
                    m_pFloatBuffer.Release();
                    m_pFloatBuffer = null;
                    m_lstEnergyList.Add(dataOut[1]);
                    m_lstEnergyList.Add(dataOut[0]);

                    CmpShader.Dispatch(m_iKernelResetEnergyHistory, 1, 1, 1);

                    if (null != m_pManager)
                    {
                        m_pManager.LogData(string.Format("step:{0} e:{1}", m_iStepNow, dataOut[0]));
                    }
                    m_iStableTick = m_iStableStep + 1;
                }
                else
                {
                    if (null != m_pManager)
                    {
                        m_pManager.LogData(string.Format("step:{0} skipping", m_iStepNow));
                    }
                }

                ++m_iStepNow;
                if (CheckStop())
                {
                    //return;
                }
            }
            break;
                #endregion
            }
        }
    }