From 10375e1faf39938d14cbd30b57193a162fccb40c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Santisi?= Date: Thu, 25 Apr 2024 21:04:24 +0000 Subject: [PATCH] =?UTF-8?q?C=C3=A1lculo=20de=20potencias?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/exclamacion_50.stl | Bin 0 -> 89484 bytes index.html | 39 +++++++++--- js/main.js | 131 +++++++++++++++++++++++++++++++------- js/screen.js | 4 +- js/spring.js | 2 +- js/windmill.js | 44 +++++++++++-- server.py | 8 ++- style.css | 50 +++++++++++---- xxx.py | 18 +++--- 9 files changed, 232 insertions(+), 64 deletions(-) create mode 100644 assets/exclamacion_50.stl diff --git a/assets/exclamacion_50.stl b/assets/exclamacion_50.stl new file mode 100644 index 0000000000000000000000000000000000000000..1d4dcca0b72cff6ad80b96741e9a728cb7fd4ee6 GIT binary patch literal 89484 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 LiZLXZ+bsKkNY#j; literal 0 HcmV?d00001 diff --git a/index.html b/index.html index a026ae2..cb9099a 100644 --- a/index.html +++ b/index.html @@ -34,14 +34,31 @@ function help() { '

Desarrollado por:

  • Dimas Barile (CSC-CONICET)
  • José Alberto Martínez Trespalacios (Universidad Tecnológica de Bolívar)
  • Sebastián Santisi (CSC-CONICET)
'); } -function up() { light.shadow.camera.top += 1; light.shadow.camera.updateProjectionMatrix(); helper.update()} +/*function up() { light.shadow.camera.top += 1; light.shadow.camera.updateProjectionMatrix(); helper.update()} function down() { light.shadow.camera.bottom -= 1; light.shadow.camera.updateProjectionMatrix(); helper.update()} function left() { light.shadow.camera.left -= 1; light.shadow.camera.updateProjectionMatrix(); helper.update()} - function right() { light.shadow.camera.right += 1; light.shadow.camera.updateProjectionMatrix(); helper.update()} + function right() { light.shadow.camera.right += 1; light.shadow.camera.updateProjectionMatrix(); helper.update()} */ +function rot(angle) { + document.getElementById("rot0").className = document.getElementById("rot225").className = document.getElementById("rot270").className = document.getElementById("rot315").className = ""; + document.getElementById("rot" + angle).className = "sel"; + ws.setRotation(angle); +} + +document.addEventListener('mousemove', follow, false); +function follow(e) { + follower = document.getElementById("follower"); + status = follower.style.display; + follower.style.display = "block"; + follower.style.left = (e.clientX - follower.clientWidth) + 'px'; + follower.style.top = (e.clientY - follower.clientHeight) + 'px'; + follower.style.display = status; +}
+
+
Resultados
-
¡SIMULAR!
-
+

Rotá tu
dispositivo

