Example #1
0
        public virtual object Clone()
        {
            SimulationBase sb = new SimulationBase(this.Molecules, this.LabelingPositions, this.Distances);

            sb.SimulationParameters = this.SimulationParameters;
            return(sb);
        }
        protected override void DoJob()
        {
            bool noinitalstates = InitialStates == null || InitialStates.Length == 0;
            int  nfinal         = noinitalstates ? FinalStatesPerInitialState : FinalStatesPerInitialState * InitialStates.Length;
            int  nrestarts      = noinitalstates ? FinalStatesPerInitialState :
                                  SimulationPrototype.IsContinuous ? InitialStates.Length : FinalStatesPerInitialState * InitialStates.Length;

            this.FinalStates = new SimulationResult[nfinal];

            // preparations
            int njobs = this.SimulationPrototype.IsContinuous ? Math.Min(Math.Min(this.NThreads, nfinal), InitialStates.Length) :
                        Math.Min(this.NThreads, nfinal);
            CancellationToken ctoken = cts.Token;

            SimulationBase[]          jobslocal  = new SimulationBase[njobs];
            Task <SimulationResult>[] taskslocal = new Task <SimulationResult> [njobs];
            int[] structuresdonebyjob            = new int[jobslocal.Length];
            for (int i = 0; i < jobslocal.Length; i++)
            {
                jobslocal[i] = (SimulationBase)SimulationPrototype.Clone();
            }

            // main loop
            int  currentstructure = 0;
            int  completedtaskindex;
            int  inputstructure      = 0;
            bool alltasksinitialized = false;

            try
            {
                while (this.StructuresDone < nfinal)
                {
                    // try to find a task that never ran
                    alltasksinitialized = Array.TrueForAll(taskslocal, t => t != null);
                    if (!alltasksinitialized)
                    {
                        completedtaskindex = Array.IndexOf(taskslocal, null);
                        structuresdonebyjob[completedtaskindex] = FinalStatesPerInitialState; // signal to "restart"
                    }
                    // something done, save and reuse this task
                    else
                    {
                        completedtaskindex = Task.WaitAny(taskslocal, ctoken);
                        this.FinalStates[StructuresDone++] = taskslocal[completedtaskindex].Result;
                        this.OnProgressChanged(StructuresDone, nfinal);
                        structuresdonebyjob[completedtaskindex]++;
                    }

                    // restart
                    // docking case: restart for each iteration
                    if (noinitalstates && currentstructure < nfinal)
                    {
                        taskslocal[completedtaskindex] = Task.Factory.StartNew <SimulationResult>(job =>
                        {
                            ((SimulationBase)job).SetState();
                            return(((SimulationBase)job).Simulate());
                        },
                                                                                                  jobslocal[completedtaskindex],
                                                                                                  ctoken);
                    }
                    // error estimation, refinement, or sampling: restart
                    else if ((!jobslocal[completedtaskindex].IsContinuous && currentstructure < nfinal) ||
                             (jobslocal[completedtaskindex].IsContinuous && structuresdonebyjob[completedtaskindex] == FinalStatesPerInitialState && inputstructure < InitialStates.Length))
                    {
                        inputstructure = jobslocal[completedtaskindex].IsContinuous ? inputstructure : currentstructure / FinalStatesPerInitialState;
                        taskslocal[completedtaskindex] = Task.Factory.StartNew <SimulationResult>(jobp =>
                        {
                            var jobptyped = jobp as Tuple <SimulationBase, SimulationResult>;
                            jobptyped.Item1.SetState(jobptyped.Item2);
                            return(jobptyped.Item1.Simulate());
                        },
                                                                                                  new Tuple <SimulationBase, SimulationResult>(jobslocal[completedtaskindex], InitialStates[inputstructure++]),
                                                                                                  ctoken);
                        structuresdonebyjob[completedtaskindex] = 0;
                    }
                    // sampling: continue
                    else if (jobslocal[completedtaskindex].IsContinuous && structuresdonebyjob[completedtaskindex] < FinalStatesPerInitialState)
                    {
                        taskslocal[completedtaskindex] = Task.Factory.StartNew <SimulationResult>(job => ((SimulationBase)job).Simulate(),
                                                                                                  jobslocal[completedtaskindex], ctoken);
                    }
                    // almost done, queue nothing
                    else
                    {
                        taskslocal[completedtaskindex] = new Task <SimulationResult>(() => { return(new SimulationResult()); }); // this task never starts
                    }
                    currentstructure++;
                }
            }
            finally
            {
                this.SimulationCompleted = true;
            }
        }