示例#1
0
        /// <summary>
        /// Based on the commissioning graph, the power and speed coefficients of each draft between the ballast and the scanlt are obtained.
        /// </summary>
        /// <param name="shipParticular">Ship Basic Data</param>
        /// <param name="seaTrialPowerToSpeedAtBallast">Power Speed Conversion factor(ballast)</param>
        /// <param name="seaTrialPowerToSpeedAtScant">Power Speed Conversion factor(scant)</param>
        /// <returns>각 10cm 별 power speed 계수 배열</returns>
        public static List <double[]> PowerToSpeedTable(SHIP_PARTICULAR shipParticular, dynamic ballastValues, dynamic scantlingValues)
        {
            double seatrialdraftScantling = (scantlingValues.DRAFT_FORE + scantlingValues.DRAFT_AFT) * 0.5; //Draft (Scantling) Fore , Draft (Scantling) Aft
            double seaTrialdraftBallast   = (ballastValues.DRAFT_FORE + ballastValues.DRAFT_AFT) * 0.5;     //Draft (Ballast) Fore, Draft (Ballast) Aft

            List <double[]> draftTable = new List <double[]> {
            };
            double startDraft          = Math.Truncate((seaTrialdraftBallast - 7) * 10);                                                     // ref draft -2 부터 시작 (-2는 여유분)

            int numerOfDraft = (int)((Math.Truncate((seatrialdraftScantling + 7) * 10)) - (Math.Truncate((seaTrialdraftBallast - 7) * 10))); // 스캔틀링까지 소수점 한자리 까지 검색, 기준 draft보다 -2 +2 만큼 큼
            int numberOfPwer = (int)(shipParticular.ME_POWER_MCR / 200);                                                                     //ME_POWER_MCr

            double[] powerTable = new double[numberOfPwer];                                                                                  // 확인 완  200 씩 파워 간격을 띄움 --> 커브피팅 알고리즘으로 x 축 배열
            double[] speedTable = new double[numberOfPwer];                                                                                  // 확인 완  파워 간격 만큼 스피드를 계산 --> 커브피팅 알고리즘으로 y 축 배열s

            for (int i = 0; i < numerOfDraft; i++)                                                                                           // 드라프트 간격 0.1 만큼 해상도의 커프피팅 테이블을 만듦
            {
                for (int j = 0; j < numberOfPwer; j++)
                {
                    powerTable[j] = (j + 1) * 200;
                    speedTable[j] =
                        ((scantlingValues.B_POWER_TO_SPEED * Math.Pow(powerTable[j], scantlingValues.A_POWER_TO_SPEED) - ballastValues.B_POWER_TO_SPEED * Math.Pow(powerTable[j], ballastValues.A_POWER_TO_SPEED)) / // Seatrial PowerToSpeed(Scant')
                         (seatrialdraftScantling - seaTrialdraftBallast) *
                         ((i + startDraft) * 0.1 - seaTrialdraftBallast) + (ballastValues.B_POWER_TO_SPEED * Math.Pow(powerTable[j], ballastValues.A_POWER_TO_SPEED)));                                              // Seatrial PowerToSpeed(Ballast')
                }

                var curve = CurveFitting.powerRegression(powerTable, speedTable);
                draftTable.Add(curve);
            }

            return(draftTable);
        }
