00001 #include "WDN.h"
00002
00003
00004
00005
00006
00007 int DiameterTable::lookupDiameterCode(float diameterSize)
00008 {
00009 int num = this->size();
00010 for (int i = 0; i < num; i++)
00011 {
00012 if (diameterSize == this->at(i).size)
00013 return i;
00014 }
00015
00016 return -1;
00017 }
00018
00019
00020
00021
00022
00023 void WDN::getNadirIdeal(vector<double>& nadir, vector<double>& ideal, int numVar)
00024 {
00025 nadir.resize(3);
00026 ideal.resize(3);
00027
00028 int* xnom = new int[numVar];
00029 for (int i = 0; i < numVar; i++)
00030 xnom[i] = 0;
00031 vector<float> flow(2*network.m, 1);
00032
00033 ideal[0] = isParallelExp() ? 0 : f1(NULL, xnom);
00034 ideal[1] = 1;
00035 ideal[2] = f3(flow);
00036
00037 for (int i = 0; i < numVar; i++)
00038 xnom[i] = diameterTable.size() - 1;
00039
00040 nadir[0] = f1(NULL, xnom);
00041 nadir[1] = 0;
00042 nadir[2] = 1;
00043
00044 delete [] xnom;
00045 }
00046
00047
00048
00049
00050
00051
00052
00053 void WDN::initialize(string simInputFileName, string simOutputFileName)
00054 {
00055 #ifdef DEBUG
00056 cout << "WDN::initialize()" << endl;
00057 #endif
00058
00059
00060
00061
00062 char temp[LEN], temp2[LEN], temp3[] = "";
00063 int errorCode = ENopen(strcpy(temp, simInputFileName.c_str()), strcpy(temp2, simOutputFileName.c_str()), temp3);
00064 if (errorCode != 0)
00065 {
00066 cerr << "WDN: EPANET simulator returned error code " << errorCode << " while trying to initialize! Exiting." << endl;
00067 exit(1);
00068 }
00069
00070
00071 ifstream infile(simInputFileName.c_str());
00072 char line[LEN], * pNext;
00073 Diameter newDiameter;
00074 Pipe newPipe;
00075
00076 skipLinesUntil(infile, HEADER_DIAMETERS);
00077 infile.getline(line, LEN);
00078 do
00079 {
00080 infile.getline(line, LEN);
00081 newDiameter.size = (float) strtod(line, &pNext);
00082 newDiameter.price = (float) strtod(pNext, NULL);
00083 diameterTable.push_back(newDiameter);
00084 }
00085 while (diameterTable.back().size != 0.0);
00086
00087 diameterTable.pop_back();
00088
00089
00090 skipLinesUntil(infile, HEADER_MISC);
00091 pressureZero = (float) strtod(getValue(infile), NULL);
00092 pressureReq = (float) strtod(getValue(infile), NULL);
00093 convDiamSize = (float) strtod(getValue(infile), NULL);
00094 parallelExp = (atoi(getValue(infile)) == 1) ? true : false;
00095
00096 infile.close();
00097
00098
00099 ENgetcount(EN_LINKCOUNT, &network.m);
00100 ENgetcount(EN_NODECOUNT, &network.n);
00101 ENgetcount(EN_TANKCOUNT, &network.r);
00102 network.n -= network.r;
00103
00104 if (parallelExp)
00105 {
00106
00107 network.m /= 2;
00108
00109
00110 newDiameter.size = 0;
00111 newDiameter.price = 0;
00112 diameterTable.insert(diameterTable.begin(), 1, newDiameter);
00113 }
00114
00115
00116 for (int i = 0; i < network.m; i++)
00117 {
00118 ENgetlinkvalue(i+1, EN_LENGTH, &newPipe.length);
00119 ENgetlinkvalue(i+1, EN_ROUGHNESS, &newPipe.roughness);
00120 ENgetlinknodes(i+1, &newPipe.beginNode, &newPipe.endNode);
00121 newPipe.beginNode--;
00122 newPipe.endNode--;
00123 network.pipe.push_back(newPipe);
00124 }
00125
00126
00127 if (parallelExp)
00128 {
00129 for (int i = 0; i < network.m; i++)
00130 {
00131 ENgetlinkvalue(i+1+network.m, EN_LENGTH, &newPipe.length);
00132 ENgetlinkvalue(i+1+network.m, EN_ROUGHNESS, &newPipe.roughness);
00133 ENgetlinknodes(i+1+network.m, &newPipe.beginNode, &newPipe.endNode);
00134 newPipe.beginNode--;
00135 newPipe.endNode--;
00136 network.existPipe.push_back(newPipe);
00137 }
00138 }
00139
00140
00141 network.elevation.resize(network.n);
00142 network.Q.resize(network.n);
00143 for (int j = 0; j < network.n; j++)
00144 {
00145 ENgetnodevalue(j+1, EN_ELEVATION, &network.elevation[j]);
00146 ENgetnodevalue(j+1, EN_BASEDEMAND, &network.Q[j]);
00147 }
00148
00149
00150 ENopenH();
00151
00152 F.resize(3, 0);
00153 }
00154
00155 void WDN::simulate(Individual* I, int* xnom, int numVar, double* noise)
00156 {
00157 #ifdef DEBUG
00158 cout << "WDN::simulate()" << endl;
00159 #endif
00160
00161 if (numVar < network.m && !(numVar == network.m / 2 && parallelExp))
00162 {
00163 cerr << "WDN: number of decision variables, numVar = " << numVar << ", is less than the number of pipes in the network, m = " << network.m
00164 << "! Exiting." << endl;
00165 close();
00166 exit(1);
00167 }
00168
00169 long t, tStep;
00170 F.assign(3, 0);
00171
00172
00173 if (noise != NULL)
00174 {
00175 for (int j = 0; j < network.n; j++)
00176 ENsetnodevalue(j+1, EN_BASEDEMAND, network.Q[j] + (noise[j] * cvDemand * network.Q[j]));
00177
00178 float a, b;
00179 for (int i = 0; i < network.m; i++)
00180 {
00181 a = network.pipe[i].roughness - (cvRoughness * network.pipe[i].roughness);
00182 b = network.pipe[i].roughness + (cvRoughness * network.pipe[i].roughness);
00183 ENsetlinkvalue(i+1, EN_ROUGHNESS, a + (noise[i+network.n] * (b-a)));
00184 }
00185 }
00186
00187
00188 for (int i = 0; i < network.m; i++)
00189 {
00190 if (diameterTable[((I != NULL) ? I->D[i] : xnom[i])].size > 0.0)
00191 {
00192 ENsetlinkvalue(i+1, EN_INITSTATUS, 1);
00193 ENsetlinkvalue(i+1, EN_DIAMETER, (diameterTable[((I != NULL) ? I->D[i] : xnom[i])].size) * convDiamSize);
00194 }
00195 else
00196 ENsetlinkvalue(i+1, EN_INITSTATUS, 0);
00197 }
00198
00199
00200 ENinitH(0);
00201 do
00202 {
00203 ENrunH(&t);
00204 ENnextH(&tStep);
00205 }
00206 while (tStep > 0);
00207
00208
00209 vector<float> flow((parallelExp) ? network.m * 2 : network.m, 0);
00210 for (int i = 0; i < network.m; i++)
00211 ENgetlinkvalue(i+1, EN_FLOW, &flow[i]);
00212
00213 if (parallelExp)
00214 {
00215 for (int i = 0; i < network.m; i++)
00216 ENgetlinkvalue(i+1+network.m, EN_FLOW, &flow[i]);
00217 }
00218
00219
00220 vector<float> pressure(network.n, 0);
00221 for (int j = 0; j < network.n; j++)
00222 {
00223 ENgetnodevalue(j+1, EN_HEAD, &pressure[j]);
00224 pressure[j] -= network.elevation[j];
00225 }
00226
00227
00228 F[0] = f1(I, xnom);
00229 F[1] = f2(pressure);
00230 F[2] = f3(flow);
00231
00232 if (I != NULL)
00233 I->F = F;
00234 }
00235
00236
00237 double WDN::f1(Individual* I, int* xnom)
00238 {
00239 #ifdef DEBUG
00240 cout << "WDN::f1()" << endl;
00241 #endif
00242
00243 double sum = 0;
00244
00245 for (int i = 0; i < network.m; i++)
00246 sum += diameterTable[((I != NULL) ? I->D[i] : xnom[i])].price * network.pipe[i].length;
00247
00248 return sum;
00249 }
00250
00251
00252 double WDN::f2(vector<float>& pressure)
00253 {
00254 #ifdef DEBUG
00255 cout << "WDN::f2()" << endl;
00256 #endif
00257
00258 vector<double> frac_met(network.n, 0);
00259 double weightedSum = 0,
00260 totalQ = 0;
00261
00262
00263 for (int j = 0; j < network.n; j++)
00264 {
00265 if (pressure[j] < pressureZero)
00266 frac_met[j] = 0;
00267 else if (pressure[j] > pressureReq)
00268 frac_met[j] = 1;
00269 else
00270 frac_met[j] = sqrt((pressure[j] - pressureZero) / (pressureReq - pressureZero));
00271 }
00272
00273 for (int j = 0; j < network.n; j++)
00274 {
00275 weightedSum += frac_met[j] * network.Q[j];
00276 totalQ += network.Q[j];
00277 }
00278
00279 return (weightedSum / totalQ);
00280 }
00281
00282
00283 double WDN::f3(vector<float>& flow)
00284 {
00285 #ifdef DEBUG
00286 cout << "WDN::f3()" << endl;
00287 #endif
00288
00289 vector<double> in(network.n, 0),
00290 s(network.n, 0);
00291 double IN = 0,
00292 S = 0;
00293
00294
00295 for (int j = 0; j < network.n; j++)
00296 {
00297
00298 for (int i = 0; i < network.m; i++)
00299 {
00300 if ((flow[i] > 0 && j == network.pipe[i].endNode) ||
00301 (flow[i] < 0 && j == network.pipe[i].beginNode))
00302 in[j] += fabs(flow[i]);
00303 }
00304
00305
00306 if (parallelExp)
00307 {
00308 for (int i = 0; i < network.m; i++)
00309 {
00310 if ((flow[i+network.m] > 0 && j == network.existPipe[i].endNode) ||
00311 (flow[i+network.m] < 0 && j == network.existPipe[i].beginNode))
00312 in[j] += fabs(flow[i+network.m]);
00313 }
00314 }
00315
00316 IN += in[j];
00317 }
00318
00319
00320 for (int j = 0; j < network.n; j++)
00321 {
00322
00323 for (int i = 0; i < network.m; i++)
00324 {
00325 if ((flow[i] > 0 && j == network.pipe[i].endNode) ||
00326 (flow[i] < 0 && j == network.pipe[i].beginNode))
00327 s[j] -= (fabs(flow[i]) / in[j]) * log(fabs(flow[i]) / in[j]);
00328 }
00329
00330
00331 if (parallelExp)
00332 {
00333 for (int i = 0; i < network.m; i++)
00334 {
00335 if ((flow[i+network.m] > 0 && j == network.existPipe[i].endNode) ||
00336 (flow[i+network.m] < 0 && j == network.existPipe[i].beginNode))
00337 s[j] -= (fabs(flow[i+network.m]) / in[j]) * log(fabs(flow[i+network.m]) / in[j]);
00338 }
00339 }
00340
00341 S += (in[j] / IN) * (s[j] - log(in[j] / IN));
00342 }
00343
00344
00345 return exp(S);
00346 }
00347
00348
00349 void WDN::close()
00350 {
00351 #ifdef DEBUG
00352 cout << "WDN::close()" << endl;
00353 #endif
00354
00355 ENcloseH();
00356 ENclose();
00357 }
00358