using System; using System.Collections.Generic; using System.Diagnostics; namespace Deltares.Stability.Calculation.Inner { public class TStressTable { private int FNPoints = 0; private int FNTests = 0; private List FSigma = new List(); private string FStressTableName = String.Empty; private List FTau = new List(); private List FTauAvg = new List(); private List FTauKar = new List(); //Constructor Create() public TStressTable() : base() { // TODO: Add any constructor code here InitStressTable(); } public string StressTableName { get { return FStressTableName; } set { SetStressTableName(value); } } public int NPoints { get { return FNPoints; } set { FNPoints = value; } } public int NTests { get { return FNTests; } set { FNTests = value; } } public double GetTauFromStress(double AStress) { double result; int LPoint; double LTangent; LPoint = 1; // First point = 0.0 // find the Sigma Value while ((AStress > FSigma[LPoint]) && (LPoint < FNPoints - 1)) { LPoint++; } if ((AStress > FSigma[LPoint])) { result = FTau[LPoint]; } else { LTangent = (FTau[LPoint] - FTau[LPoint - 1])/(FSigma[LPoint] - FSigma[LPoint - 1]); result = FTau[LPoint - 1] + LTangent*(AStress - FSigma[LPoint - 1]); } return result; } // Minimum stress in Tau-sigma curves // =========================================================================================== // Date ID Modification // 2004-02-18 Tuk Created this header // =========================================================================================== // =========================================================================================== // Description: Returns the value of the normal standard deviation // asuming that the Sigma Char := xmean - 1,64 * Stdev. // // Date ID Modification // 2003-11-14 Best Created // =========================================================================================== public double GetNormalCoefOfVariation(double AStress) { double result; double LAverage; double LKarak; LAverage = GetTauAverageFromStress(AStress); LKarak = GetTauKarakFromStress(AStress); result = (LAverage - LKarak)/1.64; result = result/LAverage; return result; } // =========================================================================================== // Description: Returns the value of the log normal standard deviation // asuming that the Sigma Char := (exp( ymean - 1,64 * Stdev y). // with // XMean := exp( ymean + 0.5 *(Stdev y)^2) // stdev y := sqrt(ln(1 + (stdev x/xmean) ^2) // Substituting results in a quadratic equation // - 0.5 * (Stdev y)^2 - 1.64 * (Stdev y) + ln(xMean/XChar) // // Date ID Modification // 2008-04-02 Best Created // =========================================================================================== public double GetLogNormalCoefOfVariation(double AStress) { double result; double a; double b; double c; double d; double Sigmay2; double x1; double Vx2; double LAverage; double LKarak; result = 0; x1 = -1; a = -0.5; b = -1.64; LAverage = GetTauAverageFromStress(AStress); LKarak = GetTauKarakFromStress(AStress); if ((LKarak == 0)) { result = 0; } else { c = Math.Log(LAverage/LKarak); // calculate discriminant d = b*b - 4*a*c; if ((d > StressTable.CMinSpan)) { x1 = (-b - Math.Sqrt(d))/(2*a); Debug.Assert((x1 >= 0)); } else if ((Math.Abs(d) < StressTable.CMinSpan)) { x1 = -b/(2*a); } else if ((d < -StressTable.CMinSpan)) { result = 0; } if ((x1 >= 0)) { Sigmay2 = x1*x1; Vx2 = Math.Exp(Sigmay2) - 1; result = Math.Sqrt(Vx2); } } return result; } public double GetTau(int AIndex) { double result; if (((AIndex >= 0) && (AIndex < FTau.Count))) { result = FTau[AIndex]; } else { result = -1; } return result; } public double GetTauAverage(int AIndex) { double result; if ((AIndex >= 0) && (AIndex <= FTauAvg.Count)) { result = FTauAvg[AIndex]; } else { result = -1; } return result; } public double GetTauKarakteristik(int AIndex) { double result; if ((AIndex >= 0) && (AIndex <= FTauKar.Count)) { result = FTauKar[AIndex]; } else { result = -1; } return result; } public double GetSigma(int AIndex) { double result; if ((AIndex >= 0) && (AIndex < FSigma.Count)) { result = FSigma[AIndex]; } else { result = -1; } return result; } public void SetTau(int AIndex, double AValue) { if ((AIndex >= 0) && (AIndex < FTau.Count)) { FTau[AIndex] = AValue; } else if ((AIndex <= FTau.Count)) { FNPoints = AIndex + 1; FTau.Add(AValue); } } public void SetTauKarakteristik(int AIndex, double AValue) { if ((AIndex >= 0) && (AIndex < FTauKar.Count)) { FTauKar[AIndex] = AValue; } else if ((AIndex <= FTauKar.Count)) { FNPoints = AIndex + 1; FTauKar.Add(AValue); } } public void SetTauAverage(int AIndex, double AValue) { if ((AIndex >= 0) && (AIndex < FTauAvg.Count)) { FTauAvg[AIndex] = AValue; } else if ((AIndex <= FTauAvg.Count)) { FNPoints = AIndex + 1; FTauAvg.Add(AValue); } } public void SetSigma(int AIndex, double AValue) { if ((AIndex >= 0) && (AIndex < FSigma.Count)) { FSigma[AIndex] = AValue; } else if ((AIndex <= FSigma.Count)) { FNPoints = AIndex + 1; FSigma.Add(AValue); } } // =========================================================================================== // Description: Initialises the object data (Tau[i]=Sigma[i]=-1, name=''). // // Date ID Modification // 1996-05-28 Bka Created // 1998-09-08 Best modified for average and karakteristik values // 2005-12-16 Zant Initialize FNTests. // =========================================================================================== public double Tau_Pseudo(int ANumPoint, double APseudoFac) { double result; double LTmp; if ((Math.Abs(APseudoFac) < 1.0E-6) || (FTauKar[ANumPoint] < StressTable.CMinSpan)) { result = FTau[ANumPoint]; } else { LTmp = APseudoFac*(FTauAvg[ANumPoint] - FTauKar[ANumPoint]); LTmp = FTauAvg[ANumPoint] - LTmp; result = LTmp*FTau[ANumPoint]/FTauKar[ANumPoint]; } return result; } public double Delta(double AEffStress, int APoint) { double result; double Ltgphi; double Ldt; double Ldt1; double Ldt2; if (APoint > FNPoints - 1) { Ldt = FTauAvg[FNPoints - 1] - FTauKar[FNPoints - 1]; } else { Ldt1 = FTauAvg[APoint - 1] - FTauKar[APoint - 1]; Ldt2 = FTauAvg[APoint] - FTauKar[APoint]; Ltgphi = (Ldt2 - Ldt1)/(FSigma[APoint] - FSigma[APoint - 1]); Ldt = Ldt2 + Ltgphi*(AEffStress - FSigma[APoint]); } result = Ldt; return result; } // =========================================================================================== // Description: Gets the coh and phi from the table, given a certain stress // // Date ID Modification // 1999-03-08 Best Created // =========================================================================================== public void GetCohPhi(double ASalfa, double APseudoFac, ref double ACoh, ref double APhi, ref int APoint) { const double CRpi = 180.0/Math.PI; double Ltgphi; APoint = 1; // First point = 0.0 // find the Sigma Value while ((ASalfa > FSigma[APoint]) && (APoint < FNPoints - 1)) { APoint ++; } if ((ASalfa > FSigma[APoint])) { // Last point exceeded ACoh = Tau_Pseudo(FNPoints - 1, APseudoFac); APhi = 0.0; } else { // interpolation Ltgphi = (Tau_Pseudo(APoint, APseudoFac) - Tau_Pseudo(APoint - 1, APseudoFac))/(FSigma[APoint] - FSigma[APoint - 1]); APhi = Math.Atan(Ltgphi)*CRpi; // Cohesie is de waarde van tau bij Salfa = 0 gegeven deze tgphi ACoh = Tau_Pseudo(APoint, APseudoFac) - Ltgphi*FSigma[APoint]; } } // =========================================================================================== // Description: Gets the coh and phi from the table, given a certain stress // // Date ID Modification // 1999-03-08 Best Created // 2003-11-10 Best overload procedure with a factor created // =========================================================================================== public void GetCohPhiDesign(double ASalfa, ref double ACoh, ref double APhi, double AFactor, ref int APoint) { const double CRpi = 180.0/Math.PI; double Ltgphi; APoint = 1; // First point = 0.0 // find the Sigma Value while ((ASalfa > FSigma[APoint]) && (APoint < FNPoints - 1)) { APoint ++; } if ((ASalfa > FSigma[APoint])) { // Last point exceeded ACoh = AFactor*FTau[APoint]; APhi = 0.0; } else { // interpolation Ltgphi = AFactor*(FTau[APoint] - FTau[APoint - 1])/(FSigma[APoint] - FSigma[APoint - 1]); APhi = Math.Atan(Ltgphi)*CRpi; // Cohesie is de waarde van tau bij Salfa = 0 gegeven deze tgphi ACoh = AFactor*FTau[APoint] - Ltgphi*FSigma[APoint]; } } // =========================================================================================== // Description: Gets the coh and phi from the table, given a certain stress // // Date ID Modification // 1999-03-08 Best Created // 2003-11-10 Best overload procedure with a factor created // =========================================================================================== public void GetCohPhiAvg(double ASalfa, ref double ACoh, ref double APhi, double AFactor, ref int APoint) { const double CRpi = 180.0/Math.PI; double Ltgphi; APoint = 1; // First point = 0.0 // find the Sigma Value while ((ASalfa > FSigma[APoint]) && (APoint < FNPoints - 1)) { APoint ++; } if ((ASalfa > FSigma[APoint])) { // Last point exceeded ACoh = AFactor*FTauAvg[APoint]; APhi = 0.0; } else { // interpolation Ltgphi = AFactor*(FTauAvg[APoint] - FTauAvg[APoint - 1])/(FSigma[APoint] - FSigma[APoint - 1]); APhi = Math.Atan(Ltgphi)*CRpi; // Cohesie is de waarde van tau bij Salfa = 0 gegeven deze tgphi ACoh = AFactor*FTauAvg[APoint] - Ltgphi*FSigma[APoint]; } } // =========================================================================================== // Description: Checks validity of stresstable : // - Sigma[0] = 0; // - Sigma[i] < Sigma[i+1] // - Tau[i] <= Tau[i+1] // Note: test on appropiate calculation method (this test only // needed if method=Bishop_Stress) should be done prior to // calling this method. // // Post-condition : - 0 if valid // - 1 if Sigma[0]<>0 // - 10 if Tau's not ascending // - 100 if Sigma's not Strictly ascending // - 1000 if stresstable holds only one point // - for combination of errors semi binary notation is used(11 // for 1 and 2, 101 for 1 and 3 etc.) // // Date ID Modification // 1996-05-28 Bka Created // 1998-09-08 Best modified for average and karakteristic values // 1998-11-30 Bka Added test for only one point in table // 1999-09-10 Best Test for caracteristic and pseudo values only if they are // actualy used // =========================================================================================== public string IsValid(bool APseudo) { string result; string error; int i; bool LValidS; bool LValidT; bool LValidk; bool LValida; bool LValidDim; error = ""; LValidT = true; LValidk = true; LValida = true; LValidS = true; LValidDim = (FSigma.Count == FNPoints) && (FTau.Count == FNPoints) && (FTauKar.Count == FNPoints) && (FTauAvg.Count == FNPoints); if (!LValidDim) { error = error + "Dimensions in stresstable are not equal " + '\r'; } if (Math.Abs(GetSigma(0)) >= StressTable.CDiff) { error = error + "First sigma value is not zero " + '\r'; } i = 1; while ((i <= FNPoints - 1)) { LValidT = LValidT && (FTau[i] - FTau[i - 1] > - StressTable.CDiff); if (APseudo) { LValidk = LValidk && (FTauKar[i] - FTauKar[i - 1] > -StressTable.CDiff); LValida = LValida && (FTauAvg[i] - FTauAvg[i - 1] > -StressTable.CDiff); } LValidS = LValidS && (FSigma[i] - FSigma[i - 1] > StressTable.CDiff); i ++; } if (!LValidT) { error = error + "Values Tau are not increasing " + '\r'; } if (APseudo && (!LValidk || !LValida)) { error = error + "Values Tau karacteristic and /or average are not increasing " + '\r'; } if (!LValidS) { error = error + "Values Sigma are not increasing " + '\r'; } if (FNPoints == 1) { error = error + "Table has only 1 point " + '\r'; } result = error; return result; } private double GetTauAverageFromStress(double AStress) { double result; int LPoint; double LTangent; LPoint = 1; // First point = 0.0 // find the Sigma Value while ((AStress > FSigma[LPoint]) && (LPoint < FNPoints - 1)) { LPoint ++; } if ((AStress > FSigma[LPoint])) { result = FTauAvg[LPoint]; } else { LTangent = (FTauAvg[LPoint] - FTauAvg[LPoint - 1])/(FSigma[LPoint] - FSigma[LPoint - 1]); result = FTauAvg[LPoint - 1] + LTangent*(AStress - FSigma[LPoint - 1]); } return result; } // =========================================================================================== // Date ID Modification // 2004-02-18 Tuk Created this header // =========================================================================================== private double GetTauKarakFromStress(double AStress) { double result; int LPoint; double LTangent; LPoint = 1; // First point = 0.0 // find the Sigma Value while ((AStress > FSigma[LPoint]) && (LPoint < FNPoints - 1)) { LPoint ++; } if ((AStress > FSigma[LPoint])) { result = FTauKar[LPoint]; } else { LTangent = (FTauKar[LPoint] - FTauKar[LPoint - 1])/(FSigma[LPoint] - FSigma[LPoint - 1]); result = FTauKar[LPoint - 1] + LTangent*(AStress - FSigma[LPoint - 1]); } return result; } private void SetStressTableName(string AName) { FStressTableName = AName; } private void InitStressTable() { FNPoints = 0; FStressTableName = ""; FNTests = 0; } } // end TStressTable } namespace Deltares.Stability.Calculation.Inner { public class StressTable { // Next const is accuracy amongst Tau/Sigma public const double CDiff = 0.001; public const double CMaxStressVal = 100000; public const double CMinSpan = 1E-5; } // end StressTable }