示例#2
0
        /// <summary>
        /// 선박 WindResistance 계산 - ISO15016,ISO19030
        /// </summary>
        /// <param name="airDensityCoef">공기밀도계수 - 온도에 따라 값 결정</param>
        /// <param name="windCoeff">바람저항계수 - 풍행에 따라 값 결정</param>
        /// <param name="draft_ref">기준 draft 값 - draft에 따른 수선상 선박 넓이 계산</param>
        /// <param name="AT_ballast">ballast시 수선상 선박 넓이</param>
        /// <param name="breadth">선박넓이</param>
        /// <param name="draft">현재 draft 값</param>
        /// <param name="airTemp">공기 온도</param>
        /// <param name="relWindSpeed">상대 풍속(m/s)</param>
        /// <param name="relWindDir">상대 풍향(m/s)</param>
        /// <param name="speedVg">선박대지속도(knot)</param>
        /// <param name="etaD0"></param>
        /// <param name="etaDM"></param>
        /// <returns></returns>
        public double resistanceWind(SHIP_PARTICULAR shipParticular, double[] windCoeff, double draft_ref, double AT_ballast, double breadth, double draft, double airTemp, double airPressure, double relWindSpeed, double relWindDir, double speedVg)
        {
            if (relWindDir > 180)
            {
                relWindDir = 360 - relWindDir;      // 상대풍속을 180도 이내로 제한 (커브피팅이 0 ~ 180도와 360 ~ 180 값이 동일)
            }
            else if (relWindDir < 0)
            {
                relWindDir = Math.Abs(relWindDir);
            }

            var airDensity = this.ConvertAirTempToAirDensity(20, 1013);  // 날씨 데이터로 바꿀 것.!!!!!!!!

            double A_XV = AT_ballast + (draft_ref - draft) * breadth;    // 수선상 트랜버스 면적을 드라프트 변화에 따라 계산

            double coefRelWind = windCoeff[7] * Math.Pow(relWindDir, 6) + windCoeff[6] * Math.Pow(relWindDir, 5) + windCoeff[5] * Math.Pow(relWindDir, 4) + windCoeff[4] * Math.Pow(relWindDir, 3) + windCoeff[3] * Math.Pow(relWindDir, 2) + windCoeff[2] * relWindDir + windCoeff[1];

            double coefZeroWind = windCoeff[1]; //WINDRESISTANCECoef[0] 값

            double Rrw = 0.5 * airDensity * coefRelWind * A_XV * Math.Pow(relWindSpeed, 2) * -1;

            double R0w = 0.5 * airDensity * coefZeroWind * A_XV * Math.Pow(speedVg * 0.5144, 2) * -1;            // knot ---> m/s 주의하자

            double deltaRw = ((Rrw - R0w) * speedVg * 0.5144) / 1000;

            if (double.IsNaN(deltaRw) || double.IsInfinity(deltaRw))
            {
                deltaRw = 0;
            }
            deltaRw = Math.Round(deltaRw, 2);
            return(deltaRw);         // 풍향이 마이너스로 나온다 확인할거
        }
示例#3
0
        //데이터 수집
        public static bool DataRetrieval()
        {
            var functionResult = true;

            //Particular File load
            shipParticular = CsvFileController.ReadParticularFile("particular.csv");
            //speed Power File Load
            speedPowerData = CsvFileController.ReadSpeedPowerDataFileToList("speedPower.csv");
            //draft Data
            draft = CsvFileController.ReadDraftFile("draft.csv");

            //선박 운항 데이터 불러오기
            sailingData = CsvFileController.Read19030DataFileToList("voyageData.csv");

            foreach (var _d in speedPowerData)
            {
                ballastPowerList.Add(_d.BALLAST_POWER);
                ballastSpeedList.Add(_d.BALLAST_SPEED);
                scantlingPowerList.Add(_d.SCANTLING_POWER);
                scantlingSpeedList.Add(_d.SCANTLING_SPEED);
            }

            if (shipParticular == null || sailingData == null)
            {
                functionResult = false;
            }
            return(functionResult);
        }
示例#4
0
        /// <summary>
        /// Create Wind Resistance Data
        /// </summary>
        /// <param name="shipParticular">Ship Basic Data</param>
        /// <param name="dataCount">Count of Sailing Data</param>
        /// <returns></returns>
        public static WindResistance CreateWindResistance(SHIP_PARTICULAR shipParticular, int dataCount)
        {
            var windResistance = new WindResistance();      //해당 클래스 부르고

            windResistance.data = new WindResistanceData(); // 데이터 입력
            windResistance.data.SetSize(dataCount);
            windResistance.data.isAveraging   = false;
            windResistance.data.loa           = shipParticular.LOA;
            windResistance.data.lbp           = shipParticular.LOA;
            windResistance.data.breadth       = shipParticular.BREADTH;
            windResistance.data.windChartType = Models.Enum.WindChartTypes.ITTC;                    //0 = fujiwara, 1 = ITTC, 2 = WindTunnel
            windResistance.data.iTTCChartType = Models.Enum.ITTCChartTypes.TankerConventionalLaden; // 0 = ContainerLadenContainer, 1 = ContainerLadenLashing, 2 = ContainerBallastLashing, 3 = ContainerBallast, 4 = TankerConventionalLaden, 5 = TankerConventionalBallast, 6 = TankerCylindericalBallast, 7 = CarCarrierAverage, 8 = LNGSpherical, 9 = LNGPrismaticExtended, 10 = LNGPrismaticIntegrated, 11 = GeneralCargoAverage, 12 = CruiseFerryAverage

            return(windResistance);
        }
