/// <summary> /// Raises the InterationCompleted event. /// </summary> /// <param name="e"></param> protected virtual void OnInterationCompleted(IterationCompletedEventArgs e) { Trace.Assert(e != null); if (IterationCompleted != null) { IterationCompleted(this, e); } }
//////////////////////////////////////////////////////////////////////////////// #region Public Methods /// <summary> /// Computes one frame of the reaction. /// </summary> /// <returns>An array containing the reaction products for the next frame. </returns> public unsafe double[, ,] ComputeReaction() { Debug.Assert(CheckInvariant(), "ComputeReaction: CheckInvariant failed"); double Xa; double Xb; double Xc; double c; double d; double f; double g0; double feedbackFromC; double feedbackFromB; iteration++; // If boundary conditions have changed since the previous frame, update them. if (this._boundaryConditionsPrev != this._boundaryConditions) { this.SetBoundaryConditions(this._boundaryConditions); this._boundaryConditionsPrev = this._boundaryConditions; } // Copy boundary values to the out buffer. for (int i = 0; i < vesselWidth; i++) { reactionOut[indexA, i, 0] = reaction[indexA, i, 0]; reactionOut[indexB, i, 0] = reaction[indexB, i, 0]; reactionOut[indexC, i, 0] = reaction[indexC, i, 0]; reactionOut[indexA, i, vesselHeight - 1] = reaction[indexA, i, vesselHeight - 1]; reactionOut[indexB, i, vesselHeight - 1] = reaction[indexB, i, vesselHeight - 1]; reactionOut[indexC, i, vesselHeight - 1] = reaction[indexC, i, vesselHeight - 1]; } for (int j = 0; j < vesselHeight; j++) { reactionOut[indexA, 0, j] = reaction[indexA, 0, j]; reactionOut[indexB, 0, j] = reaction[indexB, 0, j]; reactionOut[indexC, 0, j] = reaction[indexC, 0, j]; reactionOut[indexA, vesselWidth - 1, j] = reaction[indexA, vesselWidth - 1, j]; reactionOut[indexB, vesselWidth - 1, j] = reaction[indexB, vesselWidth - 1, j]; reactionOut[indexC, vesselWidth - 1, j] = reaction[indexC, vesselWidth - 1, j]; } // Traverse the grid and compute concentrations for // all three reactants. This implements the Gontar model. for (int i = 1; i < vesselWidth - 1; i++) { for (int j = 1; j < vesselHeight - 1; j++) { try { // Compute concentrations at cell (i,j). feedbackFromC = Math.Exp(-W1 / weight(indexC, i, j)); feedbackFromB = Math.Exp(-W2 * weight(indexB, i, j)); g0 = (K1 * K2 * feedbackFromC * feedbackFromB) / (1.0 + K1 * feedbackFromC); // Compute concentrations at cell (i,j). //c = -W1 / weight(2, i, j); //f = -W2 * weight(1, i, j); //e_to_c = Math.Exp(c); //e_to_f = Math.Exp(f); //d = 1.0 + K1 * e_to_c; //g0 = (K1 * K2 * e_to_c * e_to_f) / d; Xc = b * (g0 / (g0 + 1)); if (Xc <= minConcentration) { Xc = minConcentration; } Xb = (K1 * feedbackFromC / (1 + K1 * feedbackFromC)) * (b - Xc); if (Xb <= minConcentration) { Xb = minConcentration; } Xa = b - Xb - Xc; if (Xa <= minConcentration) { Xa = minConcentration; } if (Xa > b) { Xa = b; } if (Xb > b) { Xb = b; } if (Xc > b) { Xc = b; } reactionOut[indexA, i, j] = Xa; reactionOut[indexB, i, j] = Xb; reactionOut[indexC, i, j] = Xc; } catch (Exception ex) { Console.WriteLine("caught exception: ", ex.ToString()); } } } int ubi = reaction.GetUpperBound(1) + 1; int ubj = reaction.GetUpperBound(2) + 1; // Copy the out buffer to the in buffer. fixed(double *pOutBuff = reactionOut, pInBuff = reaction) { uint buffSize = (uint)(3 * ubi * ubj * sizeof(double)); uint count = buffSize; double *ps = pOutBuff; double *pd = pInBuff; lock (reactionOut.SyncRoot) { try { CopyMemory((void *)pd, (void *)ps, count); } catch (Exception ex) { Trace.WriteLine(ex.Message); } } } // Raise the IterationCompleted event. IterationCompletedEventArgs e = new IterationCompletedEventArgs(this.iteration); OnInterationCompleted(e); return(reactionOut); }