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 } } }