示例#5
0
        public static List <ISO19030File> FilteringForReferenceCondition(List <ISO19030File> sailingData, SHIP_PARTICULAR shipParticular, dynamic ballastValues, dynamic scantlingValues, WindResistance windResistance)
        {
            int index = 0;

            foreach (var item in sailingData)
            {
                //if (item.VALID_CHAUVENT == true && item.VALID_VALIDATION == true && item.VALID_REFCONDITION == true)
                //{
                var minDraft = (item.DRAFT_FORE + item.DRAFT_AFT) / 2;
                var deltaT   = (ballastValues.DRAFT_FORE + ballastValues.DRAFT_AFT) / 2 - minDraft;
                var A        = shipParticular.TRANSVERSE_PROJECTION_AREA_BALLAST + deltaT * shipParticular.BREADTH;
                var Za       = 18.2 + deltaT;
                windResistance.data.zref[index]   = (shipParticular.TRANSVERSE_PROJECTION_AREA_BALLAST * (10 + deltaT) + 0.5 * shipParticular.BREADTH * Math.Pow(deltaT, 2)) / A;
                windResistance.data.axv[index]    = shipParticular.TRANSVERSE_PROJECTION_AREA_BALLAST + ((ballastValues.DRAFT_FORE + ballastValues.DRAFT_AFT) / 2 - minDraft) * shipParticular.BREADTH;
                windResistance.data.za[index]     = /*shipModelTestData.ZA_BALLAST*/ 18.2 + ((ballastValues.DRAFT_FORE + ballastValues.DRAFT_AFT) / 2 - minDraft);
                windResistance.data.vg[index]     = item.SPEED_VG * 0.5144;
                windResistance.data.psi0[index]   = Math.PI * item.SHIP_HEADING / 180;
                windResistance.data.rhoair[index] = /*item.AMBIENT_DENSITY;*/ 1.225;
                windResistance.data.vwr[index]    = item.REL_WIND_SPEED;
                windResistance.data.psiwr[index]  = Math.PI * item.REL_WIND_DIR / 180;
                index++;
                //}
            }
            //바람 저항도 계산
            windResistance.CalculateWindResistance();

            index = 0;

            //마지막 필터 계산
            foreach (var item in afterValID_shipdata)
            {
                var windSpeedTrue = windResistance.data.vwtref[item.ID];

                var speedLw = item.SPEED_LW * 0.5144f;
                //수심의 깊이 체크
                var waterDepth1 = 3 * Math.Sqrt(shipParticular.BREADTH * ((item.DRAFT_FORE + item.DRAFT_AFT) / 2));
                var waterDepth2 = 2.75 * (speedLw * speedLw) / 9.80665;

                if (waterDepth1 < waterDepth2)
                {
                    waterDepth1 = waterDepth2;
                }
                if (index == 22)
                {
                    var check = 0;
                }


                if (item.WATER_DEPTH < -999)
                {
                    item.WATER_DEPTH = 9999;
                }
                //수온이 너무 낮거나! 바람의 세기가 8이상 타각이 5이상인걸 날림
                if (item.SW_TEMP < 2 || item.WATER_DEPTH <= waterDepth1 || windSpeedTrue > 7.9 || Math.Abs(item.RUDDER_ANGLE) > 5)
                {
                    sailingData.ElementAt((int)item.ID).VALID_REFCONDITION = false;
                    REF_CONDITION_COUNT++;
                    FILTER_TOTAL_COUNT++;
                    errorList.Add(item.ID);
                }
                else
                {
                    //통과한 것만 넣음
                    afterRef_shipdata.Add(item);
                }
                index++;
            }

            return(sailingData);
        }