Advertisement
Guest User

Untitled

a guest
Nov 17th, 2019
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.31 KB | None | 0 0
  1. from __future__ import division
  2. import math
  3. import time
  4. from multiprocessing import Pool
  5. import random
  6. import os
  7. from numba import jit, prange
  8. import numpy as np
  9. import matplotlib.pyplot as plt
  10. from decimal import Decimal
  11. from productionoptimization import *
  12. from shutil import copyfile
  13. import re
  14. import subprocess
  15. import re
  16. import numpy as np
  17. import matplotlib.pyplot as plt
  18. import seaborn as sns
  19. import pandas as pd
  20. from mpl_toolkits.mplot3d import Axes3D
  21. import math
  22. from copy import deepcopy
  23. import pickle
  24. from shutil import copyfile
  25. import pickle
  26. import threading
  27.  
  28. import multiprocessing
  29. #.....................IMPORT MAIN Functions..................
  30. def check_Verticallayers(horizons, wells):
  31. for i, well in enumerate(wells):
  32. wells[i].horizons = []
  33. for j, horizon in enumerate(horizons):
  34. horizon_z = horizon.get_grid_block(well.trajectory_nodes[0].x, well.trajectory_nodes[0].y).get_center().prop
  35. if horizon_z > well.trajectory_nodes[0].prop and horizon_z < well.trajectory_nodes[1].prop:
  36. wells[i].horizons.append(j + 1)
  37.  
  38.  
  39. def get_well_welspecs(well, i, skeleton, well_type):
  40. if well_type == 'p':
  41. string = 'PRD' + str(i).zfill(3) + ' PRODUCER '
  42. end_string = 'OIL /\n'
  43. else:
  44. string = 'INJ' + str(i).zfill(3) + ' INJECTOR '
  45. end_string = 'WATER /\n'
  46.  
  47. grid_block = skeleton.get_grid_block(well.trajectory_nodes[0].x, well.trajectory_nodes[0].y)
  48. string += str(grid_block.i) + ', ' + str(182 - grid_block.j) + ', 1* ' + end_string
  49. return string
  50.  
  51.  
  52. def get_well_compdat(well, i, skeleton, well_type, horizon=None):
  53. well_lines = []
  54. if well_type == 'p':
  55. start_string = 'PRD' + str(i).zfill(3) + ' '
  56. else:
  57. start_string = 'INJ' + str(i).zfill(3) + ' '
  58.  
  59. if len(well.trajectory_nodes) == 2: # vertical
  60. node_skeleton = skeleton.get_grid_block(well.trajectory_nodes[0].x, well.trajectory_nodes[0].y)
  61. i = node_skeleton.i
  62. j = 182 - node_skeleton.j
  63.  
  64. for h in well.horizons:
  65. string = start_string + str(i) + ' ' + str(j) + ' ' + str(h) + ' ' + str(h)
  66.  
  67. string += ' OPEN 1* 1* 0.19050 1* 0.00 1* Z 1* /\n'
  68.  
  69. well_lines.append(string)
  70.  
  71. else:
  72. prev_i = 0
  73. prev_j = 0
  74. for node in well.trajectory_nodes:
  75. node_skeleton = skeleton.get_grid_block(node.x, node.y)
  76. i = node_skeleton.i
  77. j = 182 - node_skeleton.j
  78. if prev_i == i and prev_j == j:
  79. continue
  80. string = start_string + str(i) + ' ' + str(j) + ' ' + horizon + ' ' + horizon
  81.  
  82. string += ' OPEN 1* 1* 0.19050 1* 0.00 1* X 1* /\n'
  83.  
  84. well_lines.append(string)
  85.  
  86. return well_lines
  87.  
  88.  
  89. def prepare_datafile(filename, particle):
  90. file = 'Run' + str(particle) + '.DATA'
  91. file1 = 'Run' + str(particle)
  92. lines = open(filename, 'r').readlines()
  93. lines[-1] = '\'RUN_sch' + str(particle) + '.INC\' /'
  94. out = open(file, 'w')
  95. out.writelines(lines)
  96. out.close()
  97. return file1
  98.  
  99.  
  100. def prepare_schedule_file(filename, particle, producers, injectors, skeleton):
  101. lines = open(filename, 'r').readlines()
  102.  
  103. new_lines = []
  104.  
  105. copying = True
  106.  
  107. for li, line in enumerate(lines):
  108. if copying:
  109. new_lines.append(line)
  110.  
  111. if re.search(r'WELSPECS', line):
  112. copying = False
  113. for i, well in enumerate(producers):
  114. line = get_well_welspecs(well, i + 1, skeleton, 'p')
  115. new_lines.append(line)
  116. for i, well in enumerate(injectors):
  117. line = get_well_welspecs(well, i + 1, skeleton, 'i')
  118. new_lines.append(line)
  119.  
  120. new_lines.append(' /\n')
  121.  
  122. if re.match(r'\s*/', line):
  123. copying = True
  124.  
  125. if re.search(r'COMPDAT', line):
  126. print(copying)
  127. copying = False
  128. for i, well in enumerate(producers):
  129. well_lines = get_well_compdat(well, i + 1, skeleton, 'p')
  130. for l in well_lines:
  131. new_lines.append(l)
  132. for i, well in enumerate(injectors):
  133. well_lines = get_well_compdat(well, i + 1, skeleton, 'i')
  134. for l in well_lines:
  135. new_lines.append(l)
  136.  
  137. new_lines.append(' /\n')
  138.  
  139. if re.search(r'WCONPROD', line):
  140. copying = False
  141. for i, well in enumerate(producers):
  142. line = lines[li + 1]
  143. line = 'PRD' + str(i + 1).zfill(3) + line[6:]
  144. new_lines.append(line)
  145.  
  146. new_lines.append(' /\n')
  147.  
  148. if re.search(r'WCONINJE', line):
  149. copying = False
  150. for i, well in enumerate(injectors):
  151. line = lines[li + 1]
  152. line = 'INJ' + str(i + 1).zfill(3) + line[6:]
  153. new_lines.append(line)
  154.  
  155. new_lines.append(' /\n')
  156.  
  157. if re.search(r'WECON', line):
  158. copying = False
  159. for i, well in enumerate(producers):
  160. line = lines[li + 1]
  161. line = 'PRD' + str(i + 1).zfill(3) + line[6:]
  162. new_lines.append(line)
  163.  
  164. new_lines.append(' /\n')
  165.  
  166. filename = 'RUN_sch' + str(particle) + '.INC'
  167. out = open(filename, 'w')
  168. out.writelines(new_lines)
  169. out.close()
  170.  
  171.  
  172. def run_simulation(particle):
  173. file = 'Run' + str(particle)
  174. subprocess.call(['C:/ecl/2016.2/bin/pc_x86_64/eclipse ', file])
  175.  
  176.  
  177. def single_platform_optimiation(map, wells):
  178. minDis = 100000000000
  179. for i, nodes in map.nodes.items():
  180. wellsCost = 0
  181. for wells_ in wells:
  182. a = math.sqrt((nodes.x - wells_.trajectory_nodes[0].x) ** 2 + (
  183. nodes.y - wells_.trajectory_nodes[0].y) ** 2)
  184. b = math.sqrt((nodes.x - wells_.trajectory_nodes[-1].x) ** 2 + (
  185. nodes.y - wells_.trajectory_nodes[-1].y) ** 2)
  186. if a > b:
  187. cost = a * 10000 + 5000 * (wells_.trajectory_nodes[0].prop)
  188. else:
  189. cost = b * 10000 + 5000 * (wells_.trajectory_nodes[-1].prop)
  190. wellsCost = wellsCost + cost
  191. if wellsCost < minDis:
  192. minDis = wellsCost
  193. minNode = [nodes.x, nodes.y, 0]
  194. return minNode
  195.  
  196.  
  197. def well_cost_discounted(wells, platform_location):
  198. wellcost = []
  199. welltime = []
  200. for wells_ in wells:
  201. a = math.sqrt((platform_location[0] - wells_.trajectory_nodes[0].x) ** 2 + (
  202. platform_location[1] - wells_.trajectory_nodes[0].y) ** 2)
  203. b = math.sqrt((platform_location[0] - wells_.trajectory_nodes[-1].x) ** 2 + (
  204. platform_location[1] - wells_.trajectory_nodes[-1].y) ** 2)
  205. if a > b:
  206. cost = a * 10000 + 5000 * (wells_.trajectory_nodes[0].prop - platform_location[2])
  207. time = 0.015 * (wells_.trajectory_nodes[0].prop - platform_location[2]) + 0.02 * a
  208. else:
  209. cost = b * 10000 + 5000 * (wells_.trajectory_nodes[-1].prop - platform_location[2])
  210. time = 0.015 * (wells_.trajectory_nodes[-1].prop - platform_location[2]) + 0.02 * b
  211. wellcost.append(cost)
  212. welltime.append(time)
  213. return wellcost, welltime
  214.  
  215.  
  216. def read_rsm(file_name):
  217. filename = file_name + '.RSM'
  218. file = open(filename, "r")
  219. OilP = []
  220. WaterP = []
  221. WaterI = []
  222. Time = []
  223. WI_mult = 1
  224. WP_mult = 1
  225. OP_mult = 1
  226. for i, line in enumerate(file):
  227. if i == 6:
  228. if line[92:98] == '*10**3':
  229. WI_mult = 1000
  230. elif line[80:86] == '*10**3':
  231. WP_mult = 1000
  232. elif line[106:112] == '*10**3':
  233. OP_mult = 1000
  234. if i >= 10:
  235. data = [float(num) for num in line.split()]
  236. WaterPP, WaterII, Oil = data[-3:]
  237. time = data[0]
  238. Oil = Oil * OP_mult
  239. WaterPP = WaterPP * WP_mult
  240. WaterII = WaterII * WI_mult
  241. OilP.append(Oil)
  242. WaterP.append(WaterPP)
  243. WaterI.append(WaterII)
  244. Time.append(time)
  245. return OilP, WaterP, WaterI, Time
  246.  
  247.  
  248. def NPV_calculation(OilP, WaterP, WaterI, time, wellcost, welltime):
  249. DiscountFactor = 0.08
  250. OilCost = 45
  251. water_pcost = 6
  252. water_icost = 2
  253. discounted_rev = 0
  254. platformCost = 0000000
  255. k = 0
  256. discounted_cost = 0
  257. for i in range(len(OilP) - 1):
  258. discounted_rev = discounted_rev + (OilP[i + 1] - OilP[i]) * OilCost * 6.28 * (1 + DiscountFactor) ** (
  259. -time[i + 1] / 365) - (WaterP[i + 1] - WaterP[i]) * water_pcost * 6.28 * (1 + DiscountFactor) ** (
  260. -time[i + 1] / 365) - (WaterI[i + 1] - WaterI[i]) * water_icost * 6.28 * (
  261. 1 + DiscountFactor) ** (-time[i + 1] / 365)
  262. for i in range(len(wellcost)):
  263. k = k + 1
  264. discounted_cost = discounted_cost + wellcost[i] * (1 + DiscountFactor) ** (-(sum(welltime[:k]) / 365))
  265. discounted_rev = discounted_rev * (1 + DiscountFactor) ** (-(sum(welltime) / 365))
  266. NPV = discounted_rev - discounted_cost - platformCost
  267.  
  268. return NPV
  269. # --- COST FUNCTION ------------------------------------------------------------+
  270. # X[0] positon of the first well,,x[1] maximum number of wells, x[2] maximum number opf producers. x[3] = well spacing factor
  271. # function we are attempting to optimize (minimize)
  272.  
  273.  
  274. def func1(y, par,netmap,cutoff_map,horizons,skeleton):
  275. y=np.array(y)
  276. y[1:] = y[1:].round()
  277. drainage_area = (2500 * len(cutoff_map.grid))
  278. well_spacing = 2*(math.sqrt(drainage_area / y[1] / math.pi) * y[0])
  279.  
  280. first_well_location = list(cutoff_map.grid.values())[int(y[3])].get_center()
  281.  
  282. first_well = Well()
  283. first_well.generate_well(first_well_location, 2085)
  284.  
  285. netmap_half_spacing = deepcopy(netmap)
  286.  
  287. netmap.remove_disk(first_well_location.x, first_well_location.y, well_spacing)
  288. netmap_half_spacing.remove_disk(first_well_location.x, first_well_location.y, well_spacing/2)
  289. bh_operator = BHPatternWaterInjectionVertical(
  290. optimization_map=netmap,
  291. optimization_map_half_well_spacing=netmap_half_spacing,
  292. z0=0,
  293. total_depth=2085,
  294. max_number_wells=y[1] - 1,
  295. max_number_producers=y[2] - 1,
  296. max_number_injectors=y[1] - y[2],
  297. well_spacing=well_spacing,
  298. radius_optimal_option=0,
  299. radius_optimal_value=340)
  300.  
  301. producers, injectors, producers_map, injectors_map = bh_operator.generate_wells()
  302. producers.insert(0,first_well)
  303. wells = producers + injectors
  304. check_Verticallayers(horizons, wells)
  305. data_file = prepare_datafile("TEST_55t2.DATA", par)
  306. prepare_schedule_file("TEST_55_SCHt2.INC", par, producers, injectors, skeleton)
  307. run_simulation(par)
  308. single_platform_optimiation(netmap, wells)
  309. OIL, WATERP, WATERI, time = read_rsm(data_file)
  310. platform_location = single_platform_optimiation(horizons[0], wells)
  311. well_cost, well_time = well_cost_discounted(wells, platform_location)
  312. NPV = NPV_calculation(OIL, WATERP, WATERI, time, well_cost, well_time)
  313. return NPV
  314.  
  315. def func2(y, par, netmap, cutoff_map, horizons, skeleton,horizon_index):
  316. y[:, 1:] = y[:, 1:].round()
  317. drainage_area = (2500 * len(cutoff_map.grid))
  318. well_spacing = 2 * (math.sqrt(drainage_area / y[1] / math.pi) * y[0])
  319.  
  320. first_well_location = list(netmap.grid.values())[int(y[3])].get_center()
  321. first_well = Well()
  322. first_well.generate_well(first_well_location, 2085)
  323. first_well.generate_horizontal_section(y[4],20,0)
  324. first_well.optimize_horizontal_section_trajectory_azimuth(netmap,20)
  325.  
  326. netmap_half_spacing = deepcopy(netmap)
  327.  
  328. netmap.remove_disk(first_well_location.x, first_well_location.y, well_spacing)
  329. netmap_half_spacing.remove_disk(first_well_location.x, first_well_location.y, well_spacing / 2)
  330. bh_operator = BHPatternWaterInjectionHorizontal(
  331. optimization_map=netmap,
  332. optimization_map_half_well_spacing=netmap_half_spacing,
  333. z0=0,
  334. max_number_wells=y[1] - 1,
  335. max_number_producers=y[2] - 1,
  336. max_number_injectors=y[1] - y[2],
  337. well_spacing=well_spacing,
  338. azimuth_increment=20,
  339. horizon=horizons[horizon_index],
  340. well_length=y[4],
  341. number_of_segments=20,
  342. radius_optimal_option=0,
  343. radius_optimal_value=340)
  344.  
  345. producers, injectors, producers_map, injectors_map = bh_operator.generate_wells()
  346. producers.insert(0, first_well)
  347. wells = producers + injectors
  348. check_Verticallayers(horizons, wells)
  349. data_file = prepare_datafile("TEST_55t2.DATA", par)
  350. prepare_schedule_file("TEST_55_SCHt2.INC", par, producers, injectors, skeleton)
  351. run_simulation(par)
  352. single_platform_optimiation(netmap, wells)
  353. OIL, WATERP, WATERI, time = read_rsm(data_file)
  354. platform_location = single_platform_optimiation(horizon, wells)
  355. well_cost, well_time = well_cost_discounted(wells, platform_location)
  356. NPV = NPV_calculation(OIL, WATERP, WATERI, time, well_cost, well_time)
  357. return NPV
  358.  
  359.  
  360. # --- MAIN ---------------------------------------------------------------------+
  361.  
  362. class Particle:
  363. def __init__(self, x0):
  364. self.position_i = [] # particle position
  365. self.velocity_i = [] # particle velocity
  366. self.pos_best_i = [] # best position individual
  367. self.err_best_i = 0 # best error individual
  368. self.err_i = 0# error individual
  369.  
  370. for i in range(0, num_dimensions):
  371. # self.velocity_i.append(random.uniform(-1, 1))
  372. self.velocity_i.append(0)
  373. self.position_i.append(x0[i])
  374.  
  375. # evaluate current fitness
  376. def evaluate(self, costFunc, i,netmap,cutoff_map,horizons,skeleton):
  377. self.err_i = costFunc(self.position_i, i,netmap,cutoff_map,horizons,skeleton)
  378.  
  379. # check to see if the current position is an individual best
  380. if self.err_i > self.err_best_i:
  381. self.pos_best_i = self.position_i
  382. self.err_best_i = self.err_i
  383.  
  384. new_particle = deepcopy(self)
  385. return new_particle
  386. # update new particle velocity
  387. def update_velocity(self, pos_best_g):
  388. w = 0.7213
  389. c1 = 1.193
  390. c2 = 1.193
  391.  
  392. for i in range(0, num_dimensions):
  393. r1 = random.random()
  394. r2 = random.random()
  395.  
  396. vel_cognitive = c1 * r1 * (self.pos_best_i[i] - self.position_i[i])
  397. vel_social = c2 * r2 * (pos_best_g[i] - self.position_i[i])
  398. self.velocity_i[i] = w * self.velocity_i[i] + vel_cognitive + vel_social
  399.  
  400. # update the particle position based off new velocity updates
  401. def update_position(self, bounds):
  402. for i in range(0, num_dimensions):
  403. self.position_i[i] = self.position_i[i] + self.velocity_i[i]
  404.  
  405. # adjust maximum position if necessary
  406. if self.position_i[i] > bounds[i][1]:
  407. self.position_i[i] = bounds[i][1]
  408.  
  409. # adjust minimum position if neseccary
  410. if self.position_i[i] < bounds[i][0]:
  411. self.position_i[i] = bounds[i][0]
  412.  
  413.  
  414. class PSO():
  415. def __init__(self, costFunc, x0, bounds, num_particles, maxiter,netmap,cutoff_map,horizons,skeleton):
  416. self.costFunc = costFunc
  417. self.x0 = x0
  418. self.bounds = bounds
  419. self.num_particles = num_particles
  420. self.maxiter = maxiter
  421. self.netmap = netmap
  422. self.cutoff_map = cutoff_map
  423. self.horizons = horizons
  424. self.skeleton = skeleton
  425.  
  426. global num_dimensions
  427. xx = []
  428. num_dimensions = len(x0[0])
  429. err_best_g = 0 # best error for group
  430. pos_best_g = [] # best position for group
  431.  
  432. # establish the swarm
  433. swarm = []
  434. for i in range(0, num_particles):
  435. swarm.append(Particle(x0[i]))
  436.  
  437.  
  438. GBest = []
  439. GBest_position = []
  440.  
  441. costs = []
  442. # begin optimization loop
  443. k = 0
  444. while k < maxiter:
  445. # print i,err_best_g
  446. # cycle through particles in swarm and evaluate fitness
  447. processes = min(multiprocessing.cpu_count()-1, num_particles)
  448.  
  449. #for i in range(num_particles):
  450. # self.parallel_func(i)
  451. self.swarm = deepcopy(swarm)
  452. pool = multiprocessing.Pool(processes=processes)
  453. self.swarm = pool.map(self.parallel_func, range(num_particles), 1)
  454. pool.close()
  455. pool.join()
  456. swarm = deepcopy(self.swarm)
  457. for j in range(0, num_particles): # determine if current particle is the best (globally)
  458. if swarm[j].err_i > err_best_g :
  459. pos_best_g = list(swarm[j].position_i)
  460. err_best_g = float(swarm[j].err_i)
  461.  
  462. # cycle through swarm and update velocities and position
  463. for j in range(0, num_particles):
  464. swarm[j].update_velocity(pos_best_g)
  465. swarm[j].update_position(bounds)
  466.  
  467. print(Decimal(err_best_g))
  468. GBest.append(err_best_g)
  469. GBest_position.append(pos_best_g)
  470. err_best_g = err_best_g * 10E-6
  471. plt.scatter(k,err_best_g)
  472. plt.pause(0.0001)
  473. # print final results
  474. k += 1
  475. print (pos_best_g)
  476.  
  477. def parallel_func(self, j):
  478. a = self.swarm[j].evaluate(self.costFunc, j, self.netmap, self.cutoff_map, self.horizons, self.skeleton)
  479. return a
  480.  
  481. class ThreadWithReturnValue(threading.Thread):
  482. def __init__(self, group=None, target=None, name=None,
  483. args=(), kwargs={}, Verbose=None):
  484. threading.Thread.__init__(self, group, target, name, args, kwargs, Verbose)
  485. self._return = None
  486. def run(self):
  487. if self._Thread__target is not None:
  488. self._return = self._Thread__target(*self._Thread__args,
  489. **self._Thread__kwargs)
  490. def join(self):
  491. threading.Thread.join(self)
  492. return self._return
  493. # --- RUN ----------------------------------------------------------------------+
  494.  
  495. #
  496. def main():
  497. netmap = DataReader.read_map_from_ascii('maps/U22')
  498.  
  499. cutoff_map = deepcopy(netmap)
  500. cutoff_map.cut_map(1.5)
  501.  
  502. skeleton = DataReader.read_map_from_ascii('maps/TOP')
  503. horizons = []
  504. for i in range(1, 8):
  505. horizon = DataReader.read_map_from_ascii('maps/Horizon ' + str(i))
  506. horizons.append(horizon)
  507.  
  508. bounds = [(1,2.5), (6,6),(3,3),(0, len(cutoff_map.grid))] #spacing factor, #wells, #producers, 1st position
  509. number_particles = 10
  510. initial = []
  511. for i in range(number_particles):
  512. init = []
  513. for bound in bounds:
  514. init.append(np.random.uniform(bound[0], bound[1]))
  515. initial.append(init)
  516.  
  517. PSO(func1, initial, bounds, number_particles, 30,netmap,cutoff_map,horizons,skeleton)
  518.  
  519. # num_cores = multiprocessing.cpu_count()
  520. # results = Parallel(n_jobs=num_cores)(delayed(processFile)(f) for f in listdir("C:\\Dropbox\\Data"))
  521.  
  522. if __name__ == "__main__":
  523. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement