Example #1
0
        static void WriteOutput(int fileIndex, string path, int numberOfSolarAreas, Ehub ehub, EhubMisc.HorizonReduction.TypicalDays typicalDays)
        {
            // check, if results folder exists in inputs folder
            string outputPath = path + @"results\";

            Directory.CreateDirectory(outputPath);

            // write a csv for each epsilon cut, name it "_e1", "_e2", .. etc
            List <string> header = new List <string>();
            // write units to 2nd row
            List <string> header_units = new List <string>();

            header.Add("Lev.Emissions");
            header_units.Add("kgCO2eq/a");
            header.Add("Lev.Cost");
            header_units.Add("CHF/a");
            header.Add("OPEX");
            header_units.Add("CHF/a");
            header.Add("CAPEX");
            header_units.Add("CHF/a");
            header.Add("DistrictHeatingCost");
            header_units.Add("CHF/a");
            header.Add("x_Battery");
            header_units.Add("kWh");
            header.Add("x_TES");
            header_units.Add("kWh");
            header.Add("x_CHP");
            header_units.Add("kW");
            header.Add("x_Boiler");
            header_units.Add("kW");
            header.Add("x_BiomassBoiler");
            header_units.Add("kW");
            header.Add("x_ASHP");
            header_units.Add("kW");
            header.Add("x_AirCon");
            header_units.Add("kW");
            header.Add("x_Battery_charge");
            header_units.Add("kWh");
            header.Add("x_Battery_discharge");
            header_units.Add("kWh");
            header.Add("x_Battery_soc");
            header_units.Add("kWh");
            header.Add("x_TES_charge");
            header_units.Add("kWh");
            header.Add("x_TES_discharge");
            header_units.Add("kWh");
            header.Add("x_TES_soc");
            header_units.Add("kWh");
            header.Add("x_CHP_op_e");
            header_units.Add("kWh");
            header.Add("x_CHP_op_h");
            header_units.Add("kWh");
            header.Add("x_CHP_dump");
            header_units.Add("kWh");
            header.Add("x_Boiler_op");
            header_units.Add("kWh");
            header.Add("x_BiomassBoiler_op");
            header_units.Add("kWh");
            header.Add("x_ASHP_op");
            header_units.Add("kWh");
            header.Add("x_AirCon_op");
            header_units.Add("kWh");
            header.Add("x_GridPurchase");
            header_units.Add("kWh");
            header.Add("x_FeedIn");
            header_units.Add("kWh");
            for (int i = 0; i < numberOfSolarAreas; i++)
            {
                header.Add("x_PV_" + i);
                header_units.Add("sqm");
            }
            for (int i = 0; i < ehub.NumberOfBuildingsInDistrict; i++)
            {
                header.Add("x_HeatExchanger_DH_" + i);
                header_units.Add("kW");
            }
            header.Add("b_PV_totalProduction");
            header_units.Add("kWh");
            header.Add("TypicalHeating");
            header_units.Add("kWh");
            header.Add("TypicalCooling");
            header_units.Add("kWh");
            header.Add("TypicalElectricity");
            header_units.Add("kWh");
            header.Add("TypicalGHI");
            header_units.Add(@"W/sqm");
            header.Add("TypicalAmbientTemp");
            header_units.Add("deg C");
            header.Add("ClusterSize");
            header_units.Add("Days");
            header.Add("BiomassConsumed");
            header_units.Add("kWh");

            for (int e = 0; e < ehub.Outputs.Length; e++)
            {
                List <List <string> > outputString = new List <List <string> >();
                if (ehub.Outputs[e].infeasible)
                {
                    outputString.Add(new List <string> {
                        "Infeasible"
                    });
                    Console.WriteLine("--- Infeasible Solution ---");
                }
                else
                {
                    outputString.Add(header);
                    outputString.Add(header_units);

                    List <string> firstLine = new List <string>();
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].carbon));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].cost));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].OPEX));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].CAPEX));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].cost_dh));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].x_bat));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].x_tes));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].x_chp));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].x_boi));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].x_bmboi));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].x_hp));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].x_ac));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].x_bat_charge[0]));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].x_bat_discharge[0]));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].x_bat_soc[0]));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].x_tes_charge[0]));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].x_tes_discharge[0]));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].x_tes_soc[0]));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].x_chp_op_e[0]));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].x_chp_op_h[0]));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].x_chp_dump[0]));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].x_boi_op[0]));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].x_bmboi_op[0]));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].x_hp_op[0]));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].x_ac_op[0]));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].x_elecpur[0]));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].x_feedin[0]));
                    for (int i = 0; i < numberOfSolarAreas; i++)
                    {
                        firstLine.Add(Convert.ToString(ehub.Outputs[e].x_pv[i]));
                    }
                    for (int i = 0; i < ehub.NumberOfBuildingsInDistrict; i++)
                    {
                        firstLine.Add(Convert.ToString(ehub.Outputs[e].x_hx_dh[i]));
                    }
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].b_pvprod[0]));

                    firstLine.Add(Convert.ToString(typicalDays.DayProfiles[0][0]));
                    firstLine.Add(Convert.ToString(typicalDays.DayProfiles[1][0]));
                    firstLine.Add(Convert.ToString(typicalDays.DayProfiles[2][0]));
                    firstLine.Add(Convert.ToString(typicalDays.DayProfiles[3][0]));
                    firstLine.Add(Convert.ToString(typicalDays.DayProfiles[4][0]));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].clustersize[0]));
                    firstLine.Add(Convert.ToString(ehub.Outputs[e].biomassConsumed));

                    outputString.Add(firstLine);

                    for (int t = 1; t < ehub.Outputs[e].x_elecpur.Length; t++)
                    {
                        List <string> newLine = new List <string>();
                        for (int skip = 0; skip < 12; skip++)
                        {
                            newLine.Add("");
                        }
                        newLine.Add(Convert.ToString(ehub.Outputs[e].x_bat_charge[t]));
                        newLine.Add(Convert.ToString(ehub.Outputs[e].x_bat_discharge[t]));
                        newLine.Add(Convert.ToString(ehub.Outputs[e].x_bat_soc[t]));
                        newLine.Add(Convert.ToString(ehub.Outputs[e].x_tes_charge[t]));
                        newLine.Add(Convert.ToString(ehub.Outputs[e].x_tes_discharge[t]));
                        newLine.Add(Convert.ToString(ehub.Outputs[e].x_tes_soc[t]));
                        newLine.Add(Convert.ToString(ehub.Outputs[e].x_chp_op_e[t]));
                        newLine.Add(Convert.ToString(ehub.Outputs[e].x_chp_op_h[t]));
                        newLine.Add(Convert.ToString(ehub.Outputs[e].x_chp_dump[t]));
                        newLine.Add(Convert.ToString(ehub.Outputs[e].x_boi_op[t]));
                        newLine.Add(Convert.ToString(ehub.Outputs[e].x_bmboi_op[t]));
                        newLine.Add(Convert.ToString(ehub.Outputs[e].x_hp_op[t]));
                        newLine.Add(Convert.ToString(ehub.Outputs[e].x_ac_op[t]));
                        newLine.Add(Convert.ToString(ehub.Outputs[e].x_elecpur[t]));
                        newLine.Add(Convert.ToString(ehub.Outputs[e].x_feedin[t]));
                        for (int skip = 0; skip < numberOfSolarAreas; skip++)
                        {
                            newLine.Add("");
                        }
                        for (int skip = 0; skip < ehub.NumberOfBuildingsInDistrict; skip++)
                        {
                            newLine.Add("");
                        }
                        newLine.Add(Convert.ToString(ehub.Outputs[e].b_pvprod[t]));

                        newLine.Add(Convert.ToString(typicalDays.DayProfiles[0][t]));
                        newLine.Add(Convert.ToString(typicalDays.DayProfiles[1][t]));
                        newLine.Add(Convert.ToString(typicalDays.DayProfiles[2][t]));
                        newLine.Add(Convert.ToString(typicalDays.DayProfiles[3][t]));
                        newLine.Add(Convert.ToString(typicalDays.DayProfiles[4][t]));
                        newLine.Add(Convert.ToString(ehub.Outputs[e].clustersize[t]));
                        newLine.Add("");

                        outputString.Add(newLine);
                    }
                }
                using var sw = new StreamWriter(outputPath + "result_" + Convert.ToString(fileIndex) + "_epsilon" + e + ".csv");
                foreach (List <string> line in outputString)
                {
                    foreach (string cell in line)
                    {
                        sw.Write(cell + ";");
                    }
                    sw.Write(Environment.NewLine);
                }
                sw.Close();
            }
        }
