private bool listenToKeepRunning() { //watch the user cancel the process if (GH_Document.IsEscapeKeyDown()) { if (MessageBox.Show("Do you want to stop the process?\nSo far " + Count.ToString() + " out of " + this._selectedCounts.ToString() + " iterations are done!", "Stop?", MessageBoxButtons.YesNo) == DialogResult.Yes) { // cancel the process by user input! return(false); } } //watch the file to stop if (!string.IsNullOrEmpty(_watchFilePath)) { if (!File.Exists(_watchFilePath)) { // watch file was deleted by user return(false); } } return(true); }
protected override void SolveInstance(IGH_DataAccess DA) { //Declare Variables Point3d startingPoint = new Point3d(0, 0, 0); List <Point3d> interests = new List <Point3d>(); List <Mesh> obstacles = new List <Mesh>(); double distance = 0; int viewDist = 30; int viewAngle = 180; Mesh obsMesh = new Mesh(); double targetradius = 1.1; double walkingdist = 1; //Attach inputs DA.GetData(0, ref startingPoint); DA.GetDataList(1, interests); DA.GetDataList(2, obstacles); DA.GetData(3, ref distance); DA.GetData(4, ref viewAngle); DA.GetData(5, ref viewDist); // Join obstacles in one Mesh foreach (Mesh mesh in obstacles) { obsMesh.Append(mesh); } //Starting //Create Person Person firstperson = new Person(startingPoint, interests); //While loop (Moving) while (firstperson.TravedledDist < distance) { //Check if ESC is pressed and if true, Abort if (GH_Document.IsEscapeKeyDown()) { GH_Document GHDocument = OnPingDocument(); GHDocument.RequestAbortSolution(); } //Find Target PointCloud interestcloud = new PointCloud(firstperson.Interests); Boolean targetisinterest = true; //Check if any interests are left if (interestcloud.Count < 1) { //If no interest left, move along Y axis firstperson.UpdateTarget(firstperson.Position + new Point3d(0, walkingdist, 0)); targetisinterest = false; break; } while (true) { //Find closets point int intindex = interestcloud.ClosestPoint(firstperson.Position); if (firstperson.Position.DistanceTo(interestcloud[intindex].Location) > viewDist) { //If closets point is not within viewdist, move along Y axis firstperson.UpdateTarget(firstperson.Position + new Point3d(0, walkingdist, 0)); targetisinterest = false; break; } //Check for within fieldview if (viewAngle < Rhino.RhinoMath.ToDegrees(Vector3d.VectorAngle(firstperson.Facing, new Vector3d(interestcloud[intindex].X - firstperson.Position.X, interestcloud[intindex].Y - firstperson.Position.Y, interestcloud[intindex].Z - firstperson.Position.Z)))) { //If the interest is not in view remove interest from interestcloud interestcloud.RemoveAt(intindex); continue; } //Check for view collision Ray3d visibleRay = new Ray3d(firstperson.Position, new Vector3d(interestcloud[intindex].X - firstperson.Position.X, interestcloud[intindex].Y - firstperson.Position.Y, interestcloud[intindex].Z - firstperson.Position.Z)); double RayT = Rhino.Geometry.Intersect.Intersection.MeshRay(obsMesh, visibleRay); if (RayT > 0) { //If there is no direct view remove interest from interestcloud interestcloud.RemoveAt(intindex); continue; } else { firstperson.UpdateTarget(interestcloud[intindex].Location); break; } } //Check if arrived at Target if (firstperson.Position.DistanceTo(firstperson.CurrentTarget) < targetradius & targetisinterest == true) { firstperson.removeinterest(); continue; } //Move in direction Vector3d direction = new Vector3d(firstperson.CurrentTarget.X - firstperson.Position.X, firstperson.CurrentTarget.Y - firstperson.Position.Y, firstperson.CurrentTarget.Z - firstperson.Position.Z); direction.Unitize(); direction = Rhino.Geometry.Vector3d.Multiply(direction, walkingdist); Point3d newpos = firstperson.Position + direction; Boolean update = firstperson.UpdatePos(newpos, direction); DA.SetData(0, firstperson.Position); DA.SetData(1, firstperson.Facing); //System.Timers.Timer timer = new System.Timers.Timer(1000); } DA.SetDataList(2, firstperson.Path); }
private void OnSolutionEnd(object sender, GH_SolutionEventArgs e) { // Unregister the event, we don't want to get called again. e.Document.SolutionEnd -= OnSolutionEnd; // If we're not supposed to run, abort now. if (!_run) { return; } // If we're already running, abort now. if (_running) { return; } // Reset run and running states. _run = false; _running = true; try { // Find the Guid for connected slides List <System.Guid> guids = new List <System.Guid>(); //empty list for guids GH.Kernel.IGH_Param selSlidersInput = this.Params.Input[0]; //ref for input where sliders are connected to this component IList <GH.Kernel.IGH_Param> sources = selSlidersInput.Sources; //list of things connected on this input bool isAnythingConnected = sources.Any(); //is there actually anything connected? // Find connected GH.Kernel.IGH_Param trigger = this.Params.Input[2].Sources[0]; //ref for input where a boolean or a button is connected GH.Kernel.Special.GH_BooleanToggle boolTrigger = trigger as GH.Kernel.Special.GH_BooleanToggle; if (isAnythingConnected) { //if something's connected, foreach (var source in sources) //for each of these connected things: { IGH_DocumentObject component = source.Attributes.GetTopLevel.DocObject; //for this connected thing, bring it into the code in a way where we can access its properties GH.Kernel.Special.GH_NumberSlider mySlider = component as GH.Kernel.Special.GH_NumberSlider; //...then cast (?) it as a slider if (mySlider == null) //of course, if the thing isn't a slider, the cast doesn't work, so we get null. let's filter out the nulls { continue; } guids.Add(mySlider.InstanceGuid); //things left over are sliders and are connected to our input. save this guid. //we now have a list of guids of sliders connected to our input, saved in list var 'mySlider' } } // Find all sliders. List <GH.Kernel.Special.GH_NumberSlider> sliders = new List <GH.Kernel.Special.GH_NumberSlider>(); foreach (IGH_DocumentObject docObject in doc.Objects) { GH.Kernel.Special.GH_NumberSlider slider = docObject as GH.Kernel.Special.GH_NumberSlider; if (slider != null) { // check if the slider is in the selected list if (isAnythingConnected) { if (guids.Contains(slider.InstanceGuid)) { sliders.Add(slider); } } else { sliders.Add(slider); } } } if (sliders.Count == 0) { System.Windows.Forms.MessageBox.Show("No sliders could be found", "<harsh buzzing sound>", MessageBoxButtons.OK); return; } //we now have all sliders //ask the user to give a sanity check int counter = 0; int totalLoops = 1; string popupMessage = ""; // create progress bar by dots and | string pb = ".................................................."; //50 of "." - There should be a better way to create this in C# > 50 * "." does it in Python! char[] pbChars = pb.ToCharArray(); int dummyCounter = 0; foreach (GH.Kernel.Special.GH_NumberSlider slider in sliders) { totalLoops *= (sliderSteps[dummyCounter] + 1); popupMessage += slider.ImpliedNickName; popupMessage += "\n"; dummyCounter++; } if (System.Windows.Forms.MessageBox.Show(sliders.Count + " slider(s) connected:\n" + popupMessage + "\n" + totalLoops.ToString() + " iterations will be done. Continue?" + "\n\n (Press ESC to pause during progressing!)", "Start?", MessageBoxButtons.YesNo) == DialogResult.No) { SetBooleanToFalse(boolTrigger); this.Message = "Release the Colibri!"; //wipe out colibri variables and compute a new solution sliderNames = new List <string>(); sliderSteps = new List <int>(); sliderStepsPositions = new Dictionary <int, int>(); computedValues = new List <string>(); e.Document.NewSolution(false); Rhino.RhinoDoc.ActiveDoc.Views.Redraw(); return; } // Set all sliders back to first tick foreach (GH.Kernel.Special.GH_NumberSlider slider in sliders) { slider.TickValue = 0; } //start a stopwatch System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew(); // Start a giant loop in which we'll permutate our way across all slider layouts. while (true) { int idx = 0; // let the user cancel the process if (GH_Document.IsEscapeKeyDown()) { if (System.Windows.Forms.MessageBox.Show("Do you want to stop the process?\nSo far " + counter.ToString() + " out of " + totalLoops.ToString() + " iterations are done!", "Stop?", MessageBoxButtons.YesNo) == DialogResult.Yes) { // cancel the process by user input! SetBooleanToFalse(boolTrigger); this.Message += "\nCanceled by user! :|"; return; } } //add the current slider values to our list of already computed values var sliderVals = GetSliderVals(sliders); if (!computedValues.Contains(sliderVals)) { computedValues.Add(sliderVals); } //move to the next set of slider positions if (!MoveToNextPermutation(ref idx, sliders)) { // study is over! SetBooleanToFalse(boolTrigger); sw.Stop(); //stop start watch UpdateProgressBar(counter, totalLoops, sw, pbChars); this.Message += "\nFinished at " + DateTime.Now.ToShortTimeString(); //wipe out colibri variables sliderNames = new List <string>(); sliderSteps = new List <int>(); sliderStepsPositions = new Dictionary <int, int>(); computedValues = new List <string>(); e.Document.NewSolution(false); Rhino.RhinoDoc.ActiveDoc.Views.Redraw(); break; } // We've just got a new valid permutation. Solve the new solution. counter++; e.Document.NewSolution(false); Rhino.RhinoDoc.ActiveDoc.Views.Redraw(); UpdateProgressBar(counter, totalLoops, sw, pbChars); } } catch { // "something went wrong!"; } finally { // Always make sure that _running is switched off. _running = false; } }
object RunPermutations(int[] lengths, GH_BooleanToggle boolTrigger, List <GH_NumberSlider> sliders, GH_SolutionEventArgs e, params object[] objs) { // create progress bar by dots and | string pb = ".................................................."; //50 of "." - There should be a better way to create this in C# > 50 * "." does it in Python! char[] pbChars = pb.ToCharArray(); Stopwatch sw = Stopwatch.StartNew(); int counter = 0; foreach (int[] idxs in new IterateNDArray(lengths)) { // let the user cancel the process if (GH_Document.IsEscapeKeyDown()) { if (System.Windows.Forms.MessageBox.Show("Do you want to stop the process?\nSo far " + counter.ToString() + " out of " + totalLoops.ToString() + " iterations are done!", "Stop?", MessageBoxButtons.YesNo) == DialogResult.Yes) { // cancel the process by user input! SetBooleanToFalse(boolTrigger); this.Message += "\nCanceled by user! :|"; return(null); } } for (int i = 0; i < sliders.Count; i++) { GH_NumberSlider slider = sliders[i]; //look up the current slider's current sliderStepsPosition and target number int totalNumberOfSteps = sliderSteps[i]; int steps = slider.TickCount / sliderSteps[i]; slider.TickValue = steps * idxs[i]; //int numTicksToAddAsInt = slider.TickCount / totalNumberOfSteps; //double numTicksToAddAsDouble = (double)slider.TickCount / (double)totalNumberOfSteps; ////find the closest tick //int closestTick = 0; //if (currentSliderStepsPosition + numTicksToAddAsInt >= sliderMidStep) //{ // closestTick = (int)Math.Ceiling(numTicksToAddAsDouble * currentSliderStepsPosition); //} //else //{ // closestTick = (int)Math.Floor(numTicksToAddAsDouble * currentSliderStepsPosition); //} // Increment the slider. } // We've just got a new valid permutation. Solve the new solution. counter++; e.Document.NewSolution(false); Rhino.RhinoDoc.ActiveDoc.Views.Redraw(); UpdateProgressBar(counter, totalLoops, sw, pbChars); } // study is over! SetBooleanToFalse(boolTrigger); sw.Stop(); //stop start watch UpdateProgressBar(counter, totalLoops, sw, pbChars); this.Message += "\nFinished at " + DateTime.Now.ToShortTimeString(); //wipe out colibri variables sliderNames = new List <string>(); sliderSteps = new int[sliderNames.Count]; sliderStepsPositions = new int[sliderNames.Count]; computedValues = new List <string>(); e.Document.NewSolution(false); Rhino.RhinoDoc.ActiveDoc.Views.Redraw(); return(null); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { if (GH_Document.IsEscapeKeyDown()) { GH_Document GHDocument = OnPingDocument(); GHDocument.RequestAbortSolution(); return; } ikvm.runtime.Startup.addBootClassPathAssemby(Assembly.Load("culebra")); ikvm.runtime.Startup.addBootClassPathAssemby(Assembly.Load("IKVM.OpenJDK.Core")); bool reset = new bool(); int iterations = new int(); List <object> init_Settings = new List <object>(); List <object> move_Settings = new List <object>(); IGH_VisualData visual_Settings = null; object behavioral_Settings = null; if (!DA.GetDataList(0, init_Settings) || init_Settings.Count == 0 || init_Settings == null) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No Init Settings Detected, please connect Init Settings to enable the component"); return; } if (!DA.GetDataList(1, move_Settings) || move_Settings.Count == 0 || move_Settings == null) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No Move Settings Detected, please connect Move Settings to enable the component"); return; } if (!DA.GetData(3, ref visual_Settings) || visual_Settings == null) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No Visual Settings Detected, please connect Visual Settings to enable the component"); return; } if (!DA.GetData(4, ref iterations)) { return; } if (!DA.GetData(5, ref reset)) { return; } Random rnd = new Random(); if (!DA.GetData(2, ref behavioral_Settings) || behavioral_Settings == null) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Input Object is Null"); return; } string objtype = behavioral_Settings.GetType().Name.ToString(); if (!(behavioral_Settings.GetType() == typeof(IGH_BehaviorData))) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "You did not input a Behavior Data Object, please ensure input is Behavior Data Object and not " + objtype); return; } else { #region Initialize / Data Parse //------------------------Init Settings-------------------------- if (init_Settings.Count != 0) { String init_Convert = ""; if (init_Settings[0].GetType() == typeof(GH_String)) { GH_String value = (GH_String)init_Settings[0]; init_Convert = value.Value; } if (init_Convert == "Box") { this.spawnData = "box"; GH_Convert.ToBox_Primary(init_Settings[3], ref this.box); GH_Convert.ToInt32(init_Settings[4], out this.spawnType, GH_Conversion.Primary); GH_Convert.ToInt32(init_Settings[5], out this.pointCount, GH_Conversion.Primary); GH_Convert.ToInt32(init_Settings[1], out this.dimensions, GH_Conversion.Primary); } else if (init_Convert == "Points") { this.spawnData = "Points"; var wrapperToGoo = GH_Convert.ToGoo(init_Settings[3]); wrapperToGoo.CastTo <List <Point3d> >(out this.ptList); GH_Convert.ToInt32(init_Settings[1], out this.dimensions, GH_Conversion.Primary); GH_Convert.ToBox_Primary(init_Settings[4], ref this.box); } GH_Convert.ToInt32(init_Settings[2], out this.bounds, GH_Conversion.Primary); } //------------------------Move Settings-------------------------- Vector3d initialVector = new Vector3d(); if (move_Settings.Count != 0) { if (move_Settings[0].GetType() == typeof(GH_Vector)) { GH_Vector value = (GH_Vector)move_Settings[0]; initialVector = value.Value; } else if (move_Settings[0].GetType() == typeof(GH_Number)) { GH_Number value = (GH_Number)move_Settings[0]; this.initialSpeed = value.Value; } GH_Convert.ToDouble(move_Settings[1], out this.maxSpeed, GH_Conversion.Primary); GH_Convert.ToDouble(move_Settings[2], out this.maxForce, GH_Conversion.Primary); GH_Convert.ToDouble(move_Settings[3], out this.velMultiplier, GH_Conversion.Primary); } //------------------------Visual Settings-------------------------- TrailData td = visual_Settings.Value.trailData; ColorData cd = visual_Settings.Value.colorData; this.trail = td.createTrail; this.displayMode = visual_Settings.Value.displayMode; this.trailStep = td.trailStep; this.maxTrailSize = td.maxTrailSize; this.particleTexture = cd.particleTexture; this.graphicType = cd.colorDataType; this.useTexture = visual_Settings.Value.useTexture; if (cd.colorDataType == "Gradient") { this.maxthick = cd.maxThickness; this.minthick = cd.minThickness; this.redValues[0] = cd.redChannel[0]; this.redValues[1] = cd.redChannel[1]; this.greenValues[0] = cd.greenChannel[0]; this.greenValues[1] = cd.greenChannel[1]; this.blueValues[0] = cd.blueChannel[0]; this.blueValues[1] = cd.blueChannel[1]; } else if (cd.colorDataType == "GraphicPolyline") { this.polylineColor = cd.color; this.dotted = cd.dotted; this.maxthick = cd.maxThickness; } else if (cd.colorDataType == "Disco") { this.maxthick = cd.maxThickness; this.minthick = cd.minThickness; } else if (cd.colorDataType == "Base") { this.maxthick = 3; this.minthick = 1; } //----------------------------------------------------------------- IGH_PreviewObject comp = (IGH_PreviewObject)this; if (comp.Hidden && (this.displayMode == 0)) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Component preview must be enabled to see Graphic Mode on Canvas, right click on component and set preview on"); } #endregion #region Pre Simulation Code //------------------------RESET STARTS HERE-------------------------- if (reset) { //We are using the reset to reinitialize all the variables and positions //----------------------------------------------------------------- this.bb = new BoundingBox(); int loopCount = new int(); bool create = new bool(); if (this.spawnData == "box") { this.bb = this.box.BoundingBox; loopCount = this.pointCount; create = true; } else if (this.spawnData == "Points") { loopCount = this.ptList.Count; create = false; this.bb = this.box.BoundingBox; } //----------------------------------------------------------------- this.moveList = new List <Vector3d>(); this.startList = new List <Vector3d>(); this.creepList = new List <CulebraObject>(); this.currentPosList = new List <Point3d>(); this.networkList = new List <Line>(); flattenedTrails = new List <Vector3d>(); for (int i = 0; i < loopCount; i++) { if (this.dimensions == 0) { //If we want 2D General.setViewport("Top", "Shaded"); if (create) { //If are creating random points inside bbox if (this.spawnType == 0 || this.spawnType == 2) { this.startPos = new Vector3d((int)bb.Min[0], rnd.Next((int)bb.Min[1], (int)bb.Max[1]), 0); //spawn along the y axis of the bounding area } else if (this.spawnType == 1 || this.spawnType == 3) { this.startPos = new Vector3d(rnd.Next((int)bb.Min[0], (int)bb.Max[0]), rnd.Next((int)bb.Min[1], (int)bb.Max[1]), 0); //spawn randomly inside the bounding area } if (initialVector.Length > 0) { this.moveVec = initialVector; //move in the user specified direction } else { this.moveVec = new Vector3d(rnd.Next(-1, 2) * initialSpeed, rnd.Next(-1, 2) * initialSpeed, 0); //move randomly in any direction 2d } } else { //If we are using user defined points this.startPos = (Vector3d)this.ptList[i]; if (initialVector.Length > 0) { this.moveVec = initialVector; //move in the user specified direction } else { this.moveVec = new Vector3d(rnd.Next(-1, 2) * initialSpeed, rnd.Next(-1, 2) * initialSpeed, 0); //move randomly in any direction 2d } } this.creep = new Creeper(this.startPos, this.moveVec, true, false); this.creepList.Add(this.creep); } else { //If we want 3D General.setViewport("Perspective", "Shaded"); if (create) { //If are creating random points inside bbox if (this.spawnType == 0 || this.spawnType == 2) { this.startPos = new Vector3d(rnd.Next((int)bb.Min[0], (int)bb.Max[0]), rnd.Next((int)bb.Min[1], (int)bb.Max[1]), (int)bb.Min[2]); //start randomly on the lowest plane of the 3d bounds if (initialVector.Length > 0) { this.moveVec = initialVector; //move in the user specified direction } else { this.moveVec = new Vector3d(rnd.Next(-2, 2) * initialSpeed, rnd.Next(-2, 2) * initialSpeed, 1 * initialSpeed); //move randomly in the xy axis and up in the z axis } } else if (this.spawnType == 1 || this.spawnType == 3) { this.startPos = new Vector3d(rnd.Next((int)bb.Min[0], (int)bb.Max[0]), rnd.Next((int)bb.Min[1], (int)bb.Max[1]), rnd.Next((int)bb.Min[2], (int)bb.Max[2])); //start randomly inside the 3d bounds if (initialVector.Length > 0) { this.moveVec = initialVector; //move in the user specified direction } else { this.moveVec = new Vector3d(rnd.Next(-2, 2) * initialSpeed, rnd.Next(-2, 2) * initialSpeed, rnd.Next(-2, 2) * initialSpeed); //move randomly in any direction 3d } } } else { //If we are using user defined points this.startPos = (Vector3d)this.ptList[i]; if (initialVector.Length > 0) { this.moveVec = initialVector; //move in the user specified direction } else { this.moveVec = new Vector3d(rnd.Next(-2, 2) * initialSpeed, rnd.Next(-2, 2) * initialSpeed, rnd.Next(-2, 2) * initialSpeed); //move randomly in any direction 3d } } this.creep = new Creeper(this.startPos, this.moveVec, true, true); this.creepList.Add(this.creep); } this.startList.Add(this.startPos); //add the initial starting positions to the list to pass once we start running this.moveList.Add(this.moveVec); //add the initial move vectors to the list to pass once we start running } #endregion #region Simulation Code this.trailTree = new DataTree <Point3d>(); this.globalEngine = new Engine_Global(); for (int z = 0; z < iterations; z++) { this.particleSet = new DataTree <Point3d>(); this.currentPosList = new List <Point3d>(); this.trailTree.Clear(); this.networkTree.Clear(); this.trailTree.TrimExcess(); this.networkTree.TrimExcess(); if (this.moveList == null) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Please Reset the CreepyCrawlers Component"); return; } try { globalEngine.Action(this.creepList, this.dimensions, behavioral_Settings, this.displayMode, this.networkList, this.maxSpeed, this.maxForce, this.velMultiplier, this.flattenedTrails, this.particleList, this.particleSet, networkTree, trailStep, maxTrailSize, bounds, bb, currentPosList, trail, trailTree); } catch (Exception e) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.Message.ToString()); return; } this.flattenedTrails.Clear(); this.flattenedTrails.TrimExcess(); #endregion } DA.SetDataList(0, this.currentPosList); DA.SetDataTree(2, networkTree); if (this.displayMode == 1 && this.trail) { DA.SetDataTree(1, trailTree); } } } }
protected void AutoFrameCompute(int inputFrame) { this.OnPingDocument().SolutionEnd -= ends; int Delay = (int)Math.Pow(10, DelayLog); this.PercentStr = ""; this.RemainStr = ""; GH_Document.GH_ScheduleDelegate callback = new GH_Document.GH_ScheduleDelegate(this.ScheduleCallback); if (this.Play) { if (GH_Document.IsEscapeKeyDown()) { this.Play = false; this.ExpireSolution(true); this.AutoFrame = -1; this.RightFrame = inputFrame; } if (AutoFrame == -1) { watchtime = Stopwatch.StartNew(); StartFrame = inputFrame; this.AutoFrame = StartFrame; this.RightFrame = AutoFrame; this.OnPingDocument().ScheduleSolution(Delay, callback); this.OnPingDocument().SolutionEnd += ends; } else { this.RightFrame = AutoFrame; if (this.AutoFrame <= this.MaxFrame) { double remain = ((watchtime.Elapsed.TotalSeconds) / (double)(AutoFrame - StartFrame + 1)) * (double)(this.MaxFrame - AutoFrame); double percent = (double)(AutoFrame - StartFrame) / (double)(this.MaxFrame - StartFrame) * 100; PercentStr = percent.ToString("f0") + "% "; RemainStr = remain.ToString("f2") + "s Left"; AutoFrame++; this.OnPingDocument().ScheduleSolution(Delay, callback); this.OnPingDocument().SolutionEnd += ends; } else { PercentStr = "Finished! "; RemainStr = "TotalTime: " + watchtime.Elapsed.TotalSeconds.ToString("f2") + "s"; watchtime = null; this.Play = false; this.AutoFrame = -1; this.RightFrame = inputFrame; this.OnPingDocument().SolutionEnd += ends; } } } else { this.RightFrame = inputFrame; AutoFrame = -1; watchtime = null; this.OnPingDocument().ScheduleSolution(0, callback); } this.RightTime = this.KeyTimes[this.RightFrame]; }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { string filepath; Domain omega; FluidSolver ffd; DataExtractor de; double t; bool resetFFD; // current filepath filepath = Path.GetDirectoryName(this.OnPingDocument().FilePath); string residualstxt = filepath + @"\\residual.txt"; // ********************************************************************************* // Inputs // ********************************************************************************* List <double> xyzsize = new List <double>(); if (!DA.GetDataList(0, xyzsize)) { return; } ; List <int> Nxyz = new List <int>(); if (!DA.GetDataList(1, Nxyz)) { return; } ; int Nx = Nxyz[0]; int Ny = Nxyz[1]; int Nz = Nxyz[2]; List <double[]> geom = new List <double[]>(); if (!DA.GetDataList(2, geom)) { return; } ; // time step double dt = 0.1; if (!DA.GetData(3, ref dt)) { return; } // horizon double t_end = 1; if (!DA.GetData(4, ref t_end)) { return; } // wind speed double Vmet = 10; if (!DA.GetData(5, ref Vmet)) { return; } //terrain type int terrain = 0; if (!DA.GetData(6, ref terrain)) { return; } bool run = false; if (!DA.GetData(7, ref run)) { return; } //List<Mesh> mshCp = new List<Mesh>(); //DA.GetDataList(10, mshCp); bool writeresults = false; DA.GetData(8, ref writeresults); bool writeVTK = false; DA.GetData(9, ref writeVTK); //DA.GetData(10, ref resetFFD); bool calcres = false; DA.GetData(12, ref calcres); int m = 10; DA.GetData(13, ref m); string strparam = null; DA.GetData(11, ref strparam); string[] str_params = null; if (strparam != null) { str_params = strparam.Split(';'); } double nu = 1.511e-5; // increase viscosity to impose turbulence. the higher velocity, the higher visc., 1e-3 FluidSolver.solver_struct solver_params = new FluidSolver.solver_struct(); double z0; if (str_params != null) { nu = Convert.ToDouble(str_params[0]); solver_params.tol = Convert.ToDouble(str_params[1]); solver_params.min_iter = Convert.ToInt16(str_params[2]); solver_params.max_iter = Convert.ToInt16(str_params[3]); solver_params.backtrace_order = Convert.ToInt16(str_params[4]); solver_params.mass_correction = str_params[5].Equals("false") ? false : true; solver_params.mass_corr_alpha = Convert.ToDouble(str_params[6]); solver_params.verbose = str_params[7].Equals("false") ? false : true; z0 = Convert.ToDouble(str_params[8]); } else { solver_params.tol = 1e-4; solver_params.min_iter = 1; solver_params.max_iter = 30; solver_params.backtrace_order = 2; solver_params.mass_correction = false; solver_params.mass_corr_alpha = 0.7; solver_params.verbose = false; z0 = 0.1; } // ********************************************************************************* // Set-up FFD Solver // ********************************************************************************* // Set initial velocity conditions double[,,] u0 = new double[Nx + 1, Ny + 2, Nz + 2]; double[,,] v0 = new double[Nx + 2, Ny + 1, Nz + 2]; double[,,] w0 = new double[Nx + 2, Ny + 2, Nz + 1]; // Create empty arrays for body forces double[,,] f_x = new double[Nx + 1, Ny + 2, Nz + 2]; double[,,] f_y = new double[Nx + 2, Ny + 1, Nz + 2]; double[,,] f_z = new double[Nx + 2, Ny + 2, Nz + 1]; // Create FFD solver and domain //if (ffd == null || resetFFD) //{ if (terrain == 4) { omega = new WindInflowOpenFoam(Nx + 2, Ny + 2, Nz + 2, xyzsize[0], xyzsize[1], xyzsize[2], Vmet, z0); } else { omega = new WindInflow(Nx + 2, Ny + 2, Nz + 2, xyzsize[0], xyzsize[1], xyzsize[2], Vmet, terrain); } foreach (double[] geo in geom) { omega.add_obstacle(geo[0], geo[1], geo[2], geo[3], geo[4], geo[5]); } ffd = new FluidSolver(omega, dt, nu, u0, v0, w0, solver_params); de = new DataExtractor(omega, ffd); t = 0; PostProcessor pp = new PostProcessor(ffd, omega); //if (resetFFD) resetFFD = false; //reset FFD solver and domain Rhino.RhinoApp.WriteLine("GRASSHOPPER FFD Air Flow Simulation."); Rhino.RhinoApp.WriteLine("GH Plug-in: https://github.com/christophwaibel/GH_Wind"); Rhino.RhinoApp.WriteLine("FFD Solver: https://github.com/lukasbystricky/GSoC_FFD"); Rhino.RhinoApp.WriteLine("________________________________________________________"); Rhino.RhinoApp.WriteLine("...Domain initialized"); Rhino.RhinoApp.WriteLine("________________________________________________________"); //} // ******************************************************************************************* // Run each time GH is updated // ******************************************************************************************* //run solver. the solving-loop (new timestep) is executed in Grasshopper with a timer-component. //!!!!!!!!!!!!!!! CHANGE if (run) { if (writeVTK) { pp.export_geometry_vtk(filepath + @"\\vtk_geometry.vtk", 0); } int counter = 0; int timestep = 0; FluidSolver[] ffd_old = new FluidSolver[m]; if (calcres) { File.AppendAllText(residualstxt, "pmin; pmax; pavg; umin; umax; uavg; vmin; vmax; vavg; wmin; wmax; wavg;\n"); } # region whileloop while (t < t_end) { if (GH_Document.IsEscapeKeyDown()) { Rhino.RhinoApp.WriteLine("Cancelled by user"); GH_Document GHDocument = OnPingDocument(); GHDocument.RequestAbortSolution(); break; } Rhino.RhinoApp.WriteLine(Convert.ToString(t) + " of " + Convert.ToString(t_end)); double[,,] p_t2 = new double[ffd.p.GetLength(0), ffd.p.GetLength(1), ffd.p.GetLength(2)]; Array.Copy(ffd.p, 0, p_t2, 0, ffd.p.Length); double[,,] u_t2 = new double[ffd.u.GetLength(0), ffd.u.GetLength(1), ffd.u.GetLength(2)]; Array.Copy(ffd.u, 0, u_t2, 0, ffd.u.Length); double[,,] v_t2 = new double[ffd.v.GetLength(0), ffd.v.GetLength(1), ffd.v.GetLength(2)]; Array.Copy(ffd.v, 0, v_t2, 0, ffd.v.Length); double[,,] w_t2 = new double[ffd.w.GetLength(0), ffd.w.GetLength(1), ffd.w.GetLength(2)]; Array.Copy(ffd.w, 0, w_t2, 0, ffd.w.Length); ffd.time_step(f_x, f_y, f_z); if (t > dt && calcres) { double[] p_residuals; double[,,] p_t1 = ffd.p; FastFluidSolverMT.Utilities.calculate_residuals(p_t1, p_t2, out p_residuals); Rhino.RhinoApp.WriteLine("p residuals: {0};{1};{2}", p_residuals[0], p_residuals[1], p_residuals[2]); double[] u_residuals; double[,,] u_t1 = ffd.u; FastFluidSolverMT.Utilities.calculate_residuals(u_t1, u_t2, out u_residuals); Rhino.RhinoApp.WriteLine("u residuals: {0};{1};{2}", u_residuals[0], u_residuals[1], u_residuals[2]); double[] v_residuals; double[,,] v_t1 = ffd.v; FastFluidSolverMT.Utilities.calculate_residuals(v_t1, v_t2, out v_residuals); Rhino.RhinoApp.WriteLine("v residuals: {0};{1};{2}", v_residuals[0], v_residuals[1], v_residuals[2]); double[] w_residuals; double[,,] w_t1 = ffd.w; FastFluidSolverMT.Utilities.calculate_residuals(w_t1, w_t2, out w_residuals); Rhino.RhinoApp.WriteLine("w residuals: {0};{1};{2}", w_residuals[0], w_residuals[1], w_residuals[2]); File.AppendAllText(residualstxt, Convert.ToString(p_residuals[0]) + ";" + Convert.ToString(p_residuals[1]) + ";" + Convert.ToString(p_residuals[2]) + ";" + Convert.ToString(u_residuals[0]) + ";" + Convert.ToString(u_residuals[1]) + ";" + Convert.ToString(u_residuals[2]) + ";" + Convert.ToString(v_residuals[0]) + ";" + Convert.ToString(v_residuals[1]) + ";" + Convert.ToString(v_residuals[2]) + ";" + Convert.ToString(w_residuals[0]) + ";" + Convert.ToString(w_residuals[1]) + ";" + Convert.ToString(w_residuals[2]) + "\n"); } if (t >= t_end - m * dt) { ffd_old[counter] = new FluidSolver(ffd); counter++; } if (writeVTK) { pp.export_data_vtk(filepath + @"\\vtk_" + timestep + ".vtk", t, false); } t += dt; timestep++; } #endregion whileloop //averaging results FluidSolver ffd_mean = new FluidSolver(ffd); ffd_mean.p = new double[ffd.p.GetLength(0), ffd.p.GetLength(1), ffd.p.GetLength(2)]; ffd_mean.u = new double[ffd.u.GetLength(0), ffd.u.GetLength(1), ffd.u.GetLength(2)]; ffd_mean.v = new double[ffd.v.GetLength(0), ffd.v.GetLength(1), ffd.v.GetLength(2)]; ffd_mean.w = new double[ffd.w.GetLength(0), ffd.w.GetLength(1), ffd.w.GetLength(2)]; for (int i = 0; i < ffd_mean.p.GetLength(0); i++) { for (int j = 0; j < ffd_mean.p.GetLength(1); j++) { for (int k = 0; k < ffd_mean.p.GetLength(2); k++) { for (int u = 0; u < counter; u++) { ffd_mean.p[i, j, k] += ffd_old[u].p[i, j, k]; } ffd_mean.p[i, j, k] /= counter; } } } for (int i = 0; i < ffd_mean.u.GetLength(0); i++) { for (int j = 0; j < ffd_mean.u.GetLength(1); j++) { for (int k = 0; k < ffd_mean.u.GetLength(2); k++) { for (int u = 0; u < counter; u++) { ffd_mean.u[i, j, k] += ffd_old[u].u[i, j, k]; } ffd_mean.u[i, j, k] /= counter; } } } for (int i = 0; i < ffd_mean.v.GetLength(0); i++) { for (int j = 0; j < ffd_mean.v.GetLength(1); j++) { for (int k = 0; k < ffd_mean.v.GetLength(2); k++) { for (int u = 0; u < counter; u++) { ffd_mean.v[i, j, k] += ffd_old[u].v[i, j, k]; } ffd_mean.v[i, j, k] /= counter; } } } for (int i = 0; i < ffd_mean.w.GetLength(0); i++) { for (int j = 0; j < ffd_mean.w.GetLength(1); j++) { for (int k = 0; k < ffd_mean.w.GetLength(2); k++) { for (int u = 0; u < counter; u++) { ffd_mean.w[i, j, k] += ffd_old[u].w[i, j, k]; } ffd_mean.w[i, j, k] /= counter; } } } de = new DataExtractor(omega, ffd_mean); }
/// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> protected virtual bool ShouldContinue() { return(OnPingDocument() != null && !Locked && !GH_Document.IsEscapeKeyDown()); }