1 /** 2 libs.weirs.sharpcrested module 3 Module for hydraulic analysis of sharp crested weirs used in diversion dams. 4 */ 5 module libs.weirs.sharpcrested; 6 7 import libs.weirs.weir; 8 import libs.utils.constants; 9 import libs.utils.hydraulics; 10 11 import std.math: abs, pow, sqrt, isNaN; 12 import std.stdio; 13 14 /** 15 SharpCrestedWeir class. 16 Contains fields and methods for hydraulic calculations 17 of sharp crested weirs. 18 */ 19 class SharpCrestedWeir : Weir 20 { 21 /////////////////////////////////////// 22 // Properties // 23 /////////////////////////////////////// 24 double dA, // Depth at approach 25 vA, // Velocity at approach 26 hA, // Height at approach 27 eE, // Energy elevation 28 ho, 29 h1, 30 h2, 31 h2_h1, 32 co, 33 correction, 34 cs; 35 36 /** 37 Empty constructor. 38 */ 39 this() 40 { 41 42 } 43 44 //++++++++++++++++++++++++++++++++++++++++++++++ 45 // Methods + 46 //+++++++++++++++++++++++++++++++++++++++++++++/ 47 48 /** 49 Performs the hydraulic analysis for sharp-crested (gated) weirs/diversion dams. 50 */ 51 bool analysis() 52 { 53 if (!isValidInputs) 54 { 55 return false; 56 } 57 58 // Reset values 59 TRIAL_INCREMENT = 0.0001; 60 calculatedDischargeIntensity = 0; 61 62 dischargeIntensity = discharge / crestLength; 63 64 // Afflux elevation initial assumption 65 affluxElevation = crestElev > tailwaterElev ? crestElev : tailwaterElev; 66 67 // Accuracy closure 68 const allowedDiff = discharge * ERROR; 69 70 // Calculation for the afflux elevation 71 while (abs(dischargeIntensity - calculatedDischargeIntensity) > allowedDiff) 72 { 73 affluxElevation += TRIAL_INCREMENT; 74 dA = affluxElevation - usApronElev; 75 vA = dischargeIntensity / dA; 76 hA = velocityHead(vA); 77 eE = affluxElevation + hA; 78 ho = eE - crestElev; 79 co = 3.33 * (1 + 0.259 * pow(ho, 2) / pow(dA, 2)); 80 h1 = affluxElevation - crestElev; 81 h2 = tailwaterElev - crestElev; 82 h2_h1 = h2 / h1; 83 if (h2 <= 0) 84 { 85 correction = 1; 86 } 87 else 88 { 89 correction = pow((1 - pow(h2_h1, (3.0/2.0))), 0.385); 90 } 91 cs = co * correction; 92 calculatedDischargeIntensity = cs / 1.811 * pow(ho, (3.0 / 2.0)); 93 94 // My root-finding acceleration 95 if (calculatedDischargeIntensity < dischargeIntensity) 96 { 97 TRIAL_INCREMENT *= 2.1; 98 } 99 else 100 { 101 affluxElevation -= TRIAL_INCREMENT; 102 TRIAL_INCREMENT *= 0.75; 103 } 104 // End of root finding acceleration 105 } 106 107 // Calculation for the hydraulic jump 108 double d1, // Pre-jump height 109 d2, // Hydraulic jump height 110 he, 111 he2 = 0, // Pre-jump height to energy grade elevation 112 v1, 113 hv1; 114 float f; // Froude number 115 116 TRIAL_INCREMENT = 0.0001; // Reset 117 d1 = 0; 118 he = eE - dsApronElev; 119 120 // Froude number calculation 121 // Hydraulic jump calculation 122 while (abs(he - he2) > ERROR) 123 { 124 d1 += TRIAL_INCREMENT; 125 v1 = dischargeIntensity / d1; 126 hv1 = velocityHead(v1); 127 he2 = d1 + hv1; 128 d2 = (-1 * d1 / 2) + sqrt((pow(d1, 2) / 4.0) + (2 * pow(v1, 2) * d1 / GRAVITY)); 129 f = v1 / sqrt(d1 * GRAVITY); 130 } 131 132 // Length of hydraulic jump 133 if (f < 1.6) 134 { 135 lengthOfHydraulicJump = 4 * d2; 136 } else { 137 lengthOfHydraulicJump = hydraulicJump(f); 138 } 139 140 preJumpElev = dsApronElev + d1; 141 jumpElev = dsApronElev + d2; 142 143 errorMessage = "Calculation successful."; 144 return true; 145 } 146 147 private bool isValidInputs() 148 { 149 // Check for each input 150 if (isNaN(discharge)) 151 { 152 errorMessage = "Discharge must be set."; 153 return false; 154 } 155 156 if (isNaN(crestElev)) 157 { 158 errorMessage = "Crest elevation must be set."; 159 return false; 160 } 161 162 if (isNaN(crestLength)) 163 { 164 errorMessage = "Crest length must be set."; 165 return false; 166 } 167 168 if (isNaN(usApronElev)) 169 { 170 errorMessage = "Elevation of upstream apron must be set."; 171 return false; 172 } 173 174 if (isNaN(dsApronElev)) 175 { 176 errorMessage = "Elevation of downstream apron must be set."; 177 return false; 178 } 179 180 if (isNaN(tailwaterElev)) 181 { 182 errorMessage = "Elevation of tail water must be set."; 183 return false; 184 } 185 186 // Check if tailwater if lower than downstream apron 187 if (tailwaterElev < dsApronElev) 188 { 189 errorMessage = "Tailwater elevation must be set higher or the same as downstream apron."; 190 return false; 191 } 192 193 // Check crest is lower than upstream apron 194 if (crestElev < usApronElev) 195 { 196 errorMessage = "Crest elevation must be the same or higher then upstream apron."; 197 return false; 198 } 199 200 return true; 201 } 202 }