Example #2
0
        /// <summary>
        /// Run Energy Hubs for multiple inputs and writes outputs for each
        /// </summary>
        static void RunMultipleEhubs()
        {
            int    numberOfTypicalDays = 12;
            string buildingInputName   = @"building_input";
            string technologyInputName = @"technology_input";

            // ask for folder with input files (pairs of demand_input and tech_params)
            Console.WriteLine();
            Console.WriteLine(@"*************************************************************************************");
            Console.WriteLine(@"****************************** E N E R G Y H U B S **********************************");
            Console.WriteLine(@"*************************************************************************************");
            Console.WriteLine(@"************************************* F O R *****************************************");
            Console.WriteLine(@"*************************************************************************************");
            Console.WriteLine(@"********************** M U L T I P L E    B U I L D I N G S *************************");
            Console.WriteLine(@"*************************************************************************************");
            Console.WriteLine(@"Please enter the path of your inputs folder in the following format: 'c:\inputs\'");
            Console.WriteLine("The folder should contain one or more pairs of csv-files in the naming convention: 'building_input_0.csv', 'technology_input_0.csv'. '0' is the integer that makes the program recognize that these two csv belong together.");
            Console.WriteLine();
            Console.Write("Enter your path now and confirm by hitting the Enter-key: ");
            string path = Console.ReadLine();

            if (!path.EndsWith(@"\"))
            {
                path = path + @"\";
            }


            // identify all valid input files in folder
            int filePairs = 0;

            string[] fileEntries = Directory.GetFiles(path);
            string[] fileNames   = new string[fileEntries.Length];
            for (int i = 0; i < fileEntries.Length; i++)
            {
                fileNames[i] = Path.GetFileName(fileEntries[i]);
            }

            List <string> inputBuildingFiles   = new List <string>();
            List <string> inputTechnologyFiles = new List <string>();
            List <int>    inputIndices         = new List <int>();

            foreach (string fileEntry in fileEntries)
            {
                string   fileName             = Path.GetFileName(fileEntry);
                string[] splitFileName        = fileName.Split('_');
                string   fileNameWithoutIndex = splitFileName[0] + '_' + splitFileName[1];
                if (string.Equals(fileNameWithoutIndex, buildingInputName))
                {
                    //find its partner. just make string search
                    string partnerFile = technologyInputName + "_" + splitFileName[splitFileName.Length - 1];
                    if (fileNames.Contains(partnerFile))
                    {
                        filePairs++;
                    }

                    inputBuildingFiles.Add(fileName);
                    inputTechnologyFiles.Add(partnerFile);
                    inputIndices.Add(Convert.ToInt32(splitFileName[splitFileName.Length - 1].Split('.')[0]));
                }
            }

            // ask, how many runs to do
            Console.WriteLine("Enter the number of Building-cases to generate Energyhubs for. There exist {0} file-pairs, hence you can select any integer number smaller equal of that:", filePairs);
            Int32.TryParse(Console.ReadLine(), out int nRuns);
            int nRunsActually = filePairs < nRuns ? filePairs : nRuns;    // if there are less file pairs in the folder than the number of runs, we actually want, only run the existing pairs in the folder

            for (int i = 0; i < nRunsActually; i++)
            {
                try
                {
                    Console.WriteLine(@"*************************************************************************************");
                    Console.WriteLine("Loading data...");
                    LoadBuildingInput(path + inputBuildingFiles[i],
                                      out List <double> heating, out List <double> cooling, out List <double> electricity, out List <double> ghi, out List <double> dhw, out List <double> Tamb, out List <double[]> solar, out List <double> solarArea);
                    LoadTechParameters(path + inputTechnologyFiles[i], out Dictionary <string, double> technologyParameters);


                    /// data preparation, clustering and typical days
                    Console.WriteLine("Clustering and generating typical days...");
                    int        numberOfSolarAreas = solar[0].Length;
                    int        numBaseLoads       = 5;                                 // heating, cooling, electricity, ghi, tamb
                    int        numLoads           = numBaseLoads + numberOfSolarAreas; // heating, cooling, electricity, ghi, tamb, solar. however, solar will include several profiles.
                    double[][] fullProfiles       = new double[numLoads][];
                    string[]   loadTypes          = new string[numLoads];
                    bool[]     peakDays           = new bool[numLoads];
                    bool[]     correctionLoad     = new bool[numLoads];
                    for (int u = 0; u < numLoads; u++)
                    {
                        fullProfiles[u] = new double[hoursPerYear];
                    }
                    loadTypes[0]      = "heating";
                    loadTypes[1]      = "cooling";
                    loadTypes[2]      = "electricity";
                    loadTypes[3]      = "ghi";
                    loadTypes[4]      = "Tamb";
                    peakDays[0]       = true;
                    peakDays[1]       = true;
                    peakDays[2]       = true;
                    peakDays[3]       = false;
                    peakDays[4]       = false;
                    correctionLoad[0] = true;
                    correctionLoad[1] = true;
                    correctionLoad[2] = true;
                    correctionLoad[3] = false;
                    correctionLoad[4] = false;

                    bool[] useForClustering = new bool[fullProfiles.Length]; // specificy here, which load is used for clustering. the others are just reshaped
                    for (int t = 0; t < hoursPerYear; t++)
                    {
                        fullProfiles[0][t]  = heating[t] + dhw[t];
                        fullProfiles[1][t]  = cooling[t];
                        fullProfiles[2][t]  = electricity[t];
                        fullProfiles[3][t]  = ghi[t];
                        fullProfiles[4][t]  = Tamb[t];
                        useForClustering[0] = true;
                        useForClustering[1] = true;
                        useForClustering[2] = true;
                        useForClustering[3] = true;
                        useForClustering[4] = false;
                    }

                    for (int u = 0; u < numberOfSolarAreas; u++)
                    {
                        useForClustering[u + numBaseLoads] = false;
                        peakDays[u + numBaseLoads]         = false;
                        correctionLoad[u + numBaseLoads]   = true;
                        loadTypes[u + numBaseLoads]        = "solar";
                        for (int t = 0; t < hoursPerYear; t++)
                        {
                            fullProfiles[u + numBaseLoads][t] = solar[t][u];
                        }
                    }

                    // TO DO: load in GHI time series, add it to full profiles (right after heating, cooling, elec), and use it for clustering. exclude other solar profiles from clustering, but they need to be reshaped too
                    EhubMisc.HorizonReduction.TypicalDays typicalDays = EhubMisc.HorizonReduction.GenerateTypicalDays(fullProfiles, loadTypes, numberOfTypicalDays, peakDays, useForClustering, correctionLoad, false);


                    /// Running Energy Hub
                    Console.WriteLine("Solving MILP optimization model...");
                    double[][] typicalSolarLoads = new double[numberOfSolarAreas][];
                    for (int u = 0; u < numberOfSolarAreas; u++)
                    {
                        typicalSolarLoads[u] = typicalDays.DayProfiles[numBaseLoads + u];
                    }
                    int[] clustersizePerTimestep = typicalDays.NumberOfDaysPerTimestep;
                    Ehub  ehub = new Ehub(typicalDays.DayProfiles[0], typicalDays.DayProfiles[1], typicalDays.DayProfiles[2],
                                          typicalSolarLoads, solarArea.ToArray(),
                                          typicalDays.DayProfiles[4], technologyParameters,
                                          clustersizePerTimestep);
                    ehub.Solve(5);

                    /// Storing Results
                    Console.WriteLine("Saving results into {0}...", path + @"results\");
                    WriteOutput(inputIndices[i], path, numberOfSolarAreas, ehub, typicalDays);

                    Console.WriteLine("Energyhubs {0} of {1} completed...", i + 1, nRunsActually);
                    Console.WriteLine(@"......");
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                    WriteErrorFile(inputIndices[i], path, ex);
                }
            }



            /// Waiting for user to close window
            Console.WriteLine(@"*************************************************************************************");
            Console.WriteLine(@"*************************************************************************************");
            Console.WriteLine(@"*************************************************************************************");
            Console.WriteLine("Program finished. Hit any key to close program...: ");
        }
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            string filePath = null;

            if (!DA.GetData(0, ref filePath))
            {
                return;
            }
            if (!filePath.EndsWith(@"\"))
            {
                filePath = filePath + @"\";
            }

            var heating     = new List <double>();
            var cooling     = new List <double>();
            var dhw         = new List <double>();
            var electricity = new List <double>();

            if (!DA.GetDataList(1, heating))
            {
                return;
            }
            if (!DA.GetDataList(2, cooling))
            {
                return;
            }
            if (!DA.GetDataList(3, dhw))
            {
                return;
            }
            if (!DA.GetDataList(4, electricity))
            {
                return;
            }

            var solarAreas = new List <double>();

            if (!DA.GetDataList(5, solarAreas))
            {
                return;
            }

            GH_Structure <GH_Number> solarPotentials;

            if (!DA.GetDataTree(6, out solarPotentials))
            {
                return;
            }
            List <List <double> > solarPotList = new List <List <double> >();

            for (int i = 0; i < solarPotentials.Branches.Count; i++)
            {
                solarPotList.Add(new List <double>());
                foreach (GH_Number gooNumber in solarPotentials.get_Branch(i))
                {
                    double numb;
                    GH_Convert.ToDouble(gooNumber, out numb, GH_Conversion.Both);
                    solarPotList[i].Add(numb);
                }
            }

            var irradiance = new double[solarPotList.Count][];

            for (int i = 0; i < solarPotList.Count; i++)
            {
                irradiance[i] = solarPotList[i].ToArray();
            }


            var ghi     = new List <double>();
            var dryBulb = new List <double>();

            if (!DA.GetDataList(7, ghi))
            {
                return;
            }
            if (!DA.GetDataList(8, dryBulb))
            {
                return;
            }


            bool run = false;

            DA.GetData(9, ref run);

            int epsilonCuts = 3;

            DA.GetData(10, ref epsilonCuts);


            if (run)
            {
                try
                {
                    LoadTechParameters(filePath + "technologies.csv", out var technologyParameters);
                    technologyParameters.Add("NumberOfBuildingsInEHub", Convert.ToDouble(1));
                    technologyParameters.Add("Peak_Htg_" + Convert.ToString(0), heating.Max());
                    technologyParameters.Add("Peak_Clg_" + Convert.ToString(0), cooling.Max());
                    Rhino.RhinoApp.WriteLine("_____LOADING INPUTS COMPLETE_____");
                    Rhino.RhinoApp.WriteLine("_________________________________");
                    Rhino.RhinoApp.WriteLine("_____CLUSTERING TYPICAL DAYS_____");

                    int numberOfSolarAreas = solarAreas.Count;
                    int numBaseLoads       = 5; // heating, cooling, electricity, ghi, tamb
                    int numLoads           =
                        numBaseLoads +
                        numberOfSolarAreas; // heating, cooling, electricity, ghi, tamb, solar. however, solar will include several profiles.
                    const int  hoursPerYear   = 8760;
                    double[][] fullProfiles   = new double[numLoads][];
                    string[]   loadTypes      = new string[numLoads];
                    bool[]     peakDays       = new bool[numLoads];
                    bool[]     correctionLoad = new bool[numLoads];
                    for (int u = 0; u < numLoads; u++)
                    {
                        fullProfiles[u] = new double[hoursPerYear];
                    }
                    loadTypes[0]      = "heating";
                    loadTypes[1]      = "cooling";
                    loadTypes[2]      = "electricity";
                    loadTypes[3]      = "ghi";
                    loadTypes[4]      = "Tamb";
                    peakDays[0]       = true;
                    peakDays[1]       = true;
                    peakDays[2]       = true;
                    peakDays[3]       = false;
                    peakDays[4]       = false;
                    correctionLoad[0] = true;
                    correctionLoad[1] = true;
                    correctionLoad[2] = true;
                    correctionLoad[3] = false;
                    correctionLoad[4] = false;

                    bool[]
                    useForClustering =
                        new bool[fullProfiles
                                 .Length]; // specificy here, which load is used for clustering. the others are just reshaped
                    for (int t = 0; t < hoursPerYear; t++)
                    {
                        fullProfiles[0][t]  = heating[t] + dhw[t];
                        fullProfiles[1][t]  = cooling[t];
                        fullProfiles[2][t]  = electricity[t];
                        fullProfiles[3][t]  = ghi[t];
                        fullProfiles[4][t]  = dryBulb[t];
                        useForClustering[0] = true;
                        useForClustering[1] = true;
                        useForClustering[2] = true;
                        useForClustering[3] = true;
                        useForClustering[4] = false;
                    }

                    for (int u = 0; u < numberOfSolarAreas; u++)
                    {
                        useForClustering[u + numBaseLoads] = false;
                        peakDays[u + numBaseLoads]         = false;
                        correctionLoad[u + numBaseLoads]   = true;
                        loadTypes[u + numBaseLoads]        = "solar";
                        for (int t = 0; t < hoursPerYear; t++)
                        {
                            fullProfiles[u + numBaseLoads][t] = irradiance[u][t];
                        }
                    }

                    // TO DO: load in GHI time series, add it to full profiles (right after heating, cooling, elec), and use it for clustering. exclude other solar profiles from clustering, but they need to be reshaped too
                    EhubMisc.HorizonReduction.TypicalDays typicalDays = EhubMisc.HorizonReduction.GenerateTypicalDays(
                        fullProfiles, loadTypes,
                        12, peakDays, useForClustering, correctionLoad, true);

                    /// Running Energy Hub
                    Rhino.RhinoApp.WriteLine("Solving MILP optimization model...");
                    double[][] typicalSolarLoads = new double[numberOfSolarAreas][];

                    // solar profiles negative or very small numbers. rounding floating numbers thing?
                    for (int u = 0; u < numberOfSolarAreas; u++)
                    {
                        typicalSolarLoads[u] = typicalDays.DayProfiles[numBaseLoads + u];
                        for (int t = 0; t < typicalSolarLoads[u].Length; t++)
                        {
                            if (typicalSolarLoads[u][t] < 0.1)
                            {
                                typicalSolarLoads[u][t] = 0.0;
                            }
                        }
                    }

                    // same for heating, cooling, elec demand... round very small numbers
                    for (int t = 0; t < typicalDays.DayProfiles[0].Length; t++)
                    {
                        for (int i = 0; i < 3; i++)
                        {
                            if (typicalDays.DayProfiles[i][t] < 0.001)
                            {
                                typicalDays.DayProfiles[i][t] = 0.0;
                            }
                        }
                    }


                    int[] clustersizePerTimestep = typicalDays.NumberOfDaysPerTimestep;
                    Ehub  ehub = new Ehub(typicalDays.DayProfiles[0], typicalDays.DayProfiles[1],
                                          typicalDays.DayProfiles[2],
                                          typicalSolarLoads, solarAreas.ToArray(),
                                          typicalDays.DayProfiles[4], technologyParameters,
                                          clustersizePerTimestep);
                    ehub.Solve(epsilonCuts, true);

                    Rhino.RhinoApp.WriteLine("___________________________");
                    Rhino.RhinoApp.WriteLine("ENERGY HUB SOLVER COMPLETED");

                    var capex     = new List <double>();
                    var opex      = new List <double>();
                    var emissions = new List <double>();
                    for (int i = 0; i < ehub.Outputs.Length; i++)
                    {
                        capex.Add(ehub.Outputs[i].CAPEX);
                        opex.Add(ehub.Outputs[i].OPEX);
                        emissions.Add(ehub.Outputs[i].carbon);
                    }
                    DA.SetDataList(0, capex);
                    DA.SetDataList(1, opex);
                    DA.SetDataList(2, emissions);


                    WriteOutput("EaCS3_HS21_Results_Ehub", filePath, numberOfSolarAreas, ehub, typicalDays, numBaseLoads);
                    Rhino.RhinoApp.WriteLine("___________________________");
                    Rhino.RhinoApp.WriteLine("RESULTS WRITTEN TO" + filePath.ToString());
                }
                catch (Exception e)
                {
                    Rhino.RhinoApp.WriteLine(e.Message);
                    throw;
                }
            }



            // return results to outputs IN GH component
        }