Exemple #1
0
        /// <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);
                    }
                }
            }
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        /// <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);
            }