diff --git a/src/app.rs b/src/app.rs index 5a494ca..be1999b 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,9 +1,9 @@ -use crate::components::BackgroundProps; use crate::components::Background; -use crate::routes::whymdc::*; -use crate::routes::home::*; -use crate::routes::empty::*; +use crate::components::BackgroundProps; use crate::routes::blog::*; +use crate::routes::empty::*; +use crate::routes::home::*; +use crate::routes::whymdc::*; use leptos::*; use leptos_meta::*; use leptos_router::*; @@ -44,4 +44,3 @@ pub fn App(cx: Scope) -> impl IntoView { } } - diff --git a/src/components/background.rs b/src/components/background.rs index 64923ed..3c2e41c 100644 --- a/src/components/background.rs +++ b/src/components/background.rs @@ -40,7 +40,11 @@ pub fn Background(cx: Scope, class: &'static str) -> impl IntoView { context_to_render.move_to(n.position.x.into(), n.position.y.into()); context_to_render.line_to(child.position.x.into(), child.position.y.into()); }; - let mut sc = SpaceColonization::new(width.try_into().unwrap(), height.try_into().unwrap(), render_node_fn); + let mut sc = SpaceColonization::new( + width.try_into().unwrap(), + height.try_into().unwrap(), + render_node_fn, + ); let nodes = Rc::new(RefCell::new(Vec::new())); nodes.borrow_mut().push(Node::new(Point::new(( (window_width / 3) as i32, diff --git a/src/components/mod.rs b/src/components/mod.rs index d9ed078..0909c65 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -1,6 +1,6 @@ -mod codeblock; -mod code; mod background; -pub use codeblock::*; -pub use code::*; +mod code; +mod codeblock; pub use background::*; +pub use code::*; +pub use codeblock::*; diff --git a/src/lib.rs b/src/lib.rs index 716860b..4e330e5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ -mod space_colonization; pub mod app; mod components; mod routes; +mod space_colonization; use cfg_if::cfg_if; cfg_if! { diff --git a/src/routes/blog/page.rs b/src/routes/blog/page.rs index 125bd47..d83074b 100644 --- a/src/routes/blog/page.rs +++ b/src/routes/blog/page.rs @@ -1,6 +1,6 @@ +use crate::components::*; use leptos::*; use leptos_meta::*; -use crate::components::*; #[component] pub fn Blog(cx: Scope) -> impl IntoView { diff --git a/src/routes/mod.rs b/src/routes/mod.rs index 22d4b35..e0a4fc8 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -1,4 +1,4 @@ -pub mod whymdc; -pub mod home; pub mod blog; pub mod empty; +pub mod home; +pub mod whymdc; diff --git a/src/routes/whymdc/components.rs b/src/routes/whymdc/components.rs index 4f80ef4..69ab382 100644 --- a/src/routes/whymdc/components.rs +++ b/src/routes/whymdc/components.rs @@ -3,7 +3,7 @@ use leptos::*; #[component] pub fn Subtitle(cx: Scope, class: &'static str, children: Children) -> impl IntoView { let class = format!("text-3xl font-bold text-white {}", class); - view! { cx, + view! { cx,
"Tous les systèmes économiques sont basés sur deux variables fondamentales: le temps et l’énergie. Depuis des millénaires l’or est dispendieux. Parce qu’il requiert beaucoup de temps et d’énergie à trouver. Depuis toujours l’eau a une valeur différente à différents endroits de la planète et moments de l’année, en fonction du temps et de l’énergie requis pour la trouver. D’ailleurs, l’énergie est souvent représentée comme fonction du temps. L’unité d’énergie choisie par le Système International, le Joule, s’exprime en Kilogramme X Mètre2 X Seconde2. "
@@ -32,14 +32,14 @@ pub fn WhyMicroDatacenters(cx: Scope) -> impl IntoView { "Il convient donc de considérer l’énergie comme fondement principal des différents systèmes économiques. Ce livre blanc vise à étudier les caractéristiques économiques selon différentes métriques naturelles, dont l’énergie est la plus importante, des différentes technologies de déploiement de centres de données. Cette analyse vise plus particulièrement à comparer l’efficacité énergétique, et donc économique, des déploiements de centres de données à très petite et très grande échelle."- "L’impact global sera calculé en fonction des 5 métriques présentées ci-dessous." + "L’impact global sera calculé en fonction des 5 métriques présentées ci-dessous."
+
"Un MCD est une unité de serveurs de petite taille pouvant être installée dans n’importe quel immeuble, tant les maisons unifamiliales que les gratte-ciels ou les usines. Sa taille est adaptée aux besoins énergétiques de l’immeuble qui l’abrite. Les rejets énergétiques, le plus souvent sous forme de chaleur, sont réutilisés au maximum dans l’immeuble pour le chauffer. Ils peuvent également être utilisée pour chauffer l’eau, ou même regénérer de l’électricité dans certains cas. Ce type de déploiement réduit également les besoins de climatisation du centre de données puisque la chaleur est transférée à d’autres usages. L’énergie totale consommée par le centre de données est donc déjà réduite."
"On estime qu’en 2030, les technologies de l’information et de la communication, qui sont principalement basées sur l’utilisation de serveurs informatiques, pourraient dans le pire des cas consommer 51% l’électricité mondiale et, dans le meilleur des cas, 8% de l’électricité mondiale (Andrae & Edler, 2015; Jones, 2018). On estime que 50% de l’électricité consommée par les CDGE sert au refroidissement des serveurs (The Impact of Data Centers on The Environment, 2022). Cette consommation d’énergie est non seulement excessive, mais aussi hautement inefficiente. À titre illustratif, les résultats d’une simulation réalisée dans le cadre d’une étude chinoise réalisée en 2018 indiquaient que la charge cumulative annuelle de refroidissement d’un CD était beaucoup plus élevée que la charge cumulative annuelle de chaleur (Yu et al., 2019, p. 154). Le potentiel de réutilisation de la chaleur est donc énorme, de même que le gaspillage énergétique actuel."
@@ -251,7 +251,7 @@ pub fn WhyMicroDatacenters(cx: Scope) -> impl IntoView {"Quant aux émissions de gaz à effet de serre (GES) des géants du web, le tableau suivant résume la situation en 2021 pour Amazon, Microsoft, Alphabet et Meta. À titre indicatif, l’empreinte carbone per capita aux États-Unis est d’environ 16 tonnes métriques d’équivalent CO2 (tCO2e) et l’empreinte per capita à l’échelle planétaire est d’environ 4 tCO2e (What Is Your Carbon Footprint? | Carbon Footprint Calculator, n.d.)" @@ -289,38 +289,38 @@ pub fn WhyMicroDatacenters(cx: Scope) -> impl IntoView { "d'Amazon, Microsoft, Alphabet et Meta"
"Le coût de construction, d’exploitation et d’entretien d’un CDGE est extrêmement élevé. En effet, le coût de construction oscille entre $7 millions et $12 millions par mégawatt (MW) (Zhang, 2022a). Sachant que les centres de données de Google Cloud Platform (GCP) consomment en moyenne 20 MW, on parle d’un coût de construction entre $140 M et $240 M."
"Or, la consommation électrique d’un CD en MW ne représente pas nécessairement sa capacité de stockage ou de traitement des données. En effet, leur consommation électrique est non seulement liée au fonctionnement des équipements informatiques, mais aussi en grande partie aux besoins de refroidissement et de distribution d'énergie. Cette consommation d’électricité augmente donc rapidement avec la taille des centres de données. "
+
"Les quatre problèmes ci-haut identifiés préoccupent de nombreuses personnes. Par exemple, dans les régions désertiques de l’Ouest américain où les big tech s’installent pour l’abondance d’énergie renouvelable, notamment l’énergie solaire, plusieurs communautés sont préoccupées par les quantités astronomiques d’eau consommées par les CDGE (Solon, 2021). En Arizona, où Apple a élu domicile pour un de ses CD, on indique que le niveau du principal réservoir d’eau de la région a atteint de bas niveaux historiques (James, 2021). La mairesse de Mesa, ville où se trouve le CD en question, se confiait à BBC News en 2021: "
-+
"When it comes to economic development, I don’t think we are fully transparent about the water concerns [...] We want to keep the image that we are a great place to invest and start a business. But we don’t like to talk about the water."
"(Solon, 2021)"
-+
"Similairement, Microsoft s’est fait reprocher de manquer de transparence quant à son utilisation dans un de ces CD au Pays-Bas. L’entreprise avait indiqué qu’elle utiliserait de 12 M à 20 M de litres d’eau par an. Or, on découvrait qu’elle avait plutôt utilisé 84 M de litres d’eau en 2021, alors que des vagues de chaleur causaient d’importantes pénuries d’eau cette même année. Ce manque de transparence chronique est révélateur d’un profond problème de responsabilité sociale de ces grandes industries."
-+
"Le manque de transparence touche non seulement la gestion environnementale des projets, mais aussi le fonctionnement desdits CD comme l’illustre le graphique ci-bas."
+
+
"Sources:"
-+
"https://www.statista.com/statistics/617136/digital-population-worldwide/?fbclid=IwAR0bHpZ0u4JbW1hW2QI5WqJKmFhsmwJBwmviNVnesn-6rNhnQQCkbYrT1OU"
-+
"https://www.pewresearch.org/internet/2019/11/15/americans-and-privacy-concerned-confused-and-feeling-lack-of-control-over-their-personal-information/?fbcli -d=IwAR3wuxdHW8VE30FMaqZ6Iuj9Cs86bRSvmij1e_zDjM6Bwo4l71n5EKcLxqY" + d=IwAR3wuxdHW8VE30FMaqZ6Iuj9Cs86bRSvmij1e_zDjM6Bwo4l71n5EKcLxqY"
"Les MCD, tels que ceux développés par NationTech, consomment une fraction de l’énergie d’un CDGE. La clé de cette augmentation de l’efficacité énergétique est la réutilisation de la chaleur. En effet, les CDGE refroidissent l’équipement informatique grâce à des systèmes de climatisation énergivores tandis que les MCD extraient la chaleur via un système d’aération ou de refroidissement liquide qui la distribue afin de combler les besoins en chauffage d’eau et d’air d’un immeuble donné. Ainsi, l’électricité normalement utilisée afin de faire chauffer une résistance dans un radiateur servira plutôt à faire chauffer des serveurs. Suivant un principe physique de base, les rejets thermiques étant pratiquement identiques."
"Antoine Lavoisier"
"Deux métriques sont ci-après utilisées afin de comparer l’efficacité énergétique des MCD par rapport à celle des CDGE: le power usage effectiveness (PUE) ainsi que le energy reuse factor (ERF). NationTech a créé une troisième métrique permettant de fusionner les deux première: le global power usage effectiveness (GPUE)."
+
"*Voir section sur le GPUE" @@ -521,24 +521,24 @@ d=IwAR3wuxdHW8VE30FMaqZ6Iuj9Cs86bRSvmij1e_zDjM6Bwo4l71n5EKcLxqY"
+
"Les MCD visent à réutiliser la majorité de l’énergie utilisée afin de faire fonctionner le CD. Les rejets thermiques de l’équipement informatiques, soit l’ensemble de l’énergie entrant dans le CD moins l’électricité utilisée pour les ventilateurs et le courant électrique passant dans la fibre optique, est réutilisée afin de chauffer un immeuble. Dans le cas des CDGE, aucune énergie n’est réutilisée. En effet, on refroidit plutôt les installations avec des systèmes de climatisation énergivores ou bien avec de l’eau qui, une fois chaude, donc chargée énergétiquement, est rejetée dans la nature sans être réutilisée."
"Les géants de l’industrie ont quelques projets sur la table afin de réutiliser la chaleur de leurs serveurs. Cependant, pour le moment, c’est une part infime de leurs CD qui recyclent la chaleur produite. Azure indique pourtant que le potentiel est énorme: selon les estimations de l’entreprise, il serait possible d’atteindre un ERF de 0.69 en hiver et 0.84 en été."
+
"Meta, Azure, Vantage, Equinix et AWS projettent toutes réutiliser l’énergie de leurs centres de données afin d’atteindre la carboneutralité d’ici 2030. À l’exception de Vantage, elles ont toutes implémenter des projets de réutilisation de la chaleur produite par l’équipement informatique de leurs centres de données. Aucune information n’a été trouvée quant à l’intention de Google d’implémenter de tels projets. Voici un bref résumé de ces initiatives."
@@ -575,7 +575,7 @@ d=IwAR3wuxdHW8VE30FMaqZ6Iuj9Cs86bRSvmij1e_zDjM6Bwo4l71n5EKcLxqY"
- @@ -587,7 +587,7 @@ d=IwAR3wuxdHW8VE30FMaqZ6Iuj9Cs86bRSvmij1e_zDjM6Bwo4l71n5EKcLxqY"
- @@ -600,8 +600,8 @@ d=IwAR3wuxdHW8VE30FMaqZ6Iuj9Cs86bRSvmij1e_zDjM6Bwo4l71n5EKcLxqY"
- @@ -613,7 +613,7 @@ d=IwAR3wuxdHW8VE30FMaqZ6Iuj9Cs86bRSvmij1e_zDjM6Bwo4l71n5EKcLxqY"
- @@ -625,7 +625,7 @@ d=IwAR3wuxdHW8VE30FMaqZ6Iuj9Cs86bRSvmij1e_zDjM6Bwo4l71n5EKcLxqY"
- @@ -635,20 +635,20 @@ d=IwAR3wuxdHW8VE30FMaqZ6Iuj9Cs86bRSvmij1e_zDjM6Bwo4l71n5EKcLxqY"
"Les MCD tels que développés par NationTech ne consomment pas d’eau. En effet, l’entreprise offre deux options afin de distribuer la chaleur dans les immeubles qu’elle chauffe: soit un système de ventilation conventionnel distribuant la chaleur des serveurs grâce à des ventilateurs, soit un système de refroidissement liquide qui absorbe la chaleur produite pour la redistribuer dans l’immeuble."
"La figure suivante présente le WUE moyen des entreprise Meta, Google, Microsoft, Vantage, Equinix et Amazon pour leur CDGE ainsi que le WUE de NationTech dans ses MCD." @@ -677,17 +677,17 @@ d=IwAR3wuxdHW8VE30FMaqZ6Iuj9Cs86bRSvmij1e_zDjM6Bwo4l71n5EKcLxqY"
"La figure suivante présente le WUE moyen des entreprise Meta, Google, Microsoft, Vantage, Equinix et Amazon pour leur CDGE ainsi que le WUE de NationTech dans ses MCD."
-
+
"1"
@@ -719,7 +719,7 @@ d=IwAR3wuxdHW8VE30FMaqZ6Iuj9Cs86bRSvmij1e_zDjM6Bwo4l71n5EKcLxqY""2"
@@ -729,7 +729,7 @@ d=IwAR3wuxdHW8VE30FMaqZ6Iuj9Cs86bRSvmij1e_zDjM6Bwo4l71n5EKcLxqY""3"
@@ -739,7 +739,7 @@ d=IwAR3wuxdHW8VE30FMaqZ6Iuj9Cs86bRSvmij1e_zDjM6Bwo4l71n5EKcLxqY""4"
@@ -747,9 +747,9 @@ d=IwAR3wuxdHW8VE30FMaqZ6Iuj9Cs86bRSvmij1e_zDjM6Bwo4l71n5EKcLxqY""Cet air est utilisé pour chauffer la maison afin d’atteindre la température cible."
-
@@ -758,7 +758,7 @@ d=IwAR3wuxdHW8VE30FMaqZ6Iuj9Cs86bRSvmij1e_zDjM6Bwo4l71n5EKcLxqY"
"Température chaude"
"1"
@@ -768,7 +768,7 @@ d=IwAR3wuxdHW8VE30FMaqZ6Iuj9Cs86bRSvmij1e_zDjM6Bwo4l71n5EKcLxqY""2"
@@ -778,7 +778,7 @@ d=IwAR3wuxdHW8VE30FMaqZ6Iuj9Cs86bRSvmij1e_zDjM6Bwo4l71n5EKcLxqY""3"
@@ -788,7 +788,7 @@ d=IwAR3wuxdHW8VE30FMaqZ6Iuj9Cs86bRSvmij1e_zDjM6Bwo4l71n5EKcLxqY""4"
diff --git a/src/space_colonization/point.rs b/src/space_colonization/point.rs index 43f72f9..e667fdf 100644 --- a/src/space_colonization/point.rs +++ b/src/space_colonization/point.rs @@ -46,20 +46,20 @@ impl Point { impl Ord for Point { fn cmp(&self, other: &Self) -> std::cmp::Ordering { - if self.x > other.x { - return std::cmp::Ordering::Greater; - } - if self.x < other.x { - return std::cmp::Ordering::Less; - } - if self.y > other.y { - return std::cmp::Ordering::Greater; - } - if self.y < other.y { - return std::cmp::Ordering::Less; - } + if self.x > other.x { + return std::cmp::Ordering::Greater; + } + if self.x < other.x { + return std::cmp::Ordering::Less; + } + if self.y > other.y { + return std::cmp::Ordering::Greater; + } + if self.y < other.y { + return std::cmp::Ordering::Less; + } - std::cmp::Ordering::Equal + std::cmp::Ordering::Equal } } @@ -69,169 +69,135 @@ mod tests { #[test] fn distance_to_itself_is_zero() { - let p = Point { - x: 1, - y: 1, - }; + let p = Point { x: 1, y: 1 }; assert_eq!(p.distance(&p), 0.0); } #[test] fn distance_same_x_is_y() { - let p1 = Point { - x: 1, - y: 1, - }; + let p1 = Point { x: 1, y: 1 }; - let p2 = Point { - x: 1, - y: 5, - }; + let p2 = Point { x: 1, y: 5 }; assert_eq!(p1.distance(&p2), 4.0); } #[test] fn distance_same_y_is_x() { - let p1 = Point::new((1,1)); - let p2 = Point::new((5,1)); + let p1 = Point::new((1, 1)); + let p2 = Point::new((5, 1)); assert_eq!(p1.distance(&p2), 4.0); } #[test] fn distance_3_4_5() { - let p1 = Point::new((0,0)); - let p2 = Point::new((3,4)); + let p1 = Point::new((0, 0)); + let p2 = Point::new((3, 4)); assert_eq!(p1.distance(&p2), 5.0); } #[test] fn distance_is_always_positive() { - let p1 = Point::new((10,10)); - let p2 = Point::new((5,10)); + let p1 = Point::new((10, 10)); + let p2 = Point::new((5, 10)); assert_eq!(p1.distance(&p2), 5.0); - let p1 = Point::new((10,10)); - let p2 = Point::new((10,5)); + let p1 = Point::new((10, 10)); + let p2 = Point::new((10, 5)); assert_eq!(p1.distance(&p2), 5.0); } #[test] fn distance_quadrant3() { - let p1 = Point { - x: 3, - y: 4, - }; + let p1 = Point { x: 3, y: 4 }; - let p2 = Point { - x: 0, - y: 0, - }; + let p2 = Point { x: 0, y: 0 }; assert_eq!(p1.distance(&p2), 5.0); } #[test] fn distance_quadrant2() { - let p1 = Point { - x: 3, - y: 4, - }; + let p1 = Point { x: 3, y: 4 }; - let p2 = Point { - x: 0, - y: 100, - }; + let p2 = Point { x: 0, y: 100 }; assert_eq!(p1.distance(&p2) as f32, 96.04687); } #[test] fn distance_quadrant2_fast() { - let p1 = Point { - x: 3, - y: 4, - }; + let p1 = Point { x: 3, y: 4 }; - let p2 = Point { - x: 3, - y: 50, - }; + let p2 = Point { x: 3, y: 50 }; assert_eq!(p1.distance(&p2), 46.0); } #[test] fn distance_quadrant4() { - let p1 = Point { - x: 3, - y: 4, - }; + let p1 = Point { x: 3, y: 4 }; - let p2 = Point { - x: 50, - y: -50, - }; + let p2 = Point { x: 50, y: -50 }; assert_eq!(p1.distance(&p2) as f32, 71.5891); } #[test] fn movement_does_nothing_when_right_length() { - let root = Point::new((0,0)); - let node = Point::new((0,1)); + let root = Point::new((0, 0)); + let node = Point::new((0, 1)); assert_eq!(root.movement(node.clone(), 1), node); } #[test] fn movement_does_not_overlap() { - let root = Point::new((0,1)); - let node = Point::new((0,0)); + let root = Point::new((0, 1)); + let node = Point::new((0, 0)); assert_eq!(root.movement(node.clone(), 2), Point::new((0, -1))); } #[test] fn movement_adjusts_to_asked_length() { - let root = Point::new((0,0)); - let node = Point::new((0,1)); - assert_eq!(root.movement(node, 10), Point::new((0,10))); + let root = Point::new((0, 0)); + let node = Point::new((0, 1)); + assert_eq!(root.movement(node, 10), Point::new((0, 10))); } #[test] fn movement_works_away_from_origin() { - let root = Point::new((10,10)); - let node = Point::new((10,11)); - assert_eq!(root.movement(node, 10), Point::new((10,20))); + let root = Point::new((10, 10)); + let node = Point::new((10, 11)); + assert_eq!(root.movement(node, 10), Point::new((10, 20))); } #[test] fn movement_works_in_two_dimension() { - let root = Point::new((10,10)); - let node = Point::new((40,50)); - assert_eq!(root.movement(node, 50), Point::new((40,50))); + let root = Point::new((10, 10)); + let node = Point::new((40, 50)); + assert_eq!(root.movement(node, 50), Point::new((40, 50))); - let root = Point::new((10,10)); - let node = Point::new((40,50)); - assert_eq!(root.movement(node, 5), Point::new((13,14))); + let root = Point::new((10, 10)); + let node = Point::new((40, 50)); + assert_eq!(root.movement(node, 5), Point::new((13, 14))); } #[test] fn movement_works_in_all_directions() { - let root = Point::new((40,50)); - let node = Point::new((10,10)); - assert_eq!(root.movement(node, 5), Point::new((37,46))); + let root = Point::new((40, 50)); + let node = Point::new((10, 10)); + assert_eq!(root.movement(node, 5), Point::new((37, 46))); - let root = Point::new((50,10)); - let node = Point::new((10,10)); - assert_eq!(root.movement(node, 5), Point::new((45,10))); + let root = Point::new((50, 10)); + let node = Point::new((10, 10)); + assert_eq!(root.movement(node, 5), Point::new((45, 10))); - let root = Point::new((10,50)); - let node = Point::new((10,10)); - assert_eq!(root.movement(node, 5), Point::new((10,45))); + let root = Point::new((10, 50)); + let node = Point::new((10, 10)); + assert_eq!(root.movement(node, 5), Point::new((10, 45))); } } - diff --git a/src/space_colonization/space_colonization.rs b/src/space_colonization/space_colonization.rs index dcb6faf..21fd581 100644 --- a/src/space_colonization/space_colonization.rs +++ b/src/space_colonization/space_colonization.rs @@ -311,7 +311,7 @@ mod test { let mut attractors = Vec::new(); attractors.push(Attractor::new(Point::new((10, 0)))); - let mut sc = SpaceColonization::new_for_tests(100, 100, attractors, |_, _|{}); + let mut sc = SpaceColonization::new_for_tests(100, 100, attractors, |_, _| {}); assert_eq!(sc.attractors.len(), 1); assert!(sc.attractors.iter().find(|a| a.dead == true).is_none()); @@ -357,7 +357,7 @@ mod test { dead: true, }); - let mut sc = SpaceColonization::new_for_tests(100, 100, attractors, |_, _|{}); + let mut sc = SpaceColonization::new_for_tests(100, 100, attractors, |_, _| {}); assert_eq!(sc.attractors.len(), 1); assert!(sc.attractors.iter().find(|a| a.dead == true).is_some()); diff --git a/src/space_colonization/spacial_index.rs b/src/space_colonization/spacial_index.rs index f833ae5..c28fd09 100644 --- a/src/space_colonization/spacial_index.rs +++ b/src/space_colonization/spacial_index.rs @@ -154,8 +154,10 @@ mod test { assert_eq!( index.get_surrounding_elements(&Point::new((50, 50))).sort(), vec![ - &4040, &4545, &5040, &6040, &4050, &5050, &6050, &5050, &5151, &6060, &4060, &5060, &6060, - ].sort() + &4040, &4545, &5040, &6040, &4050, &5050, &6050, &5050, &5151, &6060, &4060, &5060, + &6060, + ] + .sort() ); }