diff --git a/js/main.js b/js/main.js index b7e3acb..08c39ee 100644 --- a/js/main.js +++ b/js/main.js @@ -26,8 +26,11 @@ class WindSimulation { this.wm = null; this.simulation = null; + this.simulationPot = null; this.xhr = null; + this.lastFrame = Date.now(); + this.rotation = Math.PI; this.targetRotation = Math.PI; this.dir = 0; @@ -64,18 +67,19 @@ class WindSimulation { for(var i = 0; i < this.mills; i++) { var wm = new WindMill(); wm.position.set(4 + 0.5, i + 5 - Math.ceil(this.mills / 2) + 0.5, 0); - wm.rotation.z = Math.PI; + wm.rotation.z = this.targetRotation; scene.add(wm); this.wms.push(wm); } this.wm = this.wms[0]; } - move(pos, ended=false) { - if(this.simulation) { - scene.remove(this.simulation); - this.simulation = null; - } + move(pos, ended=false, count=2) { + if(this.simulation) + this.resetSimulation(); + + if(! count) + return false; var wm = this.wm; @@ -85,11 +89,22 @@ class WindSimulation { } if(wm == null) return false; - if(pos.x > this.width - 0.5 || pos.x < 0.5 || pos.y > this.height - 0.5 || pos.y < 0.5) return false; + if(pos.x > this.width - 0.5 || pos.x < 0.5 || pos.y > this.height - 0.5 || pos.y < 0.5) { + if(pos.x > this.width - 0.5) + pos.x = this.width - 0.5; + if(pos.x < 0.5) + pos.x = 0.5; + if(pos.y > this.height - 0.5) + pos.y = this.height - 0.5; + if(pos.y < 0.5) + pos.y = 0.5; + return this.move(pos, ended, count - 1); + } for(var i = 0; i < this.wms.length; i++) { if(this.wms[i] == wm) continue; - if(pos.clone().sub(this.wms[i].position).length() < 1) - return false; + if(pos.clone().sub(this.wms[i].position).length() < 1) { + return this.move(this.wms[i].position.clone().add(pos.clone().sub(this.wms[i].position).normalize()), ended, count - 1); + } } wm.position.x = pos.x; wm.position.y = pos.y; @@ -99,11 +114,14 @@ class WindSimulation { animate() { requestAnimationFrame(() => { this.animate(); }); + var now = Date.now(); + var step = (now - this.lastFrame) / 1000; + if(!Screen.isMobile || (Screen.isMobile && screen.clicked)) { const intersects = screen.raycaster.intersectObjects(this.wms); var wm = null; for(var i = 0; i < intersects.length; i++) { - if(intersects[i].object.geometry.constructor.name != "CylinderGeometry") { + if(intersects[i].object.constructor.name != "Spring") { wm = intersects[i].object.parent; break; } @@ -111,22 +129,32 @@ class WindSimulation { if(!screen.clicked || Screen.isMobile) { if(this.wm != wm) { - if(this.wm != null) this.wm.select(false); - if(wm != null) wm.select(true); + if(this.wm != null) { + this.wm.select(false); + document.getElementById("follower").style.display = "none"; + } + if(wm != null) { + wm.select(true); + if(this.simulation) { + var i = this.wms.indexOf(wm); + var follower = document.getElementById("follower"); + follower.innerHTML = "Aerogenerador Nº" + (i + 1) + "
" + (Math.round(this.simulationPot[i] * 100) / 100) + " GWh (" + Math.round(this.simulationPot[i] * 100 / 14.95) + "%)"; + follower.style.display = "block"; + } + } } this.wm = wm; } } for(var i = 0; i < this.wms.length; i++) - this.wms[i].animate(); + this.wms[i].animate(step); - var speed = 0.02; + var speed = 2 * step; if(Math.abs(this.targetRotation - this.rotation) > speed) { var step = speed * Math.sign(this.targetRotation - this.rotation); this.rotation += step; for(var i = 0; i < this.wms.length; i++) { - this.wms[i].animate(); this.wms[i].rotation.z += step; } this.flag.rotation.z += step; @@ -134,14 +162,25 @@ class WindSimulation { this.flag.animate(); + if(window.exclamation) + window.exclamation.rotation.y += 0.02; + + this.lastFrame = now; + renderer.render(scene, camera); } + resetSimulation() { + scene.remove(this.simulation); + this.simulation = null; + this.simulationPot = null; + document.getElementById("follower").style.display = "none"; + document.getElementById("results").style.display = "none"; + } + setRotation(dir) { - if(this.simulation) { - scene.remove(this.simulation); - this.simulation = null; - } + if(this.simulation) + this.resetSimulation(); var rotations = {}; rotations[0] = Math.PI; @@ -153,6 +192,30 @@ class WindSimulation { this.targetRotation = rotations[dir]; } + addWindMill() { + if(this.mills >= 10) return; + + this.mills++; + this.reset(); + } + + removeWindMill() { + if(this.mills <= 1) return; + + this.mills--; + this.reset(); + } + + reset() { + for(var i = 0; i < this.wms.length; i++) + scene.remove(this.wms[i]); + + this.wms = []; + this.rotation = this.targetRotation; + + this.init_windmills(); + } + simulate() { if(this.xhr != null) this.xhr.abort(); @@ -165,7 +228,8 @@ class WindSimulation { if(this.xhr != xhr) return; if (xhr.readyState === 4 && xhr.status === 200) { var json = JSON.parse(xhr.responseText); - this.add_simulation(json.ws); + console.log(json.pot) + this.add_simulation(json.ws, json.pot); this.xhr = null; } }; @@ -176,7 +240,17 @@ class WindSimulation { xhr.send(data); } - add_simulation(ws) { + add_simulation(ws, pot) { + var sum = 0; + for(let i = 0; i < pot.length; i++) { + this.wms[i].lowPower(pot[i] < 2.75/*14.95 * 0.8*/) + sum += pot[i]; + } + + var results = document.getElementById("results") + results.innerHTML = (Math.round(sum * 100) / 100) + " GWh (" + Math.round(sum * 100 / 14.95 / pot.length) + "%)"; + results.style.display = "block"; + var geometry = new THREE.PlaneGeometry(this.width, this.height, 10 * this.width, 10 * this.height); var colors = new three.BufferAttribute(new Float32Array(geometry.attributes.position.count * 4), 4); geometry.setAttribute('color', colors); @@ -190,8 +264,9 @@ class WindSimulation { } if(this.simulation) - scene.remove(this.simulation); + this.resetSimulation(); this.simulation = mesh; + this.simulationPot = pot; scene.add(mesh); } } @@ -200,7 +275,7 @@ var width = 10; var height = 10; var ws = new WindSimulation(width, height, 5); -var screen = new Screen(camera, renderer, new THREE.Vector3(width / 2 + 0.5, height / 2, -0.65)); +var screen = new Screen(camera, renderer, new THREE.Vector3(width / 2 + 0.5, height / 2, -0.3)); screen.setMoveCallBack((pos, end) => { ws.move(pos, end); }); screen.onResize(); @@ -232,6 +307,16 @@ window.light = light; //scene.add( helper); //window.helper = helper; + + + + +window.windmill = WindMill; + + + + + window.ws = ws; window.screen = screen; window.scene = scene; diff --git a/js/screen.js b/js/screen.js index 023d49c..569dc9d 100644 --- a/js/screen.js +++ b/js/screen.js @@ -14,11 +14,11 @@ class Screen { this.pointerScreen = new THREE.Vector2(); this.pointerWorld = new THREE.Vector3(); - this.radius = 24; + this.radius = 26; this.phi = -0.5; this.theta = 0.45; this.z = 15; - this.aspect = 2.13; + this.aspect = 1.94; this.clicked = false; diff --git a/js/spring.js b/js/spring.js index cb92868..b2be7aa 100644 --- a/js/spring.js +++ b/js/spring.js @@ -1,7 +1,7 @@ import * as THREE from 'three'; // https://discourse.threejs.org/t/solved-create-a-spring/45135/9 -class Spring extends THREE.Mesh{ +class Spring extends THREE.Mesh { constructor(radius, turns, segmentsPerTurn, height, growth, material){ let g = new THREE.CylinderGeometry(0.005, 0.005, 1, 16, segmentsPerTurn * turns).translate(0, 0.5, 0).rotateX(Math.PI * 0.5); let initPos = g.attributes.position.clone(); diff --git a/js/windmill.js b/js/windmill.js index 7251fc6..591dd6b 100644 --- a/js/windmill.js +++ b/js/windmill.js @@ -6,6 +6,7 @@ import { Spring } from './spring.js'; class WindMill extends THREE.Group { static geometryBody = null; static geometryBlades = null; + static geometryExclamation = null; static { const loader = new STLLoader(); @@ -16,15 +17,25 @@ class WindMill extends THREE.Group { //loader.load('assets/cuerpo_126m_50.stl', function(geometry) { WindMill.geometryBody = geometry; }); + loader.load('assets/exclamacion_50.stl', function(geometry) { + WindMill.geometryExclamation = geometry; + var colors = new three.BufferAttribute(new Float32Array(geometry.attributes.position.array.length), 3); + for(let i = 0; i < colors.count; i++) + if(Math.abs(geometry.attributes.position.getZ(i)) < 7.4) + colors.setXYZ(i, 0xfa / 0xff, 0xd5 / 0xff, 0x0a / 0xff); + WindMill.geometryExclamation.setAttribute('color', colors); + }); } static isReady() { - return WindMill.geometryBody != null && WindMill.geometryBlades != null; + return WindMill.geometryBody != null && WindMill.geometryBlades != null && WindMill.geometryExclamation != null; } constructor() { super() + this.isLow = false; + this.material = new THREE.MeshStandardMaterial({color: 0xffffff, roughness: 0.15}); this.materialCircle = new THREE.MeshStandardMaterial({color: 0xaa0000}); //this.materialCircle.transparent = true; @@ -84,20 +95,32 @@ class WindMill extends THREE.Group { this.spring1.visible = this.spring2.visible = this.spring3.visible = false; + var material = new THREE.MeshStandardMaterial({color: 0xfad50a, roughness: 0.15, vertexColors: true}); + this.meshExclamation = new THREE.Mesh(WindMill.geometryExclamation, material); + this.meshExclamation.castShadow = true; + //this.meshExclamation.receiveShadow = true; + this.meshExclamation.scale.setScalar(0.002); + this.meshExclamation.rotateX(Math.PI / 2); + this.meshExclamation.position.z = (90 + 126 / 2 + 1) / 126; + this.add(this.meshExclamation); + this.meshExclamation.visible = false; + this.selected = false; } - animate() { - this.meshBlades.rotation.x += 0.1; - this.spring1.rotation.x += 0.1; - this.spring2.rotation.x += 0.1; - this.spring3.rotation.x += 0.1; + animate(step) { + var inc = (this.isLow ? 0.3 : 3) * step; + this.meshBlades.rotation.x += inc; + this.spring1.rotation.x += inc; + this.spring2.rotation.x += inc; + this.spring3.rotation.x += inc; + this.meshExclamation.rotation.y += 4 * step; } select(selected) { if(selected == this.selected) return; this.selected = selected; - this.meshCircle.visible = selected; + this.meshCircle.visible = selected; if(selected) this.material.color.set(0xff0000); @@ -105,6 +128,13 @@ class WindMill extends THREE.Group { this.material.color.set(0xffffff); } + lowPower(isLow) { + if(this.isLow == isLow) return; + this.isLow = isLow; + + this.meshExclamation.visible = isLow; + } + show_springs(value) { this.spring1.visible = this.spring2.visible = this.spring3.visible = value; } diff --git a/server.py b/server.py index 25386f8..961e36e 100644 --- a/server.py +++ b/server.py @@ -9,13 +9,19 @@ import xxx def index(): if request.method != 'POST' or not request.data: return abort(400); + params = json.loads(request.data.decode(encoding='utf-8')) pos = params['pos'] direction = params['dir'] - ws = xxx.run(direction, pos); + + if len(pos) > 10 or direction not in (0, 225, 270, 315): + return abort(400); + + ws, pot = xxx.run(direction, pos); return { 'pos': pos, 'ws': ws, + 'pot': pot, 'dir': direction, } diff --git a/style.css b/style.css index e5fec23..b6f94a8 100644 --- a/style.css +++ b/style.css @@ -1,3 +1,8 @@ +* { + margin: 0; + padding: 0; +} + body { margin: 0; font-family: "Encode Sans", sans-serif; @@ -34,7 +39,7 @@ body { } #popup p + p { - margin-top: -3vh; + margin-top: 1vh; } .l { @@ -58,9 +63,7 @@ body { } #button { - position: absolute; - right: 4vh; - top: 4vh; + display: inline-block; padding: 4vh; background: darkblue; font-weight: 800; @@ -70,24 +73,45 @@ body { background: blue; } -#help { +#right { position: absolute; - right: 4vh; - top: 16vh; + max-width: 75vw; + text-align: right; + right: 1vh; + top: 1vh; font-weight: 800; font-size: .8em; } -#help li { - display: block; - float: left; +#right li { + display: inline-block; border: solid white .5vh; - padding: .1vh 1vh; border-radius: 1vh; cursor: pointer; - margin-left: 1vh; - width: 2.5vh; + margin-bottom: 1vh; + width: 4vh; + height: 4vh; text-align: center; + opacity: 0.5; +} + +#right li.sel, #right li:hover { + opacity: 1; +} + +#follower, #results { + border: solid white 1px; + z-index: 900; + position: absolute; + background: #00000088; + padding: 1vh; + font-size: .5em; + display: none; +} + +#results { + bottom: 1vh; + left: 1vh; } #copyright { diff --git a/xxx.py b/xxx.py index 0a5bd90..bd46890 100644 --- a/xxx.py +++ b/xxx.py @@ -65,15 +65,15 @@ def py_wake_Initial_Cong(D,name,h,U_ref,initial_position=initial_position): method='linear')) - - - - windTurbines = py_wake_Initial_Cong(D, 'NREL_5MW', h, U_ref) +grid = XYGrid(x=np.arange(0, 10.01, 0.1)*D, y=np.arange(0, 10.01, 0.1)*D) def run(direction=0, initial_position=initial_position, U_ref=U_ref): initial_position = np.array(initial_position); - site = UniformSite(p_wd=[1] * 8, + p_wd = [0] * 360 + #p_wd[direction * n // 360] = 1 + p_wd[direction] = 1 + site = UniformSite(p_wd=p_wd, ws=U_ref, initial_position=initial_position*D) #ds = xr.Dataset( @@ -84,7 +84,9 @@ def run(direction=0, initial_position=initial_position, U_ref=U_ref): wt_x, wt_y = site.initial_position.T/D wfm = PropagateDownwind(site, windTurbines, wake_deficitModel=TurboGaussianDeficit()) - grid = XYGrid(x=np.arange(0, 10.01, 0.1)*126, y=np.arange(0, 10.01, 0.1)*126) - xa = wfm(x=wt_x*126, y=wt_y*126, wd=direction, yaw=0).flow_map(grid) + xa = wfm(x=wt_x*D, y=wt_y*D, wd=direction, yaw=0).flow_map(grid) ws = xa.WS_eff - return ws[:,:,0,0].values[:,:,0].tolist() + + aep = wfm(x=wt_x*D, y=wt_y*D).aep() + + return ws[:,:,0,0].values[:,:,0].tolist(), [sum(aep.values[i,:,0]) for i in aep.wt.values]