From f7250af4442351c9a667fca97571cf4943a9746d Mon Sep 17 00:00:00 2001 From: Pierre C Date: Wed, 15 May 2024 15:54:41 -0400 Subject: [PATCH 001/138] README update --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c24b551..f729ffa 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ APECSS is a software toolbox to compute pressure-driven bubble dynamics and the Key features of APECSS are: - Bubble dynamics using widely-used models (Rayleigh-Plesset, Keller-Miksis, Gilmore), solved using an in-built 5th-order Runge-Kutta scheme with adaptive time stepping. - Acoustic emissions of the bubble under different assumptions (incompressible, quasi-acoustic, fully compressible). +- *(Work in progress)* Interbubble interactions within a cavitation cluster - Prediction of the formation and attenuation of shock fronts emitted by the bubble. - Viscoelastic media (Kelvin-Voigt, Zener, Oldroyd-B). - Lipid monolayer coating of the bubble as used for ultrasound contrast agents. From 6db35db6c85f84790f6e897fc0272d8f23e25919 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Thu, 16 May 2024 12:38:48 -0400 Subject: [PATCH 002/138] APECSS ; interactions update -> new struct, new functions to compute two type of interbubble interactions for now --- include/apecss.h | 10 ++++ src/bubble.c | 1 + src/interactions.c | 124 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+) create mode 100644 src/interactions.c diff --git a/include/apecss.h b/include/apecss.h index 7f5b9d1..f083e9c 100644 --- a/include/apecss.h +++ b/include/apecss.h @@ -311,6 +311,13 @@ struct APECSS_Excitation APECSS_FLOAT dp; // Maximum pressure amplitude [Pa] }; +struct APECSS_Interaction +{ + int nBubbles; // Number of bubbles in the whole cluster considered + APECSS_FLOAT location[3]; // 3D coordinates of the considered bubble + APECSS_FLOAT dp_neighbor; // Pressure induced by interactions with neighboring bubbles +} + struct APECSS_ResultsBubble { int freq; // Frequency with which the results are stored (with respect to the time-step number) @@ -444,6 +451,9 @@ struct APECSS_Bubble // Excitation of the bubble (if applicable) struct APECSS_Excitation *Excitation; + // Interactions with neighboring bubbles (if applicable) + struct APECSS_Interaction *Interaction; + // Pointers to the functions describing the liquid pressure and its derivative at infinity APECSS_FLOAT (*get_pressure_infinity)(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); APECSS_FLOAT (*get_pressurederivative_infinity)(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); diff --git a/src/bubble.c b/src/bubble.c index af564f2..fd5e8e1 100644 --- a/src/bubble.c +++ b/src/bubble.c @@ -39,6 +39,7 @@ int apecss_bubble_initializestruct(struct APECSS_Bubble *Bubble) Bubble->Liquid = NULL; Bubble->Interface = NULL; Bubble->Excitation = NULL; + Bubble->Interaction = NULL; Bubble->Emissions = NULL; Bubble->Results = NULL; diff --git a/src/interactions.c b/src/interactions.c new file mode 100644 index 0000000..564370a --- /dev/null +++ b/src/interactions.c @@ -0,0 +1,124 @@ +// This source file is part of APECSS, an open-source software toolbox +// for the computation of pressure-driven bubble dynamics and acoustic +// emissions in spherical symmetry. +// +// Copyright (C) 2022-2024 The APECSS Developers +// +// The APECSS Developers are listed in the README.md file available in +// the GitHub repository at https://github.com/polycfd/apecss. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +#include "apecss.h" + +// ------------------------------------------------------------------- +// OPTIONS +// ------------------------------------------------------------------- +// Functions computing different types of interactions between cavita- +// tion bubbles inside a cluster +// ------------------------------------------------------------------- + +int apecss_instantaneous_interactions(struct APECSS_Bubble *Bubble_1, struct APECSS_Bubble *Bubble_2) +{ + // Compute interactions by considering them instantaneous (fully incompressible approach) + struct APECSS_Interaction *Interaction_1 = Bubble_1->Interaction; + struct APECSS_Interaction *Interaction_2 = Bubble_2->Interaction; + + // Both bubbles are supposed to be in the same liquid + struct APECSS_Liquid *Liquid = Bubble_1->Liquid; + + APECSS_FLOAT loc_1[3] = Interaction_1->location; + APECSS_FLOAT loc_2[3] = Interaction_2->location; + + APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(loc_1[0] - loc_2[0]) + APECSS_POW2(loc_1[1] - loc_2[1]) + APECSS_POW2(loc_1[2] - loc_2[2])); + + APECSS_FLOAT dp_1_2 = + Liquid->rhoref * ((2.0 * Bubble_1->R * APECSS_POW2(Bubble_1->U) + APECSS_POW2(Bubble_1->R) * Bubble_1->ode[0](Bubble_1->ODEsSol, Bubble_1->t, Bubble_1)) * + (1 / interbubble_dist) - + (APECSS_POW4(Bubble_1->R) * APECSS_POW2(Bubble_1->U)) * (1 / (2 * APECSS_POW4(interbubble_dist)))); + + APECSS_FLOAT dp_2_1 = + Liquid->rhoref * ((2.0 * Bubble_2->R * APECSS_POW2(Bubble_2->U) + APECSS_POW2(Bubble_2->R) * Bubble_2->ode[0](Bubble_2->ODEsSol, Bubble_2->t, Bubble_2)) * + (1 / interbubble_dist) - + (APECSS_POW4(Bubble_2->R) * APECSS_POW2(Bubble_2->U)) * (1 / (2 * APECSS_POW4(interbubble_dist)))); + + Interaction_1->dp_neighbor += dp_2_1; + Interaction_2->dp_neighbor += dp_1_2; + + return (0); +} + +int apecss_quasi_acoustic_interactions(struct APECSS_Bubble *Bubbles[]) +{ + // Compute interactions using emission nodes in the quasi acoustic assumption + int nBubbles = Bubbles[0]->Interaction->nBubbles; + + struct APECSS_Interaction *Interactions[nBubbles]; + for (register int i = 0; i < nBubbles; i++) + { + Interactions[i] = Bubbles[i]->Interaction; + } + + // All bubbles are supposed to be in the same liquid + struct APECSS_Liquid *Liquid = Bubbles[0]->Liquid; + + for (register int i = 0; i < nBubbles; i++) + { + APECSS_FLOAT sumU = 0.0; + APECSS_FLOAT sumG = 0.0; + + for (register int j = 0; j < nBubbles; j++) + { + if (j != i) + { + APECSS_FLOAT sumU_bubble = 0.0; + APECSS_FLOAT sumG_bubble = 0.0; + int nodecount_bubble = 0; + + APECSS_FLOAT loc_i[3] = Interactions[i]->location; + APECSS_FLOAT loc_j[3] = Interactions[j]->location; + + APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(loc_i[0] - loc_j[0]) + APECSS_POW2(loc_i[1] - loc_j[1]) + APECSS_POW2(loc_i[2] - loc_j[2])); + + double r_b = Bubbles[i]->R; + + // The loop over the emission nodes begins with the most far away from the emitting bubble + struct APECSS_EmissionNode *Current = Bubbles[j]->Emissions->LastNode; + while (Current != NULL) + { + if (Current->r < interbubble_dist - r_b) + // The following emission nodes have not yet reached the bubble of interest + Current = NULL; + else if (Current->r > interbubble_dist + r_b) + // The bubble of interest is still not reached + Current = Current->backward; + else + { + // The current emission node is located inside the bubble of interest + APECSS_FLOAT gr = Current->g / Current->r; + sumU_bubble += (Current->f / APECSS_POW2(Current->r)) + (gr) / Liquid->cref; + sumG_bubble += gr; + nodecount_bubble++; + Current = Current->backward; + } + } + + APECSS_FLOAT dp = 0.0; + if (nodecount_bubble != 0) + { + APECSS_FLOAT inv_nodecount = 1 / (APECSS_FLOAT) nodecount_bubble; + APECSS_FLOAT sumU_temp = sumU_bubble * inv_nodecount; + APECSS_FLOAT sumG_temp = sumG_bubble * inv_nodecount; + + sumU += (sumU_temp); + sumG += (sumG_temp); + } + } + } + Interactions[i]->dp_neighbor += Liquid->rhoref * (sumG - 0.5 * APECSS_POW2(sumU)); + } + + return (0); +} \ No newline at end of file From 028daef0e722f50555a78bf1c5bf7f3b2878378a Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 24 May 2024 11:30:41 -0400 Subject: [PATCH 003/138] Changing instanteanous interactions function to be uniform in structure --- src/interactions.c | 50 +++++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/src/interactions.c b/src/interactions.c index 564370a..f29f4bc 100644 --- a/src/interactions.c +++ b/src/interactions.c @@ -20,32 +20,41 @@ // tion bubbles inside a cluster // ------------------------------------------------------------------- -int apecss_instantaneous_interactions(struct APECSS_Bubble *Bubble_1, struct APECSS_Bubble *Bubble_2) +int apecss_instantaneous_interactions(struct APECSS_Bubble *Bubbles[]) { - // Compute interactions by considering them instantaneous (fully incompressible approach) - struct APECSS_Interaction *Interaction_1 = Bubble_1->Interaction; - struct APECSS_Interaction *Interaction_2 = Bubble_2->Interaction; + // Compute interactions uby considering them instantaneous (fully incompressible approach) + int nBubbles = Bubbles[0]->Interaction->nBubbles; - // Both bubbles are supposed to be in the same liquid - struct APECSS_Liquid *Liquid = Bubble_1->Liquid; + struct APECSS_Interaction *Interactions[nBubbles]; + for (register int i = 0; i < nBubbles; i++) + { + Interactions[i] = Bubbles[i]->Interaction; + } - APECSS_FLOAT loc_1[3] = Interaction_1->location; - APECSS_FLOAT loc_2[3] = Interaction_2->location; + // All bubbles are supposed to be in the same liquid + struct APECSS_Liquid *Liquid = Bubbles[0]->Liquid; - APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(loc_1[0] - loc_2[0]) + APECSS_POW2(loc_1[1] - loc_2[1]) + APECSS_POW2(loc_1[2] - loc_2[2])); + for (register int i = 0; i < nBubbles; i++) + { + APECSS_FLOAT loc_i[3] = Interactions[i]->location; - APECSS_FLOAT dp_1_2 = - Liquid->rhoref * ((2.0 * Bubble_1->R * APECSS_POW2(Bubble_1->U) + APECSS_POW2(Bubble_1->R) * Bubble_1->ode[0](Bubble_1->ODEsSol, Bubble_1->t, Bubble_1)) * - (1 / interbubble_dist) - - (APECSS_POW4(Bubble_1->R) * APECSS_POW2(Bubble_1->U)) * (1 / (2 * APECSS_POW4(interbubble_dist)))); + for (register int j = 0; j < nBubbles; j++) + { + if (j != i) + { + APECSS_FLOAT loc_j[3] = Interactions[j]->location; + + APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(loc_i[0] - loc_j[0]) + APECSS_POW2(loc_i[1] - loc_j[1]) + APECSS_POW2(loc_i[2] - loc_j[2])); - APECSS_FLOAT dp_2_1 = - Liquid->rhoref * ((2.0 * Bubble_2->R * APECSS_POW2(Bubble_2->U) + APECSS_POW2(Bubble_2->R) * Bubble_2->ode[0](Bubble_2->ODEsSol, Bubble_2->t, Bubble_2)) * - (1 / interbubble_dist) - - (APECSS_POW4(Bubble_2->R) * APECSS_POW2(Bubble_2->U)) * (1 / (2 * APECSS_POW4(interbubble_dist)))); + APECSS_FLOAT dp = Liquid->rhoref * ((2.0 * Bubbles[j]->R * APECSS_POW2(Bubbles[j]->U) + + APECSS_POW2(Bubbles[j]->R) * Bubbles[j]->ode[0](Bubbles[j]->ODEsSol, Bubbles[j]->t, Bubbles[j])) * + (1 / interbubble_dist) - + (APECSS_POW4(Bubbles[j]->R) * APECSS_POW2(Bubbles[j]->U)) * (1 / (2 * APECSS_POW4(interbubble_dist)))); - Interaction_1->dp_neighbor += dp_2_1; - Interaction_2->dp_neighbor += dp_1_2; + Interactions[i]->dp_neighbor += dp; + } + } + } return (0); } @@ -69,6 +78,8 @@ int apecss_quasi_acoustic_interactions(struct APECSS_Bubble *Bubbles[]) APECSS_FLOAT sumU = 0.0; APECSS_FLOAT sumG = 0.0; + APECSS_FLOAT loc_i[3] = Interactions[i]->location; + for (register int j = 0; j < nBubbles; j++) { if (j != i) @@ -77,7 +88,6 @@ int apecss_quasi_acoustic_interactions(struct APECSS_Bubble *Bubbles[]) APECSS_FLOAT sumG_bubble = 0.0; int nodecount_bubble = 0; - APECSS_FLOAT loc_i[3] = Interactions[i]->location; APECSS_FLOAT loc_j[3] = Interactions[j]->location; APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(loc_i[0] - loc_j[0]) + APECSS_POW2(loc_i[1] - loc_j[1]) + APECSS_POW2(loc_i[2] - loc_j[2])); From 0668c6483692a30f371caa8046396c3c209ade7a Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 24 May 2024 12:05:42 -0400 Subject: [PATCH 004/138] Changes for proper library compilation --- include/apecss.h | 2 +- src/interactions.c | 37 ++++++++++++++++--------------------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/include/apecss.h b/include/apecss.h index f083e9c..7804f40 100644 --- a/include/apecss.h +++ b/include/apecss.h @@ -316,7 +316,7 @@ struct APECSS_Interaction int nBubbles; // Number of bubbles in the whole cluster considered APECSS_FLOAT location[3]; // 3D coordinates of the considered bubble APECSS_FLOAT dp_neighbor; // Pressure induced by interactions with neighboring bubbles -} +}; struct APECSS_ResultsBubble { diff --git a/src/interactions.c b/src/interactions.c index f29f4bc..e5488ec 100644 --- a/src/interactions.c +++ b/src/interactions.c @@ -25,33 +25,31 @@ int apecss_instantaneous_interactions(struct APECSS_Bubble *Bubbles[]) // Compute interactions uby considering them instantaneous (fully incompressible approach) int nBubbles = Bubbles[0]->Interaction->nBubbles; - struct APECSS_Interaction *Interactions[nBubbles]; - for (register int i = 0; i < nBubbles; i++) - { - Interactions[i] = Bubbles[i]->Interaction; - } - // All bubbles are supposed to be in the same liquid struct APECSS_Liquid *Liquid = Bubbles[0]->Liquid; for (register int i = 0; i < nBubbles; i++) { - APECSS_FLOAT loc_i[3] = Interactions[i]->location; + APECSS_FLOAT x_i = Bubbles[i]->Interaction->location[0]; + APECSS_FLOAT y_i = Bubbles[i]->Interaction->location[1]; + APECSS_FLOAT z_i = Bubbles[i]->Interaction->location[2]; for (register int j = 0; j < nBubbles; j++) { if (j != i) { - APECSS_FLOAT loc_j[3] = Interactions[j]->location; + APECSS_FLOAT x_j = Bubbles[j]->Interaction->location[0]; + APECSS_FLOAT y_j = Bubbles[j]->Interaction->location[1]; + APECSS_FLOAT z_j = Bubbles[j]->Interaction->location[2]; - APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(loc_i[0] - loc_j[0]) + APECSS_POW2(loc_i[1] - loc_j[1]) + APECSS_POW2(loc_i[2] - loc_j[2])); + APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); APECSS_FLOAT dp = Liquid->rhoref * ((2.0 * Bubbles[j]->R * APECSS_POW2(Bubbles[j]->U) + APECSS_POW2(Bubbles[j]->R) * Bubbles[j]->ode[0](Bubbles[j]->ODEsSol, Bubbles[j]->t, Bubbles[j])) * (1 / interbubble_dist) - (APECSS_POW4(Bubbles[j]->R) * APECSS_POW2(Bubbles[j]->U)) * (1 / (2 * APECSS_POW4(interbubble_dist)))); - Interactions[i]->dp_neighbor += dp; + Bubbles[i]->Interaction->dp_neighbor += dp; } } } @@ -64,12 +62,6 @@ int apecss_quasi_acoustic_interactions(struct APECSS_Bubble *Bubbles[]) // Compute interactions using emission nodes in the quasi acoustic assumption int nBubbles = Bubbles[0]->Interaction->nBubbles; - struct APECSS_Interaction *Interactions[nBubbles]; - for (register int i = 0; i < nBubbles; i++) - { - Interactions[i] = Bubbles[i]->Interaction; - } - // All bubbles are supposed to be in the same liquid struct APECSS_Liquid *Liquid = Bubbles[0]->Liquid; @@ -78,7 +70,9 @@ int apecss_quasi_acoustic_interactions(struct APECSS_Bubble *Bubbles[]) APECSS_FLOAT sumU = 0.0; APECSS_FLOAT sumG = 0.0; - APECSS_FLOAT loc_i[3] = Interactions[i]->location; + APECSS_FLOAT x_i = Bubbles[i]->Interaction->location[0]; + APECSS_FLOAT y_i = Bubbles[i]->Interaction->location[1]; + APECSS_FLOAT z_i = Bubbles[i]->Interaction->location[2]; for (register int j = 0; j < nBubbles; j++) { @@ -88,9 +82,11 @@ int apecss_quasi_acoustic_interactions(struct APECSS_Bubble *Bubbles[]) APECSS_FLOAT sumG_bubble = 0.0; int nodecount_bubble = 0; - APECSS_FLOAT loc_j[3] = Interactions[j]->location; + APECSS_FLOAT x_j = Bubbles[j]->Interaction->location[0]; + APECSS_FLOAT y_j = Bubbles[j]->Interaction->location[1]; + APECSS_FLOAT z_j = Bubbles[j]->Interaction->location[2]; - APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(loc_i[0] - loc_j[0]) + APECSS_POW2(loc_i[1] - loc_j[1]) + APECSS_POW2(loc_i[2] - loc_j[2])); + APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); double r_b = Bubbles[i]->R; @@ -115,7 +111,6 @@ int apecss_quasi_acoustic_interactions(struct APECSS_Bubble *Bubbles[]) } } - APECSS_FLOAT dp = 0.0; if (nodecount_bubble != 0) { APECSS_FLOAT inv_nodecount = 1 / (APECSS_FLOAT) nodecount_bubble; @@ -127,7 +122,7 @@ int apecss_quasi_acoustic_interactions(struct APECSS_Bubble *Bubbles[]) } } } - Interactions[i]->dp_neighbor += Liquid->rhoref * (sumG - 0.5 * APECSS_POW2(sumU)); + Bubbles[i]->Interaction->dp_neighbor += Liquid->rhoref * (sumG - 0.5 * APECSS_POW2(sumU)); } return (0); From 6a5d1b47c3e6813295dcd550313d599ec36659b1 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 24 May 2024 13:58:26 -0400 Subject: [PATCH 005/138] completion for properly implementing interactions in APECSS --- include/apecss.h | 6 ++++++ src/bubble.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/include/apecss.h b/include/apecss.h index 7804f40..83ccaa5 100644 --- a/include/apecss.h +++ b/include/apecss.h @@ -587,6 +587,12 @@ APECSS_FLOAT apecss_interface_pressurederivative_viscous_marmottantexpl(APECSS_F APECSS_FLOAT apecss_interface_pressurederivative_viscous_cleanimpl(APECSS_FLOAT R, struct APECSS_Interface *Interface); APECSS_FLOAT apecss_interface_pressurederivative_viscous_marmottantimpl(APECSS_FLOAT R, struct APECSS_Interface *Interface); +// --------------------- +// interactions.c + +int apecss_instantaneous_interactions(struct APECSS_Bubble *Bubbles[]); +int apecss_quasi_acoustic_interactions(struct APECSS_Bubble *Bubbles[]); + // --------------------- // liquid.c diff --git a/src/bubble.c b/src/bubble.c index fd5e8e1..9ba6b7b 100644 --- a/src/bubble.c +++ b/src/bubble.c @@ -868,6 +868,12 @@ int apecss_bubble_freestruct(struct APECSS_Bubble *Bubble) Bubble->Emissions = NULL; } + if (Bubble->Interaction != NULL) + { + free(Bubble->Interaction); + Bubble->Interaction = NULL; + } + if (Bubble->Results != NULL) { if (Bubble->Results->RayleighPlesset != NULL) From 40cb272b05d44220efdfe8e765baa8718437c64e Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 24 May 2024 14:03:57 -0400 Subject: [PATCH 006/138] binaryinteraction ; changes in order to implement new interaction structure and function --- .../src/binaryinteraction_apecss.c | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/examples/binaryinteraction/src/binaryinteraction_apecss.c b/examples/binaryinteraction/src/binaryinteraction_apecss.c index 6fc2e9e..3c536b6 100644 --- a/examples/binaryinteraction/src/binaryinteraction_apecss.c +++ b/examples/binaryinteraction/src/binaryinteraction_apecss.c @@ -165,6 +165,12 @@ int main(int argc, char **args) // Use the revised pressure at infinity, including neighbor contributions for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressure_infinity = interaction_bubble_pressure_infinity; + // Initialisize interaction structure + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); + + // Update interaction structure + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction->nBubbles = nBubbles; + // Define the size of each bubble for (register int i = 0; i < nBubbles; i++) { @@ -175,6 +181,23 @@ int main(int argc, char **args) Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; } + + // Define center location for each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (0 == i) + { + Bubbles[i]->Interaction->location[0] = 0.0; + Bubbles[i]->Interaction->location[1] = 0.0; + Bubbles[i]->Interaction->location[2] = 0.0; + } + else if (1 == i) + { + Bubbles[i]->Interaction->location[0] = bubble_bubble_dist; + Bubbles[i]->Interaction->location[1] = 0.0; + Bubbles[i]->Interaction->location[2] = 0.0; + } + } // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< clock_t starttimebubble = clock(); @@ -201,19 +224,12 @@ int main(int argc, char **args) for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // Update the contribution of the neighbor bubble - struct Interaction *data_0 = Bubbles[0]->user_data; - data_0->dp_neighbor = - Liquid->rhoref * - (APECSS_POW2(Bubbles[1]->R) * Bubbles[1]->ode[0](Bubbles[1]->ODEsSol, Bubbles[1]->t, Bubbles[1]) + 2.0 * Bubbles[1]->R * APECSS_POW2(Bubbles[1]->U)) / - bubble_bubble_dist; - - struct Interaction *data_1 = Bubbles[1]->user_data; - data_1->dp_neighbor = - Liquid->rhoref * - (APECSS_POW2(Bubbles[0]->R) * Bubbles[0]->ode[0](Bubbles[0]->ODEsSol, Bubbles[0]->t, Bubbles[0]) + 2.0 * Bubbles[0]->R * APECSS_POW2(Bubbles[0]->U)) / - bubble_bubble_dist; + apecss_instantaneous_interactions(Bubbles); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< } From 1fe3b572c3aae0a83fe4e44ebbef445cd03fb0f4 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 27 May 2024 12:00:42 -0400 Subject: [PATCH 007/138] binaryinteraction ; small changes to properly use interaction struture --- .../src/binaryinteraction_apecss.c | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/binaryinteraction/src/binaryinteraction_apecss.c b/examples/binaryinteraction/src/binaryinteraction_apecss.c index 3c536b6..af09da6 100644 --- a/examples/binaryinteraction/src/binaryinteraction_apecss.c +++ b/examples/binaryinteraction/src/binaryinteraction_apecss.c @@ -95,17 +95,17 @@ int main(int argc, char **args) for (register int i = 0; i < nBubbles; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); for (register int i = 0; i < nBubbles; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Allocate and set bubble-associated variables for the interaction - for (register int i = 0; i < nBubbles; i++) - { - struct Interaction *interaction_data = (struct Interaction *) malloc(sizeof(struct Interaction)); - interaction_data->dp_neighbor = 0.0; // Pressure excerted by the neighbor bubbles - - // Hook interaction-structure to the void data pointer - Bubbles[i]->user_data = interaction_data; - } - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + // // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // // Allocate and set bubble-associated variables for the interaction + // for (register int i = 0; i < nBubbles; i++) + // { + // struct Interaction *interaction_data = (struct Interaction *) malloc(sizeof(struct Interaction)); + // interaction_data->dp_neighbor = 0.0; // Pressure excerted by the neighbor bubbles + + // // Hook interaction-structure to the void data pointer + // Bubbles[i]->user_data = interaction_data; + // } + // // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< /* Allocate the structures for the fluid properties and ODE solver parameters */ struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); @@ -165,8 +165,9 @@ int main(int argc, char **args) // Use the revised pressure at infinity, including neighbor contributions for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressure_infinity = interaction_bubble_pressure_infinity; - // Initialisize interaction structure + // Initialize interaction structure for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction->nBubbles = nBubbles; // Update interaction structure for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction->nBubbles = nBubbles; @@ -262,6 +263,5 @@ int main(int argc, char **args) APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { - struct Interaction *temp_struct = Bubble->user_data; - return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * t) + temp_struct->dp_neighbor); + return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * t) + Bubble->Interaction->dp_neighbor); } \ No newline at end of file From 75175b59ca640971abdfe393b28ea802e17528ac Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 27 May 2024 13:26:05 -0400 Subject: [PATCH 008/138] binaryinteraction ; small correction to prevent doing the same operation twice --- examples/binaryinteraction/src/binaryinteraction_apecss.c | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/binaryinteraction/src/binaryinteraction_apecss.c b/examples/binaryinteraction/src/binaryinteraction_apecss.c index af09da6..4ccb2e6 100644 --- a/examples/binaryinteraction/src/binaryinteraction_apecss.c +++ b/examples/binaryinteraction/src/binaryinteraction_apecss.c @@ -167,7 +167,6 @@ int main(int argc, char **args) // Initialize interaction structure for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction->nBubbles = nBubbles; // Update interaction structure for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction->nBubbles = nBubbles; From b89ed0ccedcbff2bacd706c001b4c68f0a90650b Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 3 Jun 2024 11:33:18 -0400 Subject: [PATCH 009/138] Adding s delete node function that considers every situation for developping later prunung methods --- include/apecss.h | 1 + src/emissions.c | 89 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 74 insertions(+), 16 deletions(-) diff --git a/include/apecss.h b/include/apecss.h index 83ccaa5..7e0883c 100644 --- a/include/apecss.h +++ b/include/apecss.h @@ -531,6 +531,7 @@ int apecss_emissions_addnode(struct APECSS_Bubble *Bubble); int apecss_emissions_prunelist(struct APECSS_Bubble *Bubble); int apecss_emissions_prune_no_node(struct APECSS_EmissionNode *Node); int apecss_emissions_removenode(struct APECSS_Bubble *Bubble); +int apecss_emissions_deletenode(struct APECSS_EmissionNode *Node); int apecss_emissions_advance_finitespeedincompressible(struct APECSS_Bubble *Bubble); int apecss_emissions_advance_quasiacoustic(struct APECSS_Bubble *Bubble); int apecss_emissions_advance_kirkwoodbethe_tait(struct APECSS_Bubble *Bubble); diff --git a/src/emissions.c b/src/emissions.c index c5a5cd4..e5d09cc 100644 --- a/src/emissions.c +++ b/src/emissions.c @@ -135,24 +135,40 @@ int apecss_emissions_addnode(struct APECSS_Bubble *Bubble) int apecss_emissions_prunelist(struct APECSS_Bubble *Bubble) { - if (Bubble->Emissions->nNodes > 2) // The list needs to consist of at least 3 nodes. - { - struct APECSS_EmissionNode *Current = Bubble->Emissions->LastNode->backward; + // if (Bubble->Emissions->nNodes > 2) // The list needs to consist of at least 3 nodes. + // { + // struct APECSS_EmissionNode *Current = Bubble->Emissions->LastNode->backward; + + // while (Current->backward != NULL) + // { + // if (Bubble->Emissions->prune_test(Current)) + // { + // struct APECSS_EmissionNode *Obsolete = Current; + // Current->backward->forward = Current->forward; + // Current->forward->backward = Current->backward; + // Current = Current->backward; + // free(Obsolete); + // } + // else + // { + // Current = Current->backward; // Move to the next node + // } + // } + // } + + struct APECSS_EmissionNode *Current = Bubble->Emissions->LastNode; - while (Current->backward != NULL) + while (Current != NULL) + { + if (Bubble->Emissions->prune_test(Current)) { - if (Bubble->Emissions->prune_test(Current)) - { - struct APECSS_EmissionNode *Obsolete = Current; - Current->backward->forward = Current->forward; - Current->forward->backward = Current->backward; - Current = Current->backward; - free(Obsolete); - } - else - { - Current = Current->backward; // Move to the next node - } + // Delete the node if it satisfies the pruning condition + apecss_emissions_deletenode(Current); + } + else + { + // Move to the next node + Current = Current->backward; } } @@ -187,6 +203,47 @@ int apecss_emissions_removenode(struct APECSS_Bubble *Bubble) return (0); } +int apecss_emissions_deletenode(struct APECSS_EmissionNode *Node) +{ + struct APECSS_EmissionNode *Obsolete = Node; + + if ((Node->backward != NULL) && (Node->forward != NULL)) + { + // The node has two neighbors + Node->backward->forward = Node->forward; + Node->forward->backward = Node->backward; + Node = Node->backward; + Bubble->Emissions->nNodes -= 1; + } + else if ((Node->backward != NULL) && (Node->forward == NULL)) + { + // The node is LastNode + Node->backward->forward = NULL; + Bubble->Emissions->LastNode = Node->backward; + Node = Node->backward; + Bubble->Emissions->nNodes -= 1; + } + else if ((Node->backward == NULL) && (Node->forward != NULL)) + { + // The node is FirstNode + Node->forward->backward = NULL; + Bubble->Emissions->FirstNode = Node->forward; + Node = NULL; + Bubble->Emissions->nNodes -= 1; + } + else + { + // There is only one node in the list + Bubble->Emissions->FirstNode = NULL; + Bubble->Emissions->LastNode = NULL; + Bubble->Emissions->nNodes = 0; + Node = NULL; + } + free(Obsolete); + + return (0); +} + // ------------------------------------------------------------------- // ADVANCE EMISSION NODES // ------------------------------------------------------------------- From 7de53959c404610d1ace3bec9f1c9186a314693a Mon Sep 17 00:00:00 2001 From: Pierre C Date: Thu, 6 Jun 2024 11:44:20 -0400 Subject: [PATCH 010/138] apecss_interactions ; functions name changes to respect nomenclature --- examples/binaryinteraction/src/binaryinteraction_apecss.c | 2 +- include/apecss.h | 4 ++-- src/interactions.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/binaryinteraction/src/binaryinteraction_apecss.c b/examples/binaryinteraction/src/binaryinteraction_apecss.c index 4ccb2e6..20224d9 100644 --- a/examples/binaryinteraction/src/binaryinteraction_apecss.c +++ b/examples/binaryinteraction/src/binaryinteraction_apecss.c @@ -228,7 +228,7 @@ int main(int argc, char **args) // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // Update the contribution of the neighbor bubble - apecss_instantaneous_interactions(Bubbles); + apecss_interactions_instantaneous(Bubbles); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< } diff --git a/include/apecss.h b/include/apecss.h index 7e0883c..2b195c0 100644 --- a/include/apecss.h +++ b/include/apecss.h @@ -591,8 +591,8 @@ APECSS_FLOAT apecss_interface_pressurederivative_viscous_marmottantimpl(APECSS_F // --------------------- // interactions.c -int apecss_instantaneous_interactions(struct APECSS_Bubble *Bubbles[]); -int apecss_quasi_acoustic_interactions(struct APECSS_Bubble *Bubbles[]); +int apecss_interactions_instantaneous(struct APECSS_Bubble *Bubbles[]); +int apecss_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[]); // --------------------- // liquid.c diff --git a/src/interactions.c b/src/interactions.c index e5488ec..682306f 100644 --- a/src/interactions.c +++ b/src/interactions.c @@ -20,7 +20,7 @@ // tion bubbles inside a cluster // ------------------------------------------------------------------- -int apecss_instantaneous_interactions(struct APECSS_Bubble *Bubbles[]) +int apecss_interactions_instantaneous(struct APECSS_Bubble *Bubbles[]) { // Compute interactions uby considering them instantaneous (fully incompressible approach) int nBubbles = Bubbles[0]->Interaction->nBubbles; @@ -57,7 +57,7 @@ int apecss_instantaneous_interactions(struct APECSS_Bubble *Bubbles[]) return (0); } -int apecss_quasi_acoustic_interactions(struct APECSS_Bubble *Bubbles[]) +int apecss_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[]) { // Compute interactions using emission nodes in the quasi acoustic assumption int nBubbles = Bubbles[0]->Interaction->nBubbles; From 38a8bbb567ca5dce154b19a684e2de87ddd018ce Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 7 Jun 2024 10:19:32 -0400 Subject: [PATCH 011/138] small correction for deletenode function in emissions.c --- include/apecss.h | 2 +- src/emissions.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/apecss.h b/include/apecss.h index 2b195c0..44cd03e 100644 --- a/include/apecss.h +++ b/include/apecss.h @@ -531,7 +531,7 @@ int apecss_emissions_addnode(struct APECSS_Bubble *Bubble); int apecss_emissions_prunelist(struct APECSS_Bubble *Bubble); int apecss_emissions_prune_no_node(struct APECSS_EmissionNode *Node); int apecss_emissions_removenode(struct APECSS_Bubble *Bubble); -int apecss_emissions_deletenode(struct APECSS_EmissionNode *Node); +int apecss_emissions_deletenode(struct APECSS_Bubble *Bubble, struct APECSS_EmissionNode *Node); int apecss_emissions_advance_finitespeedincompressible(struct APECSS_Bubble *Bubble); int apecss_emissions_advance_quasiacoustic(struct APECSS_Bubble *Bubble); int apecss_emissions_advance_kirkwoodbethe_tait(struct APECSS_Bubble *Bubble); diff --git a/src/emissions.c b/src/emissions.c index e5d09cc..e91b9ca 100644 --- a/src/emissions.c +++ b/src/emissions.c @@ -163,7 +163,7 @@ int apecss_emissions_prunelist(struct APECSS_Bubble *Bubble) if (Bubble->Emissions->prune_test(Current)) { // Delete the node if it satisfies the pruning condition - apecss_emissions_deletenode(Current); + apecss_emissions_deletenode(Bubble, Current); } else { @@ -203,7 +203,7 @@ int apecss_emissions_removenode(struct APECSS_Bubble *Bubble) return (0); } -int apecss_emissions_deletenode(struct APECSS_EmissionNode *Node) +int apecss_emissions_deletenode(struct APECSS_Bubble *Bubble, struct APECSS_EmissionNode *Node) { struct APECSS_EmissionNode *Obsolete = Node; From 16650cf5cf166cc31f992ced7f490c3fbcc8bdf8 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 17 Jun 2024 15:15:11 -0400 Subject: [PATCH 012/138] adding parallelization attempt --- .../parallelinteraction/build/CMakeLists.txt | 41 ++ examples/parallelinteraction/build/compile.sh | 5 + examples/parallelinteraction/execmpi.sh | 4 + .../src/parallelinteraction_apecss.c | 425 ++++++++++++++++++ 4 files changed, 475 insertions(+) create mode 100644 examples/parallelinteraction/build/CMakeLists.txt create mode 100755 examples/parallelinteraction/build/compile.sh create mode 100755 examples/parallelinteraction/execmpi.sh create mode 100644 examples/parallelinteraction/src/parallelinteraction_apecss.c diff --git a/examples/parallelinteraction/build/CMakeLists.txt b/examples/parallelinteraction/build/CMakeLists.txt new file mode 100644 index 0000000..5b49e67 --- /dev/null +++ b/examples/parallelinteraction/build/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.12) + +project (parallelinteraction_apecss) +set(CMAKE_C_COMPILER /usr/lib64/mpich/bin/mpicc) + +include_directories($ENV{APECSS_DIR}/include) +FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) + +set (mylibs m apecss) +link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) + +foreach(arg ${myincludes}) + IF (arg MATCHES "-I") + STRING(REGEX REPLACE "-I" "" myinc ${arg}) + message("Additional include: ${myinc}") + include_directories(${myinc}) + ENDIF(arg MATCHES "-I") +endforeach(arg ${myincludes}) + +foreach(arg ${mylibs}) + STRING(REGEX REPLACE "lib" "" myl1 ${arg}) + STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) + set(mylibs ${myl2} ${mylibs} ${myl2}) +endforeach(arg ${mylibs}) + +if(NOT CMAKE_BUILD_TYPE) + message(STATUS "Optimization: No optimization specified.") + set(CMAKE_BUILD_TYPE Release) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + message(STATUS "Optimization: Debug") + set(CMAKE_C_FLAGS_DEBUG "-Wall -g") +elseif(CMAKE_BUILD_TYPE STREQUAL "Release") + message(STATUS "Optimization: Release") + add_definitions(-DNDEBUG) + set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") +endif() + +add_executable(parallelinteraction_apecss ${myfiles}) +target_link_libraries(parallelinteraction_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/parallelinteraction/build/compile.sh b/examples/parallelinteraction/build/compile.sh new file mode 100755 index 0000000..ae9493a --- /dev/null +++ b/examples/parallelinteraction/build/compile.sh @@ -0,0 +1,5 @@ +#!/bin/bash +rm parallelinteraction_apecss +cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release +make +rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/parallelinteraction/execmpi.sh b/examples/parallelinteraction/execmpi.sh new file mode 100755 index 0000000..851ec24 --- /dev/null +++ b/examples/parallelinteraction/execmpi.sh @@ -0,0 +1,4 @@ +cd build +./compile.sh +cd .. +mpiexec -n 7 ./build/parallelinteraction_apecss -options run.apecss -freq 15.7e3 -amp -120e3 -tend 7.5e-4 diff --git a/examples/parallelinteraction/src/parallelinteraction_apecss.c b/examples/parallelinteraction/src/parallelinteraction_apecss.c new file mode 100644 index 0000000..1d07465 --- /dev/null +++ b/examples/parallelinteraction/src/parallelinteraction_apecss.c @@ -0,0 +1,425 @@ +// This source file is part of APECSS, an open-source software toolbox +// for the computation of pressure-driven bubble dynamics and acoustic +// emissions in spherical symmetry. +// +// Copyright (C) 2022-2024 The APECSS Developers +// +// The APECSS Developers are listed in the README.md file available in +// the GitHub repository at https://github.com/polycfd/apecss. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// ------------------------------------------------------------------- +// APECSS standalone example of acoustically-interacting microbubbles, +// demonstrating a simple parallelization of APECSS. +// ------------------------------------------------------------------- + +#include +#include +#include "apecss.h" + +struct APECSS_Parallel_Cluster +{ + int rank, size; + int nBubbles_local, nBubbles_global; + + int *bubblerank; // max id of bubbles for each rank + APECSS_FLOAT *bubbleglobal_x, *bubbleglobal_y, *bubbleglobal_z; // x,y,z location of all bubbles + APECSS_FLOAT *sumGU_rank; // Contributions from local bubbles to all bubbles +}; + +// Declaration of additional case-dependent functions +APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubble[], struct APECSS_Parallel_Cluster *RankInfo); + +int main(int argc, char **args) +{ + /* Initialize MPI */ + int mpi_rank, mpi_size; + MPI_Init(&argc, &args); + MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); + MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); + + char OptionsDir[APECSS_STRINGLENGTH]; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Set the case-dependent simulation parameters + const int nBubbles_x = 5; + const int nBubbles = nBubbles_x * nBubbles_x; // Number of bubbles + APECSS_FLOAT bubble_bubble_dist = 200.0e-6; // Bubble-bubble distance + + // Interbubble time-step, defining the frequency with which the neighbor influence is updated + APECSS_FLOAT dt_interbubble = 1.0e-8; + + // Initialize the simulation parameters given by the execution command + double tEnd = 0.0; + double fa = 0.0; + double pa = 0.0; + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + apecss_infoscreen(); + + /* Read commandline options */ + sprintf(OptionsDir, "./run.apecss"); // This is the default + int j = 1; // First argument is the call to the executable + while (j < argc) + { + if (strcmp("-options", args[j]) == 0) + { + sprintf(OptionsDir, "%s", args[j + 1]); + j += 2; + } + else if (strcmp("-tend", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &tEnd); + j += 2; + } + else if (strcmp("-freq", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &fa); + j += 2; + } + else if (strcmp("-amp", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &pa); + j += 2; + } + else if (strcmp("-h", args[j]) == 0) + { + apecss_helpscreen(); + } + else + { + char str[APECSS_STRINGLENGTH_SPRINTF]; + sprintf(str, "Unknown command line options: %s", args[j]); + apecss_erroronscreen(1, str); + ++j; + } + } + + /* Allocate structure for parallel data */ + struct APECSS_Parallel_Cluster *RankInfo = (struct APECSS_Parallel_Cluster *) malloc(sizeof(struct APECSS_Parallel_Cluster)); + RankInfo->rank = mpi_rank; + RankInfo->size = mpi_size; + + /* Determine the number of bubbles per rank */ + int max_per_rank = ceil((double) nBubbles / (double) mpi_size); + RankInfo->nBubbles_local = APECSS_MIN(max_per_rank, nBubbles - mpi_rank * max_per_rank); + + /* Share the parallel distribution of bubbles with all ranks */ + + RankInfo->bubblerank = malloc((RankInfo->size + 1) * sizeof(int)); + + RankInfo->nBubbles_global = 0; + RankInfo->bubblerank[0] = 0; + for (int r = 0; r < RankInfo->size; r++) + { + int temp = RankInfo->nBubbles_local; + MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); + RankInfo->bubblerank[r + 1] = RankInfo->bubblerank[r] + temp; + RankInfo->nBubbles_global += temp; + } + + /* Allocate and initialize Bubble structure */ + struct APECSS_Bubble *Bubbles[RankInfo->nBubbles_local]; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(sizeof(struct APECSS_Bubble)); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_initializestruct(Bubbles[i]); + + /* Set default options and read the options for the bubble */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); + + /* Allocate the structures for the fluid properties and ODE solver parameters */ + struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); + struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); + struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); + struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); + + /* Set the default options for the fluid properties and solver parameters */ + apecss_gas_setdefaultoptions(Gas); + apecss_liquid_setdefaultoptions(Liquid); + apecss_interface_setdefaultoptions(Interface); + apecss_odesolver_setdefaultoptions(NumericsODE); + + /* Read the options file for the fluid properties and solver parameters */ + apecss_gas_readoptions(Gas, OptionsDir); + apecss_liquid_readoptions(Liquid, OptionsDir); + apecss_interface_readoptions(Interface, OptionsDir); + apecss_odesolver_readoptions(NumericsODE, OptionsDir); + + /* Associate the bubble with the relevant fluid properties and solver parameters */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->Gas = Gas; + Bubbles[i]->Liquid = Liquid; + Bubbles[i]->Interface = Interface; + Bubbles[i]->NumericsODE = NumericsODE; + } + + /* Allocate and set the excitation parameters */ + struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); + Excitation->type = APECSS_EXCITATION_SIN; + Excitation->f = (APECSS_FLOAT) fa; + Excitation->dp = (APECSS_FLOAT) pa; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Excitation = Excitation; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Create individual folders for the results of each bubble + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + if (Bubbles[i]->Results != NULL) + { + sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", RankInfo->bubblerank[RankInfo->rank] + i); + struct stat st = {0}; + if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Process all options */ + apecss_gas_processoptions(Gas); + apecss_liquid_processoptions(Liquid); + apecss_interface_processoptions(Interface); + apecss_odesolver_processoptions(NumericsODE); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_processoptions(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Use the revised pressure at infinity, including neighbor contributions + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->get_pressure_infinity = parallel_interactions_bubble_pressure_infinity; + + // Allocate interaction structure + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); + + // Update interaction structure + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->nBubbles = nBubbles; // Not used? + + // Define the size of each bubble + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + if ((i + mpi_rank * max_per_rank) % 2) + Bubbles[i]->R0 = 5.0e-6; + else + Bubbles[i]->R0 = 10.0e-6; + + Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; + } + + // Define center location for each bubble + + int ri = 0, rj = 0; + if (mpi_rank) + { + ri = mpi_rank * max_per_rank % nBubbles_x; + rj = mpi_rank * max_per_rank / nBubbles_x; + } + + for (register int n = 0; n < RankInfo->nBubbles_local; n++) + { + Bubbles[n]->Interaction->location[0] = ((APECSS_FLOAT) ri) * bubble_bubble_dist; + Bubbles[n]->Interaction->location[1] = ((APECSS_FLOAT) rj) * bubble_bubble_dist; + Bubbles[n]->Interaction->location[2] = 0.0; + + if (ri < nBubbles_x - 1) + { + ri++; + } + else + { + ri = 0; + rj++; + } + } + + // Share the location of each bubble with all ranks + + RankInfo->bubbleglobal_x = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + RankInfo->bubbleglobal_y = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + RankInfo->bubbleglobal_z = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + + for (int r = 0; r < RankInfo->size; r++) + { + int temp = RankInfo->nBubbles_local; + MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); + + APECSS_FLOAT temp_array[3]; + + for (int i = 0; i < temp; i++) + { + if (r == RankInfo->rank) + { + temp_array[0] = Bubbles[i]->Interaction->location[0]; + temp_array[1] = Bubbles[i]->Interaction->location[1]; + temp_array[2] = Bubbles[i]->Interaction->location[2]; + } + + MPI_Bcast(temp_array, 3, MPI_DOUBLE, r, MPI_COMM_WORLD); + + RankInfo->bubbleglobal_x[RankInfo->bubblerank[r] + i] = temp_array[0]; + RankInfo->bubbleglobal_y[RankInfo->bubblerank[r] + i] = temp_array[1]; + RankInfo->bubbleglobal_z[RankInfo->bubblerank[r] + i] = temp_array[2]; + } + } + + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + // apecss_erroronscreen(-1, "OUT"); + + clock_t starttimebubble = clock(); + APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->tStart = tSim; + Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; + Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step + } + + /* Initialize the bubble based on the selected options */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_initialize(Bubbles[i]); + + /* Initialize */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_initialize(Bubbles[i]); + + // Allocate the pressure contribution array + RankInfo->sumGU_rank = malloc(2 * RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + + /* Solve the bubble dynamics */ + while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered + { + APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); + tSim += dtSim; + printf("%e\n", tSim); + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Update the contribution of the neighbor bubble + parallel_interactions_quasi_acoustic(Bubbles, RankInfo); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + } + + /* Finalize the simulation*/ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_finalize(Bubbles[i]); + + char str[APECSS_STRINGLENGTH_SPRINTF]; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", i, Bubbles[i]->dtNumber, Bubbles[i]->nSubIter, + (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); + apecss_writeonscreen(str); + } + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); + + /* Make sure all allocated memory is freed */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_freestruct(Bubbles[i]); + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) free(Bubbles[i]); + free(Gas); + free(Liquid); + free(Interface); + free(NumericsODE); + free(Excitation); + + free(RankInfo->sumGU_rank); + RankInfo->sumGU_rank = NULL; + free(RankInfo); + + MPI_Finalize(); + + return (0); +} + +APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * t) + Bubble->Interaction->dp_neighbor); +} + +int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo) +{ + // All bubbles are supposed to be in the same liquid + struct APECSS_Liquid *Liquid = Bubbles[0]->Liquid; + + // Reset pressure contributions of the neighours + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0; + + // Locally compute the contribution to each bubble + for (register int i = 0; i < RankInfo->nBubbles_global; i++) + { + APECSS_FLOAT x_i = RankInfo->bubbleglobal_x[i]; + APECSS_FLOAT y_i = RankInfo->bubbleglobal_y[i]; + APECSS_FLOAT z_i = RankInfo->bubbleglobal_z[i]; + + RankInfo->sumGU_rank[i] = 0.0; + RankInfo->sumGU_rank[i + RankInfo->nBubbles_global] = 0.0; + + for (register int j = 0; j < RankInfo->nBubbles_local; j++) + { + if (j != i) + { + APECSS_FLOAT sumU_bubble = 0.0; + APECSS_FLOAT sumG_bubble = 0.0; + int nodecount_bubble = 0; + + APECSS_FLOAT x_j = Bubbles[j]->Interaction->location[0]; + APECSS_FLOAT y_j = Bubbles[j]->Interaction->location[1]; + APECSS_FLOAT z_j = Bubbles[j]->Interaction->location[2]; + + APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); + + double r_b = Bubbles[i]->R; + + // The loop over the emission nodes begins with the most far away from the emitting bubble + struct APECSS_EmissionNode *Current = Bubbles[j]->Emissions->LastNode; + while (Current != NULL) + { + if (Current->r < interbubble_dist - r_b) + // The following emission nodes have not yet reached the bubble of interest + Current = NULL; + else if (Current->r > interbubble_dist + r_b) + // The bubble of interest is still not reached + Current = Current->backward; + else + { + // The current emission node is located inside the bubble of interest + APECSS_FLOAT gr = Current->g / Current->r; + sumU_bubble += (Current->f / APECSS_POW2(Current->r)) + (gr) / Liquid->cref; + sumG_bubble += gr; + nodecount_bubble++; + Current = Current->backward; + } + } + + if (nodecount_bubble) + { + APECSS_FLOAT inv_nodecount = 1.0 / (APECSS_FLOAT) nodecount_bubble; + RankInfo->sumGU_rank[i] += sumG_bubble * inv_nodecount; + RankInfo->sumGU_rank[i + RankInfo->nBubbles_global] += sumU_bubble * inv_nodecount; + } + } + } + } + + APECSS_FLOAT *sumGU_all = malloc(2 * RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + for (register int i = 0; i < 2 * RankInfo->nBubbles_local; i++) sumGU_all[i] = 0.0; + + // Share the contributions from each rank to all bubbles + for (int r = 0; r < RankInfo->size; r++) + { + APECSS_FLOAT *temp = RankInfo->sumGU_rank; + MPI_Bcast(temp, 2 * RankInfo->nBubbles_global, MPI_INT, r, MPI_COMM_WORLD); + for (register int i = 0; i < 2 * RankInfo->nBubbles_global; i++) sumGU_all[i] += temp[i]; + } + + // Compute the total pressure contributions of the neighbours for all local bubbles + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + Bubbles[i]->Interaction->dp_neighbor = Liquid->rhoref * (sumGU_all[i] - 0.5 * APECSS_POW2(sumGU_all[RankInfo->nBubbles_global])); + + free(sumGU_all); + + return (0); +} \ No newline at end of file From fc647e5784d91265995b7c231a63147bd7071646 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 17 Jun 2024 15:15:49 -0400 Subject: [PATCH 013/138] .apecss file for parallelization --- examples/parallelinteraction/run.apecss | 38 +++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 examples/parallelinteraction/run.apecss diff --git a/examples/parallelinteraction/run.apecss b/examples/parallelinteraction/run.apecss new file mode 100644 index 0000000..c463ad7 --- /dev/null +++ b/examples/parallelinteraction/run.apecss @@ -0,0 +1,38 @@ +######################################################### +# # +# APECSS Options File # +# # +######################################################### + +BUBBLE +RPModel KM +Emissions QA 250.0e-6 +PressureAmbient 1.0e5 +END + +GAS +EoS HC +ReferencePressure 1.0e5 +ReferenceDensity 1.2 +PolytropicExponent 1.4 +END + +LIQUID +ReferencePressure 1.0e5 +ReferenceDensity 1000.0 +ReferenceSoundSpeed 1500.0 +Viscosity 1.002e-3 +END + +INTERFACE +SurfaceTensionCoeff 0.0728 +END + +RESULTS +Bubble +OutputFreqRP 5 +END + +ODESOLVER +tolerance 1.0e-10 +END From f57604bf5be73d593b9f8a19c762c8d42d2214cc Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 21 Jun 2024 12:46:13 -0400 Subject: [PATCH 014/138] parallelinteraction ; small changes to solve issues (work in progress) --- .../src/binaryinteraction_apecss.c | 6 +- examples/parallelinteraction/execmpi.sh | 2 +- examples/parallelinteraction/run.apecss | 2 + .../src/parallelinteraction_apecss.c | 202 ++++++++++++++++-- 4 files changed, 197 insertions(+), 15 deletions(-) diff --git a/examples/binaryinteraction/src/binaryinteraction_apecss.c b/examples/binaryinteraction/src/binaryinteraction_apecss.c index 20224d9..b2bb223 100644 --- a/examples/binaryinteraction/src/binaryinteraction_apecss.c +++ b/examples/binaryinteraction/src/binaryinteraction_apecss.c @@ -169,7 +169,11 @@ int main(int argc, char **args) for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); // Update interaction structure - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction->nBubbles = nBubbles; + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Interaction->nBubbles = nBubbles; + Bubbles[i]->Interaction->dp_neighbor = 0.0; + } // Define the size of each bubble for (register int i = 0; i < nBubbles; i++) diff --git a/examples/parallelinteraction/execmpi.sh b/examples/parallelinteraction/execmpi.sh index 851ec24..1494ef3 100755 --- a/examples/parallelinteraction/execmpi.sh +++ b/examples/parallelinteraction/execmpi.sh @@ -1,4 +1,4 @@ cd build ./compile.sh cd .. -mpiexec -n 7 ./build/parallelinteraction_apecss -options run.apecss -freq 15.7e3 -amp -120e3 -tend 7.5e-4 +/usr/lib64/mpich/bin/mpiexec -np 4 ./build/parallelinteraction_apecss -options run.apecss -freq 15.7e3 -amp -120e3 -tend 7.5e-4 diff --git a/examples/parallelinteraction/run.apecss b/examples/parallelinteraction/run.apecss index c463ad7..01a20c7 100644 --- a/examples/parallelinteraction/run.apecss +++ b/examples/parallelinteraction/run.apecss @@ -35,4 +35,6 @@ END ODESOLVER tolerance 1.0e-10 +MinTimeStep 1.0e-14 +MaxTimeStep 1.0e-05 END diff --git a/examples/parallelinteraction/src/parallelinteraction_apecss.c b/examples/parallelinteraction/src/parallelinteraction_apecss.c index 1d07465..27b1dcf 100644 --- a/examples/parallelinteraction/src/parallelinteraction_apecss.c +++ b/examples/parallelinteraction/src/parallelinteraction_apecss.c @@ -18,6 +18,7 @@ #include #include +#include #include "apecss.h" struct APECSS_Parallel_Cluster @@ -26,13 +27,17 @@ struct APECSS_Parallel_Cluster int nBubbles_local, nBubbles_global; int *bubblerank; // max id of bubbles for each rank + APECSS_FLOAT *bubbleglobal_r; // instantaneous radius of all bubbles APECSS_FLOAT *bubbleglobal_x, *bubbleglobal_y, *bubbleglobal_z; // x,y,z location of all bubbles APECSS_FLOAT *sumGU_rank; // Contributions from local bubbles to all bubbles }; // Declaration of additional case-dependent functions APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubble[], struct APECSS_Parallel_Cluster *RankInfo); +APECSS_FLOAT parallel_proper_cut_off_distance(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo); +int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo); + +int new_apecss_bubble_solver_run(APECSS_FLOAT tend, struct APECSS_Bubble *Bubble, int bubble_id); int main(int argc, char **args) { @@ -117,7 +122,9 @@ int main(int argc, char **args) for (int r = 0; r < RankInfo->size; r++) { int temp = RankInfo->nBubbles_local; + MPI_Barrier(MPI_COMM_WORLD); MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); + MPI_Barrier(MPI_COMM_WORLD); RankInfo->bubblerank[r + 1] = RankInfo->bubblerank[r] + temp; RankInfo->nBubbles_global += temp; } @@ -193,7 +200,11 @@ int main(int argc, char **args) for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); // Update interaction structure - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->nBubbles = nBubbles; // Not used? + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->Interaction->nBubbles = nBubbles; // Not used? + Bubbles[i]->Interaction->dp_neighbor = 0.0; + } // Define the size of each bubble for (register int i = 0; i < RankInfo->nBubbles_local; i++) @@ -206,6 +217,28 @@ int main(int argc, char **args) Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; } + // Share all initial radii + RankInfo->bubbleglobal_r = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + + for (int r = 0; r < RankInfo->size; r++) + { + int temp = RankInfo->nBubbles_local; + MPI_Barrier(MPI_COMM_WORLD); + MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); + MPI_Barrier(MPI_COMM_WORLD); + + APECSS_FLOAT temp_r; + + for (int i = 0; i < temp; i++) + { + if (r == RankInfo->rank) temp_r = Bubbles[i]->R0; + MPI_Barrier(MPI_COMM_WORLD); + MPI_Bcast(&temp_r, 1, MPI_DOUBLE, r, MPI_COMM_WORLD); + MPI_Barrier(MPI_COMM_WORLD); + RankInfo->bubbleglobal_r[RankInfo->bubblerank[r] + i] = temp_r; + } + } + // Define center location for each bubble int ri = 0, rj = 0; @@ -241,7 +274,9 @@ int main(int argc, char **args) for (int r = 0; r < RankInfo->size; r++) { int temp = RankInfo->nBubbles_local; + MPI_Barrier(MPI_COMM_WORLD); MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); + MPI_Barrier(MPI_COMM_WORLD); APECSS_FLOAT temp_array[3]; @@ -254,7 +289,9 @@ int main(int argc, char **args) temp_array[2] = Bubbles[i]->Interaction->location[2]; } + MPI_Barrier(MPI_COMM_WORLD); MPI_Bcast(temp_array, 3, MPI_DOUBLE, r, MPI_COMM_WORLD); + MPI_Barrier(MPI_COMM_WORLD); RankInfo->bubbleglobal_x[RankInfo->bubblerank[r] + i] = temp_array[0]; RankInfo->bubbleglobal_y[RankInfo->bubblerank[r] + i] = temp_array[1]; @@ -262,6 +299,9 @@ int main(int argc, char **args) } } + // Update emissions cut off distance for each bubble + parallel_proper_cut_off_distance(Bubbles, RankInfo); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // apecss_erroronscreen(-1, "OUT"); @@ -289,11 +329,43 @@ int main(int argc, char **args) { APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); tSim += dtSim; - printf("%e\n", tSim); - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); + if (RankInfo->rank == 0) printf("%e\n", tSim); + + // for (register int i = 0; i < RankInfo->nBubbles_local; i++) + // printf("Bubble %d dp_neighbor %e R %e\n", RankInfo->bubblerank[RankInfo->rank] + i, Bubbles[i]->Interaction->dp_neighbor, Bubbles[i]->R); - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) new_apecss_bubble_solver_run(tSim, Bubbles[i], RankInfo->bubblerank[RankInfo->rank] + i); + + // for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; + + // for (register int i = 0; i < RankInfo->nBubbles_local; i++) + // printf("Bubble %d counts %d nodes with R=%e\n", RankInfo->bubblerank[RankInfo->rank] + i, Bubbles[i]->Emissions->nNodes, Bubbles[i]->R); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Share instantaneous radii + for (int r = 0; r < RankInfo->size; r++) + { + int temp = RankInfo->nBubbles_local; + MPI_Barrier(MPI_COMM_WORLD); + MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); + MPI_Barrier(MPI_COMM_WORLD); + + APECSS_FLOAT temp_r; + + for (int i = 0; i < temp; i++) + { + if (r == RankInfo->rank) temp_r = Bubbles[i]->R; + MPI_Barrier(MPI_COMM_WORLD); + MPI_Bcast(&temp_r, 1, MPI_DOUBLE, r, MPI_COMM_WORLD); + MPI_Barrier(MPI_COMM_WORLD); + RankInfo->bubbleglobal_r[RankInfo->bubblerank[r] + i] = temp_r; + } + } + + // if (RankInfo->rank == 0) + // for (register int i = 0; i < RankInfo->nBubbles_global; i++) printf("%d %e\n", i, RankInfo->bubbleglobal_r[i]); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // Update the contribution of the neighbor bubble @@ -339,13 +411,41 @@ APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, stru return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * t) + Bubble->Interaction->dp_neighbor); } +APECSS_FLOAT parallel_proper_cut_off_distance(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo) +{ + // Determine a proper cut off distance for the emissions + // For each bubble, we determine its most distant neighbor + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + APECSS_FLOAT x_i = Bubbles[i]->Interaction->location[0]; + APECSS_FLOAT y_i = Bubbles[i]->Interaction->location[1]; + APECSS_FLOAT z_i = Bubbles[i]->Interaction->location[2]; + APECSS_FLOAT dist = 0.0; + + for (register int j = 0; j < RankInfo->nBubbles_global; j++) + { + APECSS_FLOAT x_j = RankInfo->bubbleglobal_x[j]; + APECSS_FLOAT y_j = RankInfo->bubbleglobal_y[j]; + APECSS_FLOAT z_j = RankInfo->bubbleglobal_z[j]; + + APECSS_FLOAT dist_ij = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); + + if (dist_ij > dist) dist = dist_ij; + } + + if (Bubbles[i]->Emissions != NULL) Bubbles[i]->Emissions->CutOffDistance = 1.05 * dist; + } + + return (0); +} + int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo) { // All bubbles are supposed to be in the same liquid struct APECSS_Liquid *Liquid = Bubbles[0]->Liquid; // Reset pressure contributions of the neighours - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; // Locally compute the contribution to each bubble for (register int i = 0; i < RankInfo->nBubbles_global; i++) @@ -359,7 +459,8 @@ int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[], struct for (register int j = 0; j < RankInfo->nBubbles_local; j++) { - if (j != i) + int bubble_id = RankInfo->bubblerank[RankInfo->rank] + j; + if (bubble_id != i) { APECSS_FLOAT sumU_bubble = 0.0; APECSS_FLOAT sumG_bubble = 0.0; @@ -371,7 +472,7 @@ int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[], struct APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); - double r_b = Bubbles[i]->R; + double r_b = RankInfo->bubbleglobal_r[i]; // The loop over the emission nodes begins with the most far away from the emitting bubble struct APECSS_EmissionNode *Current = Bubbles[j]->Emissions->LastNode; @@ -394,7 +495,7 @@ int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[], struct } } - if (nodecount_bubble) + if (nodecount_bubble != 0) { APECSS_FLOAT inv_nodecount = 1.0 / (APECSS_FLOAT) nodecount_bubble; RankInfo->sumGU_rank[i] += sumG_bubble * inv_nodecount; @@ -404,22 +505,97 @@ int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[], struct } } - APECSS_FLOAT *sumGU_all = malloc(2 * RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + APECSS_FLOAT *sumGU_all = malloc(2 * RankInfo->nBubbles_local * sizeof(APECSS_FLOAT)); for (register int i = 0; i < 2 * RankInfo->nBubbles_local; i++) sumGU_all[i] = 0.0; // Share the contributions from each rank to all bubbles for (int r = 0; r < RankInfo->size; r++) { APECSS_FLOAT *temp = RankInfo->sumGU_rank; - MPI_Bcast(temp, 2 * RankInfo->nBubbles_global, MPI_INT, r, MPI_COMM_WORLD); - for (register int i = 0; i < 2 * RankInfo->nBubbles_global; i++) sumGU_all[i] += temp[i]; + MPI_Barrier(MPI_COMM_WORLD); + MPI_Bcast(temp, 2 * RankInfo->nBubbles_global, MPI_DOUBLE, r, MPI_COMM_WORLD); + MPI_Barrier(MPI_COMM_WORLD); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) sumGU_all[i] += temp[RankInfo->bubblerank[RankInfo->rank] + i]; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + sumGU_all[i + RankInfo->nBubbles_local] += temp[RankInfo->nBubbles_global + RankInfo->bubblerank[RankInfo->rank] + i]; } // Compute the total pressure contributions of the neighbours for all local bubbles for (register int i = 0; i < RankInfo->nBubbles_local; i++) - Bubbles[i]->Interaction->dp_neighbor = Liquid->rhoref * (sumGU_all[i] - 0.5 * APECSS_POW2(sumGU_all[RankInfo->nBubbles_global])); + { + Bubbles[i]->Interaction->dp_neighbor = Liquid->rhoref * (sumGU_all[i] - 0.5 * APECSS_POW2(sumGU_all[RankInfo->nBubbles_local + i])); + // printf("%d %e\n", RankInfo->bubblerank[RankInfo->rank] + i, Bubbles[i]->Interaction->dp_neighbor); + } free(sumGU_all); + return (0); +} + +int new_apecss_bubble_solver_run(APECSS_FLOAT tend, struct APECSS_Bubble *Bubble, int bubble_id) +{ + while (Bubble->t < tend - 0.01 * Bubble->NumericsODE->dtMin) + { + // Store the previous solution for sub-iterations + for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSolOld[i] = Bubble->ODEsSol[i]; + + if (bubble_id == 1) printf("t=%e R=%e U=%e p_infty=%e\n", Bubble->t, Bubble->R, Bubble->U, Bubble->get_pressure_infinity(Bubble->t, Bubble)); + + if (isnan(Bubble->R)) + { + printf("Pause because of bubble %d at t=%e", bubble_id, Bubble->t); + pause(); + } + + // Check what comes next: the end of the solver run or, if applicable, a time instance to output the emissions + APECSS_FLOAT next_event_time = Bubble->results_emissionstime_check(tend, Bubble); + + // Set the time-step for the ODEs + apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); + + // Solve the ODEs + Bubble->err = apecss_odesolver(Bubble); + + // Perform sub-iterations on the control of the time-step when err > tol + register int subiter = 0; + while ((Bubble->err > Bubble->NumericsODE->tol) && (subiter < Bubble->NumericsODE->maxSubIter)) + { + ++subiter; + // Rewind the solution + for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSol[i] = Bubble->ODEsSolOld[i]; + // Set the time-step for the ODEs + apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); + // Solve the ODEs again + Bubble->err = apecss_odesolver(Bubble); + } + Bubble->nSubIter += subiter; + + // Set new values + ++(Bubble->dtNumber); + Bubble->t += Bubble->dt; + Bubble->U = Bubble->ODEsSol[0]; + Bubble->R = Bubble->ODEsSol[1]; + + // Update allocation of the results (if necessary) + Bubble->results_emissionsnodeminmax_identify(Bubble); + Bubble->results_emissionsnode_alloc(Bubble); + + // Acoustic emissions (if applicable) + Bubble->emissions_update(Bubble); + + // Store results (if applicable) + Bubble->results_rayleighplesset_store(Bubble); + Bubble->results_emissionsspace_store(Bubble); + + // Write one-off results (if applicable) + Bubble->results_emissionstime_write(Bubble); + + // Update the last-step solution of the RK54 scheme + for (register int i = 0; i < Bubble->nODEs; i++) Bubble->kLast[i] = Bubble->k7[i]; + + // Update progress screen in the terminal (if applicable) + Bubble->progress_update(&(*Bubble).progress, Bubble->t - Bubble->tStart, Bubble->tEnd - Bubble->tStart); + } + return (0); } \ No newline at end of file From dd8d97a4d0d488975dbd3e4d49999a6a91a3984e Mon Sep 17 00:00:00 2001 From: Pierre C Date: Wed, 3 Jul 2024 14:55:07 -0400 Subject: [PATCH 015/138] binaryinteraction ; adding new pressurederivative_infinity function, to account for every excitation pulse and interactions in the derivative of p_infinity --- .../src/binaryinteraction_apecss.c | 25 ++++++++++++++++++- include/apecss.h | 2 ++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/examples/binaryinteraction/src/binaryinteraction_apecss.c b/examples/binaryinteraction/src/binaryinteraction_apecss.c index b2bb223..3112ed4 100644 --- a/examples/binaryinteraction/src/binaryinteraction_apecss.c +++ b/examples/binaryinteraction/src/binaryinteraction_apecss.c @@ -21,6 +21,7 @@ // Declaration of additional case-dependent functions APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); // Declaration of the structure holding the interaction variables of each bubble struct Interaction @@ -164,6 +165,7 @@ int main(int argc, char **args) // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // Use the revised pressure at infinity, including neighbor contributions for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressure_infinity = interaction_bubble_pressure_infinity; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressurederivative_infinity = interaction_bubble_pressurederivative_infinity; // Initialize interaction structure for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); @@ -173,6 +175,8 @@ int main(int argc, char **args) { Bubbles[i]->Interaction->nBubbles = nBubbles; Bubbles[i]->Interaction->dp_neighbor = 0.0; + Bubbles[i]->Interaction->last_t = 0.0; + Bubbles[i]->Interaction->last_pinfinity = Bubbles[i]->p0; } // Define the size of each bubble @@ -233,8 +237,13 @@ int main(int argc, char **args) // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // Update the contribution of the neighbor bubble apecss_interactions_instantaneous(Bubbles); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Interaction->last_t = Bubbles[i]->t; + Bubbles[i]->Interaction->last_pinfinity = Bubbles[i]->get_pressure_infinity(Bubbles[i]->t, Bubbles[i]); + } } /* Finalize the simulation*/ @@ -267,4 +276,18 @@ int main(int argc, char **args) APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * t) + Bubble->Interaction->dp_neighbor); +} + +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + // Approximate numerical computation of p_infinity + APECSS_FLOAT delta_t = t - Bubble->Interaction->last_t; + if (delta_t == 0) + { + return 0.0; + } + else + { + return (Bubble->get_pressure_infinity(t, Bubble) - Bubble->Interaction->last_pinfinity) / delta_t; + } } \ No newline at end of file diff --git a/include/apecss.h b/include/apecss.h index 44cd03e..c693b04 100644 --- a/include/apecss.h +++ b/include/apecss.h @@ -316,6 +316,8 @@ struct APECSS_Interaction int nBubbles; // Number of bubbles in the whole cluster considered APECSS_FLOAT location[3]; // 3D coordinates of the considered bubble APECSS_FLOAT dp_neighbor; // Pressure induced by interactions with neighboring bubbles + APECSS_FLOAT last_t; // Previous timestep when interaction where considered + APECSS_FLOAT last_pinfinity; // Pressure in the liquid at the bubble wall during the previous timestep where interactions where considered }; struct APECSS_ResultsBubble From 43b75cb0c0e456776062e6a56c4d1d4e5d491148 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Wed, 3 Jul 2024 17:25:42 -0400 Subject: [PATCH 016/138] Ida example-cavitation onset; first draft --- .../cavitationonset/IC/build/CMakeLists.txt | 41 ++ examples/cavitationonset/IC/build/compile.sh | 5 + examples/cavitationonset/IC/gather_results.py | 0 examples/cavitationonset/IC/run.apecss | 36 ++ .../IC/src/cavitationonset_apecss.c | 425 ++++++++++++++++++ examples/cavitationonset/README.md | 1 + examples/cavitationonset/plot_results.py | 0 .../cavitationonset/run_cavitationonset.sh | 12 + 8 files changed, 520 insertions(+) create mode 100644 examples/cavitationonset/IC/build/CMakeLists.txt create mode 100755 examples/cavitationonset/IC/build/compile.sh create mode 100644 examples/cavitationonset/IC/gather_results.py create mode 100644 examples/cavitationonset/IC/run.apecss create mode 100644 examples/cavitationonset/IC/src/cavitationonset_apecss.c create mode 100644 examples/cavitationonset/README.md create mode 100644 examples/cavitationonset/plot_results.py create mode 100755 examples/cavitationonset/run_cavitationonset.sh diff --git a/examples/cavitationonset/IC/build/CMakeLists.txt b/examples/cavitationonset/IC/build/CMakeLists.txt new file mode 100644 index 0000000..8e43b7f --- /dev/null +++ b/examples/cavitationonset/IC/build/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.12) + +project (cavitationonset_apecss) +set(CMAKE_C_COMPILER /usr/bin/gcc) + +include_directories($ENV{APECSS_DIR}/include) +FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) + +set (mylibs m apecss) +link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) + +foreach(arg ${myincludes}) + IF (arg MATCHES "-I") + STRING(REGEX REPLACE "-I" "" myinc ${arg}) + message("Additional include: ${myinc}") + include_directories(${myinc}) + ENDIF(arg MATCHES "-I") +endforeach(arg ${myincludes}) + +foreach(arg ${mylibs}) + STRING(REGEX REPLACE "lib" "" myl1 ${arg}) + STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) + set(mylibs ${myl2} ${mylibs} ${myl2}) +endforeach(arg ${mylibs}) + +if(NOT CMAKE_BUILD_TYPE) + message(STATUS "Optimization: No optimization specified.") + set(CMAKE_BUILD_TYPE Release) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + message(STATUS "Optimization: Debug") + set(CMAKE_C_FLAGS_DEBUG "-Wall -g") +elseif(CMAKE_BUILD_TYPE STREQUAL "Release") + message(STATUS "Optimization: Release") + add_definitions(-DNDEBUG) + set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") +endif() + +add_executable(cavitationonset_apecss ${myfiles}) +target_link_libraries(cavitationonset_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/cavitationonset/IC/build/compile.sh b/examples/cavitationonset/IC/build/compile.sh new file mode 100755 index 0000000..02b82c5 --- /dev/null +++ b/examples/cavitationonset/IC/build/compile.sh @@ -0,0 +1,5 @@ +#!/bin/bash +rm cavitationonset_apecss +cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release +make +rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/cavitationonset/IC/gather_results.py b/examples/cavitationonset/IC/gather_results.py new file mode 100644 index 0000000..e69de29 diff --git a/examples/cavitationonset/IC/run.apecss b/examples/cavitationonset/IC/run.apecss new file mode 100644 index 0000000..6006bc7 --- /dev/null +++ b/examples/cavitationonset/IC/run.apecss @@ -0,0 +1,36 @@ +######################################################### +# # +# APECSS Options File # +# # +######################################################### + +BUBBLE +RPModel KM +Emissions IC 600.0e-06 +PressureAmbient 0.1013e6 +END + +GAS +EoS IG +ReferenceDensity 1.2 +PolytropicExponent 1 +END + +LIQUID +ReferencePressure 0.1013e6 +ReferenceDensity 1000.0 +ReferenceSoundSpeed 1500.0 +Viscosity 1.002e-3 +END + +INTERFACE +SurfaceTensionCoeff 0.0728 +END + +RESULTS +Bubble +END + +ODESOLVER +tolerance 1.0e-10 +END diff --git a/examples/cavitationonset/IC/src/cavitationonset_apecss.c b/examples/cavitationonset/IC/src/cavitationonset_apecss.c new file mode 100644 index 0000000..de0f70a --- /dev/null +++ b/examples/cavitationonset/IC/src/cavitationonset_apecss.c @@ -0,0 +1,425 @@ +// This source file is part of APECSS, an open-source software toolbox +// for the computation of pressure-driven bubble dynamics and acoustic +// emissions in spherical symmetry. +// +// Copyright (C) 2022-2024 The APECSS Developers +// +// The APECSS Developers are listed in the README.md file available in +// the GitHub repository at https://github.com/polycfd/apecss. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// ------------------------------------------------------------------- +// APECSS standalone example of cavitation onset with acoustically-in- +// teracting microbubbles, based on Ida (2009), Physics of Fluids 21 +// (11), 113302, DOI : 10.1063/1.3265547 +// ------------------------------------------------------------------- + +#include +#include "apecss.h" + +// Declaration of additional case-dependent functions +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); + +// Declaration of the structure holding the interaction variables of each bubble +struct Interaction +{ + APECSS_FLOAT dp_neighbor; +}; + +int main(int argc, char **args) +{ + char OptionsDir[APECSS_STRINGLENGTH]; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Interbubble time-step, defining the frequency with which the neighbor influence is updated + APECSS_FLOAT dt_interbubble = 1.0e-8; + + // Initialize the simulation parameters given by the execution command + int nBubbles = 2; + double tEnd = 0.0; + double fa = 0.0; + double pa = 0.0; + int cluster_distrib = 0; + int cluster_size = 0; + int inttype = 0; + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + apecss_infoscreen(); + + /* Read commandline options */ + sprintf(OptionsDir, "./run.apecss"); // This is the default + int j = 1; // First argument is the call to the executable + while (j < argc) + { + if (strcmp("-options", args[j]) == 0) + { + sprintf(OptionsDir, "%s", args[j + 1]); + j += 2; + } + else if (strcmp("-tend", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &tEnd); + j += 2; + } + else if (strcmp("-freq", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &fa); + j += 2; + } + else if (strcmp("-amp", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &pa); + j += 2; + } + else if (strcmp("-nbb", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &nBubbles); + j += 2; + } + else if (strcmp("-cldistrib", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &cluster_distrib); + j += 2; + } + else if (strcmp("-clsize", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &cluster_size); + j += 2; + } + else if (strcmp("-inttype", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &inttype); + j += 2; + } + else if (strcmp("-h", args[j]) == 0) + { + apecss_helpscreen(); + } + else + { + char str[APECSS_STRINGLENGTH_SPRINTF]; + sprintf(str, "Unknown command line options: %s", args[j]); + apecss_erroronscreen(1, str); + ++j; + } + } + + /* Allocate and initialize Bubble structure */ + struct APECSS_Bubble *Bubbles[nBubbles]; + for (register int i = 0; i < nBubbles; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(nBubbles * sizeof(struct APECSS_Bubble)); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initializestruct(Bubbles[i]); + + /* Set default options and read the options for the bubble */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); + + /* Allocate the structures for the fluid properties and ODE solver parameters */ + struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); + struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); + struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); + struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); + + /* Set the default options for the fluid properties and solver parameters */ + apecss_gas_setdefaultoptions(Gas); + apecss_liquid_setdefaultoptions(Liquid); + apecss_interface_setdefaultoptions(Interface); + apecss_odesolver_setdefaultoptions(NumericsODE); + + /* Read the options file for the fluid properties and solver parameters */ + apecss_gas_readoptions(Gas, OptionsDir); + apecss_liquid_readoptions(Liquid, OptionsDir); + apecss_interface_readoptions(Interface, OptionsDir); + apecss_odesolver_readoptions(NumericsODE, OptionsDir); + + /* Associate the bubble with the relevant fluid properties and solver parameters */ + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Gas = Gas; + Bubbles[i]->Liquid = Liquid; + Bubbles[i]->Interface = Interface; + Bubbles[i]->NumericsODE = NumericsODE; + } + + /* Allocate and set the excitation parameters */ + struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); + Excitation->type = APECSS_EXCITATION_SIN; + Excitation->f = (APECSS_FLOAT) fa; + Excitation->dp = (APECSS_FLOAT) pa; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Excitation = Excitation; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Create individual folders for the results of each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (Bubbles[i]->Results != NULL) + { + sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", i); + struct stat st = {0}; + if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Process all options */ + apecss_gas_processoptions(Gas); + apecss_liquid_processoptions(Liquid); + apecss_interface_processoptions(Interface); + apecss_odesolver_processoptions(NumericsODE); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_processoptions(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Use the revised pressure at infinity, including neighbor contributions + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressure_infinity = interaction_bubble_pressure_infinity; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressurederivative_infinity = interaction_bubble_pressurederivative_infinity; + + // Initialize interaction structure + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); + + // Update interaction structure + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Interaction->nBubbles = nBubbles; + Bubbles[i]->Interaction->dp_neighbor = 0.0; + Bubbles[i]->Interaction->last_t = 0.0; + Bubbles[i]->Interaction->last_pinfinity = Bubbles[i]->p0; + } + + // Define the size of each bubble + if (cluster_distrib == 0) + { + // Two bubbles of different initial size interacting + Bubbles[0]->R0 = 2.0e-06; + Bubbles[1]->R0 = 20.0e-06; + } + else + { + // Monodispersed multibubble distributions + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->R0 = 20.0e-06; + } + } + + // Define center location for each bubble + if (cluster_distrib == 0) + { + // Two bubbles of different initial size interacting + Bubbles[0]->Interaction->location[0] = 0.0; + Bubbles[0]->Interaction->location[1] = 0.0; + Bubbles[0]->Interaction->location[2] = 0.0; + + Bubbles[1]->Interaction->location[0] = (APECSS_FLOAT) cluster_size * (Bubbles[0]->R0 + Bubbles[1]->R0); + Bubbles[1]->Interaction->location[1] = 0.0; + Bubbles[1]->Interaction->location[2] = 0.0; + } + else + { + // Monodispersed multibubble distributions + APECSS_FLOAT D = 400.0e-06; + if (nBubbles == 1) + { + // Single bubble + Bubbles[0]->Interaction->location[0] = 0.0; + Bubbles[0]->Interaction->location[1] = 0.0; + Bubbles[0]->Interaction->location[2] = 0.0; + } + else if (nBubbles == 2) + { + // Two bubbles + Bubbles[0]->Interaction->location[0] = 0.0; + Bubbles[0]->Interaction->location[1] = 0.0; + Bubbles[0]->Interaction->location[2] = 0.0; + + Bubbles[1]->Interaction->location[0] = D; + Bubbles[1]->Interaction->location[1] = 0.0; + Bubbles[1]->Interaction->location[2] = 0.0; + } + else if (nBubbles == 3) + { + // Regular triangle + Bubbles[0]->Interaction->location[0] = 0.0; + Bubbles[0]->Interaction->location[1] = 0.0; + Bubbles[0]->Interaction->location[2] = 0.0; + + Bubbles[1]->Interaction->location[0] = D; + Bubbles[1]->Interaction->location[1] = 0.0; + Bubbles[1]->Interaction->location[2] = 0.0; + + Bubbles[2]->Interaction->location[0] = 0.5 * D; + Bubbles[2]->Interaction->location[1] = D * APECSS_SIN(APECSS_ONETHIRD * APECSS_PI); + Bubbles[2]->Interaction->location[2] = 0.0; + } + else if (nBubbles == 4) + { + // Regular tetragon + Bubbles[0]->Interaction->location[0] = 0.0; + Bubbles[0]->Interaction->location[1] = 0.0; + Bubbles[0]->Interaction->location[2] = 0.0; + + Bubbles[1]->Interaction->location[0] = D; + Bubbles[1]->Interaction->location[1] = 0.0; + Bubbles[1]->Interaction->location[2] = 0.0; + + Bubbles[2]->Interaction->location[0] = 0.0; + Bubbles[2]->Interaction->location[1] = D; + Bubbles[2]->Interaction->location[2] = 0.0; + + Bubbles[3]->Interaction->location[0] = D; + Bubbles[3]->Interaction->location[1] = D; + Bubbles[3]->Interaction->location[2] = 0.0; + } + else if (nBubbles == 8) + { + // Regular hexaedron + Bubbles[0]->Interaction->location[0] = 0.0; + Bubbles[0]->Interaction->location[1] = 0.0; + Bubbles[0]->Interaction->location[2] = 0.0; + + Bubbles[1]->Interaction->location[0] = D; + Bubbles[1]->Interaction->location[1] = 0.0; + Bubbles[1]->Interaction->location[2] = 0.0; + + Bubbles[2]->Interaction->location[0] = 0.0; + Bubbles[2]->Interaction->location[1] = D; + Bubbles[2]->Interaction->location[2] = 0.0; + + Bubbles[3]->Interaction->location[0] = D; + Bubbles[3]->Interaction->location[1] = D; + Bubbles[3]->Interaction->location[2] = 0.0; + + Bubbles[4]->Interaction->location[0] = 0.0; + Bubbles[4]->Interaction->location[1] = 0.0; + Bubbles[4]->Interaction->location[2] = D; + + Bubbles[5]->Interaction->location[0] = D; + Bubbles[5]->Interaction->location[1] = 0.0; + Bubbles[5]->Interaction->location[2] = D; + + Bubbles[6]->Interaction->location[0] = 0.0; + Bubbles[6]->Interaction->location[1] = D; + Bubbles[6]->Interaction->location[2] = D; + + Bubbles[7]->Interaction->location[0] = D; + Bubbles[7]->Interaction->location[1] = D; + Bubbles[7]->Interaction->location[2] = D; + } + else + { + char str[APECSS_STRINGLENGTH_SPRINTF]; + sprintf(str, "Wrong number of bubbles as input for this specific cluster distribution (1, 2, 3, 4 or 8)"); + apecss_erroronscreen(1, str); + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + clock_t starttimebubble = clock(); + APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system + + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->tStart = tSim; + Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; + Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step + } + + /* Initialize the bubble based on the selected options */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initialize(Bubbles[i]); + + /* Initialize */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_initialize(Bubbles[i]); + + /* Solve the bubble dynamics */ + while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered + { + APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); + tSim += dtSim; + + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); + + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Update the contribution of the neighbor bubble + if (inttype == 1) + { + apecss_interactions_instantaneous(Bubbles); + } + else if (inttype == 2) + { + apecss_interactions_quasi_acoustic(Bubbles); + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + printf("%e %e %e %e %e\n", tSim, Bubbles[0]->R, Bubbles[0]->get_pressure_infinity(tSim, Bubbles[0]), Bubbles[0]->Interaction->dp_neighbor, + Bubbles[0]->get_pressurederivative_infinity(tSim, Bubbles[0]) * Bubbles[0]->R / Liquid->cref); + + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Interaction->last_t = Bubbles[i]->t; + Bubbles[i]->Interaction->last_pinfinity = Bubbles[i]->get_pressure_infinity(Bubbles[i]->t, Bubbles[i]); + } + } + + /* Finalize the simulation*/ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_finalize(Bubbles[i]); + + char str[APECSS_STRINGLENGTH_SPRINTF]; + for (register int i = 0; i < nBubbles; i++) + { + sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", i, Bubbles[i]->dtNumber, Bubbles[i]->nSubIter, + (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); + apecss_writeonscreen(str); + } + + for (register int i = 0; i < nBubbles; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); + for (register int i = 0; i < nBubbles; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); + + /* Make sure all allocated memory is freed */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_freestruct(Bubbles[i]); + + for (register int i = 0; i < nBubbles; i++) free(Bubbles[i]); + free(Gas); + free(Liquid); + free(Interface); + free(NumericsODE); + free(Excitation); + + return (0); +} + +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + APECSS_FLOAT T = 10.0e-06; + if (t < T) + { + return (Bubble->p0 + Bubble->Interaction->dp_neighbor); + } + else if (t > 2 * T) + { + return (Bubble->Excitation->dp + Bubble->Interaction->dp_neighbor); + } + else + { + APECSS_FLOAT W = 0.5 * (1 - APECSS_COS((t + T) * APECSS_PI / T)); + return (Bubble->p0 + W * (Bubble->Excitation->dp - Bubble->p0) + Bubble->Interaction->dp_neighbor); + } +} + +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + // Approximate numerical computation of p_infinity + APECSS_FLOAT delta_t = t - Bubble->Interaction->last_t; + if (delta_t == 0) + { + return 0.0; + } + else + { + APECSS_FLOAT derivative = (Bubble->get_pressure_infinity(t, Bubble) - Bubble->Interaction->last_pinfinity) / delta_t; + return derivative; + } +} \ No newline at end of file diff --git a/examples/cavitationonset/README.md b/examples/cavitationonset/README.md new file mode 100644 index 0000000..bad759c --- /dev/null +++ b/examples/cavitationonset/README.md @@ -0,0 +1 @@ +This example builds a standalone APECSS code for two (or more) interaction microbubbles, following the work of [Ida, M. (2009). Multibubble cavitation inception. Physics of Fluids, 21(11), 113302.](https://doi.org/10.1063/1.3265547), using the _standard incompressible model_ and the newly developped _quasi acoustic model_ to compute the acoustic emissions. There is three folders, representing each a specific interaction model ("NI" for "no interaction, "IC" for the _standard incompressible model_ and "QA" for the _quasi acoustic model_). Each folder is containing a provided [run.apecss](./IC/run.apecss) file to reproduce the bubble dynamics shown in Figs. 2, 3, 4, 5, 6 and 16 of the paper of Ida such as a [gather_results.py](./IC/gather_results.py) to properly keep the results. The [run_cavitationonset.sh](./run_cavitationonset.sh) file provides the whole execution commands needed to gather data in order to reproduce results from the source article. \ No newline at end of file diff --git a/examples/cavitationonset/plot_results.py b/examples/cavitationonset/plot_results.py new file mode 100644 index 0000000..e69de29 diff --git a/examples/cavitationonset/run_cavitationonset.sh b/examples/cavitationonset/run_cavitationonset.sh new file mode 100755 index 0000000..4673ac5 --- /dev/null +++ b/examples/cavitationonset/run_cavitationonset.sh @@ -0,0 +1,12 @@ +cd IC/build +./compile.sh +cd .. +nbubble=2 +png=-25325 +./build/cavitationonset_apecss -options run.apecss -amp $png -tend 60.0e-6 -nbb $nbubble -cldistrib 0 -clsize 20 -inttype 1 +# for ((c=0; c<$nbubble; c++)) +# do +# rm -r Bubble_$c +# done + +cd .. \ No newline at end of file From 8248d27803d6d0d79b799d6f49859a3fe20c5da9 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Thu, 4 Jul 2024 12:02:35 -0400 Subject: [PATCH 017/138] cavitationonset ; correction for pressurederivative_infinity --- .../IC/src/cavitationonset_apecss.c | 43 +++++++++++++------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/examples/cavitationonset/IC/src/cavitationonset_apecss.c b/examples/cavitationonset/IC/src/cavitationonset_apecss.c index de0f70a..7f7d9fc 100644 --- a/examples/cavitationonset/IC/src/cavitationonset_apecss.c +++ b/examples/cavitationonset/IC/src/cavitationonset_apecss.c @@ -184,8 +184,10 @@ int main(int argc, char **args) { Bubbles[i]->Interaction->nBubbles = nBubbles; Bubbles[i]->Interaction->dp_neighbor = 0.0; - Bubbles[i]->Interaction->last_t = 0.0; - Bubbles[i]->Interaction->last_pinfinity = Bubbles[i]->p0; + Bubbles[i]->Interaction->last_t_1 = 0.0; + Bubbles[i]->Interaction->last_t_2 = 0.0; + Bubbles[i]->Interaction->last_p_1 = 0.0; + Bubbles[i]->Interaction->last_p_2 = 0.0; } // Define the size of each bubble @@ -354,13 +356,22 @@ int main(int argc, char **args) } // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - printf("%e %e %e %e %e\n", tSim, Bubbles[0]->R, Bubbles[0]->get_pressure_infinity(tSim, Bubbles[0]), Bubbles[0]->Interaction->dp_neighbor, - Bubbles[0]->get_pressurederivative_infinity(tSim, Bubbles[0]) * Bubbles[0]->R / Liquid->cref); + int index = 1; + APECSS_FLOAT derivative = (Bubbles[index]->Interaction->last_p_1 - Bubbles[index]->Interaction->last_p_2) / + (Bubbles[index]->Interaction->last_t_1 - Bubbles[index]->Interaction->last_t_2); + printf("%e Bubble %d R %e U %e A %e t_1 %e t_2 %e inv_t %e p_1 %e p_2 %e diff_p %e derivative %e\n", tSim, index, Bubbles[index]->R, Bubbles[index]->U, + Bubbles[index]->ode[0](Bubbles[index]->ODEsSol, Bubbles[index]->t, Bubbles[index]), Bubbles[index]->Interaction->last_t_1, + Bubbles[index]->Interaction->last_t_2, 1 / (Bubbles[index]->Interaction->last_t_1 - Bubbles[index]->Interaction->last_t_2), + Bubbles[index]->Interaction->last_p_1, Bubbles[index]->Interaction->last_p_2, + (Bubbles[index]->Interaction->last_p_1 - Bubbles[index]->Interaction->last_p_2), derivative); for (register int i = 0; i < nBubbles; i++) { - Bubbles[i]->Interaction->last_t = Bubbles[i]->t; - Bubbles[i]->Interaction->last_pinfinity = Bubbles[i]->get_pressure_infinity(Bubbles[i]->t, Bubbles[i]); + Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; + Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; + + Bubbles[i]->Interaction->last_t_1 = tSim; + Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; } } @@ -411,15 +422,23 @@ APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_ APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { - // Approximate numerical computation of p_infinity - APECSS_FLOAT delta_t = t - Bubble->Interaction->last_t; - if (delta_t == 0) + // Approximate numerical computation of p_infinity derivative + APECSS_FLOAT T = 10.0e-06; + APECSS_FLOAT derivative = 0.0; + if ((t >= T) && (t <= 2 * T)) + { + APECSS_FLOAT inv_T = 1 / T; + derivative = 0.5 * APECSS_PI * inv_T * APECSS_SIN(APECSS_PI * (t + T) * inv_T) * (Bubble->Excitation->dp - Bubble->p0); + } + + APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; + if (delta_t > Bubble->dt) { - return 0.0; + APECSS_FLOAT inv_delta_t = 1 / delta_t; + return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) * inv_delta_t)); } else { - APECSS_FLOAT derivative = (Bubble->get_pressure_infinity(t, Bubble) - Bubble->Interaction->last_pinfinity) / delta_t; - return derivative; + return (derivative); } } \ No newline at end of file From 62669b9c8e75ebfbf900c986e75558f9f9ae9caa Mon Sep 17 00:00:00 2001 From: Pierre C Date: Thu, 4 Jul 2024 19:58:28 -0400 Subject: [PATCH 018/138] interactions ; small corrections and printf for debugging --- src/interactions.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/interactions.c b/src/interactions.c index 682306f..ed8a78e 100644 --- a/src/interactions.c +++ b/src/interactions.c @@ -22,12 +22,20 @@ int apecss_interactions_instantaneous(struct APECSS_Bubble *Bubbles[]) { - // Compute interactions uby considering them instantaneous (fully incompressible approach) + // Compute interactions by considering them instantaneous (fully incompressible approach) int nBubbles = Bubbles[0]->Interaction->nBubbles; // All bubbles are supposed to be in the same liquid struct APECSS_Liquid *Liquid = Bubbles[0]->Liquid; + // Preliminary step to gather bubble wall acceleration values + APECSS_FLOAT Bubbles_A[nBubbles]; + for (register int i = 0; i < nBubbles; i++) + { + APECSS_FLOAT acceleration = Bubbles[i]->ode[0](Bubbles[i]->ODEsSol, Bubbles[i]->t, Bubbles[i]); + Bubbles_A[i] = acceleration; + } + for (register int i = 0; i < nBubbles; i++) { APECSS_FLOAT x_i = Bubbles[i]->Interaction->location[0]; @@ -43,13 +51,23 @@ int apecss_interactions_instantaneous(struct APECSS_Bubble *Bubbles[]) APECSS_FLOAT z_j = Bubbles[j]->Interaction->location[2]; APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); + // printf("Bubble %d vs Bubble %d, %e %e %e", i, j, interbubble_dist, Bubbles[i]->ode[0](Bubbles[i]->ODEsSol, Bubbles[i]->t, Bubbles[i]), + // Bubbles[j]->ode[0](Bubbles[j]->ODEsSol, Bubbles[j]->t, Bubbles[j])); + // printf("Bubble %d vs Bubble %d, %e %e %e", i, j, interbubble_dist, Bubbles_A[i], Bubbles_A[j]); + + // APECSS_FLOAT dp = Liquid->rhoref * ((2.0 * Bubbles[j]->R * APECSS_POW2(Bubbles[j]->U) + + // APECSS_POW2(Bubbles[j]->R) * Bubbles[j]->ode[0](Bubbles[j]->ODEsSol, Bubbles[j]->t, Bubbles[j])) * + // (1 / interbubble_dist) - + // (APECSS_POW4(Bubbles[j]->R) * APECSS_POW2(Bubbles[j]->U)) * (1 / (2 * APECSS_POW4(interbubble_dist)))); - APECSS_FLOAT dp = Liquid->rhoref * ((2.0 * Bubbles[j]->R * APECSS_POW2(Bubbles[j]->U) + - APECSS_POW2(Bubbles[j]->R) * Bubbles[j]->ode[0](Bubbles[j]->ODEsSol, Bubbles[j]->t, Bubbles[j])) * - (1 / interbubble_dist) - - (APECSS_POW4(Bubbles[j]->R) * APECSS_POW2(Bubbles[j]->U)) * (1 / (2 * APECSS_POW4(interbubble_dist)))); + APECSS_FLOAT dp = + Liquid->rhoref * ((2.0 * Bubbles[j]->R * APECSS_POW2(Bubbles[j]->U) + APECSS_POW2(Bubbles[j]->R) * Bubbles_A[j]) * (1 / interbubble_dist) - + (APECSS_POW4(Bubbles[j]->R) * APECSS_POW2(Bubbles[j]->U)) * (1 / (2 * APECSS_POW4(interbubble_dist)))); Bubbles[i]->Interaction->dp_neighbor += dp; + // printf(" %e %e\n", Bubbles[i]->ode[0](Bubbles[i]->ODEsSol, Bubbles[i]->t, Bubbles[i]), + // Bubbles[j]->ode[0](Bubbles[j]->ODEsSol, Bubbles[j]->t, Bubbles[j])); + // printf(" %e\n", Bubbles[i]->Interaction->dp_neighbor); } } } @@ -87,6 +105,7 @@ int apecss_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[]) APECSS_FLOAT z_j = Bubbles[j]->Interaction->location[2]; APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); + // printf("Bubble %d vs Bubble %d, %e", i, j, interbubble_dist); double r_b = Bubbles[i]->R; @@ -123,6 +142,7 @@ int apecss_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[]) } } Bubbles[i]->Interaction->dp_neighbor += Liquid->rhoref * (sumG - 0.5 * APECSS_POW2(sumU)); + // printf(" %e\n", Bubbles[i]->Interaction->dp_neighbor); } return (0); From 826bcc579a885d055fea90d40477f3b2735f573f Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 5 Jul 2024 11:34:33 -0400 Subject: [PATCH 019/138] parallelinteraction ; working simple 5x5 bubbly screen example --- .../parallelinteraction/build/CMakeLists.txt | 2 +- examples/parallelinteraction/execmpi.sh | 11 +- examples/parallelinteraction/run.apecss | 4 +- .../src/parallelinteraction_apecss.c | 284 ++++-------------- 4 files changed, 77 insertions(+), 224 deletions(-) diff --git a/examples/parallelinteraction/build/CMakeLists.txt b/examples/parallelinteraction/build/CMakeLists.txt index 5b49e67..6d24867 100644 --- a/examples/parallelinteraction/build/CMakeLists.txt +++ b/examples/parallelinteraction/build/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.12) project (parallelinteraction_apecss) -set(CMAKE_C_COMPILER /usr/lib64/mpich/bin/mpicc) +set(CMAKE_C_COMPILER mpicc) include_directories($ENV{APECSS_DIR}/include) FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) diff --git a/examples/parallelinteraction/execmpi.sh b/examples/parallelinteraction/execmpi.sh index 1494ef3..ed503b3 100755 --- a/examples/parallelinteraction/execmpi.sh +++ b/examples/parallelinteraction/execmpi.sh @@ -1,4 +1,13 @@ cd build ./compile.sh cd .. -/usr/lib64/mpich/bin/mpiexec -np 4 ./build/parallelinteraction_apecss -options run.apecss -freq 15.7e3 -amp -120e3 -tend 7.5e-4 +mpiexec -n 5 ./build/parallelinteraction_apecss -options run.apecss -freq 15.7e3 -amp -120e3 -tend 7.5e-4 + +#mpiexec -n 2 valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valout.txt ./build/parallelinteraction_apecss -options run.apecss -freq 15.7e3 -amp -120e3 -tend 7.5e-8 +#valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valout.txt ./build/parallelinteraction_apecss -options run.apecss -freq 15.7e3 -amp -120e3 -tend 7.5e-8 +#valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valout.txt mpiexec -n 2 ./build/parallelinteraction_apecss -options run.apecss -freq 15.7e3 -amp -120e3 -tend 7.5e-8 + +for ((c=0; c<25; c++)) +do + rm -rf Bubble_$c +done \ No newline at end of file diff --git a/examples/parallelinteraction/run.apecss b/examples/parallelinteraction/run.apecss index 01a20c7..9d8552a 100644 --- a/examples/parallelinteraction/run.apecss +++ b/examples/parallelinteraction/run.apecss @@ -11,7 +11,7 @@ PressureAmbient 1.0e5 END GAS -EoS HC +EoS IG ReferencePressure 1.0e5 ReferenceDensity 1.2 PolytropicExponent 1.4 @@ -35,6 +35,4 @@ END ODESOLVER tolerance 1.0e-10 -MinTimeStep 1.0e-14 -MaxTimeStep 1.0e-05 END diff --git a/examples/parallelinteraction/src/parallelinteraction_apecss.c b/examples/parallelinteraction/src/parallelinteraction_apecss.c index 27b1dcf..214f2ff 100644 --- a/examples/parallelinteraction/src/parallelinteraction_apecss.c +++ b/examples/parallelinteraction/src/parallelinteraction_apecss.c @@ -17,8 +17,7 @@ // ------------------------------------------------------------------- #include -#include -#include +#include #include "apecss.h" struct APECSS_Parallel_Cluster @@ -27,17 +26,13 @@ struct APECSS_Parallel_Cluster int nBubbles_local, nBubbles_global; int *bubblerank; // max id of bubbles for each rank - APECSS_FLOAT *bubbleglobal_r; // instantaneous radius of all bubbles - APECSS_FLOAT *bubbleglobal_x, *bubbleglobal_y, *bubbleglobal_z; // x,y,z location of all bubbles + APECSS_FLOAT *bubbleglobal_R, *bubbleglobal_x, *bubbleglobal_y, *bubbleglobal_z; // Radius and x,y,z location of all bubbles APECSS_FLOAT *sumGU_rank; // Contributions from local bubbles to all bubbles }; // Declaration of additional case-dependent functions APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -APECSS_FLOAT parallel_proper_cut_off_distance(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo); -int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo); - -int new_apecss_bubble_solver_run(APECSS_FLOAT tend, struct APECSS_Bubble *Bubble, int bubble_id); +int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubble[], struct APECSS_Parallel_Cluster *RankInfo); int main(int argc, char **args) { @@ -111,8 +106,8 @@ int main(int argc, char **args) /* Determine the number of bubbles per rank */ int max_per_rank = ceil((double) nBubbles / (double) mpi_size); - RankInfo->nBubbles_local = APECSS_MIN(max_per_rank, nBubbles - mpi_rank * max_per_rank); - + RankInfo->nBubbles_local = APECSS_MAX(0, APECSS_MIN(max_per_rank, nBubbles - mpi_rank * max_per_rank)); + // printf("[%i] %i\n", mpi_rank, RankInfo->nBubbles_local); /* Share the parallel distribution of bubbles with all ranks */ RankInfo->bubblerank = malloc((RankInfo->size + 1) * sizeof(int)); @@ -122,9 +117,7 @@ int main(int argc, char **args) for (int r = 0; r < RankInfo->size; r++) { int temp = RankInfo->nBubbles_local; - MPI_Barrier(MPI_COMM_WORLD); MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); - MPI_Barrier(MPI_COMM_WORLD); RankInfo->bubblerank[r + 1] = RankInfo->bubblerank[r] + temp; RankInfo->nBubbles_global += temp; } @@ -197,15 +190,15 @@ int main(int argc, char **args) for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->get_pressure_infinity = parallel_interactions_bubble_pressure_infinity; // Allocate interaction structure - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); - - // Update interaction structure for (register int i = 0; i < RankInfo->nBubbles_local; i++) { - Bubbles[i]->Interaction->nBubbles = nBubbles; // Not used? + Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); Bubbles[i]->Interaction->dp_neighbor = 0.0; } + // Update interaction structure + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->nBubbles = nBubbles; // Not used? + // Define the size of each bubble for (register int i = 0; i < RankInfo->nBubbles_local; i++) { @@ -217,28 +210,6 @@ int main(int argc, char **args) Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; } - // Share all initial radii - RankInfo->bubbleglobal_r = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - - for (int r = 0; r < RankInfo->size; r++) - { - int temp = RankInfo->nBubbles_local; - MPI_Barrier(MPI_COMM_WORLD); - MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); - MPI_Barrier(MPI_COMM_WORLD); - - APECSS_FLOAT temp_r; - - for (int i = 0; i < temp; i++) - { - if (r == RankInfo->rank) temp_r = Bubbles[i]->R0; - MPI_Barrier(MPI_COMM_WORLD); - MPI_Bcast(&temp_r, 1, MPI_DOUBLE, r, MPI_COMM_WORLD); - MPI_Barrier(MPI_COMM_WORLD); - RankInfo->bubbleglobal_r[RankInfo->bubblerank[r] + i] = temp_r; - } - } - // Define center location for each bubble int ri = 0, rj = 0; @@ -267,6 +238,7 @@ int main(int argc, char **args) // Share the location of each bubble with all ranks + RankInfo->bubbleglobal_R = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); RankInfo->bubbleglobal_x = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); RankInfo->bubbleglobal_y = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); RankInfo->bubbleglobal_z = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); @@ -274,11 +246,9 @@ int main(int argc, char **args) for (int r = 0; r < RankInfo->size; r++) { int temp = RankInfo->nBubbles_local; - MPI_Barrier(MPI_COMM_WORLD); MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); - MPI_Barrier(MPI_COMM_WORLD); - APECSS_FLOAT temp_array[3]; + APECSS_FLOAT temp_array[4]; for (int i = 0; i < temp; i++) { @@ -287,23 +257,19 @@ int main(int argc, char **args) temp_array[0] = Bubbles[i]->Interaction->location[0]; temp_array[1] = Bubbles[i]->Interaction->location[1]; temp_array[2] = Bubbles[i]->Interaction->location[2]; + temp_array[3] = Bubbles[i]->R; } - MPI_Barrier(MPI_COMM_WORLD); - MPI_Bcast(temp_array, 3, MPI_DOUBLE, r, MPI_COMM_WORLD); - MPI_Barrier(MPI_COMM_WORLD); + MPI_Bcast(temp_array, 4, MPI_DOUBLE, r, MPI_COMM_WORLD); RankInfo->bubbleglobal_x[RankInfo->bubblerank[r] + i] = temp_array[0]; RankInfo->bubbleglobal_y[RankInfo->bubblerank[r] + i] = temp_array[1]; RankInfo->bubbleglobal_z[RankInfo->bubblerank[r] + i] = temp_array[2]; + RankInfo->bubbleglobal_R[RankInfo->bubblerank[r] + i] = temp_array[3]; } } - // Update emissions cut off distance for each bubble - parallel_proper_cut_off_distance(Bubbles, RankInfo); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - // apecss_erroronscreen(-1, "OUT"); clock_t starttimebubble = clock(); APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system @@ -330,42 +296,9 @@ int main(int argc, char **args) APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); tSim += dtSim; - if (RankInfo->rank == 0) printf("%e\n", tSim); - - // for (register int i = 0; i < RankInfo->nBubbles_local; i++) - // printf("Bubble %d dp_neighbor %e R %e\n", RankInfo->bubblerank[RankInfo->rank] + i, Bubbles[i]->Interaction->dp_neighbor, Bubbles[i]->R); - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) new_apecss_bubble_solver_run(tSim, Bubbles[i], RankInfo->bubblerank[RankInfo->rank] + i); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); - // for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; - - // for (register int i = 0; i < RankInfo->nBubbles_local; i++) - // printf("Bubble %d counts %d nodes with R=%e\n", RankInfo->bubblerank[RankInfo->rank] + i, Bubbles[i]->Emissions->nNodes, Bubbles[i]->R); - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Share instantaneous radii - for (int r = 0; r < RankInfo->size; r++) - { - int temp = RankInfo->nBubbles_local; - MPI_Barrier(MPI_COMM_WORLD); - MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); - MPI_Barrier(MPI_COMM_WORLD); - - APECSS_FLOAT temp_r; - - for (int i = 0; i < temp; i++) - { - if (r == RankInfo->rank) temp_r = Bubbles[i]->R; - MPI_Barrier(MPI_COMM_WORLD); - MPI_Bcast(&temp_r, 1, MPI_DOUBLE, r, MPI_COMM_WORLD); - MPI_Barrier(MPI_COMM_WORLD); - RankInfo->bubbleglobal_r[RankInfo->bubblerank[r] + i] = temp_r; - } - } - - // if (RankInfo->rank == 0) - // for (register int i = 0; i < RankInfo->nBubbles_global; i++) printf("%d %e\n", i, RankInfo->bubbleglobal_r[i]); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // Update the contribution of the neighbor bubble @@ -379,8 +312,8 @@ int main(int argc, char **args) char str[APECSS_STRINGLENGTH_SPRINTF]; for (register int i = 0; i < RankInfo->nBubbles_local; i++) { - sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", i, Bubbles[i]->dtNumber, Bubbles[i]->nSubIter, - (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); + sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", RankInfo->bubblerank[RankInfo->rank] + i, Bubbles[i]->dtNumber, + Bubbles[i]->nSubIter, (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); apecss_writeonscreen(str); } @@ -397,6 +330,16 @@ int main(int argc, char **args) free(NumericsODE); free(Excitation); + free(RankInfo->bubblerank); + RankInfo->bubblerank = NULL; + free(RankInfo->bubbleglobal_R); + RankInfo->bubbleglobal_R = NULL; + free(RankInfo->bubbleglobal_x); + RankInfo->bubbleglobal_x = NULL; + free(RankInfo->bubbleglobal_y); + RankInfo->bubbleglobal_y = NULL; + free(RankInfo->bubbleglobal_z); + RankInfo->bubbleglobal_z = NULL; free(RankInfo->sumGU_rank); RankInfo->sumGU_rank = NULL; free(RankInfo); @@ -411,191 +354,94 @@ APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, stru return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * t) + Bubble->Interaction->dp_neighbor); } -APECSS_FLOAT parallel_proper_cut_off_distance(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo) -{ - // Determine a proper cut off distance for the emissions - // For each bubble, we determine its most distant neighbor - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - APECSS_FLOAT x_i = Bubbles[i]->Interaction->location[0]; - APECSS_FLOAT y_i = Bubbles[i]->Interaction->location[1]; - APECSS_FLOAT z_i = Bubbles[i]->Interaction->location[2]; - APECSS_FLOAT dist = 0.0; - - for (register int j = 0; j < RankInfo->nBubbles_global; j++) - { - APECSS_FLOAT x_j = RankInfo->bubbleglobal_x[j]; - APECSS_FLOAT y_j = RankInfo->bubbleglobal_y[j]; - APECSS_FLOAT z_j = RankInfo->bubbleglobal_z[j]; - - APECSS_FLOAT dist_ij = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); - - if (dist_ij > dist) dist = dist_ij; - } - - if (Bubbles[i]->Emissions != NULL) Bubbles[i]->Emissions->CutOffDistance = 1.05 * dist; - } - - return (0); -} - int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo) { // All bubbles are supposed to be in the same liquid struct APECSS_Liquid *Liquid = Bubbles[0]->Liquid; + // Update bubble radii info + APECSS_FLOAT *tempR = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + for (register int j = 0; j < RankInfo->nBubbles_global; j++) tempR[j] = 0.0; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) tempR[RankInfo->bubblerank[RankInfo->rank] + i] = Bubbles[i]->R; + MPI_Allreduce(tempR, RankInfo->bubbleglobal_R, RankInfo->nBubbles_global, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + free(tempR); + // Reset pressure contributions of the neighours - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0; // Locally compute the contribution to each bubble - for (register int i = 0; i < RankInfo->nBubbles_global; i++) + for (register int j = 0; j < RankInfo->nBubbles_global; j++) { - APECSS_FLOAT x_i = RankInfo->bubbleglobal_x[i]; - APECSS_FLOAT y_i = RankInfo->bubbleglobal_y[i]; - APECSS_FLOAT z_i = RankInfo->bubbleglobal_z[i]; + APECSS_FLOAT x_j = RankInfo->bubbleglobal_x[j]; + APECSS_FLOAT y_j = RankInfo->bubbleglobal_y[j]; + APECSS_FLOAT z_j = RankInfo->bubbleglobal_z[j]; + + RankInfo->sumGU_rank[j] = 0.0; + RankInfo->sumGU_rank[j + RankInfo->nBubbles_global] = 0.0; - RankInfo->sumGU_rank[i] = 0.0; - RankInfo->sumGU_rank[i + RankInfo->nBubbles_global] = 0.0; + double R_j = RankInfo->bubbleglobal_R[j]; - for (register int j = 0; j < RankInfo->nBubbles_local; j++) + for (register int i = 0; i < RankInfo->nBubbles_local; i++) { - int bubble_id = RankInfo->bubblerank[RankInfo->rank] + j; - if (bubble_id != i) + if (j != RankInfo->bubblerank[RankInfo->rank] + i) { APECSS_FLOAT sumU_bubble = 0.0; APECSS_FLOAT sumG_bubble = 0.0; int nodecount_bubble = 0; - APECSS_FLOAT x_j = Bubbles[j]->Interaction->location[0]; - APECSS_FLOAT y_j = Bubbles[j]->Interaction->location[1]; - APECSS_FLOAT z_j = Bubbles[j]->Interaction->location[2]; + APECSS_FLOAT x_i = Bubbles[i]->Interaction->location[0]; + APECSS_FLOAT y_i = Bubbles[i]->Interaction->location[1]; + APECSS_FLOAT z_i = Bubbles[i]->Interaction->location[2]; APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); - double r_b = RankInfo->bubbleglobal_r[i]; - // The loop over the emission nodes begins with the most far away from the emitting bubble - struct APECSS_EmissionNode *Current = Bubbles[j]->Emissions->LastNode; + struct APECSS_EmissionNode *Current = Bubbles[i]->Emissions->LastNode; while (Current != NULL) { - if (Current->r < interbubble_dist - r_b) + if (Current->r < interbubble_dist - R_j) + { // The following emission nodes have not yet reached the bubble of interest Current = NULL; - else if (Current->r > interbubble_dist + r_b) + } + else if (Current->r > interbubble_dist + R_j) + { // The bubble of interest is still not reached Current = Current->backward; + } else { // The current emission node is located inside the bubble of interest APECSS_FLOAT gr = Current->g / Current->r; - sumU_bubble += (Current->f / APECSS_POW2(Current->r)) + (gr) / Liquid->cref; + sumU_bubble += (Current->f / APECSS_POW2(Current->r)) + gr / Liquid->cref; sumG_bubble += gr; nodecount_bubble++; Current = Current->backward; } } - if (nodecount_bubble != 0) + if (nodecount_bubble) { APECSS_FLOAT inv_nodecount = 1.0 / (APECSS_FLOAT) nodecount_bubble; - RankInfo->sumGU_rank[i] += sumG_bubble * inv_nodecount; - RankInfo->sumGU_rank[i + RankInfo->nBubbles_global] += sumU_bubble * inv_nodecount; + RankInfo->sumGU_rank[j] += sumG_bubble * inv_nodecount; + RankInfo->sumGU_rank[j + RankInfo->nBubbles_global] += sumU_bubble * inv_nodecount; } } } } - APECSS_FLOAT *sumGU_all = malloc(2 * RankInfo->nBubbles_local * sizeof(APECSS_FLOAT)); - for (register int i = 0; i < 2 * RankInfo->nBubbles_local; i++) sumGU_all[i] = 0.0; - - // Share the contributions from each rank to all bubbles - for (int r = 0; r < RankInfo->size; r++) - { - APECSS_FLOAT *temp = RankInfo->sumGU_rank; - MPI_Barrier(MPI_COMM_WORLD); - MPI_Bcast(temp, 2 * RankInfo->nBubbles_global, MPI_DOUBLE, r, MPI_COMM_WORLD); - MPI_Barrier(MPI_COMM_WORLD); - for (register int i = 0; i < RankInfo->nBubbles_local; i++) sumGU_all[i] += temp[RankInfo->bubblerank[RankInfo->rank] + i]; - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - sumGU_all[i + RankInfo->nBubbles_local] += temp[RankInfo->nBubbles_global + RankInfo->bubblerank[RankInfo->rank] + i]; - } + APECSS_FLOAT *sumGU_all = malloc(2 * RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + MPI_Allreduce(RankInfo->sumGU_rank, sumGU_all, 2 * RankInfo->nBubbles_global, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); // Compute the total pressure contributions of the neighbours for all local bubbles for (register int i = 0; i < RankInfo->nBubbles_local; i++) { - Bubbles[i]->Interaction->dp_neighbor = Liquid->rhoref * (sumGU_all[i] - 0.5 * APECSS_POW2(sumGU_all[RankInfo->nBubbles_local + i])); - // printf("%d %e\n", RankInfo->bubblerank[RankInfo->rank] + i, Bubbles[i]->Interaction->dp_neighbor); + Bubbles[i]->Interaction->dp_neighbor = + Liquid->rhoref * (sumGU_all[RankInfo->bubblerank[RankInfo->rank] + i] - + 0.5 * APECSS_POW2(sumGU_all[RankInfo->nBubbles_global + RankInfo->bubblerank[RankInfo->rank] + i])); } free(sumGU_all); - return (0); -} - -int new_apecss_bubble_solver_run(APECSS_FLOAT tend, struct APECSS_Bubble *Bubble, int bubble_id) -{ - while (Bubble->t < tend - 0.01 * Bubble->NumericsODE->dtMin) - { - // Store the previous solution for sub-iterations - for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSolOld[i] = Bubble->ODEsSol[i]; - - if (bubble_id == 1) printf("t=%e R=%e U=%e p_infty=%e\n", Bubble->t, Bubble->R, Bubble->U, Bubble->get_pressure_infinity(Bubble->t, Bubble)); - - if (isnan(Bubble->R)) - { - printf("Pause because of bubble %d at t=%e", bubble_id, Bubble->t); - pause(); - } - - // Check what comes next: the end of the solver run or, if applicable, a time instance to output the emissions - APECSS_FLOAT next_event_time = Bubble->results_emissionstime_check(tend, Bubble); - - // Set the time-step for the ODEs - apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); - - // Solve the ODEs - Bubble->err = apecss_odesolver(Bubble); - - // Perform sub-iterations on the control of the time-step when err > tol - register int subiter = 0; - while ((Bubble->err > Bubble->NumericsODE->tol) && (subiter < Bubble->NumericsODE->maxSubIter)) - { - ++subiter; - // Rewind the solution - for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSol[i] = Bubble->ODEsSolOld[i]; - // Set the time-step for the ODEs - apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); - // Solve the ODEs again - Bubble->err = apecss_odesolver(Bubble); - } - Bubble->nSubIter += subiter; - - // Set new values - ++(Bubble->dtNumber); - Bubble->t += Bubble->dt; - Bubble->U = Bubble->ODEsSol[0]; - Bubble->R = Bubble->ODEsSol[1]; - - // Update allocation of the results (if necessary) - Bubble->results_emissionsnodeminmax_identify(Bubble); - Bubble->results_emissionsnode_alloc(Bubble); - - // Acoustic emissions (if applicable) - Bubble->emissions_update(Bubble); - - // Store results (if applicable) - Bubble->results_rayleighplesset_store(Bubble); - Bubble->results_emissionsspace_store(Bubble); - - // Write one-off results (if applicable) - Bubble->results_emissionstime_write(Bubble); - - // Update the last-step solution of the RK54 scheme - for (register int i = 0; i < Bubble->nODEs; i++) Bubble->kLast[i] = Bubble->k7[i]; - - // Update progress screen in the terminal (if applicable) - Bubble->progress_update(&(*Bubble).progress, Bubble->t - Bubble->tStart, Bubble->tEnd - Bubble->tStart); - } - return (0); } \ No newline at end of file From e31691f6281ff24e32d57e761a755ef11349bfa7 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Wed, 10 Jul 2024 16:44:25 -0400 Subject: [PATCH 020/138] Update in IC interactions computations ; adding a function to compute cut off distance of emissions if needed ; new variables for computing pressurederivative_infinity --- include/apecss.h | 7 +++-- src/interactions.c | 72 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 66 insertions(+), 13 deletions(-) diff --git a/include/apecss.h b/include/apecss.h index c693b04..f4c55ec 100644 --- a/include/apecss.h +++ b/include/apecss.h @@ -316,8 +316,10 @@ struct APECSS_Interaction int nBubbles; // Number of bubbles in the whole cluster considered APECSS_FLOAT location[3]; // 3D coordinates of the considered bubble APECSS_FLOAT dp_neighbor; // Pressure induced by interactions with neighboring bubbles - APECSS_FLOAT last_t; // Previous timestep when interaction where considered - APECSS_FLOAT last_pinfinity; // Pressure in the liquid at the bubble wall during the previous timestep where interactions where considered + APECSS_FLOAT last_t_1; // Previous timestep when interaction where considered + APECSS_FLOAT last_t_2; // Previous timestep when interaction where considered before last_t_1 + APECSS_FLOAT last_p_1; // Pressure induced by neighboring bubbles or total pressure in the far field at last_t_1 + APECSS_FLOAT last_p_2; // Pressure induced by neighboring bubbles or total pressure in the far field at last_t_2 }; struct APECSS_ResultsBubble @@ -595,6 +597,7 @@ APECSS_FLOAT apecss_interface_pressurederivative_viscous_marmottantimpl(APECSS_F int apecss_interactions_instantaneous(struct APECSS_Bubble *Bubbles[]); int apecss_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[]); +int apecss_interactions_cutoffdistance(struct APECSS_Bubble *Bubbles[]); // --------------------- // liquid.c diff --git a/src/interactions.c b/src/interactions.c index ed8a78e..6f691c7 100644 --- a/src/interactions.c +++ b/src/interactions.c @@ -29,12 +29,18 @@ int apecss_interactions_instantaneous(struct APECSS_Bubble *Bubbles[]) struct APECSS_Liquid *Liquid = Bubbles[0]->Liquid; // Preliminary step to gather bubble wall acceleration values - APECSS_FLOAT Bubbles_A[nBubbles]; - for (register int i = 0; i < nBubbles; i++) - { - APECSS_FLOAT acceleration = Bubbles[i]->ode[0](Bubbles[i]->ODEsSol, Bubbles[i]->t, Bubbles[i]); - Bubbles_A[i] = acceleration; - } + // APECSS_FLOAT Bubbles_A[nBubbles]; + // for (register int i = 0; i < nBubbles; i++) + // { + // APECSS_FLOAT acceleration = Bubbles[i]->ode[0](Bubbles[i]->ODEsSol, Bubbles[i]->t, Bubbles[i]); + // Bubbles_A[i] = acceleration; + // } + + // // Reset pressure contributions of the neighbours + // for (register int i = 0; i < nBubbles; i++) + // { + // Bubbles[i]->Interaction->dp_neighbor = 0.0; + // } for (register int i = 0; i < nBubbles; i++) { @@ -42,6 +48,8 @@ int apecss_interactions_instantaneous(struct APECSS_Bubble *Bubbles[]) APECSS_FLOAT y_i = Bubbles[i]->Interaction->location[1]; APECSS_FLOAT z_i = Bubbles[i]->Interaction->location[2]; + Bubbles[i]->Interaction->dp_neighbor = 0.0; + for (register int j = 0; j < nBubbles; j++) { if (j != i) @@ -60,9 +68,18 @@ int apecss_interactions_instantaneous(struct APECSS_Bubble *Bubbles[]) // (1 / interbubble_dist) - // (APECSS_POW4(Bubbles[j]->R) * APECSS_POW2(Bubbles[j]->U)) * (1 / (2 * APECSS_POW4(interbubble_dist)))); - APECSS_FLOAT dp = - Liquid->rhoref * ((2.0 * Bubbles[j]->R * APECSS_POW2(Bubbles[j]->U) + APECSS_POW2(Bubbles[j]->R) * Bubbles_A[j]) * (1 / interbubble_dist) - - (APECSS_POW4(Bubbles[j]->R) * APECSS_POW2(Bubbles[j]->U)) * (1 / (2 * APECSS_POW4(interbubble_dist)))); + // APECSS_FLOAT dp = + // Liquid->rhoref * (((2.0 * Bubbles[j]->R * APECSS_POW2(Bubbles[j]->U) + APECSS_POW2(Bubbles[j]->R) * Bubbles_A[j]) * (1 / interbubble_dist)) - + // ((APECSS_POW4(Bubbles[j]->R) * APECSS_POW2(Bubbles[j]->U)) * (1 / (2 * APECSS_POW4(interbubble_dist))))); + + APECSS_FLOAT dp = Liquid->rhoref * 2.0 * Bubbles[j]->R * APECSS_POW2(Bubbles[j]->U) * (1 / interbubble_dist); + dp += Liquid->rhoref * APECSS_POW2(Bubbles[j]->R) * Bubbles[j]->ode[0](Bubbles[j]->ODEsSol, Bubbles[j]->t, Bubbles[j]) * (1 / interbubble_dist); + dp += Liquid->rhoref * APECSS_POW4(Bubbles[j]->R) * APECSS_POW2(Bubbles[j]->U) * (1 / (2 * APECSS_POW4(interbubble_dist))); + + // if ((i == 0) && (j == 1)) + // printf(" %e %e %e", 2.0 * Bubbles[j]->R * APECSS_POW2(Bubbles[j]->U) * (1 / interbubble_dist), + // APECSS_POW2(Bubbles[j]->R) * Bubbles_A[j] * (1 / interbubble_dist), + // (APECSS_POW4(Bubbles[j]->R) * APECSS_POW2(Bubbles[j]->U)) * (1 / (2 * APECSS_POW4(interbubble_dist)))); Bubbles[i]->Interaction->dp_neighbor += dp; // printf(" %e %e\n", Bubbles[i]->ode[0](Bubbles[i]->ODEsSol, Bubbles[i]->t, Bubbles[i]), @@ -83,6 +100,12 @@ int apecss_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[]) // All bubbles are supposed to be in the same liquid struct APECSS_Liquid *Liquid = Bubbles[0]->Liquid; + // Reset pressure contributions of the neighbours + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Interaction->dp_neighbor = 0.0; + } + for (register int i = 0; i < nBubbles; i++) { APECSS_FLOAT sumU = 0.0; @@ -105,9 +128,8 @@ int apecss_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[]) APECSS_FLOAT z_j = Bubbles[j]->Interaction->location[2]; APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); - // printf("Bubble %d vs Bubble %d, %e", i, j, interbubble_dist); - double r_b = Bubbles[i]->R; + APECSS_FLOAT r_b = Bubbles[i]->R; // The loop over the emission nodes begins with the most far away from the emitting bubble struct APECSS_EmissionNode *Current = Bubbles[j]->Emissions->LastNode; @@ -145,5 +167,33 @@ int apecss_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[]) // printf(" %e\n", Bubbles[i]->Interaction->dp_neighbor); } + return (0); +} + +int apecss_interactions_cutoffdistance(struct APECSS_Bubble *Bubbles[]) +{ + // Compute the proper cut off distance for each bubbles in a cluster depending on the location of their neighbors + int nBubbles = Bubbles[0]->Interaction->nBubbles; + + for (register int i = 0; i < nBubbles; i++) + { + APECSS_FLOAT x_i = Bubbles[i]->Interaction->location[0]; + APECSS_FLOAT y_i = Bubbles[i]->Interaction->location[1]; + APECSS_FLOAT z_i = Bubbles[i]->Interaction->location[2]; + APECSS_FLOAT dist = 0.0; + + for (register int j = 0; j < nBubbles; j++) + { + APECSS_FLOAT x_j = Bubbles[j]->Interaction->location[0]; + APECSS_FLOAT y_j = Bubbles[j]->Interaction->location[1]; + APECSS_FLOAT z_j = Bubbles[j]->Interaction->location[2]; + + APECSS_FLOAT dist_ij = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); + + if (dist_ij > dist) dist = dist_ij; + } + if (Bubbles[i]->Emissions != NULL) Bubbles[i]->Emissions->CutOffDistance = 1.05 * dist; + } + return (0); } \ No newline at end of file From e69e0bfaf30e0b3c6eba046c65cc3fe48290abb2 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Wed, 10 Jul 2024 16:46:42 -0400 Subject: [PATCH 021/138] Cavitation onset test case ; beginning to properly define the working folders ; no interactions test cases with results gathered --- .../cavitationonset/NI/build/CMakeLists.txt | 41 ++ examples/cavitationonset/NI/build/compile.sh | 5 + examples/cavitationonset/NI/gather_results.py | 29 ++ examples/cavitationonset/NI/run.apecss | 36 ++ .../NI/src/cavitationonset_apecss.c | 468 ++++++++++++++++++ .../cavitationonset/QA/build/CMakeLists.txt | 41 ++ examples/cavitationonset/QA/build/compile.sh | 5 + examples/cavitationonset/QA/run.apecss | 36 ++ .../QA/src/cavitationonset_apecss.c | 468 ++++++++++++++++++ .../cavitationonset/run_cavitationonset.sh | 109 +++- 10 files changed, 1230 insertions(+), 8 deletions(-) create mode 100644 examples/cavitationonset/NI/build/CMakeLists.txt create mode 100755 examples/cavitationonset/NI/build/compile.sh create mode 100644 examples/cavitationonset/NI/gather_results.py create mode 100644 examples/cavitationonset/NI/run.apecss create mode 100644 examples/cavitationonset/NI/src/cavitationonset_apecss.c create mode 100644 examples/cavitationonset/QA/build/CMakeLists.txt create mode 100755 examples/cavitationonset/QA/build/compile.sh create mode 100644 examples/cavitationonset/QA/run.apecss create mode 100644 examples/cavitationonset/QA/src/cavitationonset_apecss.c diff --git a/examples/cavitationonset/NI/build/CMakeLists.txt b/examples/cavitationonset/NI/build/CMakeLists.txt new file mode 100644 index 0000000..8e43b7f --- /dev/null +++ b/examples/cavitationonset/NI/build/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.12) + +project (cavitationonset_apecss) +set(CMAKE_C_COMPILER /usr/bin/gcc) + +include_directories($ENV{APECSS_DIR}/include) +FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) + +set (mylibs m apecss) +link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) + +foreach(arg ${myincludes}) + IF (arg MATCHES "-I") + STRING(REGEX REPLACE "-I" "" myinc ${arg}) + message("Additional include: ${myinc}") + include_directories(${myinc}) + ENDIF(arg MATCHES "-I") +endforeach(arg ${myincludes}) + +foreach(arg ${mylibs}) + STRING(REGEX REPLACE "lib" "" myl1 ${arg}) + STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) + set(mylibs ${myl2} ${mylibs} ${myl2}) +endforeach(arg ${mylibs}) + +if(NOT CMAKE_BUILD_TYPE) + message(STATUS "Optimization: No optimization specified.") + set(CMAKE_BUILD_TYPE Release) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + message(STATUS "Optimization: Debug") + set(CMAKE_C_FLAGS_DEBUG "-Wall -g") +elseif(CMAKE_BUILD_TYPE STREQUAL "Release") + message(STATUS "Optimization: Release") + add_definitions(-DNDEBUG) + set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") +endif() + +add_executable(cavitationonset_apecss ${myfiles}) +target_link_libraries(cavitationonset_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/cavitationonset/NI/build/compile.sh b/examples/cavitationonset/NI/build/compile.sh new file mode 100755 index 0000000..02b82c5 --- /dev/null +++ b/examples/cavitationonset/NI/build/compile.sh @@ -0,0 +1,5 @@ +#!/bin/bash +rm cavitationonset_apecss +cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release +make +rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/cavitationonset/NI/gather_results.py b/examples/cavitationonset/NI/gather_results.py new file mode 100644 index 0000000..d0c6538 --- /dev/null +++ b/examples/cavitationonset/NI/gather_results.py @@ -0,0 +1,29 @@ +import os + +# File designed to recover data for plotting results in cavitation onset case + +file = open("Ida2009_results.txt", "r") +lines = file.readlines() +file.close() + +count = float(lines[0].split(" ")[0]) +png = float(lines[0].split(" ")[5]) +cl_size = int(lines[0].split(" ")[7]) +cl_distrib = int(lines[0].split(" ")[9]) + +if cl_distrib == 0 : + # Two bubbles of different size + file_name = "{}_{:.4E}_{}.txt".format(count, png, cl_size) + +else : + # Monodispersed system + file_name = "{}_{:.4E}.txt".format(count, png) + +working_path = os.getcwd() +results_path = os.path.join(working_path, "results") +file_results = open(os.path.join(results_path, file_name), "w") + +for line in lines : + file_results.write(line) + +file_results.close() \ No newline at end of file diff --git a/examples/cavitationonset/NI/run.apecss b/examples/cavitationonset/NI/run.apecss new file mode 100644 index 0000000..66cab93 --- /dev/null +++ b/examples/cavitationonset/NI/run.apecss @@ -0,0 +1,36 @@ +######################################################### +# # +# APECSS Options File # +# # +######################################################### + +BUBBLE +RPModel KM +Emissions IC 900.0e-06 +PressureAmbient 0.1013e6 +END + +GAS +EoS IG +ReferenceDensity 1.2 +PolytropicExponent 1 +END + +LIQUID +ReferencePressure 0.1013e6 +ReferenceDensity 1000.0 +ReferenceSoundSpeed 1500.0 +Viscosity 1.002e-3 +END + +INTERFACE +SurfaceTensionCoeff 0.0728 +END + +RESULTS +Bubble +END + +ODESOLVER +tolerance 1.0e-10 +END diff --git a/examples/cavitationonset/NI/src/cavitationonset_apecss.c b/examples/cavitationonset/NI/src/cavitationonset_apecss.c new file mode 100644 index 0000000..33ccb6b --- /dev/null +++ b/examples/cavitationonset/NI/src/cavitationonset_apecss.c @@ -0,0 +1,468 @@ +// This source file is part of APECSS, an open-source software toolbox +// for the computation of pressure-driven bubble dynamics and acoustic +// emissions in spherical symmetry. +// +// Copyright (C) 2022-2024 The APECSS Developers +// +// The APECSS Developers are listed in the README.md file available in +// the GitHub repository at https://github.com/polycfd/apecss. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// ------------------------------------------------------------------- +// APECSS standalone example of cavitation onset with acoustically-in- +// teracting microbubbles, based on Ida (2009), Physics of Fluids 21 +// (11), 113302, DOI : 10.1063/1.3265547 +// ------------------------------------------------------------------- + +#include +#include "apecss.h" + +// Declaration of additional case-dependent functions +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); + +// Declaration of the structure holding the interaction variables of each bubble +struct Interaction +{ + APECSS_FLOAT dp_neighbor; +}; + +int main(int argc, char **args) +{ + char OptionsDir[APECSS_STRINGLENGTH]; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Interbubble time-step, defining the frequency with which the neighbor influence is updated + APECSS_FLOAT dt_interbubble = 1.0e-8; + + // Initialize the simulation parameters given by the execution command + int nBubbles = 2; + double tEnd = 0.0; + double fa = 0.0; + double pa = 0.0; + int cluster_distrib = 0; + int cluster_size = 0; + int inttype = 0; + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + apecss_infoscreen(); + + /* Read commandline options */ + sprintf(OptionsDir, "./run.apecss"); // This is the default + int j = 1; // First argument is the call to the executable + while (j < argc) + { + if (strcmp("-options", args[j]) == 0) + { + sprintf(OptionsDir, "%s", args[j + 1]); + j += 2; + } + else if (strcmp("-tend", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &tEnd); + j += 2; + } + else if (strcmp("-freq", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &fa); + j += 2; + } + else if (strcmp("-amp", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &pa); + j += 2; + } + else if (strcmp("-nbb", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &nBubbles); + j += 2; + } + else if (strcmp("-cldistrib", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &cluster_distrib); + j += 2; + } + else if (strcmp("-clsize", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &cluster_size); + j += 2; + } + else if (strcmp("-inttype", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &inttype); + j += 2; + } + else if (strcmp("-dt_inter", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &dt_interbubble); + j += 2; + } + else if (strcmp("-h", args[j]) == 0) + { + apecss_helpscreen(); + } + else + { + char str[APECSS_STRINGLENGTH_SPRINTF]; + sprintf(str, "Unknown command line options: %s", args[j]); + apecss_erroronscreen(1, str); + ++j; + } + } + dt_interbubble = (APECSS_FLOAT) dt_interbubble; + + /* Allocate and initialize Bubble structure */ + struct APECSS_Bubble *Bubbles[nBubbles]; + for (register int i = 0; i < nBubbles; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(nBubbles * sizeof(struct APECSS_Bubble)); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initializestruct(Bubbles[i]); + + /* Set default options and read the options for the bubble */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); + + /* Allocate the structures for the fluid properties and ODE solver parameters */ + struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); + struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); + struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); + struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); + + /* Set the default options for the fluid properties and solver parameters */ + apecss_gas_setdefaultoptions(Gas); + apecss_liquid_setdefaultoptions(Liquid); + apecss_interface_setdefaultoptions(Interface); + apecss_odesolver_setdefaultoptions(NumericsODE); + + /* Read the options file for the fluid properties and solver parameters */ + apecss_gas_readoptions(Gas, OptionsDir); + apecss_liquid_readoptions(Liquid, OptionsDir); + apecss_interface_readoptions(Interface, OptionsDir); + apecss_odesolver_readoptions(NumericsODE, OptionsDir); + + /* Associate the bubble with the relevant fluid properties and solver parameters */ + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Gas = Gas; + Bubbles[i]->Liquid = Liquid; + Bubbles[i]->Interface = Interface; + Bubbles[i]->NumericsODE = NumericsODE; + } + + /* Allocate and set the excitation parameters */ + struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); + Excitation->type = APECSS_EXCITATION_SIN; + Excitation->f = (APECSS_FLOAT) fa; + Excitation->dp = (APECSS_FLOAT) pa; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Excitation = Excitation; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Create individual folders for the results of each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (Bubbles[i]->Results != NULL) + { + sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", i); + struct stat st = {0}; + if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Process all options */ + apecss_gas_processoptions(Gas); + apecss_liquid_processoptions(Liquid); + apecss_interface_processoptions(Interface); + apecss_odesolver_processoptions(NumericsODE); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_processoptions(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Use the revised pressure at infinity, including neighbor contributions + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressure_infinity = interaction_bubble_pressure_infinity; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressurederivative_infinity = interaction_bubble_pressurederivative_infinity; + + // Initialize interaction structure + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); + + // Update interaction structure + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Interaction->nBubbles = nBubbles; + Bubbles[i]->Interaction->dp_neighbor = 0.0; + Bubbles[i]->Interaction->last_t_1 = 0.0; + Bubbles[i]->Interaction->last_t_2 = 0.0; + Bubbles[i]->Interaction->last_p_1 = 0.0; + Bubbles[i]->Interaction->last_p_2 = 0.0; + } + + // Define the size of each bubble + if (cluster_distrib == 0) + { + // Two bubbles of different initial size interacting + Bubbles[0]->R0 = 2.0e-06; + Bubbles[1]->R0 = 20.0e-06; + } + else + { + // Monodispersed multibubble distributions + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->R0 = 20.0e-06; + } + } + + // Define center location for each bubble + if (cluster_distrib == 0) + { + // Two bubbles of different initial size interacting + Bubbles[0]->Interaction->location[0] = 0.0; + Bubbles[0]->Interaction->location[1] = 0.0; + Bubbles[0]->Interaction->location[2] = 0.0; + + Bubbles[1]->Interaction->location[0] = (APECSS_FLOAT) cluster_size * (Bubbles[0]->R0 + Bubbles[1]->R0); + Bubbles[1]->Interaction->location[1] = 0.0; + Bubbles[1]->Interaction->location[2] = 0.0; + } + else + { + // Monodispersed multibubble distributions + APECSS_FLOAT D = 400.0e-06; + if (nBubbles == 1) + { + // Single bubble + Bubbles[0]->Interaction->location[0] = 0.0; + Bubbles[0]->Interaction->location[1] = 0.0; + Bubbles[0]->Interaction->location[2] = 0.0; + } + else if (nBubbles == 2) + { + // Two bubbles + Bubbles[0]->Interaction->location[0] = 0.0; + Bubbles[0]->Interaction->location[1] = 0.0; + Bubbles[0]->Interaction->location[2] = 0.0; + + Bubbles[1]->Interaction->location[0] = D; + Bubbles[1]->Interaction->location[1] = 0.0; + Bubbles[1]->Interaction->location[2] = 0.0; + } + else if (nBubbles == 3) + { + // Regular triangle + Bubbles[0]->Interaction->location[0] = 0.0; + Bubbles[0]->Interaction->location[1] = 0.0; + Bubbles[0]->Interaction->location[2] = 0.0; + + Bubbles[1]->Interaction->location[0] = D; + Bubbles[1]->Interaction->location[1] = 0.0; + Bubbles[1]->Interaction->location[2] = 0.0; + + Bubbles[2]->Interaction->location[0] = 0.5 * D; + Bubbles[2]->Interaction->location[1] = D * APECSS_SIN(APECSS_ONETHIRD * APECSS_PI); + Bubbles[2]->Interaction->location[2] = 0.0; + } + else if (nBubbles == 4) + { + // Regular tetragon + Bubbles[0]->Interaction->location[0] = 0.0; + Bubbles[0]->Interaction->location[1] = 0.0; + Bubbles[0]->Interaction->location[2] = 0.0; + + Bubbles[1]->Interaction->location[0] = D; + Bubbles[1]->Interaction->location[1] = 0.0; + Bubbles[1]->Interaction->location[2] = 0.0; + + Bubbles[2]->Interaction->location[0] = 0.0; + Bubbles[2]->Interaction->location[1] = D; + Bubbles[2]->Interaction->location[2] = 0.0; + + Bubbles[3]->Interaction->location[0] = D; + Bubbles[3]->Interaction->location[1] = D; + Bubbles[3]->Interaction->location[2] = 0.0; + } + else if (nBubbles == 8) + { + // Regular hexaedron + Bubbles[0]->Interaction->location[0] = 0.0; + Bubbles[0]->Interaction->location[1] = 0.0; + Bubbles[0]->Interaction->location[2] = 0.0; + + Bubbles[1]->Interaction->location[0] = D; + Bubbles[1]->Interaction->location[1] = 0.0; + Bubbles[1]->Interaction->location[2] = 0.0; + + Bubbles[2]->Interaction->location[0] = 0.0; + Bubbles[2]->Interaction->location[1] = D; + Bubbles[2]->Interaction->location[2] = 0.0; + + Bubbles[3]->Interaction->location[0] = D; + Bubbles[3]->Interaction->location[1] = D; + Bubbles[3]->Interaction->location[2] = 0.0; + + Bubbles[4]->Interaction->location[0] = 0.0; + Bubbles[4]->Interaction->location[1] = 0.0; + Bubbles[4]->Interaction->location[2] = D; + + Bubbles[5]->Interaction->location[0] = D; + Bubbles[5]->Interaction->location[1] = 0.0; + Bubbles[5]->Interaction->location[2] = D; + + Bubbles[6]->Interaction->location[0] = 0.0; + Bubbles[6]->Interaction->location[1] = D; + Bubbles[6]->Interaction->location[2] = D; + + Bubbles[7]->Interaction->location[0] = D; + Bubbles[7]->Interaction->location[1] = D; + Bubbles[7]->Interaction->location[2] = D; + } + else + { + char str[APECSS_STRINGLENGTH_SPRINTF]; + sprintf(str, "Wrong number of bubbles as input for this specific cluster distribution (1, 2, 3, 4 or 8)"); + apecss_erroronscreen(1, str); + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + clock_t starttimebubble = clock(); + APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system + + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->tStart = tSim; + Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; + Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step + } + + /* Initialize the bubble based on the selected options */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initialize(Bubbles[i]); + + /* Initialize */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_initialize(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // File to retrieve all valuable information for cavitation onset test case + FILE *file_ida2009; + file_ida2009 = fopen("Ida2009_results.txt", "w"); + fprintf(file_ida2009, "%d Bubbles p0(pa) %e png(Pa) %e D_multiplier(-) %d cl_distrib %d Interaction-type %d\n", nBubbles, Liquid->pref, pa, cluster_size, + cluster_distrib, inttype); + fprintf(file_ida2009, "Initial_radii(m)"); + for (register int i = 0; i < nBubbles; i++) fprintf(file_ida2009, " %e", Bubbles[i]->R0); + fprintf(file_ida2009, "\n"); + fprintf(file_ida2009, "#Time(s) R(m) Pt(Pa)\n"); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Solve the bubble dynamics */ + while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered + { + APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); + tSim += dtSim; + + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Update the contribution of the neighbor bubbles + if (inttype == 1) + { + apecss_interactions_instantaneous(Bubbles); + } + else if (inttype == 2) + { + apecss_interactions_quasi_acoustic(Bubbles); + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Retrieve data + fprintf(file_ida2009, "%e", tSim); + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_ida2009, " %e", Bubbles[i]->R); + } + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_ida2009, " %e", Bubbles[i]->get_pressure_infinity(tSim, Bubbles[i])); + } + fprintf(file_ida2009, "\n"); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; + Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; + + Bubbles[i]->Interaction->last_t_1 = tSim; + Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; + } + } + + fclose(file_ida2009); + + /* Finalize the simulation*/ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_finalize(Bubbles[i]); + + char str[APECSS_STRINGLENGTH_SPRINTF]; + for (register int i = 0; i < nBubbles; i++) + { + sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", i, Bubbles[i]->dtNumber, Bubbles[i]->nSubIter, + (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); + apecss_writeonscreen(str); + } + + for (register int i = 0; i < nBubbles; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); + for (register int i = 0; i < nBubbles; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); + + /* Make sure all allocated memory is freed */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_freestruct(Bubbles[i]); + + for (register int i = 0; i < nBubbles; i++) free(Bubbles[i]); + free(Gas); + free(Liquid); + free(Interface); + free(NumericsODE); + free(Excitation); + + return (0); +} + +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + APECSS_FLOAT T = 10.0e-06; + if (t < T) + { + return (Bubble->p0 + Bubble->Interaction->dp_neighbor); + } + else if (t > 2 * T) + { + return (Bubble->Excitation->dp + Bubble->Interaction->dp_neighbor); + } + else + { + APECSS_FLOAT W = 0.5 * (1 - APECSS_COS((t + T) * APECSS_PI / T)); + return (Bubble->p0 + W * (Bubble->Excitation->dp - Bubble->p0) + Bubble->Interaction->dp_neighbor); + } +} + +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + // Approximate numerical computation of p_infinity derivative + APECSS_FLOAT T = 10.0e-06; + APECSS_FLOAT derivative = 0.0; + if ((t >= T) && (t <= 2 * T)) + { + APECSS_FLOAT inv_T = 1 / T; + derivative = 0.5 * APECSS_PI * inv_T * APECSS_SIN(APECSS_PI * (t + T) * inv_T) * (Bubble->Excitation->dp - Bubble->p0); + } + return (derivative); + + // APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; + // if (delta_t > Bubble->dt) + // { + // APECSS_FLOAT inv_delta_t = 1 / delta_t; + // return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) * inv_delta_t)); + // } + // else + // { + // return (derivative); + // } +} \ No newline at end of file diff --git a/examples/cavitationonset/QA/build/CMakeLists.txt b/examples/cavitationonset/QA/build/CMakeLists.txt new file mode 100644 index 0000000..8e43b7f --- /dev/null +++ b/examples/cavitationonset/QA/build/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.12) + +project (cavitationonset_apecss) +set(CMAKE_C_COMPILER /usr/bin/gcc) + +include_directories($ENV{APECSS_DIR}/include) +FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) + +set (mylibs m apecss) +link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) + +foreach(arg ${myincludes}) + IF (arg MATCHES "-I") + STRING(REGEX REPLACE "-I" "" myinc ${arg}) + message("Additional include: ${myinc}") + include_directories(${myinc}) + ENDIF(arg MATCHES "-I") +endforeach(arg ${myincludes}) + +foreach(arg ${mylibs}) + STRING(REGEX REPLACE "lib" "" myl1 ${arg}) + STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) + set(mylibs ${myl2} ${mylibs} ${myl2}) +endforeach(arg ${mylibs}) + +if(NOT CMAKE_BUILD_TYPE) + message(STATUS "Optimization: No optimization specified.") + set(CMAKE_BUILD_TYPE Release) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + message(STATUS "Optimization: Debug") + set(CMAKE_C_FLAGS_DEBUG "-Wall -g") +elseif(CMAKE_BUILD_TYPE STREQUAL "Release") + message(STATUS "Optimization: Release") + add_definitions(-DNDEBUG) + set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") +endif() + +add_executable(cavitationonset_apecss ${myfiles}) +target_link_libraries(cavitationonset_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/cavitationonset/QA/build/compile.sh b/examples/cavitationonset/QA/build/compile.sh new file mode 100755 index 0000000..02b82c5 --- /dev/null +++ b/examples/cavitationonset/QA/build/compile.sh @@ -0,0 +1,5 @@ +#!/bin/bash +rm cavitationonset_apecss +cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release +make +rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/cavitationonset/QA/run.apecss b/examples/cavitationonset/QA/run.apecss new file mode 100644 index 0000000..2e45cda --- /dev/null +++ b/examples/cavitationonset/QA/run.apecss @@ -0,0 +1,36 @@ +######################################################### +# # +# APECSS Options File # +# # +######################################################### + +BUBBLE +RPModel KM +Emissions QA 900.0e-06 +PressureAmbient 0.1013e6 +END + +GAS +EoS IG +ReferenceDensity 1.2 +PolytropicExponent 1 +END + +LIQUID +ReferencePressure 0.1013e6 +ReferenceDensity 1000.0 +ReferenceSoundSpeed 1500.0 +Viscosity 1.002e-3 +END + +INTERFACE +SurfaceTensionCoeff 0.0728 +END + +RESULTS +Bubble +END + +ODESOLVER +tolerance 1.0e-10 +END diff --git a/examples/cavitationonset/QA/src/cavitationonset_apecss.c b/examples/cavitationonset/QA/src/cavitationonset_apecss.c new file mode 100644 index 0000000..33ccb6b --- /dev/null +++ b/examples/cavitationonset/QA/src/cavitationonset_apecss.c @@ -0,0 +1,468 @@ +// This source file is part of APECSS, an open-source software toolbox +// for the computation of pressure-driven bubble dynamics and acoustic +// emissions in spherical symmetry. +// +// Copyright (C) 2022-2024 The APECSS Developers +// +// The APECSS Developers are listed in the README.md file available in +// the GitHub repository at https://github.com/polycfd/apecss. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// ------------------------------------------------------------------- +// APECSS standalone example of cavitation onset with acoustically-in- +// teracting microbubbles, based on Ida (2009), Physics of Fluids 21 +// (11), 113302, DOI : 10.1063/1.3265547 +// ------------------------------------------------------------------- + +#include +#include "apecss.h" + +// Declaration of additional case-dependent functions +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); + +// Declaration of the structure holding the interaction variables of each bubble +struct Interaction +{ + APECSS_FLOAT dp_neighbor; +}; + +int main(int argc, char **args) +{ + char OptionsDir[APECSS_STRINGLENGTH]; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Interbubble time-step, defining the frequency with which the neighbor influence is updated + APECSS_FLOAT dt_interbubble = 1.0e-8; + + // Initialize the simulation parameters given by the execution command + int nBubbles = 2; + double tEnd = 0.0; + double fa = 0.0; + double pa = 0.0; + int cluster_distrib = 0; + int cluster_size = 0; + int inttype = 0; + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + apecss_infoscreen(); + + /* Read commandline options */ + sprintf(OptionsDir, "./run.apecss"); // This is the default + int j = 1; // First argument is the call to the executable + while (j < argc) + { + if (strcmp("-options", args[j]) == 0) + { + sprintf(OptionsDir, "%s", args[j + 1]); + j += 2; + } + else if (strcmp("-tend", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &tEnd); + j += 2; + } + else if (strcmp("-freq", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &fa); + j += 2; + } + else if (strcmp("-amp", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &pa); + j += 2; + } + else if (strcmp("-nbb", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &nBubbles); + j += 2; + } + else if (strcmp("-cldistrib", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &cluster_distrib); + j += 2; + } + else if (strcmp("-clsize", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &cluster_size); + j += 2; + } + else if (strcmp("-inttype", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &inttype); + j += 2; + } + else if (strcmp("-dt_inter", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &dt_interbubble); + j += 2; + } + else if (strcmp("-h", args[j]) == 0) + { + apecss_helpscreen(); + } + else + { + char str[APECSS_STRINGLENGTH_SPRINTF]; + sprintf(str, "Unknown command line options: %s", args[j]); + apecss_erroronscreen(1, str); + ++j; + } + } + dt_interbubble = (APECSS_FLOAT) dt_interbubble; + + /* Allocate and initialize Bubble structure */ + struct APECSS_Bubble *Bubbles[nBubbles]; + for (register int i = 0; i < nBubbles; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(nBubbles * sizeof(struct APECSS_Bubble)); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initializestruct(Bubbles[i]); + + /* Set default options and read the options for the bubble */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); + + /* Allocate the structures for the fluid properties and ODE solver parameters */ + struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); + struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); + struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); + struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); + + /* Set the default options for the fluid properties and solver parameters */ + apecss_gas_setdefaultoptions(Gas); + apecss_liquid_setdefaultoptions(Liquid); + apecss_interface_setdefaultoptions(Interface); + apecss_odesolver_setdefaultoptions(NumericsODE); + + /* Read the options file for the fluid properties and solver parameters */ + apecss_gas_readoptions(Gas, OptionsDir); + apecss_liquid_readoptions(Liquid, OptionsDir); + apecss_interface_readoptions(Interface, OptionsDir); + apecss_odesolver_readoptions(NumericsODE, OptionsDir); + + /* Associate the bubble with the relevant fluid properties and solver parameters */ + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Gas = Gas; + Bubbles[i]->Liquid = Liquid; + Bubbles[i]->Interface = Interface; + Bubbles[i]->NumericsODE = NumericsODE; + } + + /* Allocate and set the excitation parameters */ + struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); + Excitation->type = APECSS_EXCITATION_SIN; + Excitation->f = (APECSS_FLOAT) fa; + Excitation->dp = (APECSS_FLOAT) pa; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Excitation = Excitation; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Create individual folders for the results of each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (Bubbles[i]->Results != NULL) + { + sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", i); + struct stat st = {0}; + if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Process all options */ + apecss_gas_processoptions(Gas); + apecss_liquid_processoptions(Liquid); + apecss_interface_processoptions(Interface); + apecss_odesolver_processoptions(NumericsODE); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_processoptions(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Use the revised pressure at infinity, including neighbor contributions + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressure_infinity = interaction_bubble_pressure_infinity; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressurederivative_infinity = interaction_bubble_pressurederivative_infinity; + + // Initialize interaction structure + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); + + // Update interaction structure + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Interaction->nBubbles = nBubbles; + Bubbles[i]->Interaction->dp_neighbor = 0.0; + Bubbles[i]->Interaction->last_t_1 = 0.0; + Bubbles[i]->Interaction->last_t_2 = 0.0; + Bubbles[i]->Interaction->last_p_1 = 0.0; + Bubbles[i]->Interaction->last_p_2 = 0.0; + } + + // Define the size of each bubble + if (cluster_distrib == 0) + { + // Two bubbles of different initial size interacting + Bubbles[0]->R0 = 2.0e-06; + Bubbles[1]->R0 = 20.0e-06; + } + else + { + // Monodispersed multibubble distributions + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->R0 = 20.0e-06; + } + } + + // Define center location for each bubble + if (cluster_distrib == 0) + { + // Two bubbles of different initial size interacting + Bubbles[0]->Interaction->location[0] = 0.0; + Bubbles[0]->Interaction->location[1] = 0.0; + Bubbles[0]->Interaction->location[2] = 0.0; + + Bubbles[1]->Interaction->location[0] = (APECSS_FLOAT) cluster_size * (Bubbles[0]->R0 + Bubbles[1]->R0); + Bubbles[1]->Interaction->location[1] = 0.0; + Bubbles[1]->Interaction->location[2] = 0.0; + } + else + { + // Monodispersed multibubble distributions + APECSS_FLOAT D = 400.0e-06; + if (nBubbles == 1) + { + // Single bubble + Bubbles[0]->Interaction->location[0] = 0.0; + Bubbles[0]->Interaction->location[1] = 0.0; + Bubbles[0]->Interaction->location[2] = 0.0; + } + else if (nBubbles == 2) + { + // Two bubbles + Bubbles[0]->Interaction->location[0] = 0.0; + Bubbles[0]->Interaction->location[1] = 0.0; + Bubbles[0]->Interaction->location[2] = 0.0; + + Bubbles[1]->Interaction->location[0] = D; + Bubbles[1]->Interaction->location[1] = 0.0; + Bubbles[1]->Interaction->location[2] = 0.0; + } + else if (nBubbles == 3) + { + // Regular triangle + Bubbles[0]->Interaction->location[0] = 0.0; + Bubbles[0]->Interaction->location[1] = 0.0; + Bubbles[0]->Interaction->location[2] = 0.0; + + Bubbles[1]->Interaction->location[0] = D; + Bubbles[1]->Interaction->location[1] = 0.0; + Bubbles[1]->Interaction->location[2] = 0.0; + + Bubbles[2]->Interaction->location[0] = 0.5 * D; + Bubbles[2]->Interaction->location[1] = D * APECSS_SIN(APECSS_ONETHIRD * APECSS_PI); + Bubbles[2]->Interaction->location[2] = 0.0; + } + else if (nBubbles == 4) + { + // Regular tetragon + Bubbles[0]->Interaction->location[0] = 0.0; + Bubbles[0]->Interaction->location[1] = 0.0; + Bubbles[0]->Interaction->location[2] = 0.0; + + Bubbles[1]->Interaction->location[0] = D; + Bubbles[1]->Interaction->location[1] = 0.0; + Bubbles[1]->Interaction->location[2] = 0.0; + + Bubbles[2]->Interaction->location[0] = 0.0; + Bubbles[2]->Interaction->location[1] = D; + Bubbles[2]->Interaction->location[2] = 0.0; + + Bubbles[3]->Interaction->location[0] = D; + Bubbles[3]->Interaction->location[1] = D; + Bubbles[3]->Interaction->location[2] = 0.0; + } + else if (nBubbles == 8) + { + // Regular hexaedron + Bubbles[0]->Interaction->location[0] = 0.0; + Bubbles[0]->Interaction->location[1] = 0.0; + Bubbles[0]->Interaction->location[2] = 0.0; + + Bubbles[1]->Interaction->location[0] = D; + Bubbles[1]->Interaction->location[1] = 0.0; + Bubbles[1]->Interaction->location[2] = 0.0; + + Bubbles[2]->Interaction->location[0] = 0.0; + Bubbles[2]->Interaction->location[1] = D; + Bubbles[2]->Interaction->location[2] = 0.0; + + Bubbles[3]->Interaction->location[0] = D; + Bubbles[3]->Interaction->location[1] = D; + Bubbles[3]->Interaction->location[2] = 0.0; + + Bubbles[4]->Interaction->location[0] = 0.0; + Bubbles[4]->Interaction->location[1] = 0.0; + Bubbles[4]->Interaction->location[2] = D; + + Bubbles[5]->Interaction->location[0] = D; + Bubbles[5]->Interaction->location[1] = 0.0; + Bubbles[5]->Interaction->location[2] = D; + + Bubbles[6]->Interaction->location[0] = 0.0; + Bubbles[6]->Interaction->location[1] = D; + Bubbles[6]->Interaction->location[2] = D; + + Bubbles[7]->Interaction->location[0] = D; + Bubbles[7]->Interaction->location[1] = D; + Bubbles[7]->Interaction->location[2] = D; + } + else + { + char str[APECSS_STRINGLENGTH_SPRINTF]; + sprintf(str, "Wrong number of bubbles as input for this specific cluster distribution (1, 2, 3, 4 or 8)"); + apecss_erroronscreen(1, str); + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + clock_t starttimebubble = clock(); + APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system + + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->tStart = tSim; + Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; + Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step + } + + /* Initialize the bubble based on the selected options */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initialize(Bubbles[i]); + + /* Initialize */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_initialize(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // File to retrieve all valuable information for cavitation onset test case + FILE *file_ida2009; + file_ida2009 = fopen("Ida2009_results.txt", "w"); + fprintf(file_ida2009, "%d Bubbles p0(pa) %e png(Pa) %e D_multiplier(-) %d cl_distrib %d Interaction-type %d\n", nBubbles, Liquid->pref, pa, cluster_size, + cluster_distrib, inttype); + fprintf(file_ida2009, "Initial_radii(m)"); + for (register int i = 0; i < nBubbles; i++) fprintf(file_ida2009, " %e", Bubbles[i]->R0); + fprintf(file_ida2009, "\n"); + fprintf(file_ida2009, "#Time(s) R(m) Pt(Pa)\n"); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Solve the bubble dynamics */ + while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered + { + APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); + tSim += dtSim; + + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Update the contribution of the neighbor bubbles + if (inttype == 1) + { + apecss_interactions_instantaneous(Bubbles); + } + else if (inttype == 2) + { + apecss_interactions_quasi_acoustic(Bubbles); + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Retrieve data + fprintf(file_ida2009, "%e", tSim); + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_ida2009, " %e", Bubbles[i]->R); + } + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_ida2009, " %e", Bubbles[i]->get_pressure_infinity(tSim, Bubbles[i])); + } + fprintf(file_ida2009, "\n"); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; + Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; + + Bubbles[i]->Interaction->last_t_1 = tSim; + Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; + } + } + + fclose(file_ida2009); + + /* Finalize the simulation*/ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_finalize(Bubbles[i]); + + char str[APECSS_STRINGLENGTH_SPRINTF]; + for (register int i = 0; i < nBubbles; i++) + { + sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", i, Bubbles[i]->dtNumber, Bubbles[i]->nSubIter, + (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); + apecss_writeonscreen(str); + } + + for (register int i = 0; i < nBubbles; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); + for (register int i = 0; i < nBubbles; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); + + /* Make sure all allocated memory is freed */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_freestruct(Bubbles[i]); + + for (register int i = 0; i < nBubbles; i++) free(Bubbles[i]); + free(Gas); + free(Liquid); + free(Interface); + free(NumericsODE); + free(Excitation); + + return (0); +} + +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + APECSS_FLOAT T = 10.0e-06; + if (t < T) + { + return (Bubble->p0 + Bubble->Interaction->dp_neighbor); + } + else if (t > 2 * T) + { + return (Bubble->Excitation->dp + Bubble->Interaction->dp_neighbor); + } + else + { + APECSS_FLOAT W = 0.5 * (1 - APECSS_COS((t + T) * APECSS_PI / T)); + return (Bubble->p0 + W * (Bubble->Excitation->dp - Bubble->p0) + Bubble->Interaction->dp_neighbor); + } +} + +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + // Approximate numerical computation of p_infinity derivative + APECSS_FLOAT T = 10.0e-06; + APECSS_FLOAT derivative = 0.0; + if ((t >= T) && (t <= 2 * T)) + { + APECSS_FLOAT inv_T = 1 / T; + derivative = 0.5 * APECSS_PI * inv_T * APECSS_SIN(APECSS_PI * (t + T) * inv_T) * (Bubble->Excitation->dp - Bubble->p0); + } + return (derivative); + + // APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; + // if (delta_t > Bubble->dt) + // { + // APECSS_FLOAT inv_delta_t = 1 / delta_t; + // return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) * inv_delta_t)); + // } + // else + // { + // return (derivative); + // } +} \ No newline at end of file diff --git a/examples/cavitationonset/run_cavitationonset.sh b/examples/cavitationonset/run_cavitationonset.sh index 4673ac5..5c5ad59 100755 --- a/examples/cavitationonset/run_cavitationonset.sh +++ b/examples/cavitationonset/run_cavitationonset.sh @@ -1,12 +1,105 @@ -cd IC/build -./compile.sh -cd .. -nbubble=2 -png=-25325 -./build/cavitationonset_apecss -options run.apecss -amp $png -tend 60.0e-6 -nbb $nbubble -cldistrib 0 -clsize 20 -inttype 1 +######### Test case ################################################################################################################################# + +# cd IC/build +# ./compile.sh +# cd .. +# nbubble=8 +# png=-25325 +# ./build/cavitationonset_apecss -options run.apecss -amp $png -tend 60.0e-6 -nbb $nbubble -cldistrib 1 -clsize 10 -inttype 1 +# python3 plot_temp.py # for ((c=0; c<$nbubble; c++)) # do -# rm -r Bubble_$c +# rm -rf Bubble_$c # done -cd .. \ No newline at end of file +# cd .. + +######### No Interaction computations ############################################################################################################### + +cd NI/build +./compile.sh +cd .. + +######### Pressure time history & Radius evolution without interaction ############################ +./build/cavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-6 -nbb 2 -cldistrib 0 -clsize 15 -inttype 0 +python3 gather_results.py + +######### Cavitation inception pressure treshold for one single bubble ############################ +png_list=(-17221 -17725.5 -18353.2 -18770.3) +for png in "${png_list[@]}" +do + ./build/cavitationonset_apecss -options run.apecss -amp $png -tend 60.0e-6 -nbb 2 -cldistrib 0 -clsize 15 -inttype 0 + python3 gather_results.py +done + +cd .. + +echo "" +echo "No interaction test cases passed" +echo "" + +######### Incompressible computations ############################################################################################################### + +cd IC/build +./compile.sh +cd .. + +######### Cavitation inception with interactions with varying distance between 2 bubbles ########## + +######### Cavitation inception with interactions with varying pressure between 2 bubbles ########## + +######### Cavitation inception with monodispersed simple distributions ############################ + +cd .. + +echo "" +echo "Incompressible test cases passed" +echo "" + +######### Quasi acoustic computations ############################################################################################################### + +cd QA/build +./compile.sh +cd .. + +######### Cavitation inception with interactions with varying distance between 2 bubbles ########## + +######### Cavitation inception with interactions with varying pressure between 2 bubbles ########## + +######### Cavitation inception with monodispersed simple distributions ############################ + +cd .. + +echo "" +echo "Quasi acoustic test cases passed" +echo "" + +######### Cleaning ################################################################################################################################## + +cd NI +rm -rf "Ida2009_results.txt" +for ((c=0; c<2; c++)) +do + rm -rf Bubble_$c +done +cd .. + +cd IC +rm -rf "Ida2009_results.txt" +for ((c=0; c<8; c++)) +do + rm -rf Bubble_$c +done +cd .. + +cd QA +rm -rf "Ida2009_results.txt" +for ((c=0; c<8; c++)) +do + rm -rf Bubble_$c +done +cd .. + +echo "" +echo "Cleaning completed" +echo "" \ No newline at end of file From d5635c474641ce35dc5a05a537dffaa4c59a4ab4 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Thu, 11 Jul 2024 10:49:42 -0400 Subject: [PATCH 022/138] cavitation onset ; working test case --- examples/cavitationonset/IC/gather_results.py | 29 ++++++++ examples/cavitationonset/IC/run.apecss | 2 +- .../IC/src/cavitationonset_apecss.c | 71 ++++++++++++++++--- examples/cavitationonset/NI/gather_results.py | 2 +- examples/cavitationonset/QA/gather_results.py | 29 ++++++++ .../QA/src/cavitationonset_apecss.c | 24 +++---- .../cavitationonset/run_cavitationonset.sh | 38 +++++++++- 7 files changed, 170 insertions(+), 25 deletions(-) create mode 100644 examples/cavitationonset/QA/gather_results.py diff --git a/examples/cavitationonset/IC/gather_results.py b/examples/cavitationonset/IC/gather_results.py index e69de29..9594998 100644 --- a/examples/cavitationonset/IC/gather_results.py +++ b/examples/cavitationonset/IC/gather_results.py @@ -0,0 +1,29 @@ +import os + +# File designed to recover data for plotting results in cavitation onset case + +file = open("Ida2009_results.txt", "r") +lines = file.readlines() +file.close() + +count = int(lines[0].split(" ")[0]) +png = float(lines[0].split(" ")[5]) +cl_size = int(lines[0].split(" ")[7]) +cl_distrib = int(lines[0].split(" ")[9]) + +if cl_distrib == 0 : + # Two bubbles of different size + file_name = "{}_{:.4E}_{}.txt".format(count, png, cl_size) + +else : + # Monodispersed system + file_name = "{}_{:.4E}.txt".format(count, png) + +working_path = os.getcwd() +results_path = os.path.join(working_path, "results") +file_results = open(os.path.join(results_path, file_name), "w") + +for line in lines : + file_results.write(line) + +file_results.close() \ No newline at end of file diff --git a/examples/cavitationonset/IC/run.apecss b/examples/cavitationonset/IC/run.apecss index 6006bc7..66cab93 100644 --- a/examples/cavitationonset/IC/run.apecss +++ b/examples/cavitationonset/IC/run.apecss @@ -6,7 +6,7 @@ BUBBLE RPModel KM -Emissions IC 600.0e-06 +Emissions IC 900.0e-06 PressureAmbient 0.1013e6 END diff --git a/examples/cavitationonset/IC/src/cavitationonset_apecss.c b/examples/cavitationonset/IC/src/cavitationonset_apecss.c index 7f7d9fc..631d3fd 100644 --- a/examples/cavitationonset/IC/src/cavitationonset_apecss.c +++ b/examples/cavitationonset/IC/src/cavitationonset_apecss.c @@ -95,6 +95,11 @@ int main(int argc, char **args) sscanf(args[j + 1], "%d", &inttype); j += 2; } + else if (strcmp("-dt_inter", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &dt_interbubble); + j += 2; + } else if (strcmp("-h", args[j]) == 0) { apecss_helpscreen(); @@ -107,6 +112,7 @@ int main(int argc, char **args) ++j; } } + dt_interbubble = (APECSS_FLOAT) dt_interbubble; /* Allocate and initialize Bubble structure */ struct APECSS_Bubble *Bubbles[nBubbles]; @@ -334,18 +340,34 @@ int main(int argc, char **args) /* Initialize */ for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_initialize(Bubbles[i]); + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // File to retrieve all valuable information for cavitation onset test case + FILE *file_ida2009; + file_ida2009 = fopen("Ida2009_results.txt", "w"); + fprintf(file_ida2009, "%d Bubbles p0(pa) %e png(Pa) %e D_multiplier(-) %d cl_distrib %d Interaction-type %d\n", nBubbles, Liquid->pref, pa, cluster_size, + cluster_distrib, inttype); + fprintf(file_ida2009, "Initial_radii(m)"); + for (register int i = 0; i < nBubbles; i++) fprintf(file_ida2009, " %e", Bubbles[i]->R0); + fprintf(file_ida2009, "\n"); + fprintf(file_ida2009, "#Time(s) R(m) Pt(Pa)\n"); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + /* Solve the bubble dynamics */ while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered { APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); tSim += dtSim; + // printf("%e", tSim); + // printf(" %e", Bubbles[0]->ode[0](Bubbles[0]->ODEsSol, Bubbles[0]->t, Bubbles[0])); for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; + // for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; + // printf(" %e", Bubbles[0]->R); + // printf(" %e", Bubbles[0]->ode[0](Bubbles[0]->ODEsSol, Bubbles[0]->t, Bubbles[0])); // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Update the contribution of the neighbor bubble + // Update the contribution of the neighbor bubbles if (inttype == 1) { apecss_interactions_instantaneous(Bubbles); @@ -355,15 +377,41 @@ int main(int argc, char **args) apecss_interactions_quasi_acoustic(Bubbles); } // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + // for (register int i = 0; i < nBubbles; i++) + // { + // printf(" %e", Bubbles[i]->get_pressure_infinity(tSim, Bubbles[i])); + // } + // printf(" %e", Bubbles[0]->get_pressure_infinity(Bubbles[0]->t, Bubbles[0])); + // printf(" %e", Bubbles[0]->ode[0](Bubbles[0]->ODEsSol, Bubbles[0]->t, Bubbles[0])); + // printf("\n"); - int index = 1; - APECSS_FLOAT derivative = (Bubbles[index]->Interaction->last_p_1 - Bubbles[index]->Interaction->last_p_2) / - (Bubbles[index]->Interaction->last_t_1 - Bubbles[index]->Interaction->last_t_2); - printf("%e Bubble %d R %e U %e A %e t_1 %e t_2 %e inv_t %e p_1 %e p_2 %e diff_p %e derivative %e\n", tSim, index, Bubbles[index]->R, Bubbles[index]->U, - Bubbles[index]->ode[0](Bubbles[index]->ODEsSol, Bubbles[index]->t, Bubbles[index]), Bubbles[index]->Interaction->last_t_1, - Bubbles[index]->Interaction->last_t_2, 1 / (Bubbles[index]->Interaction->last_t_1 - Bubbles[index]->Interaction->last_t_2), - Bubbles[index]->Interaction->last_p_1, Bubbles[index]->Interaction->last_p_2, - (Bubbles[index]->Interaction->last_p_1 - Bubbles[index]->Interaction->last_p_2), derivative); + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Retrieve data + fprintf(file_ida2009, "%e", tSim); + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_ida2009, " %e", Bubbles[i]->R); + } + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_ida2009, " %e", Bubbles[i]->get_pressure_infinity(tSim, Bubbles[i])); + } + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_ida2009, " %e", Bubbles[i]->ode[0](Bubbles[i]->ODEsSol, Bubbles[i]->t, Bubbles[i])); + } + fprintf(file_ida2009, "\n"); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + // int index = 0; + // // APECSS_FLOAT derivative = (Bubbles[index]->Interaction->last_p_1 - Bubbles[index]->Interaction->last_p_2) / + // // (Bubbles[index]->Interaction->last_t_1 - Bubbles[index]->Interaction->last_t_2); + // printf("%e Bubble %d R %e U %e A %e t_1 %e t_2 %e inv_t %e p_1 %e p_2 %e diff_p %e derivative %e pinfty %e\n", tSim, index, Bubbles[index]->R, + // Bubbles[index]->U, Bubbles[index]->ode[0](Bubbles[index]->ODEsSol, Bubbles[index]->t, Bubbles[index]), Bubbles[index]->Interaction->last_t_1, + // Bubbles[index]->Interaction->last_t_2, 1 / (Bubbles[index]->Interaction->last_t_1 - Bubbles[index]->Interaction->last_t_2), + // Bubbles[index]->Interaction->last_p_1, Bubbles[index]->Interaction->last_p_2, + // (Bubbles[index]->Interaction->last_p_1 - Bubbles[index]->Interaction->last_p_2), + // Bubbles[index]->get_pressurederivative_infinity(tSim, Bubbles[index]), Bubbles[index]->get_pressure_infinity(tSim, Bubbles[index])); for (register int i = 0; i < nBubbles; i++) { @@ -375,6 +423,8 @@ int main(int argc, char **args) } } + fclose(file_ida2009); + /* Finalize the simulation*/ for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_finalize(Bubbles[i]); @@ -430,6 +480,7 @@ APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, stru APECSS_FLOAT inv_T = 1 / T; derivative = 0.5 * APECSS_PI * inv_T * APECSS_SIN(APECSS_PI * (t + T) * inv_T) * (Bubble->Excitation->dp - Bubble->p0); } + return (derivative); APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; if (delta_t > Bubble->dt) diff --git a/examples/cavitationonset/NI/gather_results.py b/examples/cavitationonset/NI/gather_results.py index d0c6538..9594998 100644 --- a/examples/cavitationonset/NI/gather_results.py +++ b/examples/cavitationonset/NI/gather_results.py @@ -6,7 +6,7 @@ lines = file.readlines() file.close() -count = float(lines[0].split(" ")[0]) +count = int(lines[0].split(" ")[0]) png = float(lines[0].split(" ")[5]) cl_size = int(lines[0].split(" ")[7]) cl_distrib = int(lines[0].split(" ")[9]) diff --git a/examples/cavitationonset/QA/gather_results.py b/examples/cavitationonset/QA/gather_results.py new file mode 100644 index 0000000..9594998 --- /dev/null +++ b/examples/cavitationonset/QA/gather_results.py @@ -0,0 +1,29 @@ +import os + +# File designed to recover data for plotting results in cavitation onset case + +file = open("Ida2009_results.txt", "r") +lines = file.readlines() +file.close() + +count = int(lines[0].split(" ")[0]) +png = float(lines[0].split(" ")[5]) +cl_size = int(lines[0].split(" ")[7]) +cl_distrib = int(lines[0].split(" ")[9]) + +if cl_distrib == 0 : + # Two bubbles of different size + file_name = "{}_{:.4E}_{}.txt".format(count, png, cl_size) + +else : + # Monodispersed system + file_name = "{}_{:.4E}.txt".format(count, png) + +working_path = os.getcwd() +results_path = os.path.join(working_path, "results") +file_results = open(os.path.join(results_path, file_name), "w") + +for line in lines : + file_results.write(line) + +file_results.close() \ No newline at end of file diff --git a/examples/cavitationonset/QA/src/cavitationonset_apecss.c b/examples/cavitationonset/QA/src/cavitationonset_apecss.c index 33ccb6b..f85be92 100644 --- a/examples/cavitationonset/QA/src/cavitationonset_apecss.c +++ b/examples/cavitationonset/QA/src/cavitationonset_apecss.c @@ -453,16 +453,16 @@ APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, stru APECSS_FLOAT inv_T = 1 / T; derivative = 0.5 * APECSS_PI * inv_T * APECSS_SIN(APECSS_PI * (t + T) * inv_T) * (Bubble->Excitation->dp - Bubble->p0); } - return (derivative); - - // APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; - // if (delta_t > Bubble->dt) - // { - // APECSS_FLOAT inv_delta_t = 1 / delta_t; - // return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) * inv_delta_t)); - // } - // else - // { - // return (derivative); - // } + // return (derivative); + + APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; + if (delta_t > Bubble->dt) + { + APECSS_FLOAT inv_delta_t = 1 / delta_t; + return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) * inv_delta_t)); + } + else + { + return (derivative); + } } \ No newline at end of file diff --git a/examples/cavitationonset/run_cavitationonset.sh b/examples/cavitationonset/run_cavitationonset.sh index 5c5ad59..29059e7 100755 --- a/examples/cavitationonset/run_cavitationonset.sh +++ b/examples/cavitationonset/run_cavitationonset.sh @@ -45,10 +45,28 @@ cd IC/build cd .. ######### Cavitation inception with interactions with varying distance between 2 bubbles ########## +dist_list=(10 11 12 12.05 12.1 15 20) +for d in "${dist_list[@]}" +do + ./build/cavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-6 -nbb 2 -cldistrib 0 -clsize $d -inttype 1 + python3 gather_results.py +done ######### Cavitation inception with interactions with varying pressure between 2 bubbles ########## +png_list=(-25325 -27351 -27958.8 -29377) +for png in "${png_list[@]}" +do + ./build/cavitationonset_apecss -options run.apecss -amp $png -tend 60.0e-6 -nbb 2 -cldistrib 0 -clsize 10 -inttype 1 + python3 gather_results.py +done -######### Cavitation inception with monodispersed simple distributions ############################ +######### Cavitation inception with monodispersed simple distributions ############################ +nbubble_list=(1 2 3 4 8) +for nbubble in "${nbubble_list[@]}" +do + ./build/cavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-6 -nbb $nbubble -cldistrib 1 -clsize 10 -inttype 1 + python3 gather_results.py +done cd .. @@ -63,10 +81,28 @@ cd QA/build cd .. ######### Cavitation inception with interactions with varying distance between 2 bubbles ########## +dist_list=(10 11 12 12.05 12.1 15 20) +for d in "${dist_list[@]}" +do + ./build/cavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-6 -nbb 2 -cldistrib 0 -clsize $d -inttype 2 -dt_inter 1.0e-09 + python3 gather_results.py +done ######### Cavitation inception with interactions with varying pressure between 2 bubbles ########## +png_list=(-25325 -26338 -26793.85 -26844.5 -27097.75 -27351 -27958.8 -29377) +for png in "${png_list[@]}" +do + ./build/cavitationonset_apecss -options run.apecss -amp $png -tend 60.0e-6 -nbb 2 -cldistrib 0 -clsize 10 -inttype 2 -dt_inter 1.0e-09 + python3 gather_results.py +done ######### Cavitation inception with monodispersed simple distributions ############################ +nbubble_list=(1 2 3 4 8) +for nbubble in "${nbubble_list[@]}" +do + ./build/cavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-6 -nbb $nbubble -cldistrib 1 -clsize 10 -inttype 2 + python3 gather_results.py +done cd .. From 0310708fc11df18fd0358a58630c7d8f454681f7 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Thu, 11 Jul 2024 11:43:43 -0400 Subject: [PATCH 023/138] cavitation onset ; small changes in cluster size type --- examples/cavitationonset/IC/gather_results.py | 4 ++-- examples/cavitationonset/IC/src/cavitationonset_apecss.c | 6 +++--- examples/cavitationonset/NI/gather_results.py | 4 ++-- examples/cavitationonset/NI/src/cavitationonset_apecss.c | 6 +++--- examples/cavitationonset/QA/gather_results.py | 4 ++-- examples/cavitationonset/QA/src/cavitationonset_apecss.c | 6 +++--- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/examples/cavitationonset/IC/gather_results.py b/examples/cavitationonset/IC/gather_results.py index 9594998..2fad87b 100644 --- a/examples/cavitationonset/IC/gather_results.py +++ b/examples/cavitationonset/IC/gather_results.py @@ -8,12 +8,12 @@ count = int(lines[0].split(" ")[0]) png = float(lines[0].split(" ")[5]) -cl_size = int(lines[0].split(" ")[7]) +cl_size = float(lines[0].split(" ")[7]) cl_distrib = int(lines[0].split(" ")[9]) if cl_distrib == 0 : # Two bubbles of different size - file_name = "{}_{:.4E}_{}.txt".format(count, png, cl_size) + file_name = "{}_{:.4E}_{:.2f}.txt".format(count, png, cl_size) else : # Monodispersed system diff --git a/examples/cavitationonset/IC/src/cavitationonset_apecss.c b/examples/cavitationonset/IC/src/cavitationonset_apecss.c index 631d3fd..cc2bfef 100644 --- a/examples/cavitationonset/IC/src/cavitationonset_apecss.c +++ b/examples/cavitationonset/IC/src/cavitationonset_apecss.c @@ -44,7 +44,7 @@ int main(int argc, char **args) double fa = 0.0; double pa = 0.0; int cluster_distrib = 0; - int cluster_size = 0; + double cluster_size = 0; int inttype = 0; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @@ -87,7 +87,7 @@ int main(int argc, char **args) } else if (strcmp("-clsize", args[j]) == 0) { - sscanf(args[j + 1], "%d", &cluster_size); + sscanf(args[j + 1], "%le", &cluster_size); j += 2; } else if (strcmp("-inttype", args[j]) == 0) @@ -344,7 +344,7 @@ int main(int argc, char **args) // File to retrieve all valuable information for cavitation onset test case FILE *file_ida2009; file_ida2009 = fopen("Ida2009_results.txt", "w"); - fprintf(file_ida2009, "%d Bubbles p0(pa) %e png(Pa) %e D_multiplier(-) %d cl_distrib %d Interaction-type %d\n", nBubbles, Liquid->pref, pa, cluster_size, + fprintf(file_ida2009, "%d Bubbles p0(pa) %e png(Pa) %e D_multiplier(-) %e cl_distrib %d Interaction-type %d\n", nBubbles, Liquid->pref, pa, cluster_size, cluster_distrib, inttype); fprintf(file_ida2009, "Initial_radii(m)"); for (register int i = 0; i < nBubbles; i++) fprintf(file_ida2009, " %e", Bubbles[i]->R0); diff --git a/examples/cavitationonset/NI/gather_results.py b/examples/cavitationonset/NI/gather_results.py index 9594998..2fad87b 100644 --- a/examples/cavitationonset/NI/gather_results.py +++ b/examples/cavitationonset/NI/gather_results.py @@ -8,12 +8,12 @@ count = int(lines[0].split(" ")[0]) png = float(lines[0].split(" ")[5]) -cl_size = int(lines[0].split(" ")[7]) +cl_size = float(lines[0].split(" ")[7]) cl_distrib = int(lines[0].split(" ")[9]) if cl_distrib == 0 : # Two bubbles of different size - file_name = "{}_{:.4E}_{}.txt".format(count, png, cl_size) + file_name = "{}_{:.4E}_{:.2f}.txt".format(count, png, cl_size) else : # Monodispersed system diff --git a/examples/cavitationonset/NI/src/cavitationonset_apecss.c b/examples/cavitationonset/NI/src/cavitationonset_apecss.c index 33ccb6b..1f2b1e9 100644 --- a/examples/cavitationonset/NI/src/cavitationonset_apecss.c +++ b/examples/cavitationonset/NI/src/cavitationonset_apecss.c @@ -44,7 +44,7 @@ int main(int argc, char **args) double fa = 0.0; double pa = 0.0; int cluster_distrib = 0; - int cluster_size = 0; + double cluster_size = 0; int inttype = 0; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @@ -87,7 +87,7 @@ int main(int argc, char **args) } else if (strcmp("-clsize", args[j]) == 0) { - sscanf(args[j + 1], "%d", &cluster_size); + sscanf(args[j + 1], "%le", &cluster_size); j += 2; } else if (strcmp("-inttype", args[j]) == 0) @@ -344,7 +344,7 @@ int main(int argc, char **args) // File to retrieve all valuable information for cavitation onset test case FILE *file_ida2009; file_ida2009 = fopen("Ida2009_results.txt", "w"); - fprintf(file_ida2009, "%d Bubbles p0(pa) %e png(Pa) %e D_multiplier(-) %d cl_distrib %d Interaction-type %d\n", nBubbles, Liquid->pref, pa, cluster_size, + fprintf(file_ida2009, "%d Bubbles p0(pa) %e png(Pa) %e D_multiplier(-) %e cl_distrib %d Interaction-type %d\n", nBubbles, Liquid->pref, pa, cluster_size, cluster_distrib, inttype); fprintf(file_ida2009, "Initial_radii(m)"); for (register int i = 0; i < nBubbles; i++) fprintf(file_ida2009, " %e", Bubbles[i]->R0); diff --git a/examples/cavitationonset/QA/gather_results.py b/examples/cavitationonset/QA/gather_results.py index 9594998..2fad87b 100644 --- a/examples/cavitationonset/QA/gather_results.py +++ b/examples/cavitationonset/QA/gather_results.py @@ -8,12 +8,12 @@ count = int(lines[0].split(" ")[0]) png = float(lines[0].split(" ")[5]) -cl_size = int(lines[0].split(" ")[7]) +cl_size = float(lines[0].split(" ")[7]) cl_distrib = int(lines[0].split(" ")[9]) if cl_distrib == 0 : # Two bubbles of different size - file_name = "{}_{:.4E}_{}.txt".format(count, png, cl_size) + file_name = "{}_{:.4E}_{:.2f}.txt".format(count, png, cl_size) else : # Monodispersed system diff --git a/examples/cavitationonset/QA/src/cavitationonset_apecss.c b/examples/cavitationonset/QA/src/cavitationonset_apecss.c index f85be92..93d0788 100644 --- a/examples/cavitationonset/QA/src/cavitationonset_apecss.c +++ b/examples/cavitationonset/QA/src/cavitationonset_apecss.c @@ -44,7 +44,7 @@ int main(int argc, char **args) double fa = 0.0; double pa = 0.0; int cluster_distrib = 0; - int cluster_size = 0; + double cluster_size = 0; int inttype = 0; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @@ -87,7 +87,7 @@ int main(int argc, char **args) } else if (strcmp("-clsize", args[j]) == 0) { - sscanf(args[j + 1], "%d", &cluster_size); + sscanf(args[j + 1], "%le", &cluster_size); j += 2; } else if (strcmp("-inttype", args[j]) == 0) @@ -344,7 +344,7 @@ int main(int argc, char **args) // File to retrieve all valuable information for cavitation onset test case FILE *file_ida2009; file_ida2009 = fopen("Ida2009_results.txt", "w"); - fprintf(file_ida2009, "%d Bubbles p0(pa) %e png(Pa) %e D_multiplier(-) %d cl_distrib %d Interaction-type %d\n", nBubbles, Liquid->pref, pa, cluster_size, + fprintf(file_ida2009, "%d Bubbles p0(pa) %e png(Pa) %e D_multiplier(-) %e cl_distrib %d Interaction-type %d\n", nBubbles, Liquid->pref, pa, cluster_size, cluster_distrib, inttype); fprintf(file_ida2009, "Initial_radii(m)"); for (register int i = 0; i < nBubbles; i++) fprintf(file_ida2009, " %e", Bubbles[i]->R0); From be3bedfee5c123bccb3acfb90e8a0ab7c856e17e Mon Sep 17 00:00:00 2001 From: Pierre C Date: Thu, 11 Jul 2024 11:44:10 -0400 Subject: [PATCH 024/138] cavitation onset ; file to plot the desired results --- examples/cavitationonset/plot_results.py | 165 +++++++++++++++++++++++ 1 file changed, 165 insertions(+) diff --git a/examples/cavitationonset/plot_results.py b/examples/cavitationonset/plot_results.py index e69de29..355f8cb 100644 --- a/examples/cavitationonset/plot_results.py +++ b/examples/cavitationonset/plot_results.py @@ -0,0 +1,165 @@ +import os +import numpy as np +import matplotlib.pyplot as plt +import matplotlib.colors as mcolors + +plt.rcParams['font.family']='serif' +plt.rcParams['font.serif']=['Times New Roman'] + plt.rcParams['font.serif'] +plt.rcParams['mathtext.fontset']='stix' +plt.rcParams['font.size']=12.5 + +color_names = list(mcolors.XKCD_COLORS) + +cm = 1/2.54 + +# File designed to recover and copy/paste results to reproduce Ida's cavitation onset test case +# DOI : https://doi.org/10.1063/1.3265547 + +######### Step 1 : Recovering data ################################################################################################################## + +inttype_list = ["NI", "IC", "QA"] + +dic_2_bubbles = {} +dic_n_bubbles = {} + +working_path = os.getcwd() + +for inttype in inttype_list : + if inttype not in list(dic_2_bubbles.keys()) : + dic_2_bubbles[inttype] = {} + + if inttype not in list(dic_n_bubbles.keys()) : + dic_n_bubbles[inttype] = {} + + inttype_path = os.path.join(working_path, inttype) + inttype_path = os.path.join(inttype_path, "results") + + for file in os.listdir(inttype_path) : + file_path = os.path.join(inttype_path, file) + file_results = open(file_path, "r") + lines = file_results.readlines() + file_results.close() + + first_line = lines[0].split(" ") + count = int(first_line[0]) + png = float(first_line[5]) + size = float(first_line[7]) + cluster = float(first_line[9]) + + if cluster == 0 : + if png not in list(dic_2_bubbles[inttype].keys()) : + dic_2_bubbles[inttype][png] = {} + if size not in list(dic_2_bubbles[inttype][png].keys()) : + dic_2_bubbles[inttype][png][size] = [] + + dic_data = dic_2_bubbles[inttype][png][size] + + else : + if count not in list(dic_n_bubbles[inttype].keys()) : + dic_n_bubbles[inttype][count] = [] + + dic_data = dic_n_bubbles[inttype][count] + + second_line = lines[1].split(" ") + for i in range(count) : + init_radius = float(second_line[i+1]) + # list format : for each bubble, [R0, t_list, R_list, Pt_list] + dic_data.append([init_radius, [], [], []]) + + for line in lines[3:] : + data = line.split(" ") + t = float(data[0]) + for i in range(count) : + r = float(data[1 + i]) + pt = float(data[1 + count + i]) + dic_data[i][1].append(t) + dic_data[i][2].append(r) + dic_data[i][3].append(pt) + +######### Step 2 : Plotting results ################################################################################################################# + +######### Initial parameters #################### + +T = 10.0e-06 +P0 = 0.1013e06 + +######### Pressure time history & radius evolution without interaction ############################ + +nrow = 1 +ncol = 2 + +fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm))) +plt.subplots_adjust(wspace=0.5*cm, hspace=0.5*cm) + +axs[0].set_title("Pressure time history (" + r"$T$ = " + "{:.1f} ".format(T*1.0e06) + r"$\mu$s)") +axs[0].set_xlabel(r"t ($\mu$s)") +axs[0].set_xlim(xmin=0.0, xmax=60.0) +axs[0].set_ylabel(r"$p_{\infty}$/$p_{0}$ (-)") +axs[0].grid() + +t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][1]) * 1.0e6 +p_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][3]) / P0 +axs[0].plot(t_list, p_list, color="black") + +axs[1].set_title("Evolution of radius without interaction") +axs[1].set_xlabel(r"t ($\mu$s)") +axs[1].set_xlim(xmin=0.0, xmax=60.0) +axs[1].set_ylabel(r"$R$ ($\mu$m)") +axs[1].grid() + +t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][1]) * 1.0e6 +r_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][2]) * 1.0e6 +axs[1].plot(t_list, r_list, color="blue", label=r"$R_{1,0}$ = 2.0 $\mu$m") + +t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][1][1]) * 1.0e6 +r_list = np.array(dic_2_bubbles["NI"][-25325][15.0][1][2]) * 1.0e6 +axs[1].plot(t_list, r_list, color="magenta", label=r"$R_{2,0}$ = 20.0 $\mu$m") + +axs[1].legend(loc="upper left") + +fig.savefig("cavitationonset_pressurehistory_radiusevolutionNI.pdf", bbox_inches='tight',pad_inches=0.35) + +######### Cavitation inception for one single bubble ############################################## + +nrow = 1 +ncol = 1 + +fig, ax = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm))) +plt.subplots_adjust(wspace=0.5*cm, hspace=0.5*cm) + +png_list = [-17221, -17725.5, -18353.2, -18770.3] + +ax.set_title("Cavitation inception of a single bubble depending on " + r"$p_{ng}$/$p_{0}$ ($R_{0}$ = 2 $\mu$m)") +ax.set_xlabel(r"t ($\mu$s)") +ax.set_xlim(xmin=10.0, xmax=60.0) +ax.set_ylabel(r"$R$ ($\mu$m)") +ax.set_ylim(ymin=0.0, ymax=14.0) +ax.grid() + +for png in png_list : + t_list = np.array(dic_2_bubbles["NI"][png][15.0][0][1]) * 1.0e6 + r_list = np.array(dic_2_bubbles["NI"][png][15.0][0][2]) * 1.0e6 + + ax.plot(t_list, r_list, color="blue") + +ax.text(25.0, 3.50, r"$-0.17$") +ax.text(31.0, 6.25, r"$-0.175$") +ax.text(28.0, 9.00, r"$-0.176$") +ax.text(22.5, 13.0, r"$-0.18$") + +fig.savefig("cavitationonset_singlebubble.pdf", bbox_inches='tight',pad_inches=0.35) + +######### Cavitation inception with interactions with varying distance between 2 bubbles ########## + +nrow = 1 +ncol = 2 + +######### Cavitation inception with interactions with varying pressure between 2 bubbles ########## + +nrow = 1 +ncol = 2 + +######### Cavitation inception with monodispersed simple distributions ############################ + +nrow = 2 +ncol = 2 \ No newline at end of file From 2b3854b21cb8dfa4ab34645720e5b6a6e1bcd37a Mon Sep 17 00:00:00 2001 From: Pierre C Date: Thu, 11 Jul 2024 14:27:02 -0400 Subject: [PATCH 025/138] gitgnore update ; no tracking of results file types, txt, pdf and png --- .gitignore | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index de32c1e..f1d2ab7 100644 --- a/.gitignore +++ b/.gitignore @@ -78,4 +78,9 @@ dkms.conf *.cmake CMakeCache.txt CMakeFiles/ -Makefile \ No newline at end of file +Makefile + +# Results +*.txt +*.pdf +*.png \ No newline at end of file From 78c11ed9648a2b738cdad100126216fa742d25b4 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Thu, 11 Jul 2024 14:27:49 -0400 Subject: [PATCH 026/138] cavitation onset ; completed test case with every plots --- examples/cavitationonset/plot_results.py | 166 +++++++++++++++++- .../cavitationonset/run_cavitationonset.sh | 10 +- 2 files changed, 172 insertions(+), 4 deletions(-) diff --git a/examples/cavitationonset/plot_results.py b/examples/cavitationonset/plot_results.py index 355f8cb..75de18e 100644 --- a/examples/cavitationonset/plot_results.py +++ b/examples/cavitationonset/plot_results.py @@ -154,12 +154,176 @@ nrow = 1 ncol = 2 +fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm))) +plt.subplots_adjust(wspace=0.5*cm, hspace=0.5*cm) + +dist_list = [10, 12, 12.1, 12.5, 15, 20] + +axs[0].set_title(r"Incompressible interactions ($p_{ng}$/$p_{0}$ = -0.25)") +axs[0].set_xlabel(r"t ($\mu$s)") +axs[0].set_xlim(xmin=0.0, xmax=60.0) +axs[0].set_ylabel(r"$R$ ($\mu$m)") +axs[0].set_ylim(ymin=0.0, ymax=80.0) +axs[0].grid() + +for dist in dist_list : + t_list = np.array(dic_2_bubbles["IC"][-25325][dist][0][1]) * 1.0e6 + r_list = np.array(dic_2_bubbles["IC"][-25325][dist][0][2]) * 1.0e6 + + axs[0].plot(t_list, r_list, color="blue") + +t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][1]) * 1.0e6 +r_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][2]) * 1.0e6 +axs[0].plot(t_list, r_list, color="blue") + +t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][1][1]) * 1.0e6 +r_list = np.array(dic_2_bubbles["NI"][-25325][15.0][1][2]) * 1.0e6 +axs[0].plot(t_list, r_list, color="magenta") + +axs[0].text(0.5, 5.0, r"$R_{1,0}$ = 2.0 $\mu$m", color="blue") +axs[0].text(0.5, 25.0, r"$R_{2,0}$ = 20.0 $\mu$m", color="magenta") + +axs[0].text(38.0, 75.0, r"$\infty$", color="blue") +axs[0].text(45.0, 75.0, r"20", color="blue") +axs[0].text(50.0, 75.0, r"15", color="blue") +axs[0].text(55.0, 55.0, r"12.5", color="blue") +axs[0].text(45.0, 15.0, r"12.1", color="blue") +axs[0].text(35.0, 7.0, r"12", color="blue") +axs[0].text(25.0, 0.5, r"10", color="blue") + +dist_list = [10, 11.9, 12, 15, 20] + +axs[1].set_title(r"Quasi acoustic interactions ($p_{ng}$/$p_{0}$ = -0.25)") +axs[1].set_xlabel(r"t ($\mu$s)") +axs[1].set_xlim(xmin=0.0, xmax=60.0) +axs[1].set_ylabel(r"$R$ ($\mu$m)") +axs[1].set_ylim(ymin=0.0, ymax=80.0) +axs[1].grid() + +for dist in dist_list : + t_list = np.array(dic_2_bubbles["QA"][-25325][dist][0][1]) * 1.0e6 + r_list = np.array(dic_2_bubbles["QA"][-25325][dist][0][2]) * 1.0e6 + + axs[1].plot(t_list, r_list, color="blue") + +t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][1]) * 1.0e6 +r_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][2]) * 1.0e6 +axs[1].plot(t_list, r_list, color="blue") + +t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][1][1]) * 1.0e6 +r_list = np.array(dic_2_bubbles["NI"][-25325][15.0][1][2]) * 1.0e6 +axs[1].plot(t_list, r_list, color="magenta") + +axs[1].text(0.5, 5.0, r"$R_{1,0}$ = 2.0 $\mu$m", color="blue") +axs[1].text(0.5, 25.0, r"$R_{2,0}$ = 20.0 $\mu$m", color="magenta") + +axs[1].text(38.0, 75.0, r"$\infty$", color="blue") +axs[1].text(45.0, 75.0, r"20", color="blue") +axs[1].text(50.0, 75.0, r"15", color="blue") +axs[1].text(51.0, 35.0, r"12", color="blue") +axs[1].text(40.0, 10.0, r"11.9", color="blue") +axs[1].text(25.0, 0.5, r"10", color="blue") + +fig.savefig("cavitationonset_varyingdistance.pdf", bbox_inches='tight',pad_inches=0.35) + ######### Cavitation inception with interactions with varying pressure between 2 bubbles ########## nrow = 1 ncol = 2 +fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm))) +plt.subplots_adjust(wspace=0.5*cm, hspace=0.5*cm) + +png_list = [-25325, -27351, -27958.8, -29377] + +axs[0].set_title(r"Incompressible interactions ($\Delta x_{12}$ = 10[$R_{1,0}$ + $R_{2,0}$])") +axs[0].set_xlabel(r"t ($\mu$s)") +axs[0].set_xlim(xmin=0.0, xmax=60.0) +axs[0].set_ylabel(r"$R$ ($\mu$m)") +axs[0].set_ylim(ymin=0.0, ymax=40.0) +axs[0].grid() + +for png in png_list : + t_list = np.array(dic_2_bubbles["IC"][png][10.0][0][1]) * 1.0e6 + r_list = np.array(dic_2_bubbles["IC"][png][10.0][0][2]) * 1.0e6 + + axs[0].plot(t_list, r_list, color="blue") + +axs[0].text(0.5, 3.0, r"$R_{1,0}$ = 2.0 $\mu$m", color="blue") + +axs[0].text(36.0, 37.5, r"-0.29", color="blue") +axs[0].text(45.0, 25.5, r"-0.276", color="blue") +axs[0].text(30.0, 8.0, r"-0.27", color="blue") +axs[0].text(25.0, 1.0, r"-0.25", color="blue") + +png_list = [-25325, -27351, -27958.8, -27654.9, -29377] + +axs[1].set_title(r"Quasi acoustic interactions ($\Delta x_{12}$ = 10[$R_{1,0}$ + $R_{2,0}$])") +axs[1].set_xlabel(r"t ($\mu$s)") +axs[1].set_xlim(xmin=0.0, xmax=60.0) +axs[1].set_ylabel(r"$R$ ($\mu$m)") +axs[1].set_ylim(ymin=0.0, ymax=40.0) +axs[1].grid() + +for png in png_list : + t_list = np.array(dic_2_bubbles["QA"][png][10.0][0][1]) * 1.0e6 + r_list = np.array(dic_2_bubbles["QA"][png][10.0][0][2]) * 1.0e6 + + axs[1].plot(t_list, r_list, color="blue") + +axs[1].text(0.5, 3.0, r"$R_{1,0}$ = 2.0 $\mu$m", color="blue") + +axs[1].text(34.5, 37.5, r"-0.29", color="blue") +axs[1].text(48.5, 37.5, r"-0.276", color="blue") +axs[1].text(54.0, 31.0, r"-0.273", color="blue") +axs[1].text(36.5, 8.0, r"-0.27", color="blue") +axs[1].text(25.0, 1.0, r"-0.25", color="blue") + +fig.savefig("cavitationonset_varyingpressure.pdf", bbox_inches='tight',pad_inches=0.35) + ######### Cavitation inception with monodispersed simple distributions ############################ nrow = 2 -ncol = 2 \ No newline at end of file +ncol = 2 + +fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm)), sharex=True) +plt.subplots_adjust(wspace=0.25*cm, hspace=0.25*cm) + +dic_color = {1 : "black", 2 : "red", 3 : "magenta", 4 : "blue", 8 : "green"} +nbubble_list = [1, 2, 3, 4, 8] +dic_shape = {1 : "single bubble", 2 : "Line of 2 bubbles", 3 : "3 bubbles-regular triangle", 4 : "4 bubbles-regular tetragon", 8 : "8 bubbles-regular hexaedron"} + +for i in range(2) : + for j in range(2) : + axs[i, j].grid() + axs[i, j].set_xlim(xmin=10.0, xmax=60.0) + +axs[0, 0].set_title(r"Incompressible interactions ($p_{ng}$/$p_{0}$ = -0.25, $\Delta x_{12}$ = 20$R_{1,0}$)") +axs[0, 1].set_title(r"Quasi acoustic interactions ($p_{ng}$/$p_{0}$ = -0.25, $\Delta x_{12}$ = 20$R_{1,0}$)") + +axs[1, 0].set_xlabel(r"t ($\mu$s)") +axs[1, 1].set_xlabel(r"t ($\mu$s)") + +axs[0, 0].set_ylabel(r"$R_{1}$ ($\mu$m)") +axs[1, 0].set_ylabel(r"$P_{1, \infty}$/$P_{0}$ (-)") +axs[1, 0].set_ylim(ymin=-0.255, ymax=0.0) +axs[1, 1].set_ylim(ymin=-0.255, ymax=0.0) + +for nbubble in nbubble_list : + t_list = np.array(dic_n_bubbles["IC"][nbubble][0][1]) * 1.0e6 + r_list = np.array(dic_n_bubbles["IC"][nbubble][0][2]) * 1.0e6 + p_list = np.array(dic_n_bubbles["IC"][nbubble][0][3]) / P0 + + axs[0, 0].plot(t_list, r_list, color=dic_color[nbubble], label=dic_shape[nbubble]) + axs[1, 0].plot(t_list, p_list, color=dic_color[nbubble]) + + t_list = np.array(dic_n_bubbles["QA"][nbubble][0][1]) * 1.0e6 + r_list = np.array(dic_n_bubbles["QA"][nbubble][0][2]) * 1.0e6 + p_list = np.array(dic_n_bubbles["QA"][nbubble][0][3]) / P0 + + axs[0, 1].plot(t_list, r_list, color=dic_color[nbubble]) + axs[1, 1].plot(t_list, p_list, color=dic_color[nbubble]) + +axs[0, 0].legend(loc="upper left") + +fig.savefig("cavitationonset_monodispersedclusters.pdf", bbox_inches='tight',pad_inches=0.35) \ No newline at end of file diff --git a/examples/cavitationonset/run_cavitationonset.sh b/examples/cavitationonset/run_cavitationonset.sh index 29059e7..c688f6b 100755 --- a/examples/cavitationonset/run_cavitationonset.sh +++ b/examples/cavitationonset/run_cavitationonset.sh @@ -45,7 +45,7 @@ cd IC/build cd .. ######### Cavitation inception with interactions with varying distance between 2 bubbles ########## -dist_list=(10 11 12 12.05 12.1 15 20) +dist_list=(10 11 12 12.05 12.1 12.5 15 20) for d in "${dist_list[@]}" do ./build/cavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-6 -nbb 2 -cldistrib 0 -clsize $d -inttype 1 @@ -81,7 +81,7 @@ cd QA/build cd .. ######### Cavitation inception with interactions with varying distance between 2 bubbles ########## -dist_list=(10 11 12 12.05 12.1 15 20) +dist_list=(10 11.9 12 15 20) for d in "${dist_list[@]}" do ./build/cavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-6 -nbb 2 -cldistrib 0 -clsize $d -inttype 2 -dt_inter 1.0e-09 @@ -89,7 +89,7 @@ do done ######### Cavitation inception with interactions with varying pressure between 2 bubbles ########## -png_list=(-25325 -26338 -26793.85 -26844.5 -27097.75 -27351 -27958.8 -29377) +png_list=(-25325 -27351 -27958.8 -27654.9 -29377) for png in "${png_list[@]}" do ./build/cavitationonset_apecss -options run.apecss -amp $png -tend 60.0e-6 -nbb 2 -cldistrib 0 -clsize 10 -inttype 2 -dt_inter 1.0e-09 @@ -110,6 +110,10 @@ echo "" echo "Quasi acoustic test cases passed" echo "" +######### Plotting results ########################################################################################################################## + +python3 plot_results.py + ######### Cleaning ################################################################################################################################## cd NI From 66df2aadbee302f6148324406ccbab5ef93a9827 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Thu, 11 Jul 2024 14:36:17 -0400 Subject: [PATCH 027/138] binaryinteraction ; taking into account pressurederivative infinity --- examples/binaryinteraction/run.apecss | 2 +- .../src/binaryinteraction_apecss.c | 26 ++++++++++++------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/examples/binaryinteraction/run.apecss b/examples/binaryinteraction/run.apecss index 97fd792..779d9bc 100644 --- a/examples/binaryinteraction/run.apecss +++ b/examples/binaryinteraction/run.apecss @@ -6,7 +6,7 @@ BUBBLE RPModel KM -Emissions IC 250.0e-6 +Emissions IC 300.0e-6 PressureAmbient 1.0e5 END diff --git a/examples/binaryinteraction/src/binaryinteraction_apecss.c b/examples/binaryinteraction/src/binaryinteraction_apecss.c index 3112ed4..074c9b0 100644 --- a/examples/binaryinteraction/src/binaryinteraction_apecss.c +++ b/examples/binaryinteraction/src/binaryinteraction_apecss.c @@ -175,8 +175,10 @@ int main(int argc, char **args) { Bubbles[i]->Interaction->nBubbles = nBubbles; Bubbles[i]->Interaction->dp_neighbor = 0.0; - Bubbles[i]->Interaction->last_t = 0.0; - Bubbles[i]->Interaction->last_pinfinity = Bubbles[i]->p0; + Bubbles[i]->Interaction->last_t_1 = 0.0; + Bubbles[i]->Interaction->last_t_2 = 0.0; + Bubbles[i]->Interaction->last_p_1 = 0.0; + Bubbles[i]->Interaction->last_p_2 = 0.0; } // Define the size of each bubble @@ -232,7 +234,7 @@ int main(int argc, char **args) for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; + // for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // Update the contribution of the neighbor bubble @@ -241,8 +243,11 @@ int main(int argc, char **args) for (register int i = 0; i < nBubbles; i++) { - Bubbles[i]->Interaction->last_t = Bubbles[i]->t; - Bubbles[i]->Interaction->last_pinfinity = Bubbles[i]->get_pressure_infinity(Bubbles[i]->t, Bubbles[i]); + Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; + Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; + + Bubbles[i]->Interaction->last_t_1 = tSim; + Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; } } @@ -280,14 +285,15 @@ APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_ APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { - // Approximate numerical computation of p_infinity - APECSS_FLOAT delta_t = t - Bubble->Interaction->last_t; - if (delta_t == 0) + // Approximate numerical computation of p_infinity derivative + APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; + APECSS_FLOAT derivative = -Bubble->Excitation->dp * 2.0 * APECSS_PI * Bubble->Excitation->f * APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * t); + if (delta_t > Bubble->dt) { - return 0.0; + return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) / (Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2))); } else { - return (Bubble->get_pressure_infinity(t, Bubble) - Bubble->Interaction->last_pinfinity) / delta_t; + return (derivative); } } \ No newline at end of file From 7ee9c2552debb785fbd5e3a6d110c47d1dfa8481 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Thu, 11 Jul 2024 16:47:49 -0400 Subject: [PATCH 028/138] spherical cluster interactions ; new test case similar to Maeda 2019 work --- .../build/compile.sh | 5 + .../sphericalclusterinteractions/execmpi.sh | 9 + .../sphericalclusterinteractions/run.apecss | 40 ++ .../src/sphericalclusterinteractions_apecss.c | 549 ++++++++++++++++++ 4 files changed, 603 insertions(+) create mode 100755 examples/sphericalclusterinteractions/build/compile.sh create mode 100755 examples/sphericalclusterinteractions/execmpi.sh create mode 100644 examples/sphericalclusterinteractions/run.apecss create mode 100644 examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c diff --git a/examples/sphericalclusterinteractions/build/compile.sh b/examples/sphericalclusterinteractions/build/compile.sh new file mode 100755 index 0000000..863779a --- /dev/null +++ b/examples/sphericalclusterinteractions/build/compile.sh @@ -0,0 +1,5 @@ +#!/bin/bash +rm sphericalclusterinteractions_apecss +cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release +make +rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/sphericalclusterinteractions/execmpi.sh b/examples/sphericalclusterinteractions/execmpi.sh new file mode 100755 index 0000000..ca665f6 --- /dev/null +++ b/examples/sphericalclusterinteractions/execmpi.sh @@ -0,0 +1,9 @@ +cd build +./compile.sh +cd .. +mpiexec -n 15 ./build/sphericalclusterinteractions_apecss -options run.apecss -freq 50.0e03 -amp -2.5e5 -tend 5.0e-07 + +for ((c=0; c<2500; c++)) +do + rm -rf Bubble_$c +done \ No newline at end of file diff --git a/examples/sphericalclusterinteractions/run.apecss b/examples/sphericalclusterinteractions/run.apecss new file mode 100644 index 0000000..41bb8de --- /dev/null +++ b/examples/sphericalclusterinteractions/run.apecss @@ -0,0 +1,40 @@ +######################################################### +# # +# APECSS Options File # +# # +######################################################### + +BUBBLE +RPModel KM +Emissions QA 250.0e-6 +PressureAmbient 1.0e5 +END + +GAS +EoS IG +ReferencePressure 1.0e5 +ReferenceDensity 1.2 +PolytropicExponent 1.4 +END + +LIQUID +ReferencePressure 1.0e5 +ReferenceDensity 1000.0 +ReferenceSoundSpeed 1500.0 +Viscosity 1.002e-3 +END + +INTERFACE +SurfaceTensionCoeff 0.0728 +END + +RESULTS +Bubble +OutputFreqRP 5 +END + +ODESOLVER +tolerance 1.0e-10 +MinTimeStep 1.0e-14 +MaxTimeStep 1.0e-05 +END diff --git a/examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c b/examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c new file mode 100644 index 0000000..5db26d1 --- /dev/null +++ b/examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c @@ -0,0 +1,549 @@ +// This source file is part of APECSS, an open-source software toolbox +// for the computation of pressure-driven bubble dynamics and acoustic +// emissions in spherical symmetry. +// +// Copyright (C) 2022-2024 The APECSS Developers +// +// The APECSS Developers are listed in the README.md file available in +// the GitHub repository at https://github.com/polycfd/apecss. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// ------------------------------------------------------------------- +// APECSS standalone example of acoustically-interacting microbubbles, +// demonstrating a simple parallelization of APECSS. +// ------------------------------------------------------------------- + +#include +#include +#include "apecss.h" + +APECSS_FLOAT rand_range(double min, double max) +{ + double random = (drand48()); + double range = (max - min) * random; + double number = min + range; + + return (APECSS_FLOAT) number; +} + +struct APECSS_Parallel_Cluster +{ + int rank, size; + int nBubbles_local, nBubbles_global; + + int *bubblerank; // max id of bubbles for each rank + APECSS_FLOAT *bubbleglobal_R, *bubbleglobal_x, *bubbleglobal_y, *bubbleglobal_z; // Radius and x,y,z location of all bubbles + APECSS_FLOAT *sumGU_rank; // Contributions from local bubbles to all bubbles +}; + +// Declaration of additional case-dependent functions +APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); + +int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubble[], struct APECSS_Parallel_Cluster *RankInfo); +int parallel_interactions_proper_cutoffdistance(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo); + +int main(int argc, char **args) +{ + /* Initialize MPI */ + int mpi_rank, mpi_size; + MPI_Init(&argc, &args); + MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); + MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); + + char OptionsDir[APECSS_STRINGLENGTH]; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Set the case-dependent simulation parameters + const int nBubbles = 1500; // Number of bubbles + APECSS_FLOAT bubble_bubble_dist = 100.0e-6; // Bubble-bubble minimal distance + APECSS_FLOAT cluster_radius = 2.5e-3; // Spherical cluster radius + + // Interbubble time-step, defining the frequency with which the neighbor influence is updated + APECSS_FLOAT dt_interbubble = 1.0e-8; + + // Initialize the simulation parameters given by the execution command + double tEnd = 0.0; + double fa = 0.0; + double pa = 0.0; + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + apecss_infoscreen(); + + /* Read commandline options */ + sprintf(OptionsDir, "./run.apecss"); // This is the default + int j = 1; // First argument is the call to the executable + while (j < argc) + { + if (strcmp("-options", args[j]) == 0) + { + sprintf(OptionsDir, "%s", args[j + 1]); + j += 2; + } + else if (strcmp("-tend", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &tEnd); + j += 2; + } + else if (strcmp("-freq", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &fa); + j += 2; + } + else if (strcmp("-amp", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &pa); + j += 2; + } + else if (strcmp("-h", args[j]) == 0) + { + apecss_helpscreen(); + } + else + { + char str[APECSS_STRINGLENGTH_SPRINTF]; + sprintf(str, "Unknown command line options: %s", args[j]); + apecss_erroronscreen(1, str); + ++j; + } + } + + /* Allocate structure for parallel data */ + struct APECSS_Parallel_Cluster *RankInfo = (struct APECSS_Parallel_Cluster *) malloc(sizeof(struct APECSS_Parallel_Cluster)); + RankInfo->rank = mpi_rank; + RankInfo->size = mpi_size; + + /* Determine the number of bubbles per rank */ + int max_per_rank = ceil((double) nBubbles / (double) mpi_size); + RankInfo->nBubbles_local = APECSS_MAX(0, APECSS_MIN(max_per_rank, nBubbles - mpi_rank * max_per_rank)); + + /* Share the parallel distribution of bubbles with all ranks */ + RankInfo->bubblerank = malloc((RankInfo->size + 1) * sizeof(int)); + + RankInfo->nBubbles_global = 0; + RankInfo->bubblerank[0] = 0; + for (int r = 0; r < RankInfo->size; r++) + { + int temp = RankInfo->nBubbles_local; + MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); + RankInfo->bubblerank[r + 1] = RankInfo->bubblerank[r] + temp; + RankInfo->nBubbles_global += temp; + } + + /* Allocate and initialize Bubble structure */ + struct APECSS_Bubble *Bubbles[RankInfo->nBubbles_local]; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(sizeof(struct APECSS_Bubble)); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_initializestruct(Bubbles[i]); + + /* Set default options and read the options for the bubble */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); + + /* Allocate the structures for the fluid properties and ODE solver parameters */ + struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); + struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); + struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); + struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); + + /* Set the default options for the fluid properties and solver parameters */ + apecss_gas_setdefaultoptions(Gas); + apecss_liquid_setdefaultoptions(Liquid); + apecss_interface_setdefaultoptions(Interface); + apecss_odesolver_setdefaultoptions(NumericsODE); + + /* Read the options file for the fluid properties and solver parameters */ + apecss_gas_readoptions(Gas, OptionsDir); + apecss_liquid_readoptions(Liquid, OptionsDir); + apecss_interface_readoptions(Interface, OptionsDir); + apecss_odesolver_readoptions(NumericsODE, OptionsDir); + + /* Associate the bubble with the relevant fluid properties and solver parameters */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->Gas = Gas; + Bubbles[i]->Liquid = Liquid; + Bubbles[i]->Interface = Interface; + Bubbles[i]->NumericsODE = NumericsODE; + } + + /* Allocate and set the excitation parameters */ + struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); + Excitation->type = APECSS_EXCITATION_SIN; + Excitation->f = (APECSS_FLOAT) fa; + Excitation->dp = (APECSS_FLOAT) pa; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Excitation = Excitation; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Create individual folders for the results of each bubble + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + if (Bubbles[i]->Results != NULL) + { + sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", RankInfo->bubblerank[RankInfo->rank] + i); + struct stat st = {0}; + if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Process all options */ + apecss_gas_processoptions(Gas); + apecss_liquid_processoptions(Liquid); + apecss_interface_processoptions(Interface); + apecss_odesolver_processoptions(NumericsODE); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_processoptions(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Use the revised pressure at infinity, including neighbor contributions + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->get_pressure_infinity = parallel_interactions_bubble_pressure_infinity; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + Bubbles[i]->get_pressurederivative_infinity = parallel_interactions_bubble_pressurederivative_infinity; + + // Allocate interaction structure + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); + Bubbles[i]->Interaction->dp_neighbor = 0.0; + Bubbles[i]->Interaction->last_t_1 = 0.0; + Bubbles[i]->Interaction->last_t_2 = 0.0; + Bubbles[i]->Interaction->last_p_1 = 0.0; + Bubbles[i]->Interaction->last_p_2 = 0.0; + } + + // Update interaction structure + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->nBubbles = nBubbles; // Not used? + + // Define the size of each bubble + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->R0 = 10.0e-6; + Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; + } + + // Define center location for each bubble + APECSS_FLOAT Bubble_Center[nBubbles][3]; + + for (register int i = 0; i < nBubbles; i++) + { + if (i == 0) + { + Bubble_Center[i][0] = 0.0; + Bubble_Center[i][1] = 0.0; + Bubble_Center[i][2] = 0.0; + } + else + { + APECSS_FLOAT x = rand_range((double) -cluster_radius, (double) cluster_radius); + APECSS_FLOAT y = rand_range((double) -cluster_radius, (double) cluster_radius); + APECSS_FLOAT z = rand_range((double) -cluster_radius, (double) cluster_radius); + + APECSS_FLOAT radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); + + while (radius > cluster_radius) + { + x = rand_range((double) -cluster_radius, (double) cluster_radius); + y = rand_range((double) -cluster_radius, (double) cluster_radius); + z = rand_range((double) -cluster_radius, (double) cluster_radius); + + radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); + } + + Bubble_Center[i][0] = x; + Bubble_Center[i][1] = y; + Bubble_Center[i][2] = z; + + for (register int k = 0; k < i; k++) + { + APECSS_FLOAT bubbledist = APECSS_SQRT(APECSS_POW2(Bubble_Center[i][0] - Bubble_Center[k][0]) + APECSS_POW2(Bubble_Center[i][1] - Bubble_Center[k][1]) + + APECSS_POW2(Bubble_Center[i][2] - Bubble_Center[k][2])); + if (bubbledist < bubble_bubble_dist) + { + i--; + break; + } + } + } + } + + for (register int n = 0; n < RankInfo->nBubbles_local; n++) + { + Bubbles[n]->Interaction->location[0] = Bubble_Center[RankInfo->bubblerank[RankInfo->rank] + n][0]; + Bubbles[n]->Interaction->location[1] = Bubble_Center[RankInfo->bubblerank[RankInfo->rank] + n][1]; + Bubbles[n]->Interaction->location[2] = Bubble_Center[RankInfo->bubblerank[RankInfo->rank] + n][2]; + } + + // Share the location of each bubble with all ranks + + RankInfo->bubbleglobal_R = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + RankInfo->bubbleglobal_x = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + RankInfo->bubbleglobal_y = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + RankInfo->bubbleglobal_z = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + + for (int r = 0; r < RankInfo->size; r++) + { + int temp = RankInfo->nBubbles_local; + MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); + + APECSS_FLOAT temp_array[4]; + + for (int i = 0; i < temp; i++) + { + if (r == RankInfo->rank) + { + temp_array[0] = Bubbles[i]->Interaction->location[0]; + temp_array[1] = Bubbles[i]->Interaction->location[1]; + temp_array[2] = Bubbles[i]->Interaction->location[2]; + temp_array[3] = Bubbles[i]->R; + } + + MPI_Bcast(temp_array, 4, MPI_DOUBLE, r, MPI_COMM_WORLD); + + RankInfo->bubbleglobal_x[RankInfo->bubblerank[r] + i] = temp_array[0]; + RankInfo->bubbleglobal_y[RankInfo->bubblerank[r] + i] = temp_array[1]; + RankInfo->bubbleglobal_z[RankInfo->bubblerank[r] + i] = temp_array[2]; + RankInfo->bubbleglobal_R[RankInfo->bubblerank[r] + i] = temp_array[3]; + } + } + + // Update cut off distance for each bubble + parallel_interactions_proper_cutoffdistance(Bubbles, RankInfo); + + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + clock_t starttimebubble = clock(); + APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->tStart = tSim; + Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; + Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step + } + + /* Initialize the bubble based on the selected options */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_initialize(Bubbles[i]); + + /* Initialize */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_initialize(Bubbles[i]); + + // Allocate the pressure contribution array + RankInfo->sumGU_rank = malloc(2 * RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + + /* Solve the bubble dynamics */ + while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered + { + APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); + tSim += dtSim; + + // To follow computations progress + if (RankInfo->rank == 0) + { + printf("%e\n", tSim); + } + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); + + // for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Update the contribution of the neighbor bubble + parallel_interactions_quasi_acoustic(Bubbles, RankInfo); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; + Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; + + Bubbles[i]->Interaction->last_t_1 = tSim; + Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; + } + } + + /* Finalize the simulation*/ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_finalize(Bubbles[i]); + + char str[APECSS_STRINGLENGTH_SPRINTF]; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", RankInfo->bubblerank[RankInfo->rank] + i, Bubbles[i]->dtNumber, + Bubbles[i]->nSubIter, (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); + apecss_writeonscreen(str); + } + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); + + /* Make sure all allocated memory is freed */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_freestruct(Bubbles[i]); + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) free(Bubbles[i]); + free(Gas); + free(Liquid); + free(Interface); + free(NumericsODE); + free(Excitation); + + free(RankInfo->bubblerank); + RankInfo->bubblerank = NULL; + free(RankInfo->bubbleglobal_R); + RankInfo->bubbleglobal_R = NULL; + free(RankInfo->bubbleglobal_x); + RankInfo->bubbleglobal_x = NULL; + free(RankInfo->bubbleglobal_y); + RankInfo->bubbleglobal_y = NULL; + free(RankInfo->bubbleglobal_z); + RankInfo->bubbleglobal_z = NULL; + free(RankInfo->sumGU_rank); + RankInfo->sumGU_rank = NULL; + free(RankInfo); + + MPI_Finalize(); + + return (0); +} + +APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + return (Bubble->p0 - + Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * (t - Bubble->Interaction->location[0] / Bubble->Liquid->cref)) + + Bubble->Interaction->dp_neighbor); +} + +APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + APECSS_FLOAT derivative = -2.0 * APECSS_PI * Bubble->Excitation->f * Bubble->Excitation->dp * + APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * (t - Bubble->Interaction->location[0] / Bubble->Liquid->cref)); + + APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; + if (delta_t > Bubble->dt) + { + return (derivative + (Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) / delta_t); + } + else + { + return (derivative); + } +} + +int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo) +{ + // All bubbles are supposed to be in the same liquid + struct APECSS_Liquid *Liquid = Bubbles[0]->Liquid; + + // Update bubble radii info + APECSS_FLOAT *tempR = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + for (register int j = 0; j < RankInfo->nBubbles_global; j++) tempR[j] = 0.0; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) tempR[RankInfo->bubblerank[RankInfo->rank] + i] = Bubbles[i]->R; + MPI_Allreduce(tempR, RankInfo->bubbleglobal_R, RankInfo->nBubbles_global, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + free(tempR); + + // Reset pressure contributions of the neighours + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; + + // Locally compute the contribution to each bubble + for (register int j = 0; j < RankInfo->nBubbles_global; j++) + { + APECSS_FLOAT x_j = RankInfo->bubbleglobal_x[j]; + APECSS_FLOAT y_j = RankInfo->bubbleglobal_y[j]; + APECSS_FLOAT z_j = RankInfo->bubbleglobal_z[j]; + + RankInfo->sumGU_rank[j] = 0.0; + RankInfo->sumGU_rank[j + RankInfo->nBubbles_global] = 0.0; + + double R_j = RankInfo->bubbleglobal_R[j]; + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + if (j != RankInfo->bubblerank[RankInfo->rank] + i) + { + APECSS_FLOAT sumU_bubble = 0.0; + APECSS_FLOAT sumG_bubble = 0.0; + int nodecount_bubble = 0; + + APECSS_FLOAT x_i = Bubbles[i]->Interaction->location[0]; + APECSS_FLOAT y_i = Bubbles[i]->Interaction->location[1]; + APECSS_FLOAT z_i = Bubbles[i]->Interaction->location[2]; + + APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); + + // The loop over the emission nodes begins with the most far away from the emitting bubble + struct APECSS_EmissionNode *Current = Bubbles[i]->Emissions->LastNode; + while (Current != NULL) + { + if (Current->r < interbubble_dist - R_j) + { + // The following emission nodes have not yet reached the bubble of interest + Current = NULL; + } + else if (Current->r > interbubble_dist + R_j) + { + // The bubble of interest is still not reached + Current = Current->backward; + } + else + { + // The current emission node is located inside the bubble of interest + APECSS_FLOAT gr = Current->g / Current->r; + sumU_bubble += (Current->f / APECSS_POW2(Current->r)) + gr / Liquid->cref; + sumG_bubble += gr; + nodecount_bubble++; + Current = Current->backward; + } + } + + if (nodecount_bubble) + { + APECSS_FLOAT inv_nodecount = 1.0 / (APECSS_FLOAT) nodecount_bubble; + RankInfo->sumGU_rank[j] += sumG_bubble * inv_nodecount; + RankInfo->sumGU_rank[j + RankInfo->nBubbles_global] += sumU_bubble * inv_nodecount; + } + } + } + } + + APECSS_FLOAT *sumGU_all = malloc(2 * RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + MPI_Allreduce(RankInfo->sumGU_rank, sumGU_all, 2 * RankInfo->nBubbles_global, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + + // Compute the total pressure contributions of the neighbours for all local bubbles + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->Interaction->dp_neighbor = + Liquid->rhoref * (sumGU_all[RankInfo->bubblerank[RankInfo->rank] + i] - + 0.5 * APECSS_POW2(sumGU_all[RankInfo->nBubbles_global + RankInfo->bubblerank[RankInfo->rank] + i])); + } + + free(sumGU_all); + + return (0); +} + +int parallel_interactions_proper_cutoffdistance(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo) +{ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + APECSS_FLOAT x_i = Bubbles[i]->Interaction->location[0]; + APECSS_FLOAT y_i = Bubbles[i]->Interaction->location[1]; + APECSS_FLOAT z_i = Bubbles[i]->Interaction->location[2]; + APECSS_FLOAT dist = 0.0; + + for (register int j = 0; j < RankInfo->nBubbles_global; j++) + { + APECSS_FLOAT x_j = RankInfo->bubbleglobal_x[j]; + APECSS_FLOAT y_j = RankInfo->bubbleglobal_y[j]; + APECSS_FLOAT z_j = RankInfo->bubbleglobal_z[j]; + + APECSS_FLOAT dist_ij = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); + + if (dist_ij > dist) + { + dist = dist_ij; + } + } + if (Bubbles[i]->Emissions != NULL) Bubbles[i]->Emissions->CutOffDistance = 1.25 * dist; + } + return (0); +} \ No newline at end of file From 83054635e3170e96beb92a1651bef0f37c9d3b95 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Thu, 11 Jul 2024 17:06:30 -0400 Subject: [PATCH 029/138] spherical cluster interactions ; recovering bubble locations --- examples/sphericalclusterinteractions/execmpi.sh | 1 + examples/sphericalclusterinteractions/run.apecss | 1 - .../src/sphericalclusterinteractions_apecss.c | 13 +++++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/examples/sphericalclusterinteractions/execmpi.sh b/examples/sphericalclusterinteractions/execmpi.sh index ca665f6..a159a5d 100755 --- a/examples/sphericalclusterinteractions/execmpi.sh +++ b/examples/sphericalclusterinteractions/execmpi.sh @@ -3,6 +3,7 @@ cd build cd .. mpiexec -n 15 ./build/sphericalclusterinteractions_apecss -options run.apecss -freq 50.0e03 -amp -2.5e5 -tend 5.0e-07 +rm -rf bubble_loc.txt for ((c=0; c<2500; c++)) do rm -rf Bubble_$c diff --git a/examples/sphericalclusterinteractions/run.apecss b/examples/sphericalclusterinteractions/run.apecss index 41bb8de..f341619 100644 --- a/examples/sphericalclusterinteractions/run.apecss +++ b/examples/sphericalclusterinteractions/run.apecss @@ -30,7 +30,6 @@ END RESULTS Bubble -OutputFreqRP 5 END ODESOLVER diff --git a/examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c b/examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c index 5db26d1..144a1e1 100644 --- a/examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c +++ b/examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c @@ -311,6 +311,19 @@ int main(int argc, char **args) // Update cut off distance for each bubble parallel_interactions_proper_cutoffdistance(Bubbles, RankInfo); + // File to retrieve the locations of bubble centers + if (RankInfo->rank == 0) + { + FILE *file_loc; + file_loc = fopen("bubble_loc.txt", "w"); + fprintf(file_loc, "#number x(m) y(m) z(m)\n"); + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_loc, "%d %e %e %e\n", i, Bubble_Center[i][0], Bubble_Center[i][1], Bubble_Center[i][2]); + } + fclose(file_loc); + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< clock_t starttimebubble = clock(); From 4e559ea7af6fb3f1598cc3bf12b5626e8cb5a652 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 16 Jul 2024 09:51:16 -0400 Subject: [PATCH 030/138] sphericalclusterinteractions ; python file to plot results --- .../plot_results.py | 380 ++++++++++++++++++ .../src/sphericalclusterinteractions_apecss.c | 2 +- 2 files changed, 381 insertions(+), 1 deletion(-) create mode 100644 examples/sphericalclusterinteractions/plot_results.py diff --git a/examples/sphericalclusterinteractions/plot_results.py b/examples/sphericalclusterinteractions/plot_results.py new file mode 100644 index 0000000..49484d0 --- /dev/null +++ b/examples/sphericalclusterinteractions/plot_results.py @@ -0,0 +1,380 @@ +import os +import numpy as np +import matplotlib.pyplot as plt +import matplotlib.colors as mcolors +from math import sqrt +from scipy.interpolate import interp1d + +plt.rcParams['font.family']='serif' +plt.rcParams['font.serif']=['Times New Roman'] + plt.rcParams['font.serif'] +plt.rcParams['mathtext.fontset']='stix' +plt.rcParams['font.size']=10 + +color_names = list(mcolors.XKCD_COLORS) + +cm = 1/2.54 + +# The goal of this scrip is to plot a 3D visualization of the computed cluster +# Later, the interest is to vizualise the temporal evolution of the cluster + +######### Step 0 : Retrieving initial data ########################################################################################################## + +# Count the number of bubbles simulated +count = 0 +listdir = os.listdir() +for f in listdir: + if "Bubble_" in f and os.path.isdir(f): + count += 1 + +# Retrieve data for each bubble +Bubbles = [] +for i in range(count): + path = os.path.join(os.getcwd(), "Bubble_{}".format(i)) + for file in os.listdir(path): + if "KellerMiksis" in file : + Bubbles.append(np.genfromtxt("Bubble_{}/".format(i) + file, delimiter=" ")) + +# Retrieve location data for each bubble and determine cluster radius +file_loc = open("bubble_loc.txt","r") +loc_lines = file_loc.readlines() + +Bubbles_loc = [] +R_c = 0 +for i in range(count): + line = loc_lines[i+1].split(" ") + Bubbles_loc.append([float(line[0]), float(line[1]), float(line[2])]) + R_b = sqrt((float(line[0])**2)+ (float(line[1])**2)+ (float(line[2])**2)) + if R_c < R_b : + R_c = R_b + +file_loc.close() + +######### Step 1 : Functions ######################################################################################################################## + +### signal sampling (for signal with non uniform timestep) ######################################## +# return two lists : t_signal and y_signal (with uniform timestep) +def _sample(t_signal_nuni, y_signal_nuni, delta_t_uni_exp, subref) : + # t_signal_nuni (list/1D array) represents computation time + # y_signal_nuni (list/1D array) represents the function y(t) we need to sample + # delta_t_uni_exp (float/int) is the power wanted for the time step of the uniform signal + # subref (bool) indicates if you want to refine the uniform signal obtained + + # Need to check the size of both y_signal_nuni and t_signal_nuni + if len(t_signal_nuni) != len(y_signal_nuni) : raise NameError("No matching size for sampling") + + delta_t_uni = 10.0**(-delta_t_uni_exp) + N_points_signal_nuni = len(t_signal_nuni) + + t_start = t_signal_nuni[0] + t_end = t_signal_nuni[-1] + TS = t_end - t_start + N_points_signal_uni = int(TS/delta_t_uni + 1) + + t_signal_uni = np.linspace(t_start, t_end, N_points_signal_uni) + t_signal_nuni_round = [0]*N_points_signal_nuni + + for i in range(0, N_points_signal_nuni): + t_signal_nuni_round[i] = round(t_signal_nuni[i], delta_t_uni_exp) + + y_signal_nuni_round_fw = [0]*N_points_signal_nuni + amp = -1e100 + for i in range(1, N_points_signal_nuni): + if y_signal_nuni[i] >= 0: + if t_signal_nuni_round[i] == t_signal_nuni_round[i-1]: + if y_signal_nuni[i] > amp: + amp = y_signal_nuni[i] + y_signal_nuni_round_fw[i] = amp + else: + amp = y_signal_nuni[i] + y_signal_nuni_round_fw[i] = amp + amp = -1e100 + + y_signal_nuni_round_bw = [0]*N_points_signal_nuni + amp = -1e100 + for i in range(N_points_signal_nuni-2,-1, -1): + if y_signal_nuni[i] >= 0: + if t_signal_nuni_round[i] == t_signal_nuni_round[i+1]: + if y_signal_nuni[i] > amp: + amp = y_signal_nuni[i] + y_signal_nuni_round_bw[i] = amp + else: + amp = y_signal_nuni[i] + y_signal_nuni_round_bw[i] = amp + amp = -1e100 + + y_signal_nuni_round = [0]*N_points_signal_nuni + for i in range(0, N_points_signal_nuni): + y_signal_nuni_round[i] = max(y_signal_nuni_round_fw[i], y_signal_nuni_round_bw[i]) + + buff = [y_signal_nuni_round[0]] + for i in range(1, N_points_signal_nuni): + if t_signal_nuni_round[i] == t_signal_nuni_round[i-1]: + buff.append(y_signal_nuni_round[i]) + else: + maxBuff = max(buff) + for j in range(i-len(buff),i): + y_signal_nuni_round[j] = maxBuff + buff = [y_signal_nuni_round[i]] + + i = 1 + while i < N_points_signal_nuni: + if i == len(t_signal_nuni_round) - 1: + break + if t_signal_nuni_round[i] == t_signal_nuni_round[i-1]: + t_signal_nuni_round.pop(i) + y_signal_nuni_round.pop(i) + i -= 1 + i += 1 + + fint = interp1d(t_signal_nuni_round, y_signal_nuni_round, kind='nearest') + y_signal_uni = fint(t_signal_uni) + + t_signal = t_signal_uni + y_signal = y_signal_uni + + if (subref == 'true'): + ref_factor = 10 + N_points_signal_ref = (N_points_signal_uni - 1)*ref_factor + 1 + + t_signal_uni_ref = np.linspace(0.0, TS, N_points_signal_ref) + y_signal_uni_ref = [] + for i in range(1, N_points_signal_uni): + t_ref = 0.0 + delta_t = t_signal_uni[i] - t_signal_uni[i-1] + y = y_signal_uni[i] + y_old = y_signal_uni[i-1] + for j in range(0, ref_factor): + t_ref = delta_t/float(ref_factor)*float(j) + y_ref = 0.5*((y_old-y)*np.cos(np.pi/delta_t*t_ref) + y + y_old) + y_signal_uni_ref.append(y_ref) + y_signal_uni_ref.append(y_signal_uni[-1]) + t_signal = t_signal_uni_ref + y_signal = y_signal_uni_ref + + return t_signal, y_signal + +def plot_cluster(ax, Bubbles, Bubbles_loc, t=0, figtitle ="Bubble cluster 3D visualisation",grid="True", show="False", legend="False", radius_vis="True") : + # # fig (figure) is a figure object where to plot the cluster + # ax is the ax where you want to plot the 3D cluster + # Bubbles is a list containing all data gathered by APECSS on every bubble computed + # Bubbles_loc is a list containing the center location of each bubble + # t represents the time at which the cluster should be displayed + # figtitle (str) is the title of the figure + # grid (bool) indicates if grid shall be displayed or not + # show (bool) indicates if the plot should be shown or not (high cost for a big cluster) + # legend (bool) indicates if the legend should be displayed or not + # radius_vis indicates if the displayed radius should be different than the true radius (to properly see even small bubbles) + # ax = fig.add_subplot(projection='3d') + + u = np.linspace(0, 2*np.pi, 100) + v = np.linspace(0, np.pi, 100) + + dic_color = {} + j = 0 + + max_l = np.max([np.max(np.array(Bubbles_loc)[:, 0]), np.max(np.array(Bubbles_loc)[:, 1]), np.max(np.array(Bubbles_loc)[:, 2])])*1e6 + + time_index_list = [0 for i in range(count)] + if t > 0 : + for i in range(count) : + time_list = Bubbles[i][:, 1] + index = 0 + while time_list[index] < t and index < len(time_list) : + index += 1 + time_index_list[i] = index + + for i in range(count) : + r = Bubbles[i][:, 3][0]*1e6 + if r not in list(dic_color.keys()) : + dic_color[r] = [1, color_names[j], "", 0, 0] + j += 1 + else : + dic_color[r][0] += 1 + + sorted_radius = sorted(list(dic_color.keys())) + + for j in range(len(sorted_radius)) : + key = sorted_radius[j] + dic_color[key][2] = r"$R_{0}=$" + "{:.2f}".format(key) + r" $\mu$m" + " ({})".format(dic_color[key][0]) + if 0.1 * max_l < key < max_l : dic_color[key][4] = key + else : dic_color[key][4] = max_l / (7.5 * (len(sorted_radius) - j)) + + radius_vis_list = [] + for i in range(count) : + if t == 0 : + r = Bubbles[i][:, 3][0]*1e6 + radius_vis_list.append(r) + else : + r = Bubbles[i][:, 3][time_index_list[i]]*1e6 + radius_vis_list.append(r) + + x_b, y_b, z_b = [], [], [] + for i in range(count): + r = Bubbles[i][:, 3][0]*1e6 + + x_b.append(Bubbles_loc[i][0]*1e6) + y_b.append(Bubbles_loc[i][1]*1e6) + z_b.append(Bubbles_loc[i][2]*1e6) + + if (radius_vis == "True") : r_visu = dic_color[r][4] + else : r_visu = r + + r_visu = radius_vis_list[i] + + x = r_visu * np.outer(np.cos(u), np.sin(v)) + x_b[-1] + y = r_visu * np.outer(np.sin(u), np.sin(v)) + y_b[-1] + z = r_visu * np.outer(np.ones(np.size(u)), np.cos(v)) + z_b[-1] + + # Display bubbles with colors depending on their location in the cluster + interval_size = 0.20e-03 + cluster_radius = 2.5e-03 + color = "grey" + + radius_center = sqrt(Bubbles_loc[i][0]**2 + Bubbles_loc[i][1]**2 + Bubbles_loc[i][2]**2) + if radius_center < interval_size : + color = "blue" + elif radius_center > cluster_radius - interval_size : + color = "black" + elif 0.5 * (cluster_radius - interval_size) < radius_center < 0.5 * (cluster_radius + interval_size) : + color = "red" + + if dic_color[r][3] == 0 : + c = ax.plot_surface(x, y, z, rstride=5, cstride=5, color=color, label=dic_color[r][2]) + dic_color[r][3] = 1 + else : + c = ax.plot_surface(x, y, z, rstride=5, cstride=5, color=color) + + c._facecolors2d=c._facecolor3d + c._edgecolors2d=c._edgecolor3d + + if figtitle != "" : ax.set_title(figtitle) + ax.set_xlabel(r"$x$ [$\mu$m]") + ax.set_ylabel(r"$y$ [$\mu$m]") + ax.set_zlabel(r"$z$ [$\mu$m]") + if legend != "False" : ax.legend() + + if grid : plt.grid() + if show == "True" : plt.show() + +def savefig(fig, filename="Cluster", format="pdf", path=None) : + # fig is a figure object you want to save + # filename (str) is the future filename + # format (str) is the format in which you want to save the figure (pdf by default) + # path (str) is the absolute path in which you want to store the figure + if path == None : savepath = "" + elif os.path.isdir(path) : savepath = path + else : savepath = "" + + fig.savefig(os.path.join(savepath, filename + "." + format), bbox_inches='tight',pad_inches=0.35) + +######### Step 2 : Plot / Savefig ################################################################################################################### + +## Radii evolution depending on the location in the cluster ######################################################################################## +dic_radii = {0.0 : [], 0.5 : [], 1.0 : []} +interval_size = 0.20e-03 + +cluster_radius = 2.5e-03 +fa = 50e03 + +max_radius_to_center = 0.0 + +for i in range(count) : + radius_to_center = sqrt(Bubbles_loc[i][0]**2 + Bubbles_loc[i][1]**2 + Bubbles_loc[i][2]**2) + if radius_to_center < 0.0 * cluster_radius + interval_size : + dic_radii[0.0].append(i) + elif 0.5 * (cluster_radius - interval_size) < radius_to_center < 0.5 * (cluster_radius + interval_size) : + dic_radii[0.5].append(i) + elif 1.0 * cluster_radius - interval_size < radius_to_center : + dic_radii[1.0].append(i) + + if radius_to_center > max_radius_to_center : + max_radius_to_center = radius_to_center + +print(dic_radii) + +dic_color_key = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} +dic_style_key = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} + +fig = plt.figure(figsize=(20*cm, 15*cm)) +ax = fig.add_subplot(1, 1, 1) +ax.set_xlabel(r"$t^{*}$") +ax.set_ylabel(r"$/R_{0}$") +ax.set_title("Spherical cluster with " + r"$N=$" + "{} bubbles".format(count)) +ax.grid() + +dic_radius_evolution = {1.0 : [], 0.5 : [], 0.0 : []} + +for k in list(dic_radii.keys()) : + index_list = dic_radii[k] + for i in range(len(index_list)) : + index = index_list[i] + t_uni, r_uni = _sample(Bubbles[index][:, 1], Bubbles[index][:, 3], 8, False) + if i == 0 : + avg_radii = np.array(r_uni) + else : + avg_radii = avg_radii + np.array(r_uni) + if i == len(index_list) - 1 : + dic_radius_evolution[k].append(np.array(t_uni)) + dic_radius_evolution[k].append(avg_radii / len(index_list)) + + +# for k in list(dic_radii.keys()) : +# index_list = dic_radii[k] +# if len(index_list) > 1 : +# for i in index_list[1:] : +# ax.plot(Bubbles[i][:, 1]*fa, Bubbles[i][:, 3]/Bubbles[i][:, 3][0], linestyle=dic_style_key[k], color=dic_color_key[k], linewidth=1.5) +# ax.plot(Bubbles[index_list[0]][:, 1]*fa, Bubbles[index_list[0]][:, 3]/Bubbles[i][:, 3][0], linestyle=dic_style_key[k], color=dic_color_key[k], linewidth=1.5, label=r"$r/R_{c} \approx$"+"{:.1f}".format(k)) +# else : +# for i in index_list : +# ax.plot(Bubbles[i][:, 1]*fa, Bubbles[i][:, 3]/Bubbles[i][:, 3][0], linestyle=dic_style_key[k], color=dic_color_key[k], linewidth=1.5, label=r"$r/R_{c} \approx$"+"{:.1f}".format(k)) + +for k in list(dic_radius_evolution.keys()) : + ax.plot(dic_radius_evolution[k][0]*fa, dic_radius_evolution[k][1]/dic_radius_evolution[k][1][0], linestyle=dic_style_key[k], color=dic_color_key[k], linewidth=1.5, label=r"$r/R_{c} \approx$"+"{:.1f}".format(k)) + +ax.legend(loc="upper right") +savefig(fig, filename="sphericalclusterinteractions_radiievolution") + +## Cluster evolution vizualisation ################################################################################################################## +plt.rcParams['font.size']=15 + +fig = plt.figure(figsize=(4*15*cm,15*cm)) +plt.subplots_adjust(wspace=0, hspace=0) + +t_star = 0 +ax = fig.add_subplot(1, 4, 1, projection='3d') +plot_cluster(ax, Bubbles, Bubbles_loc, t=t_star/fa, figtitle="", grid="False", radius_vis="False") +ax.view_init(elev=90, azim=-90) +ax.set_aspect('equal') +ax.set_box_aspect(None, zoom=1.5) +ax.set_axis_off() +ax.set_title(r"$t^{*}$ = " + "{:.1f}".format(t_star)) + +t_star = 0.8 +ax = fig.add_subplot(1, 4, 2, projection='3d') +plot_cluster(ax, Bubbles, Bubbles_loc, t=t_star/fa, figtitle="", grid="False", radius_vis="False") +ax.view_init(elev=90, azim=-90) +ax.set_aspect('equal') +ax.set_box_aspect(None, zoom=1.5) +ax.set_axis_off() +ax.set_title(r"$t^{*}$ = " + "{:.1f}".format(t_star)) + +t_star = 1.0 +ax = fig.add_subplot(1, 4, 3, projection='3d') +plot_cluster(ax, Bubbles, Bubbles_loc, t=t_star/fa, figtitle="", grid="False", radius_vis="False") +ax.view_init(elev=90, azim=-90) +ax.set_aspect('equal') +ax.set_box_aspect(None, zoom=1.5) +ax.set_axis_off() +ax.set_title(r"$t^{*}$ = " + "{:.1f}".format(t_star)) + +t_star = 1.2 +ax = fig.add_subplot(1, 4, 4, projection='3d') +plot_cluster(ax, Bubbles, Bubbles_loc, t=t_star/fa, figtitle="", grid="False", radius_vis="False") +ax.view_init(elev=90, azim=-90) +ax.set_aspect('equal') +ax.set_box_aspect(None, zoom=1.5) +ax.set_axis_off() +ax.set_title(r"$t^{*}$ = " + "{:.1f}".format(t_star)) + +# plot_cluster(fig, Bubbles, Bubbles_loc) +savefig(fig, filename="sphericalclusterinteractions_clusterevolution", format="png") \ No newline at end of file diff --git a/examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c b/examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c index 144a1e1..d4c6bd5 100644 --- a/examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c +++ b/examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c @@ -58,7 +58,7 @@ int main(int argc, char **args) // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // Set the case-dependent simulation parameters - const int nBubbles = 1500; // Number of bubbles + const int nBubbles = 2500; // Number of bubbles APECSS_FLOAT bubble_bubble_dist = 100.0e-6; // Bubble-bubble minimal distance APECSS_FLOAT cluster_radius = 2.5e-3; // Spherical cluster radius From 8802556957bf74e0a461cb930223ac0bd4f36add Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 16 Jul 2024 09:51:55 -0400 Subject: [PATCH 031/138] spherical cluster cavitation onset ; working folder --- .../build/compile.sh | 5 + .../execmpi.sh | 10 + .../run.apecss | 38 ++ .../sphericalclustercavitationonset_apecss.c | 626 ++++++++++++++++++ 4 files changed, 679 insertions(+) create mode 100755 examples/sphericalclustercavitationonset/build/compile.sh create mode 100755 examples/sphericalclustercavitationonset/execmpi.sh create mode 100644 examples/sphericalclustercavitationonset/run.apecss create mode 100644 examples/sphericalclustercavitationonset/src/sphericalclustercavitationonset_apecss.c diff --git a/examples/sphericalclustercavitationonset/build/compile.sh b/examples/sphericalclustercavitationonset/build/compile.sh new file mode 100755 index 0000000..33147c8 --- /dev/null +++ b/examples/sphericalclustercavitationonset/build/compile.sh @@ -0,0 +1,5 @@ +#!/bin/bash +rm sphericalclustercavitationonset_apecss +cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release +make +rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/execmpi.sh b/examples/sphericalclustercavitationonset/execmpi.sh new file mode 100755 index 0000000..969f5c1 --- /dev/null +++ b/examples/sphericalclustercavitationonset/execmpi.sh @@ -0,0 +1,10 @@ +cd build +./compile.sh +cd .. +mpiexec -n 15 ./build/sphericalclustercavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-06 + +# rm -rf bubble_loc.txt +# for ((c=0; c<2500; c++)) +# do +# rm -rf Bubble_$c +# done \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/run.apecss b/examples/sphericalclustercavitationonset/run.apecss new file mode 100644 index 0000000..04eb3d9 --- /dev/null +++ b/examples/sphericalclustercavitationonset/run.apecss @@ -0,0 +1,38 @@ +######################################################### +# # +# APECSS Options File # +# # +######################################################### + +BUBBLE +RPModel KM +Emissions QA 250.0e-6 +PressureAmbient 0.1013e6 +END + +GAS +EoS IG +ReferenceDensity 1.2 +PolytropicExponent 1.4 +END + +LIQUID +ReferencePressure 0.1013e6 +ReferenceDensity 1000.0 +ReferenceSoundSpeed 1500.0 +Viscosity 1.002e-3 +END + +INTERFACE +SurfaceTensionCoeff 0.0728 +END + +RESULTS +Bubble +END + +ODESOLVER +tolerance 1.0e-10 +MinTimeStep 1.0e-14 +MaxTimeStep 1.0e-05 +END diff --git a/examples/sphericalclustercavitationonset/src/sphericalclustercavitationonset_apecss.c b/examples/sphericalclustercavitationonset/src/sphericalclustercavitationonset_apecss.c new file mode 100644 index 0000000..d86857d --- /dev/null +++ b/examples/sphericalclustercavitationonset/src/sphericalclustercavitationonset_apecss.c @@ -0,0 +1,626 @@ +// This source file is part of APECSS, an open-source software toolbox +// for the computation of pressure-driven bubble dynamics and acoustic +// emissions in spherical symmetry. +// +// Copyright (C) 2022-2024 The APECSS Developers +// +// The APECSS Developers are listed in the README.md file available in +// the GitHub repository at https://github.com/polycfd/apecss. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// ------------------------------------------------------------------- +// APECSS standalone example of acoustically-interacting microbubbles, +// demonstrating a simple parallelization of APECSS. +// ------------------------------------------------------------------- + +#include +#include +#include "apecss.h" + +APECSS_FLOAT rand_range(double min, double max) +{ + double random = (drand48()); + double range = (max - min) * random; + double number = min + range; + + return (APECSS_FLOAT) number; +} + +APECSS_FLOAT normal_distribution(double mu, double sigma) +{ + // Generating a normal distribution using Box-Muller transform, with mu as mean and sigma**2 as variance + double u1 = (drand48()); + while (u1 == 0.0) u1 = (drand48()); + double u2 = (drand48()); + + double mag = sigma * APECSS_SQRT(-2.0 * APECSS_LOG(u1)); + double z1 = mag * cos(2 * APECSS_PI * u2) + mu; + return (APECSS_FLOAT) z1; +} + +struct APECSS_Parallel_Cluster +{ + int rank, size; + int nBubbles_local, nBubbles_global; + + int *bubblerank; // max id of bubbles for each rank + APECSS_FLOAT *bubbleglobal_R, *bubbleglobal_x, *bubbleglobal_y, *bubbleglobal_z; // Radius and x,y,z location of all bubbles + APECSS_FLOAT *sumGU_rank; // Contributions from local bubbles to all bubbles +}; + +// Declaration of additional case-dependent functions +APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); + +int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubble[], struct APECSS_Parallel_Cluster *RankInfo); +int parallel_interactions_proper_cutoffdistance(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo); + +int main(int argc, char **args) +{ + /* Initialize MPI */ + int mpi_rank, mpi_size; + MPI_Init(&argc, &args); + MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); + MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); + + char OptionsDir[APECSS_STRINGLENGTH]; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Set the case-dependent simulation parameters + const int nBubbles = 2500; // Number of bubbles + APECSS_FLOAT bubble_bubble_dist = 100.0e-6; // Bubble-bubble minimal distance + APECSS_FLOAT cluster_radius = 2.5e-3; // Spherical cluster radius + + // Interbubble time-step, defining the frequency with which the neighbor influence is updated + APECSS_FLOAT dt_interbubble = 1.0e-8; + + // Initialize the simulation parameters given by the execution command + double tEnd = 0.0; + double fa = 0.0; + double pa = 0.0; + int cluster_distrib = 0; + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + apecss_infoscreen(); + + /* Read commandline options */ + sprintf(OptionsDir, "./run.apecss"); // This is the default + int j = 1; // First argument is the call to the executable + while (j < argc) + { + if (strcmp("-options", args[j]) == 0) + { + sprintf(OptionsDir, "%s", args[j + 1]); + j += 2; + } + else if (strcmp("-tend", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &tEnd); + j += 2; + } + else if (strcmp("-freq", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &fa); + j += 2; + } + else if (strcmp("-amp", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &pa); + j += 2; + } + else if (strcmp("-cldistrib", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &cluster_distrib); + j += 2; + } + else if (strcmp("-h", args[j]) == 0) + { + apecss_helpscreen(); + } + else + { + char str[APECSS_STRINGLENGTH_SPRINTF]; + sprintf(str, "Unknown command line options: %s", args[j]); + apecss_erroronscreen(1, str); + ++j; + } + } + + /* Allocate structure for parallel data */ + struct APECSS_Parallel_Cluster *RankInfo = (struct APECSS_Parallel_Cluster *) malloc(sizeof(struct APECSS_Parallel_Cluster)); + RankInfo->rank = mpi_rank; + RankInfo->size = mpi_size; + + /* Determine the number of bubbles per rank */ + int max_per_rank = ceil((double) nBubbles / (double) mpi_size); + RankInfo->nBubbles_local = APECSS_MAX(0, APECSS_MIN(max_per_rank, nBubbles - mpi_rank * max_per_rank)); + + /* Share the parallel distribution of bubbles with all ranks */ + RankInfo->bubblerank = malloc((RankInfo->size + 1) * sizeof(int)); + + RankInfo->nBubbles_global = 0; + RankInfo->bubblerank[0] = 0; + for (int r = 0; r < RankInfo->size; r++) + { + int temp = RankInfo->nBubbles_local; + MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); + RankInfo->bubblerank[r + 1] = RankInfo->bubblerank[r] + temp; + RankInfo->nBubbles_global += temp; + } + + /* Allocate and initialize Bubble structure */ + struct APECSS_Bubble *Bubbles[RankInfo->nBubbles_local]; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(sizeof(struct APECSS_Bubble)); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_initializestruct(Bubbles[i]); + + /* Set default options and read the options for the bubble */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); + + /* Allocate the structures for the fluid properties and ODE solver parameters */ + struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); + struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); + struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); + struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); + + /* Set the default options for the fluid properties and solver parameters */ + apecss_gas_setdefaultoptions(Gas); + apecss_liquid_setdefaultoptions(Liquid); + apecss_interface_setdefaultoptions(Interface); + apecss_odesolver_setdefaultoptions(NumericsODE); + + /* Read the options file for the fluid properties and solver parameters */ + apecss_gas_readoptions(Gas, OptionsDir); + apecss_liquid_readoptions(Liquid, OptionsDir); + apecss_interface_readoptions(Interface, OptionsDir); + apecss_odesolver_readoptions(NumericsODE, OptionsDir); + + /* Associate the bubble with the relevant fluid properties and solver parameters */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->Gas = Gas; + Bubbles[i]->Liquid = Liquid; + Bubbles[i]->Interface = Interface; + Bubbles[i]->NumericsODE = NumericsODE; + } + + /* Allocate and set the excitation parameters */ + struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); + Excitation->type = APECSS_EXCITATION_SIN; + Excitation->f = (APECSS_FLOAT) fa; + Excitation->dp = (APECSS_FLOAT) pa; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Excitation = Excitation; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Create individual folders for the results of each bubble + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + if (Bubbles[i]->Results != NULL) + { + sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", RankInfo->bubblerank[RankInfo->rank] + i); + struct stat st = {0}; + if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Process all options */ + apecss_gas_processoptions(Gas); + apecss_liquid_processoptions(Liquid); + apecss_interface_processoptions(Interface); + apecss_odesolver_processoptions(NumericsODE); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_processoptions(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Use the revised pressure at infinity, including neighbor contributions + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->get_pressure_infinity = parallel_interactions_bubble_pressure_infinity; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + Bubbles[i]->get_pressurederivative_infinity = parallel_interactions_bubble_pressurederivative_infinity; + + // Allocate interaction structure + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); + Bubbles[i]->Interaction->dp_neighbor = 0.0; + Bubbles[i]->Interaction->last_t_1 = 0.0; + Bubbles[i]->Interaction->last_t_2 = 0.0; + Bubbles[i]->Interaction->last_p_1 = 0.0; + Bubbles[i]->Interaction->last_p_2 = 0.0; + } + + // Update interaction structure + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->nBubbles = nBubbles; // Not used? + + // Define the size of each bubble + if (cluster_distrib == 0) + { + // Monodispersed cluster + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->R0 = 10.0e-6; + Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; + } + } + else + { + // Polydispersed cluster (radii distribution is following a log normal law) + double mu = 0.0; + double sigma = 0.7; + APECSS_FLOAT radius_ref = 10.0e-6; + APECSS_FLOAT Bubble_Radius[nBubbles]; + for (register int i = 0; i < nBubbles; i++) + { + APECSS_FLOAT radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); + while (radius > 20 * radius_ref) + { + // Small step to ensure no too big bubbles are generated (the distribution is conserved still) + radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); + } + Bubble_Radius[i] = radius; + } + + for (register int n = 0; n < RankInfo->nBubbles_local; n++) + { + Bubbles[n]->R0 = Bubble_Radius[RankInfo->bubblerank[RankInfo->rank] + n]; + Bubbles[n]->r_hc = Bubbles[n]->R0 / 8.54; + } + } + + // Define center location for each bubble + APECSS_FLOAT Bubble_Center[nBubbles][3]; + + for (register int i = 0; i < nBubbles; i++) + { + if (i == 0) + { + Bubble_Center[i][0] = 0.0; + Bubble_Center[i][1] = 0.0; + Bubble_Center[i][2] = 0.0; + } + else + { + APECSS_FLOAT x = rand_range((double) -cluster_radius, (double) cluster_radius); + APECSS_FLOAT y = rand_range((double) -cluster_radius, (double) cluster_radius); + APECSS_FLOAT z = rand_range((double) -cluster_radius, (double) cluster_radius); + + APECSS_FLOAT radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); + + while (radius > cluster_radius) + { + x = rand_range((double) -cluster_radius, (double) cluster_radius); + y = rand_range((double) -cluster_radius, (double) cluster_radius); + z = rand_range((double) -cluster_radius, (double) cluster_radius); + + radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); + } + + Bubble_Center[i][0] = x; + Bubble_Center[i][1] = y; + Bubble_Center[i][2] = z; + + for (register int k = 0; k < i; k++) + { + APECSS_FLOAT bubbledist = APECSS_SQRT(APECSS_POW2(Bubble_Center[i][0] - Bubble_Center[k][0]) + APECSS_POW2(Bubble_Center[i][1] - Bubble_Center[k][1]) + + APECSS_POW2(Bubble_Center[i][2] - Bubble_Center[k][2])); + if (bubbledist < bubble_bubble_dist) + { + i--; + break; + } + } + } + } + + for (register int n = 0; n < RankInfo->nBubbles_local; n++) + { + Bubbles[n]->Interaction->location[0] = Bubble_Center[RankInfo->bubblerank[RankInfo->rank] + n][0]; + Bubbles[n]->Interaction->location[1] = Bubble_Center[RankInfo->bubblerank[RankInfo->rank] + n][1]; + Bubbles[n]->Interaction->location[2] = Bubble_Center[RankInfo->bubblerank[RankInfo->rank] + n][2]; + } + + // Share the location of each bubble with all ranks + + RankInfo->bubbleglobal_R = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + RankInfo->bubbleglobal_x = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + RankInfo->bubbleglobal_y = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + RankInfo->bubbleglobal_z = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + + for (int r = 0; r < RankInfo->size; r++) + { + int temp = RankInfo->nBubbles_local; + MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); + + APECSS_FLOAT temp_array[4]; + + for (int i = 0; i < temp; i++) + { + if (r == RankInfo->rank) + { + temp_array[0] = Bubbles[i]->Interaction->location[0]; + temp_array[1] = Bubbles[i]->Interaction->location[1]; + temp_array[2] = Bubbles[i]->Interaction->location[2]; + temp_array[3] = Bubbles[i]->R; + } + + MPI_Bcast(temp_array, 4, MPI_DOUBLE, r, MPI_COMM_WORLD); + + RankInfo->bubbleglobal_x[RankInfo->bubblerank[r] + i] = temp_array[0]; + RankInfo->bubbleglobal_y[RankInfo->bubblerank[r] + i] = temp_array[1]; + RankInfo->bubbleglobal_z[RankInfo->bubblerank[r] + i] = temp_array[2]; + RankInfo->bubbleglobal_R[RankInfo->bubblerank[r] + i] = temp_array[3]; + } + } + + // Update cut off distance for each bubble + parallel_interactions_proper_cutoffdistance(Bubbles, RankInfo); + + // File to retrieve the locations of bubble centers + if (RankInfo->rank == 0) + { + FILE *file_loc; + file_loc = fopen("bubble_loc.txt", "w"); + fprintf(file_loc, "#number x(m) y(m) z(m)\n"); + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_loc, "%d %e %e %e\n", i, Bubble_Center[i][0], Bubble_Center[i][1], Bubble_Center[i][2]); + } + fclose(file_loc); + } + + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + clock_t starttimebubble = clock(); + APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->tStart = tSim; + Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; + Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step + } + + /* Initialize the bubble based on the selected options */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_initialize(Bubbles[i]); + + /* Initialize */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_initialize(Bubbles[i]); + + // Allocate the pressure contribution array + RankInfo->sumGU_rank = malloc(2 * RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + + /* Solve the bubble dynamics */ + while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered + { + APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); + tSim += dtSim; + + // To follow computations progress + if (RankInfo->rank == 0) + { + printf("%e\n", tSim); + } + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); + + // for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Update the contribution of the neighbor bubble + parallel_interactions_quasi_acoustic(Bubbles, RankInfo); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; + Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; + + Bubbles[i]->Interaction->last_t_1 = tSim; + Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; + } + } + + /* Finalize the simulation*/ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_finalize(Bubbles[i]); + + char str[APECSS_STRINGLENGTH_SPRINTF]; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", RankInfo->bubblerank[RankInfo->rank] + i, Bubbles[i]->dtNumber, + Bubbles[i]->nSubIter, (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); + apecss_writeonscreen(str); + } + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); + + /* Make sure all allocated memory is freed */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_freestruct(Bubbles[i]); + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) free(Bubbles[i]); + free(Gas); + free(Liquid); + free(Interface); + free(NumericsODE); + free(Excitation); + + free(RankInfo->bubblerank); + RankInfo->bubblerank = NULL; + free(RankInfo->bubbleglobal_R); + RankInfo->bubbleglobal_R = NULL; + free(RankInfo->bubbleglobal_x); + RankInfo->bubbleglobal_x = NULL; + free(RankInfo->bubbleglobal_y); + RankInfo->bubbleglobal_y = NULL; + free(RankInfo->bubbleglobal_z); + RankInfo->bubbleglobal_z = NULL; + free(RankInfo->sumGU_rank); + RankInfo->sumGU_rank = NULL; + free(RankInfo); + + MPI_Finalize(); + + return (0); +} + +APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + APECSS_FLOAT T = 10.0e-06; + if (t < T) + { + return (Bubble->p0 + Bubble->Interaction->dp_neighbor); + } + else if (t > 2 * T) + { + return (Bubble->Excitation->dp + Bubble->Interaction->dp_neighbor); + } + else + { + APECSS_FLOAT W = 0.5 * (1 - APECSS_COS((t + T) * APECSS_PI / T)); + return (Bubble->p0 + W * (Bubble->Excitation->dp - Bubble->p0) + Bubble->Interaction->dp_neighbor); + } +} + +APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + // Approximate numerical computation of p_infinity derivative + APECSS_FLOAT T = 10.0e-06; + APECSS_FLOAT derivative = 0.0; + if ((t >= T) && (t <= 2 * T)) + { + APECSS_FLOAT inv_T = 1 / T; + derivative = 0.5 * APECSS_PI * inv_T * APECSS_SIN(APECSS_PI * (t + T) * inv_T) * (Bubble->Excitation->dp - Bubble->p0); + } + + APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; + if (delta_t > Bubble->dt) + { + APECSS_FLOAT inv_delta_t = 1 / delta_t; + return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) * inv_delta_t)); + } + else + { + return (derivative); + } +} + +int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo) +{ + // All bubbles are supposed to be in the same liquid + struct APECSS_Liquid *Liquid = Bubbles[0]->Liquid; + + // Update bubble radii info + APECSS_FLOAT *tempR = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + for (register int j = 0; j < RankInfo->nBubbles_global; j++) tempR[j] = 0.0; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) tempR[RankInfo->bubblerank[RankInfo->rank] + i] = Bubbles[i]->R; + MPI_Allreduce(tempR, RankInfo->bubbleglobal_R, RankInfo->nBubbles_global, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + free(tempR); + + // Reset pressure contributions of the neighours + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; + + // Locally compute the contribution to each bubble + for (register int j = 0; j < RankInfo->nBubbles_global; j++) + { + APECSS_FLOAT x_j = RankInfo->bubbleglobal_x[j]; + APECSS_FLOAT y_j = RankInfo->bubbleglobal_y[j]; + APECSS_FLOAT z_j = RankInfo->bubbleglobal_z[j]; + + RankInfo->sumGU_rank[j] = 0.0; + RankInfo->sumGU_rank[j + RankInfo->nBubbles_global] = 0.0; + + double R_j = RankInfo->bubbleglobal_R[j]; + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + if (j != RankInfo->bubblerank[RankInfo->rank] + i) + { + APECSS_FLOAT sumU_bubble = 0.0; + APECSS_FLOAT sumG_bubble = 0.0; + int nodecount_bubble = 0; + + APECSS_FLOAT x_i = Bubbles[i]->Interaction->location[0]; + APECSS_FLOAT y_i = Bubbles[i]->Interaction->location[1]; + APECSS_FLOAT z_i = Bubbles[i]->Interaction->location[2]; + + APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); + + // The loop over the emission nodes begins with the most far away from the emitting bubble + struct APECSS_EmissionNode *Current = Bubbles[i]->Emissions->LastNode; + while (Current != NULL) + { + if (Current->r < interbubble_dist - R_j) + { + // The following emission nodes have not yet reached the bubble of interest + Current = NULL; + } + else if (Current->r > interbubble_dist + R_j) + { + // The bubble of interest is still not reached + Current = Current->backward; + } + else + { + // The current emission node is located inside the bubble of interest + APECSS_FLOAT gr = Current->g / Current->r; + sumU_bubble += (Current->f / APECSS_POW2(Current->r)) + gr / Liquid->cref; + sumG_bubble += gr; + nodecount_bubble++; + Current = Current->backward; + } + } + + if (nodecount_bubble) + { + APECSS_FLOAT inv_nodecount = 1.0 / (APECSS_FLOAT) nodecount_bubble; + RankInfo->sumGU_rank[j] += sumG_bubble * inv_nodecount; + RankInfo->sumGU_rank[j + RankInfo->nBubbles_global] += sumU_bubble * inv_nodecount; + } + } + } + } + + APECSS_FLOAT *sumGU_all = malloc(2 * RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + MPI_Allreduce(RankInfo->sumGU_rank, sumGU_all, 2 * RankInfo->nBubbles_global, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + + // Compute the total pressure contributions of the neighbours for all local bubbles + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->Interaction->dp_neighbor = + Liquid->rhoref * (sumGU_all[RankInfo->bubblerank[RankInfo->rank] + i] - + 0.5 * APECSS_POW2(sumGU_all[RankInfo->nBubbles_global + RankInfo->bubblerank[RankInfo->rank] + i])); + } + + free(sumGU_all); + + return (0); +} + +int parallel_interactions_proper_cutoffdistance(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo) +{ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + APECSS_FLOAT x_i = Bubbles[i]->Interaction->location[0]; + APECSS_FLOAT y_i = Bubbles[i]->Interaction->location[1]; + APECSS_FLOAT z_i = Bubbles[i]->Interaction->location[2]; + APECSS_FLOAT dist = 0.0; + + for (register int j = 0; j < RankInfo->nBubbles_global; j++) + { + APECSS_FLOAT x_j = RankInfo->bubbleglobal_x[j]; + APECSS_FLOAT y_j = RankInfo->bubbleglobal_y[j]; + APECSS_FLOAT z_j = RankInfo->bubbleglobal_z[j]; + + APECSS_FLOAT dist_ij = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); + + if (dist_ij > dist) + { + dist = dist_ij; + } + } + if (Bubbles[i]->Emissions != NULL) Bubbles[i]->Emissions->CutOffDistance = 1.25 * dist; + } + return (0); +} \ No newline at end of file From d146a8f93982235176fafab7352a23adc4b47c2c Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 16 Jul 2024 11:33:43 -0400 Subject: [PATCH 032/138] spherical cluster interactions ; results tuning + add README file --- .../sphericalclusterinteractions/README.md | 1 + .../plot_results.py | 40 ++++++++++++------- 2 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 examples/sphericalclusterinteractions/README.md diff --git a/examples/sphericalclusterinteractions/README.md b/examples/sphericalclusterinteractions/README.md new file mode 100644 index 0000000..fe473e1 --- /dev/null +++ b/examples/sphericalclusterinteractions/README.md @@ -0,0 +1 @@ +This example builds a standalone APECSS code for a spherical cluster of 2500 bubbles (the number can be modified in the [.c source file](./build/sphericalclusterinteractions_apecss)) interacting with each other using the quasi acoustic interaction model and excited by a sinusoidal propagating wave (propagating along the x-axis from negative to positive values). This example is inspired by one of the first clusters presented in [Maeda, K., & Colonius, T. (2019). Bubble cloud dynamics in an ultrasound field. Journal of Fluid Mechanics, 862, 1105‑1134](https://doi.org/10.1017/jfm.2018.968). In order to optimize computational costs, parallelization is used. The computation took around 4 complete days (96 hours) by running on 15 cores from a 13th Gen Intel i7-13700K x24. The results displayed at the end are the global cluster evolution at different times and the averaged radius evolution of bubbles depending on their location inside the cluster. \ No newline at end of file diff --git a/examples/sphericalclusterinteractions/plot_results.py b/examples/sphericalclusterinteractions/plot_results.py index 49484d0..f194c9c 100644 --- a/examples/sphericalclusterinteractions/plot_results.py +++ b/examples/sphericalclusterinteractions/plot_results.py @@ -42,8 +42,8 @@ R_c = 0 for i in range(count): line = loc_lines[i+1].split(" ") - Bubbles_loc.append([float(line[0]), float(line[1]), float(line[2])]) - R_b = sqrt((float(line[0])**2)+ (float(line[1])**2)+ (float(line[2])**2)) + Bubbles_loc.append([float(line[1]), float(line[2]), float(line[3])]) + R_b = sqrt((float(line[1])**2)+ (float(line[2])**2)+ (float(line[3])**2)) if R_c < R_b : R_c = R_b @@ -290,16 +290,14 @@ def savefig(fig, filename="Cluster", format="pdf", path=None) : if radius_to_center > max_radius_to_center : max_radius_to_center = radius_to_center -print(dic_radii) - dic_color_key = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} dic_style_key = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} fig = plt.figure(figsize=(20*cm, 15*cm)) ax = fig.add_subplot(1, 1, 1) -ax.set_xlabel(r"$t^{*}$") -ax.set_ylabel(r"$/R_{0}$") -ax.set_title("Spherical cluster with " + r"$N=$" + "{} bubbles".format(count)) +ax.set_xlabel(r"$t^{*}$", fontsize=15) +ax.set_ylabel(r"$/R_{0}$", fontsize=15) +ax.set_title("Spherical cluster with " + r"$N=$" + "{} bubbles".format(count), fontsize=15) ax.grid() dic_radius_evolution = {1.0 : [], 0.5 : [], 0.0 : []} @@ -317,6 +315,15 @@ def savefig(fig, filename="Cluster", format="pdf", path=None) : dic_radius_evolution[k].append(np.array(t_uni)) dic_radius_evolution[k].append(avg_radii / len(index_list)) +label_edge_front = 0 +label_edge_back = 0 + +for index in dic_radii[1.0] : + if -cluster_radius < Bubbles_loc[index][0] < -cluster_radius + interval_size : + label_edge_front = index + elif cluster_radius - interval_size < Bubbles_loc[index][0] < cluster_radius : + label_edge_back = index + # for k in list(dic_radii.keys()) : # index_list = dic_radii[k] @@ -327,8 +334,11 @@ def savefig(fig, filename="Cluster", format="pdf", path=None) : # else : # for i in index_list : # ax.plot(Bubbles[i][:, 1]*fa, Bubbles[i][:, 3]/Bubbles[i][:, 3][0], linestyle=dic_style_key[k], color=dic_color_key[k], linewidth=1.5, label=r"$r/R_{c} \approx$"+"{:.1f}".format(k)) - -for k in list(dic_radius_evolution.keys()) : + +ax.plot(Bubbles[label_edge_front][:, 1]*fa, Bubbles[label_edge_front][:, 3]/Bubbles[label_edge_front][:, 3][0], linestyle="solid", color="black", linewidth=1.5, label=r"$r/R_{c} \approx 1.0$ (front)") +ax.plot(Bubbles[label_edge_back][:, 1]*fa, Bubbles[label_edge_back][:, 3]/Bubbles[label_edge_back][:, 3][0], linestyle="solid", color="grey", linewidth=1.5, label=r"$r/R_{c} \approx 1.0$ (back)") + +for k in list(dic_radius_evolution.keys())[1:] : ax.plot(dic_radius_evolution[k][0]*fa, dic_radius_evolution[k][1]/dic_radius_evolution[k][1][0], linestyle=dic_style_key[k], color=dic_color_key[k], linewidth=1.5, label=r"$r/R_{c} \approx$"+"{:.1f}".format(k)) ax.legend(loc="upper right") @@ -347,16 +357,16 @@ def savefig(fig, filename="Cluster", format="pdf", path=None) : ax.set_aspect('equal') ax.set_box_aspect(None, zoom=1.5) ax.set_axis_off() -ax.set_title(r"$t^{*}$ = " + "{:.1f}".format(t_star)) +ax.set_title(r"$t^{*}$ = " + "{:.2f}".format(t_star)) -t_star = 0.8 +t_star = 0.75 ax = fig.add_subplot(1, 4, 2, projection='3d') plot_cluster(ax, Bubbles, Bubbles_loc, t=t_star/fa, figtitle="", grid="False", radius_vis="False") ax.view_init(elev=90, azim=-90) ax.set_aspect('equal') ax.set_box_aspect(None, zoom=1.5) ax.set_axis_off() -ax.set_title(r"$t^{*}$ = " + "{:.1f}".format(t_star)) +ax.set_title(r"$t^{*}$ = " + "{:.2f}".format(t_star)) t_star = 1.0 ax = fig.add_subplot(1, 4, 3, projection='3d') @@ -365,16 +375,16 @@ def savefig(fig, filename="Cluster", format="pdf", path=None) : ax.set_aspect('equal') ax.set_box_aspect(None, zoom=1.5) ax.set_axis_off() -ax.set_title(r"$t^{*}$ = " + "{:.1f}".format(t_star)) +ax.set_title(r"$t^{*}$ = " + "{:.2f}".format(t_star)) -t_star = 1.2 +t_star = 1.25 ax = fig.add_subplot(1, 4, 4, projection='3d') plot_cluster(ax, Bubbles, Bubbles_loc, t=t_star/fa, figtitle="", grid="False", radius_vis="False") ax.view_init(elev=90, azim=-90) ax.set_aspect('equal') ax.set_box_aspect(None, zoom=1.5) ax.set_axis_off() -ax.set_title(r"$t^{*}$ = " + "{:.1f}".format(t_star)) +ax.set_title(r"$t^{*}$ = " + "{:.2f}".format(t_star)) # plot_cluster(fig, Bubbles, Bubbles_loc) savefig(fig, filename="sphericalclusterinteractions_clusterevolution", format="png") \ No newline at end of file From 5cabf020290bf006397b4f98f490eaf1a05edb57 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 16 Jul 2024 11:34:07 -0400 Subject: [PATCH 033/138] cavitation onset ; small correction in README --- examples/cavitationonset/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/cavitationonset/README.md b/examples/cavitationonset/README.md index bad759c..2b982c1 100644 --- a/examples/cavitationonset/README.md +++ b/examples/cavitationonset/README.md @@ -1 +1 @@ -This example builds a standalone APECSS code for two (or more) interaction microbubbles, following the work of [Ida, M. (2009). Multibubble cavitation inception. Physics of Fluids, 21(11), 113302.](https://doi.org/10.1063/1.3265547), using the _standard incompressible model_ and the newly developped _quasi acoustic model_ to compute the acoustic emissions. There is three folders, representing each a specific interaction model ("NI" for "no interaction, "IC" for the _standard incompressible model_ and "QA" for the _quasi acoustic model_). Each folder is containing a provided [run.apecss](./IC/run.apecss) file to reproduce the bubble dynamics shown in Figs. 2, 3, 4, 5, 6 and 16 of the paper of Ida such as a [gather_results.py](./IC/gather_results.py) to properly keep the results. The [run_cavitationonset.sh](./run_cavitationonset.sh) file provides the whole execution commands needed to gather data in order to reproduce results from the source article. \ No newline at end of file +This example builds a standalone APECSS code for two (or more) interacting microbubbles, following the work of [Ida, M. (2009). Multibubble cavitation inception. Physics of Fluids, 21(11), 113302.](https://doi.org/10.1063/1.3265547), using the _standard incompressible model_ and the newly developped _quasi acoustic model_ to compute the acoustic emissions. There is three folders, representing each a specific interaction model ("NI" for "no interaction, "IC" for the _standard incompressible model_ and "QA" for the _quasi acoustic model_). Each folder is containing a provided [run.apecss](./IC/run.apecss) file to reproduce the bubble dynamics shown in Figs. 2, 3, 4, 5, 6 and 16 of the paper of Ida such as a [gather_results.py](./IC/gather_results.py) to properly keep the results. The [run_cavitationonset.sh](./run_cavitationonset.sh) file provides the whole execution commands needed to gather data in order to reproduce results from the source article. \ No newline at end of file From 7c2201907b0c842dca5562ba033d7c67121bef4d Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 16 Jul 2024 11:39:22 -0400 Subject: [PATCH 034/138] parallelinteractions ; adding pressure derivative infinity approximation --- .../src/parallelinteraction_apecss.c | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/examples/parallelinteraction/src/parallelinteraction_apecss.c b/examples/parallelinteraction/src/parallelinteraction_apecss.c index 214f2ff..93ed069 100644 --- a/examples/parallelinteraction/src/parallelinteraction_apecss.c +++ b/examples/parallelinteraction/src/parallelinteraction_apecss.c @@ -32,6 +32,7 @@ struct APECSS_Parallel_Cluster // Declaration of additional case-dependent functions APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubble[], struct APECSS_Parallel_Cluster *RankInfo); int main(int argc, char **args) @@ -188,12 +189,18 @@ int main(int argc, char **args) // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // Use the revised pressure at infinity, including neighbor contributions for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->get_pressure_infinity = parallel_interactions_bubble_pressure_infinity; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + Bubbles[i]->get_pressurederivative_infinity = parallel_interactions_bubble_pressurederivative_infinity; // Allocate interaction structure for (register int i = 0; i < RankInfo->nBubbles_local; i++) { Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); Bubbles[i]->Interaction->dp_neighbor = 0.0; + Bubbles[i]->Interaction->last_t_1 = 0.0; + Bubbles[i]->Interaction->last_t_2 = 0.0; + Bubbles[i]->Interaction->last_p_1 = 0.0; + Bubbles[i]->Interaction->last_p_2 = 0.0; } // Update interaction structure @@ -304,6 +311,15 @@ int main(int argc, char **args) // Update the contribution of the neighbor bubble parallel_interactions_quasi_acoustic(Bubbles, RankInfo); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; + Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; + + Bubbles[i]->Interaction->last_t_1 = tSim; + Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; + } } /* Finalize the simulation*/ @@ -354,6 +370,20 @@ APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, stru return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * t) + Bubble->Interaction->dp_neighbor); } +APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + APECSS_FLOAT derivative = -2.0 * APECSS_PI * Bubble->Excitation->f * Bubble->Excitation->dp * APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * t); + APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; + if (delta_t > Bubble->dt) + { + return (derivative + (Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) / delta_t); + } + else + { + return (derivative); + } +} + int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo) { // All bubbles are supposed to be in the same liquid From ca4f3002cd6c5bfc87c26d92e6b1245d91d42695 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 16 Jul 2024 13:24:39 -0400 Subject: [PATCH 035/138] bubblyscreen ; working folder --- examples/bubblyscreen/QA/build/compile.sh | 5 + examples/bubblyscreen/QA/execmpi.sh | 9 + examples/bubblyscreen/QA/run.apecss | 38 ++ .../bubblyscreen/QA/src/bubblyscreen_apecss.c | 507 ++++++++++++++++++ examples/bubblyscreen/README.md | 1 + 5 files changed, 560 insertions(+) create mode 100755 examples/bubblyscreen/QA/build/compile.sh create mode 100755 examples/bubblyscreen/QA/execmpi.sh create mode 100644 examples/bubblyscreen/QA/run.apecss create mode 100644 examples/bubblyscreen/QA/src/bubblyscreen_apecss.c create mode 100644 examples/bubblyscreen/README.md diff --git a/examples/bubblyscreen/QA/build/compile.sh b/examples/bubblyscreen/QA/build/compile.sh new file mode 100755 index 0000000..1569080 --- /dev/null +++ b/examples/bubblyscreen/QA/build/compile.sh @@ -0,0 +1,5 @@ +#!/bin/bash +rm bubblyscreen_apecss +cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release +make +rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/bubblyscreen/QA/execmpi.sh b/examples/bubblyscreen/QA/execmpi.sh new file mode 100755 index 0000000..15cb642 --- /dev/null +++ b/examples/bubblyscreen/QA/execmpi.sh @@ -0,0 +1,9 @@ +cd build +./compile.sh +cd .. +mpiexec -n 15 ./build/bubblyscreen_apecss -options run.apecss -freq 3.262e6 -amp 100.0 -tend 1.0e-6 + +for ((c=0; c<2601; c++)) +do + rm -rf Bubble_$c +done \ No newline at end of file diff --git a/examples/bubblyscreen/QA/run.apecss b/examples/bubblyscreen/QA/run.apecss new file mode 100644 index 0000000..5c2d8d9 --- /dev/null +++ b/examples/bubblyscreen/QA/run.apecss @@ -0,0 +1,38 @@ +######################################################### +# # +# APECSS Options File # +# # +######################################################### + +BUBBLE +RPModel KM +Emissions QA 250.0e-6 +PressureAmbient 1.0e5 +END + +GAS +EoS IG +ReferencePressure 1.0e5 +ReferenceDensity 1.2 +PolytropicExponent 1.4 +END + +LIQUID +ReferencePressure 1.0e5 +ReferenceDensity 1000.0 +ReferenceSoundSpeed 1500.0 +Viscosity 0.00 +END + +INTERFACE +SurfaceTensionCoeff 0.00 +END + +RESULTS +Bubble +OutputFreqRP 5 +END + +ODESOLVER +tolerance 1.0e-10 +END diff --git a/examples/bubblyscreen/QA/src/bubblyscreen_apecss.c b/examples/bubblyscreen/QA/src/bubblyscreen_apecss.c new file mode 100644 index 0000000..7919996 --- /dev/null +++ b/examples/bubblyscreen/QA/src/bubblyscreen_apecss.c @@ -0,0 +1,507 @@ +// This source file is part of APECSS, an open-source software toolbox +// for the computation of pressure-driven bubble dynamics and acoustic +// emissions in spherical symmetry. +// +// Copyright (C) 2022-2024 The APECSS Developers +// +// The APECSS Developers are listed in the README.md file available in +// the GitHub repository at https://github.com/polycfd/apecss. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// ------------------------------------------------------------------- +// APECSS standalone example of acoustically-interacting microbubbles, +// demonstrating a simple parallelization of APECSS. +// ------------------------------------------------------------------- + +#include +#include +#include "apecss.h" + +struct APECSS_Parallel_Cluster +{ + int rank, size; + int nBubbles_local, nBubbles_global; + + int *bubblerank; // max id of bubbles for each rank + APECSS_FLOAT *bubbleglobal_R, *bubbleglobal_x, *bubbleglobal_y, *bubbleglobal_z; // Radius and x,y,z location of all bubbles + APECSS_FLOAT *sumGU_rank; // Contributions from local bubbles to all bubbles +}; + +// Declaration of additional case-dependent functions +APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubble[], struct APECSS_Parallel_Cluster *RankInfo); +int parallel_interactions_proper_cutoffdistance(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo); + +int main(int argc, char **args) +{ + /* Initialize MPI */ + int mpi_rank, mpi_size; + MPI_Init(&argc, &args); + MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); + MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); + + char OptionsDir[APECSS_STRINGLENGTH]; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Set the case-dependent simulation parameters + const int nBubbles_x = 51; + const int nBubbles = nBubbles_x * nBubbles_x; // Number of bubbles + APECSS_FLOAT bubble_bubble_dist = 400.0e-6; // Bubble-bubble distance + + // Interbubble time-step, defining the frequency with which the neighbor influence is updated + APECSS_FLOAT dt_interbubble = 1.0e-8; + + // Initialize the simulation parameters given by the execution command + double tEnd = 0.0; + double fa = 0.0; + double pa = 0.0; + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + apecss_infoscreen(); + + /* Read commandline options */ + sprintf(OptionsDir, "./run.apecss"); // This is the default + int j = 1; // First argument is the call to the executable + while (j < argc) + { + if (strcmp("-options", args[j]) == 0) + { + sprintf(OptionsDir, "%s", args[j + 1]); + j += 2; + } + else if (strcmp("-tend", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &tEnd); + j += 2; + } + else if (strcmp("-freq", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &fa); + j += 2; + } + else if (strcmp("-amp", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &pa); + j += 2; + } + else if (strcmp("-h", args[j]) == 0) + { + apecss_helpscreen(); + } + else + { + char str[APECSS_STRINGLENGTH_SPRINTF]; + sprintf(str, "Unknown command line options: %s", args[j]); + apecss_erroronscreen(1, str); + ++j; + } + } + + /* Allocate structure for parallel data */ + struct APECSS_Parallel_Cluster *RankInfo = (struct APECSS_Parallel_Cluster *) malloc(sizeof(struct APECSS_Parallel_Cluster)); + RankInfo->rank = mpi_rank; + RankInfo->size = mpi_size; + + /* Determine the number of bubbles per rank */ + int max_per_rank = ceil((double) nBubbles / (double) mpi_size); + RankInfo->nBubbles_local = APECSS_MAX(0, APECSS_MIN(max_per_rank, nBubbles - mpi_rank * max_per_rank)); + // printf("[%i] %i\n", mpi_rank, RankInfo->nBubbles_local); + /* Share the parallel distribution of bubbles with all ranks */ + + RankInfo->bubblerank = malloc((RankInfo->size + 1) * sizeof(int)); + + RankInfo->nBubbles_global = 0; + RankInfo->bubblerank[0] = 0; + for (int r = 0; r < RankInfo->size; r++) + { + int temp = RankInfo->nBubbles_local; + MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); + RankInfo->bubblerank[r + 1] = RankInfo->bubblerank[r] + temp; + RankInfo->nBubbles_global += temp; + } + + /* Allocate and initialize Bubble structure */ + struct APECSS_Bubble *Bubbles[RankInfo->nBubbles_local]; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(sizeof(struct APECSS_Bubble)); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_initializestruct(Bubbles[i]); + + /* Set default options and read the options for the bubble */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); + + /* Allocate the structures for the fluid properties and ODE solver parameters */ + struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); + struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); + struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); + struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); + + /* Set the default options for the fluid properties and solver parameters */ + apecss_gas_setdefaultoptions(Gas); + apecss_liquid_setdefaultoptions(Liquid); + apecss_interface_setdefaultoptions(Interface); + apecss_odesolver_setdefaultoptions(NumericsODE); + + /* Read the options file for the fluid properties and solver parameters */ + apecss_gas_readoptions(Gas, OptionsDir); + apecss_liquid_readoptions(Liquid, OptionsDir); + apecss_interface_readoptions(Interface, OptionsDir); + apecss_odesolver_readoptions(NumericsODE, OptionsDir); + + /* Associate the bubble with the relevant fluid properties and solver parameters */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->Gas = Gas; + Bubbles[i]->Liquid = Liquid; + Bubbles[i]->Interface = Interface; + Bubbles[i]->NumericsODE = NumericsODE; + } + + /* Allocate and set the excitation parameters */ + struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); + Excitation->type = APECSS_EXCITATION_SIN; + Excitation->f = (APECSS_FLOAT) fa; + Excitation->dp = (APECSS_FLOAT) pa; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Excitation = Excitation; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Create individual folders for the results of each bubble + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + if (Bubbles[i]->Results != NULL) + { + sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", RankInfo->bubblerank[RankInfo->rank] + i); + struct stat st = {0}; + if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Process all options */ + apecss_gas_processoptions(Gas); + apecss_liquid_processoptions(Liquid); + apecss_interface_processoptions(Interface); + apecss_odesolver_processoptions(NumericsODE); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_processoptions(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Use the revised pressure at infinity, including neighbor contributions + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->get_pressure_infinity = parallel_interactions_bubble_pressure_infinity; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + Bubbles[i]->get_pressurederivative_infinity = parallel_interactions_bubble_pressurederivative_infinity; + + // Allocate interaction structure + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); + Bubbles[i]->Interaction->dp_neighbor = 0.0; + Bubbles[i]->Interaction->last_t_1 = 0.0; + Bubbles[i]->Interaction->last_t_2 = 0.0; + Bubbles[i]->Interaction->last_p_1 = 0.0; + Bubbles[i]->Interaction->last_p_2 = 0.0; + } + + // Update interaction structure + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->nBubbles = nBubbles; // Not used? + + // Define the size of each bubble + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->R0 = 10.0e-6; + Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; + } + + // Define center location for each bubble + + int ri = 0, rj = 0; + if (mpi_rank) + { + ri = mpi_rank * max_per_rank % nBubbles_x; + rj = mpi_rank * max_per_rank / nBubbles_x; + } + + for (register int n = 0; n < RankInfo->nBubbles_local; n++) + { + Bubbles[n]->Interaction->location[0] = ((APECSS_FLOAT) ri) * bubble_bubble_dist; + Bubbles[n]->Interaction->location[1] = ((APECSS_FLOAT) rj) * bubble_bubble_dist; + Bubbles[n]->Interaction->location[2] = 0.0; + + if (ri < nBubbles_x - 1) + { + ri++; + } + else + { + ri = 0; + rj++; + } + } + + // Share the location of each bubble with all ranks + + RankInfo->bubbleglobal_R = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + RankInfo->bubbleglobal_x = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + RankInfo->bubbleglobal_y = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + RankInfo->bubbleglobal_z = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + + for (int r = 0; r < RankInfo->size; r++) + { + int temp = RankInfo->nBubbles_local; + MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); + + APECSS_FLOAT temp_array[4]; + + for (int i = 0; i < temp; i++) + { + if (r == RankInfo->rank) + { + temp_array[0] = Bubbles[i]->Interaction->location[0]; + temp_array[1] = Bubbles[i]->Interaction->location[1]; + temp_array[2] = Bubbles[i]->Interaction->location[2]; + temp_array[3] = Bubbles[i]->R; + } + + MPI_Bcast(temp_array, 4, MPI_DOUBLE, r, MPI_COMM_WORLD); + + RankInfo->bubbleglobal_x[RankInfo->bubblerank[r] + i] = temp_array[0]; + RankInfo->bubbleglobal_y[RankInfo->bubblerank[r] + i] = temp_array[1]; + RankInfo->bubbleglobal_z[RankInfo->bubblerank[r] + i] = temp_array[2]; + RankInfo->bubbleglobal_R[RankInfo->bubblerank[r] + i] = temp_array[3]; + } + } + + // Update cut off distance for each bubble + parallel_interactions_proper_cutoffdistance(Bubbles, RankInfo); + + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + clock_t starttimebubble = clock(); + APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->tStart = tSim; + Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; + Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step + } + + /* Initialize the bubble based on the selected options */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_initialize(Bubbles[i]); + + /* Initialize */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_initialize(Bubbles[i]); + + // Allocate the pressure contribution array + RankInfo->sumGU_rank = malloc(2 * RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + + /* Solve the bubble dynamics */ + while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered + { + APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); + tSim += dtSim; + + // See progress during computation + printf("%e\n", tSim); + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Update the contribution of the neighbor bubble + parallel_interactions_quasi_acoustic(Bubbles, RankInfo); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; + Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; + + Bubbles[i]->Interaction->last_t_1 = tSim; + Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; + } + } + + /* Finalize the simulation*/ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_finalize(Bubbles[i]); + + char str[APECSS_STRINGLENGTH_SPRINTF]; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", RankInfo->bubblerank[RankInfo->rank] + i, Bubbles[i]->dtNumber, + Bubbles[i]->nSubIter, (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); + apecss_writeonscreen(str); + } + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); + + /* Make sure all allocated memory is freed */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_freestruct(Bubbles[i]); + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) free(Bubbles[i]); + free(Gas); + free(Liquid); + free(Interface); + free(NumericsODE); + free(Excitation); + + free(RankInfo->bubblerank); + RankInfo->bubblerank = NULL; + free(RankInfo->bubbleglobal_R); + RankInfo->bubbleglobal_R = NULL; + free(RankInfo->bubbleglobal_x); + RankInfo->bubbleglobal_x = NULL; + free(RankInfo->bubbleglobal_y); + RankInfo->bubbleglobal_y = NULL; + free(RankInfo->bubbleglobal_z); + RankInfo->bubbleglobal_z = NULL; + free(RankInfo->sumGU_rank); + RankInfo->sumGU_rank = NULL; + free(RankInfo); + + MPI_Finalize(); + + return (0); +} + +APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * t) + Bubble->Interaction->dp_neighbor); +} + +APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + APECSS_FLOAT derivative = -2.0 * APECSS_PI * Bubble->Excitation->f * Bubble->Excitation->dp * APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * t); + APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; + if (delta_t > Bubble->dt) + { + return (derivative + (Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) / delta_t); + } + else + { + return (derivative); + } +} + +int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo) +{ + // All bubbles are supposed to be in the same liquid + struct APECSS_Liquid *Liquid = Bubbles[0]->Liquid; + + // Update bubble radii info + APECSS_FLOAT *tempR = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + for (register int j = 0; j < RankInfo->nBubbles_global; j++) tempR[j] = 0.0; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) tempR[RankInfo->bubblerank[RankInfo->rank] + i] = Bubbles[i]->R; + MPI_Allreduce(tempR, RankInfo->bubbleglobal_R, RankInfo->nBubbles_global, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + free(tempR); + + // Reset pressure contributions of the neighours + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0; + + // Locally compute the contribution to each bubble + for (register int j = 0; j < RankInfo->nBubbles_global; j++) + { + APECSS_FLOAT x_j = RankInfo->bubbleglobal_x[j]; + APECSS_FLOAT y_j = RankInfo->bubbleglobal_y[j]; + APECSS_FLOAT z_j = RankInfo->bubbleglobal_z[j]; + + RankInfo->sumGU_rank[j] = 0.0; + RankInfo->sumGU_rank[j + RankInfo->nBubbles_global] = 0.0; + + double R_j = RankInfo->bubbleglobal_R[j]; + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + if (j != RankInfo->bubblerank[RankInfo->rank] + i) + { + APECSS_FLOAT sumU_bubble = 0.0; + APECSS_FLOAT sumG_bubble = 0.0; + int nodecount_bubble = 0; + + APECSS_FLOAT x_i = Bubbles[i]->Interaction->location[0]; + APECSS_FLOAT y_i = Bubbles[i]->Interaction->location[1]; + APECSS_FLOAT z_i = Bubbles[i]->Interaction->location[2]; + + APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); + + // The loop over the emission nodes begins with the most far away from the emitting bubble + struct APECSS_EmissionNode *Current = Bubbles[i]->Emissions->LastNode; + while (Current != NULL) + { + if (Current->r < interbubble_dist - R_j) + { + // The following emission nodes have not yet reached the bubble of interest + Current = NULL; + } + else if (Current->r > interbubble_dist + R_j) + { + // The bubble of interest is still not reached + Current = Current->backward; + } + else + { + // The current emission node is located inside the bubble of interest + APECSS_FLOAT gr = Current->g / Current->r; + sumU_bubble += (Current->f / APECSS_POW2(Current->r)) + gr / Liquid->cref; + sumG_bubble += gr; + nodecount_bubble++; + Current = Current->backward; + } + } + + if (nodecount_bubble) + { + APECSS_FLOAT inv_nodecount = 1.0 / (APECSS_FLOAT) nodecount_bubble; + RankInfo->sumGU_rank[j] += sumG_bubble * inv_nodecount; + RankInfo->sumGU_rank[j + RankInfo->nBubbles_global] += sumU_bubble * inv_nodecount; + } + } + } + } + + APECSS_FLOAT *sumGU_all = malloc(2 * RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + MPI_Allreduce(RankInfo->sumGU_rank, sumGU_all, 2 * RankInfo->nBubbles_global, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + + // Compute the total pressure contributions of the neighbours for all local bubbles + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->Interaction->dp_neighbor = + Liquid->rhoref * (sumGU_all[RankInfo->bubblerank[RankInfo->rank] + i] - + 0.5 * APECSS_POW2(sumGU_all[RankInfo->nBubbles_global + RankInfo->bubblerank[RankInfo->rank] + i])); + } + + free(sumGU_all); + + return (0); +} + +int parallel_interactions_proper_cutoffdistance(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo) +{ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + APECSS_FLOAT x_i = Bubbles[i]->Interaction->location[0]; + APECSS_FLOAT y_i = Bubbles[i]->Interaction->location[1]; + APECSS_FLOAT z_i = Bubbles[i]->Interaction->location[2]; + APECSS_FLOAT dist = 0.0; + + for (register int j = 0; j < RankInfo->nBubbles_global; j++) + { + APECSS_FLOAT x_j = RankInfo->bubbleglobal_x[j]; + APECSS_FLOAT y_j = RankInfo->bubbleglobal_y[j]; + APECSS_FLOAT z_j = RankInfo->bubbleglobal_z[j]; + + APECSS_FLOAT dist_ij = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); + + if (dist_ij > dist) + { + dist = dist_ij; + } + } + if (Bubbles[i]->Emissions != NULL) Bubbles[i]->Emissions->CutOffDistance = 1.25 * dist; + } + return (0); +} \ No newline at end of file diff --git a/examples/bubblyscreen/README.md b/examples/bubblyscreen/README.md new file mode 100644 index 0000000..bd82f21 --- /dev/null +++ b/examples/bubblyscreen/README.md @@ -0,0 +1 @@ +This example builds a standalone APECSS code for a 51x51 finite bubbly screen of interacting microbubbles, inspired by [](). \ No newline at end of file From 0bf5c56003653982b89367545ad4ce033b7f6c01 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 16 Jul 2024 15:18:31 -0400 Subject: [PATCH 036/138] bubblyscreen ; QA working folder completed (files to gather results finalized) --- examples/bubblyscreen/QA/execmpi.sh | 14 +- examples/bubblyscreen/QA/gather_results.py | 44 +++++ .../bubblyscreen/QA/src/bubblyscreen_apecss.c | 158 +++++++++++++++++- 3 files changed, 205 insertions(+), 11 deletions(-) create mode 100644 examples/bubblyscreen/QA/gather_results.py diff --git a/examples/bubblyscreen/QA/execmpi.sh b/examples/bubblyscreen/QA/execmpi.sh index 15cb642..ebcd1ff 100755 --- a/examples/bubblyscreen/QA/execmpi.sh +++ b/examples/bubblyscreen/QA/execmpi.sh @@ -1,9 +1,19 @@ +ncore=15 +nbubble=2601 + cd build ./compile.sh cd .. -mpiexec -n 15 ./build/bubblyscreen_apecss -options run.apecss -freq 3.262e6 -amp 100.0 -tend 1.0e-6 +mpiexec -n $ncore ./build/bubblyscreen_apecss -options run.apecss -freq 3.262e6 -amp 100.0 -tend 1.0e-6 +python3 gather_results.py -for ((c=0; c<2601; c++)) +for ((c=0; c<$nbubble; c++)) do rm -rf Bubble_$c +done + +rm -rf bubblyscreen_radii.txt +for ((c=0; c<$ncore; c++)) +do + rm -rf bubblyscreen_extremum_$c.txt done \ No newline at end of file diff --git a/examples/bubblyscreen/QA/gather_results.py b/examples/bubblyscreen/QA/gather_results.py new file mode 100644 index 0000000..71cc38c --- /dev/null +++ b/examples/bubblyscreen/QA/gather_results.py @@ -0,0 +1,44 @@ +import os + +# File designed to recover data for plotting results in bubbly screen case + +file_radii = open("bubblyscreen_radii.txt", "r") +lines_radii = file_radii.readlines() +file_radii.close() + +count_core = 0 +for file in os.listdir() : + if "bubblyscreen_extremum_" in file : + count_core += 1 + +lines_extremum = [] +for i in range(count_core) : + file_extremum = open("bubblyscreen_extremum_{}.txt".format(i), "r") + lines = file_extremum.readlines() + file_extremum.close() + lines_extremum.append(lines) + +firstline = lines_radii[0].split(" ") +f = float(firstline[3]) +p = float(firstline[5]) +d = float(firstline[7]) + +file_name = "bubblyscreen_{:.3E}_{:.2E}_{:.1f}".format(f, p, d) + +working_path = os.getcwd() +results_path = os.path.join(working_path, "results") + +results_radii = open(os.path.join(results_path, file_name + "_radii.txt"), "w") +for line in lines_radii : + results_radii.write(line) +results_radii.close() + +results_extremum = open(os.path.join(results_path, file_name + "_extremum.txt"), "w") +for i in range(len(lines_extremum)) : + if i == 0 : + for line in lines_extremum[i] : + results_extremum.write(line) + else : + for line in lines_extremum[i][2:] : + results_extremum.write(line) +results_extremum.close() \ No newline at end of file diff --git a/examples/bubblyscreen/QA/src/bubblyscreen_apecss.c b/examples/bubblyscreen/QA/src/bubblyscreen_apecss.c index 7919996..756e133 100644 --- a/examples/bubblyscreen/QA/src/bubblyscreen_apecss.c +++ b/examples/bubblyscreen/QA/src/bubblyscreen_apecss.c @@ -35,6 +35,10 @@ APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, stru APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubble[], struct APECSS_Parallel_Cluster *RankInfo); int parallel_interactions_proper_cutoffdistance(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo); +int apecss_bubble_new_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble); + +APECSS_FLOAT maxR; +APECSS_FLOAT minR; int main(int argc, char **args) { @@ -109,9 +113,8 @@ int main(int argc, char **args) /* Determine the number of bubbles per rank */ int max_per_rank = ceil((double) nBubbles / (double) mpi_size); RankInfo->nBubbles_local = APECSS_MAX(0, APECSS_MIN(max_per_rank, nBubbles - mpi_rank * max_per_rank)); - // printf("[%i] %i\n", mpi_rank, RankInfo->nBubbles_local); - /* Share the parallel distribution of bubbles with all ranks */ + /* Share the parallel distribution of bubbles with all ranks */ RankInfo->bubblerank = malloc((RankInfo->size + 1) * sizeof(int)); RankInfo->nBubbles_global = 0; @@ -210,7 +213,7 @@ int main(int argc, char **args) // Define the size of each bubble for (register int i = 0; i < RankInfo->nBubbles_local; i++) { - Bubbles[i]->R0 = 10.0e-6; + Bubbles[i]->R0 = 1.0e-6; Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; } @@ -225,8 +228,8 @@ int main(int argc, char **args) for (register int n = 0; n < RankInfo->nBubbles_local; n++) { - Bubbles[n]->Interaction->location[0] = ((APECSS_FLOAT) ri) * bubble_bubble_dist; - Bubbles[n]->Interaction->location[1] = ((APECSS_FLOAT) rj) * bubble_bubble_dist; + Bubbles[n]->Interaction->location[0] = ((APECSS_FLOAT) ri) * bubble_bubble_dist - (0.5 * (nBubbles_x - 1)) * bubble_bubble_dist; + Bubbles[n]->Interaction->location[1] = ((APECSS_FLOAT) rj) * bubble_bubble_dist - (0.5 * (nBubbles_x - 1)) * bubble_bubble_dist; Bubbles[n]->Interaction->location[2] = 0.0; if (ri < nBubbles_x - 1) @@ -297,6 +300,38 @@ int main(int argc, char **args) // Allocate the pressure contribution array RankInfo->sumGU_rank = malloc(2 * RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Lists to gather maximum and minimum radius achieved by each bubble in steady state + APECSS_FLOAT max_radii[RankInfo->nBubbles_local]; + APECSS_FLOAT min_radii[RankInfo->nBubbles_local]; + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + max_radii[i] = Bubbles[i]->R; + min_radii[i] = Bubbles[i]->R; + } + + // File to retrieve the maximum and minimum radius evolution achieved in steady state + FILE *file_extremum; + char file_name[APECSS_STRINGLENGTH_SPRINTF_LONG]; + sprintf(file_name, "bubblyscreen_extremum_%d.txt", RankInfo->rank); + file_extremum = fopen(file_name, "w"); + + APECSS_FLOAT p0 = Bubbles[0]->p0; + APECSS_FLOAT poly = Gas->Gamma; + APECSS_FLOAT rho = Liquid->rhoref; + APECSS_FLOAT w0 = APECSS_SQRT((3 * poly * p0) / (APECSS_POW2(Bubbles[0]->R0) * rho)); + + fprintf(file_extremum, "w0(rad/s) %e f(Hz) %e p(Pa) %e D/R0 %e\n", w0, fa, pa, bubble_bubble_dist / Bubbles[0]->R0); + fprintf(file_extremum, "label x(m) y(m) z(m) R0(m) Rmin(m) Rmax(m)\n"); + + // File to retrieve the radius evolution during computation + FILE *file_radii; + file_radii = fopen("bubblyscreen_radii.txt", "w"); + fprintf(file_radii, "w0(rad/s) %e f(Hz) %e p(Pa) %e D/R0 %e\n", w0, fa, pa, bubble_bubble_dist / Bubbles[0]->R0); + fprintf(file_radii, "t(s) R(m)\n"); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + /* Solve the bubble dynamics */ while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered { @@ -304,17 +339,42 @@ int main(int argc, char **args) tSim += dtSim; // See progress during computation - printf("%e\n", tSim); + if (RankInfo->rank == 0) + { + printf("D:%le, f:%le, time:%e\n", bubble_bubble_dist, fa, tSim); + } - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + maxR = 0.0; + minR = Bubbles[i]->R0; + apecss_bubble_new_solver_run(tSim, tEnd, Bubbles[i]); - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; + if (maxR > max_radii[i]) + { + max_radii[i] = maxR; + } + if (minR < min_radii[i]) + { + min_radii[i] = minR; + } + } // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // Update the contribution of the neighbor bubble parallel_interactions_quasi_acoustic(Bubbles, RankInfo); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + if (RankInfo->rank == 0) + { + fprintf(file_radii, "%e", tSim); + for (register int i = 0; i < RankInfo->nBubbles_global; i++) + { + fprintf(file_radii, " %e", RankInfo->bubbleglobal_R[i]); + } + fprintf(file_radii, "\n"); + } + for (register int i = 0; i < RankInfo->nBubbles_local; i++) { Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; @@ -325,6 +385,16 @@ int main(int argc, char **args) } } + /* Complete results file */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + fprintf(file_extremum, "%d %e %e %e %e %e %e\n", RankInfo->bubblerank[RankInfo->rank] + i, Bubbles[i]->Interaction->location[0], + Bubbles[i]->Interaction->location[1], Bubbles[i]->Interaction->location[2], Bubbles[i]->R0, min_radii[i], max_radii[i]); + } + fclose(file_extremum); + + fclose(file_radii); + /* Finalize the simulation*/ for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_finalize(Bubbles[i]); @@ -400,7 +470,7 @@ int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[], struct free(tempR); // Reset pressure contributions of the neighours - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; // Locally compute the contribution to each bubble for (register int j = 0; j < RankInfo->nBubbles_global; j++) @@ -503,5 +573,75 @@ int parallel_interactions_proper_cutoffdistance(struct APECSS_Bubble *Bubbles[], } if (Bubbles[i]->Emissions != NULL) Bubbles[i]->Emissions->CutOffDistance = 1.25 * dist; } + return (0); +} + +int apecss_bubble_new_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble) +{ + while (Bubble->t < tend - 0.01 * Bubble->NumericsODE->dtMin) + { + // Store the previous solution for sub-iterations + for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSolOld[i] = Bubble->ODEsSol[i]; + + // Check what comes next: the end of the solver run or, if applicable, a time instance to output the emissions + APECSS_FLOAT next_event_time = Bubble->results_emissionstime_check(tend, Bubble); + + // Set the time-step for the ODEs + apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); + + // Solve the ODEs + Bubble->err = apecss_odesolver(Bubble); + + // Perform sub-iterations on the control of the time-step when err > tol + register int subiter = 0; + while ((Bubble->err > Bubble->NumericsODE->tol) && (subiter < Bubble->NumericsODE->maxSubIter)) + { + ++subiter; + // Rewind the solution + for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSol[i] = Bubble->ODEsSolOld[i]; + // Set the time-step for the ODEs + apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); + // Solve the ODEs again + Bubble->err = apecss_odesolver(Bubble); + } + Bubble->nSubIter += subiter; + + // Set new values + ++(Bubble->dtNumber); + Bubble->t += Bubble->dt; + Bubble->U = Bubble->ODEsSol[0]; + Bubble->R = Bubble->ODEsSol[1]; + + // Retrieve data to compute radius oscillation amplitude during + if (Bubble->t > tEnd - 10.0 / Bubble->Excitation->f) + { + maxR = APECSS_MAX(maxR, Bubble->R); + } + if (Bubble->t > tEnd - 10.0 / Bubble->Excitation->f) + { + minR = APECSS_MIN(minR, Bubble->R); + } + + // Update allocation of the results (if necessary) + Bubble->results_emissionsnodeminmax_identify(Bubble); + Bubble->results_emissionsnode_alloc(Bubble); + + // Acoustic emissions (if applicable) + Bubble->emissions_update(Bubble); + + // Store results (if applicable) + Bubble->results_rayleighplesset_store(Bubble); + Bubble->results_emissionsspace_store(Bubble); + + // Write one-off results (if applicable) + Bubble->results_emissionstime_write(Bubble); + + // Update the last-step solution of the RK54 scheme + for (register int i = 0; i < Bubble->nODEs; i++) Bubble->kLast[i] = Bubble->k7[i]; + + // Update progress screen in the terminal (if applicable) + Bubble->progress_update(&(*Bubble).progress, Bubble->t - Bubble->tStart, Bubble->tEnd - Bubble->tStart); + } + return (0); } \ No newline at end of file From d132cc58082bc9b4c06af1d57ffdddfd749b3430 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Wed, 17 Jul 2024 16:05:53 -0400 Subject: [PATCH 037/138] bubbly screen ; fully working IC computations --- examples/bubblyscreen/IC/build/compile.sh | 5 + examples/bubblyscreen/IC/gather_results.py | 31 ++ examples/bubblyscreen/IC/run.apecss | 38 ++ .../bubblyscreen/IC/src/bubblyscreen_apecss.c | 417 ++++++++++++++++++ examples/bubblyscreen/README.md | 2 +- examples/bubblyscreen/plot_results.py | 130 ++++++ examples/bubblyscreen/run_bubblyscreen.sh | 65 +++ 7 files changed, 687 insertions(+), 1 deletion(-) create mode 100755 examples/bubblyscreen/IC/build/compile.sh create mode 100644 examples/bubblyscreen/IC/gather_results.py create mode 100644 examples/bubblyscreen/IC/run.apecss create mode 100644 examples/bubblyscreen/IC/src/bubblyscreen_apecss.c create mode 100644 examples/bubblyscreen/plot_results.py create mode 100755 examples/bubblyscreen/run_bubblyscreen.sh diff --git a/examples/bubblyscreen/IC/build/compile.sh b/examples/bubblyscreen/IC/build/compile.sh new file mode 100755 index 0000000..1569080 --- /dev/null +++ b/examples/bubblyscreen/IC/build/compile.sh @@ -0,0 +1,5 @@ +#!/bin/bash +rm bubblyscreen_apecss +cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release +make +rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/bubblyscreen/IC/gather_results.py b/examples/bubblyscreen/IC/gather_results.py new file mode 100644 index 0000000..7987f11 --- /dev/null +++ b/examples/bubblyscreen/IC/gather_results.py @@ -0,0 +1,31 @@ +import os + +# File designed to recover data for plotting results in bubbly screen case + +file_radii = open("bubblyscreen_radii.txt", "r") +lines_radii = file_radii.readlines() +file_radii.close() + +file_extremum = open("bubblyscreen_extremum.txt", "r") +lines_extremum = file_extremum.readlines() +file_extremum.close() + +firstline = lines_radii[0].split(" ") +f = float(firstline[3]) +p = float(firstline[5]) +d = float(firstline[7]) + +file_name = "bubblyscreen_{:.3E}_{:.2E}_{:.1f}".format(f, p, d) + +working_path = os.getcwd() +results_path = os.path.join(working_path, "results") + +results_radii = open(os.path.join(results_path, file_name + "_radii.txt"), "w") +for line in lines_radii : + results_radii.write(line) +results_radii.close() + +results_extremum = open(os.path.join(results_path, file_name + "_extremum.txt"), "w") +for line in lines_extremum : + results_extremum.write(line) +results_extremum.close() \ No newline at end of file diff --git a/examples/bubblyscreen/IC/run.apecss b/examples/bubblyscreen/IC/run.apecss new file mode 100644 index 0000000..cf42dde --- /dev/null +++ b/examples/bubblyscreen/IC/run.apecss @@ -0,0 +1,38 @@ +######################################################### +# # +# APECSS Options File # +# # +######################################################### + +BUBBLE +RPModel KM +Emissions IC 300.0e-6 +PressureAmbient 1.0e5 +END + +GAS +EoS IG +ReferencePressure 1.0e5 +ReferenceDensity 1.2 +PolytropicExponent 1.4 +END + +LIQUID +ReferencePressure 1.0e5 +ReferenceDensity 1000.0 +ReferenceSoundSpeed 1500.0 +Viscosity 0.00 +END + +INTERFACE +SurfaceTensionCoeff 0.00 +END + +RESULTS +Bubble +OutputFreqRP 5 +END + +ODESOLVER +tolerance 1.0e-10 +END diff --git a/examples/bubblyscreen/IC/src/bubblyscreen_apecss.c b/examples/bubblyscreen/IC/src/bubblyscreen_apecss.c new file mode 100644 index 0000000..f2aaf78 --- /dev/null +++ b/examples/bubblyscreen/IC/src/bubblyscreen_apecss.c @@ -0,0 +1,417 @@ +// This source file is part of APECSS, an open-source software toolbox +// for the computation of pressure-driven bubble dynamics and acoustic +// emissions in spherical symmetry. +// +// Copyright (C) 2022-2024 The APECSS Developers +// +// The APECSS Developers are listed in the README.md file available in +// the GitHub repository at https://github.com/polycfd/apecss. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// ------------------------------------------------------------------- +// APECSS standalone example of acoustically-interacting microbubbles +// in a finite bubbly screen based on Fan, Y., Li, H., & Fuster, +// D. (2021). Time-delayed interactions on acoustically driven bubbly +// screens. The Journal of the Acoustical Society of America, 150(6), +// 4219‑4231. https://doi.org/10.1121/10.0008905 +// ------------------------------------------------------------------- + +#include +#include "apecss.h" + +// Declaration of additional case-dependent functions +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +int apecss_bubble_new_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble); + +APECSS_FLOAT maxR; +APECSS_FLOAT minR; + +int main(int argc, char **args) +{ + char OptionsDir[APECSS_STRINGLENGTH]; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Set the case-dependent simulation parameters + const int nBubbles_x = 51; + const int nBubbles = nBubbles_x * nBubbles_x; // Number of bubbles + APECSS_FLOAT bubble_bubble_dist = 400.0e-6; // Bubble-bubble distance + + // Interbubble time-step, defining the frequency with which the neighbor influence is updated + APECSS_FLOAT dt_interbubble = 1.0e-8; + + // Initialize the simulation parameters given by the execution command + double tEnd = 0.0; + double fa = 0.0; + double pa = 0.0; + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + apecss_infoscreen(); + + /* Read commandline options */ + sprintf(OptionsDir, "./run.apecss"); // This is the default + int j = 1; // First argument is the call to the executable + while (j < argc) + { + if (strcmp("-options", args[j]) == 0) + { + sprintf(OptionsDir, "%s", args[j + 1]); + j += 2; + } + else if (strcmp("-tend", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &tEnd); + j += 2; + } + else if (strcmp("-freq", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &fa); + j += 2; + } + else if (strcmp("-amp", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &pa); + j += 2; + } + else if (strcmp("-h", args[j]) == 0) + { + apecss_helpscreen(); + } + else + { + char str[APECSS_STRINGLENGTH_SPRINTF]; + sprintf(str, "Unknown command line options: %s", args[j]); + apecss_erroronscreen(1, str); + ++j; + } + } + + /* Allocate and initialize Bubble structure */ + struct APECSS_Bubble *Bubbles[nBubbles]; + for (register int i = 0; i < nBubbles; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(nBubbles * sizeof(struct APECSS_Bubble)); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initializestruct(Bubbles[i]); + + /* Set default options and read the options for the bubble */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); + + /* Allocate the structures for the fluid properties and ODE solver parameters */ + struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); + struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); + struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); + struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); + + /* Set the default options for the fluid properties and solver parameters */ + apecss_gas_setdefaultoptions(Gas); + apecss_liquid_setdefaultoptions(Liquid); + apecss_interface_setdefaultoptions(Interface); + apecss_odesolver_setdefaultoptions(NumericsODE); + + /* Read the options file for the fluid properties and solver parameters */ + apecss_gas_readoptions(Gas, OptionsDir); + apecss_liquid_readoptions(Liquid, OptionsDir); + apecss_interface_readoptions(Interface, OptionsDir); + apecss_odesolver_readoptions(NumericsODE, OptionsDir); + + /* Associate the bubble with the relevant fluid properties and solver parameters */ + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Gas = Gas; + Bubbles[i]->Liquid = Liquid; + Bubbles[i]->Interface = Interface; + Bubbles[i]->NumericsODE = NumericsODE; + } + + /* Allocate and set the excitation parameters */ + struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); + Excitation->type = APECSS_EXCITATION_SIN; + Excitation->f = (APECSS_FLOAT) fa; + Excitation->dp = (APECSS_FLOAT) pa; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Excitation = Excitation; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Create individual folders for the results of each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (Bubbles[i]->Results != NULL) + { + sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", i); + struct stat st = {0}; + if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Process all options */ + apecss_gas_processoptions(Gas); + apecss_liquid_processoptions(Liquid); + apecss_interface_processoptions(Interface); + apecss_odesolver_processoptions(NumericsODE); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_processoptions(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Use the revised pressure at infinity, including neighbor contributions + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressure_infinity = interaction_bubble_pressure_infinity; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressurederivative_infinity = interaction_bubble_pressurederivative_infinity; + + // Initialize interaction structure + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); + + // Update interaction structure + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Interaction->nBubbles = nBubbles; + Bubbles[i]->Interaction->dp_neighbor = 0.0; + Bubbles[i]->Interaction->last_t_1 = 0.0; + Bubbles[i]->Interaction->last_t_2 = 0.0; + Bubbles[i]->Interaction->last_p_1 = 0.0; + Bubbles[i]->Interaction->last_p_2 = 0.0; + } + + // Define the size of each bubble + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->R0 = 1.0e-6; + Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; + } + + // Define center location for each bubble + int space = (int) (0.5 * (nBubbles_x - 1)); + int row = 0; + int col = 0; + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Interaction->location[0] = (col - space) * bubble_bubble_dist; + Bubbles[i]->Interaction->location[1] = (row - space) * bubble_bubble_dist; + Bubbles[i]->Interaction->location[2] = 0.0; + if ((col < 2 * space) && (col >= 0)) + { + col += 1; + } + else + { + row += 1; + col = 0; + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + clock_t starttimebubble = clock(); + APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system + + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->tStart = tSim; + Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; + Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step + } + + /* Initialize the bubble based on the selected options */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initialize(Bubbles[i]); + + /* Initialize */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_initialize(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Lists to gather maximum and minimum radius achieved by each bubble in steady state + APECSS_FLOAT max_radii[nBubbles]; + APECSS_FLOAT min_radii[nBubbles]; + + for (register int i = 0; i < nBubbles; i++) + { + max_radii[i] = Bubbles[i]->R; + min_radii[i] = Bubbles[i]->R; + } + + // File to retrieve the maximum and minimum radius evolution achieved in steady state + FILE *file_extremum; + file_extremum = fopen("bubblyscreen_extremum.txt", "w"); + + APECSS_FLOAT p0 = Bubbles[0]->p0; + APECSS_FLOAT poly = Gas->Gamma; + APECSS_FLOAT rho = Liquid->rhoref; + APECSS_FLOAT w0 = APECSS_SQRT((3 * poly * p0) / (APECSS_POW2(Bubbles[0]->R0) * rho)); + + fprintf(file_extremum, "w0(rad/s) %e f(Hz) %e p(Pa) %e D/R0 %e\n", w0, fa, pa, bubble_bubble_dist / Bubbles[0]->R0); + fprintf(file_extremum, "label x(m) y(m) z(m) R0(m) Rmin(m) Rmax(m)\n"); + + // File to retrieve the radius evolution during computation + FILE *file_radii; + file_radii = fopen("bubblyscreen_radii.txt", "w"); + fprintf(file_radii, "w0(rad/s) %e f(Hz) %e p(Pa) %e D/R0 %e\n", w0, fa, pa, bubble_bubble_dist / Bubbles[0]->R0); + fprintf(file_radii, "t(s) R(m)\n"); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Solve the bubble dynamics */ + while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered + { + APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); + tSim += dtSim; + + for (register int i = 0; i < nBubbles; i++) + { + maxR = 0.0; + minR = Bubbles[i]->R0; + apecss_bubble_new_solver_run(tSim, tEnd, Bubbles[i]); + + if (maxR > max_radii[i]) + { + max_radii[i] = maxR; + } + if (minR < min_radii[i]) + { + min_radii[i] = minR; + } + } + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Update the contribution of the neighbor bubble + apecss_interactions_instantaneous(Bubbles); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + fprintf(file_radii, "%e", tSim); + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_radii, " %e", Bubbles[i]->R); + } + fprintf(file_radii, "\n"); + + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; + Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; + + Bubbles[i]->Interaction->last_t_1 = tSim; + Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; + } + } + + /* Complete results file */ + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_extremum, "%d %e %e %e %e %e %e\n", i, Bubbles[i]->Interaction->location[0], Bubbles[i]->Interaction->location[1], + Bubbles[i]->Interaction->location[2], Bubbles[i]->R0, min_radii[i], max_radii[i]); + } + fclose(file_extremum); + + fclose(file_radii); + + /* Finalize the simulation*/ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_finalize(Bubbles[i]); + + char str[APECSS_STRINGLENGTH_SPRINTF]; + for (register int i = 0; i < nBubbles; i++) + { + sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", i, Bubbles[i]->dtNumber, Bubbles[i]->nSubIter, + (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); + apecss_writeonscreen(str); + } + + for (register int i = 0; i < nBubbles; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); + for (register int i = 0; i < nBubbles; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); + + /* Make sure all allocated memory is freed */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_freestruct(Bubbles[i]); + + for (register int i = 0; i < nBubbles; i++) free(Bubbles[i]); + free(Gas); + free(Liquid); + free(Interface); + free(NumericsODE); + free(Excitation); + + return (0); +} + +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * t) + Bubble->Interaction->dp_neighbor); +} + +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + // Approximate numerical computation of p_infinity derivative + APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; + APECSS_FLOAT derivative = -Bubble->Excitation->dp * 2.0 * APECSS_PI * Bubble->Excitation->f * APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * t); + if (delta_t > Bubble->dt) + { + return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) / (Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2))); + } + else + { + return (derivative); + } +} + +int apecss_bubble_new_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble) +{ + while (Bubble->t < tend - 0.01 * Bubble->NumericsODE->dtMin) + { + // Store the previous solution for sub-iterations + for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSolOld[i] = Bubble->ODEsSol[i]; + + // Check what comes next: the end of the solver run or, if applicable, a time instance to output the emissions + APECSS_FLOAT next_event_time = Bubble->results_emissionstime_check(tend, Bubble); + + // Set the time-step for the ODEs + apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); + + // Solve the ODEs + Bubble->err = apecss_odesolver(Bubble); + + // Perform sub-iterations on the control of the time-step when err > tol + register int subiter = 0; + while ((Bubble->err > Bubble->NumericsODE->tol) && (subiter < Bubble->NumericsODE->maxSubIter)) + { + ++subiter; + // Rewind the solution + for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSol[i] = Bubble->ODEsSolOld[i]; + // Set the time-step for the ODEs + apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); + // Solve the ODEs again + Bubble->err = apecss_odesolver(Bubble); + } + Bubble->nSubIter += subiter; + + // Set new values + ++(Bubble->dtNumber); + Bubble->t += Bubble->dt; + Bubble->U = Bubble->ODEsSol[0]; + Bubble->R = Bubble->ODEsSol[1]; + + // Retrieve data to compute radius oscillation amplitude during + if (Bubble->t > tEnd - 10.0 / Bubble->Excitation->f) + { + maxR = APECSS_MAX(maxR, Bubble->R); + } + if (Bubble->t > tEnd - 10.0 / Bubble->Excitation->f) + { + minR = APECSS_MIN(minR, Bubble->R); + } + + // Update allocation of the results (if necessary) + Bubble->results_emissionsnodeminmax_identify(Bubble); + Bubble->results_emissionsnode_alloc(Bubble); + + // Acoustic emissions (if applicable) + Bubble->emissions_update(Bubble); + + // Store results (if applicable) + Bubble->results_rayleighplesset_store(Bubble); + Bubble->results_emissionsspace_store(Bubble); + + // Write one-off results (if applicable) + Bubble->results_emissionstime_write(Bubble); + + // Update the last-step solution of the RK54 scheme + for (register int i = 0; i < Bubble->nODEs; i++) Bubble->kLast[i] = Bubble->k7[i]; + + // Update progress screen in the terminal (if applicable) + Bubble->progress_update(&(*Bubble).progress, Bubble->t - Bubble->tStart, Bubble->tEnd - Bubble->tStart); + } + + return (0); +} \ No newline at end of file diff --git a/examples/bubblyscreen/README.md b/examples/bubblyscreen/README.md index bd82f21..8059ba6 100644 --- a/examples/bubblyscreen/README.md +++ b/examples/bubblyscreen/README.md @@ -1 +1 @@ -This example builds a standalone APECSS code for a 51x51 finite bubbly screen of interacting microbubbles, inspired by [](). \ No newline at end of file +This example builds a standalone APECSS code for a 51x51 finite bubbly screen of interacting microbubbles, inspired by [Fan, Y., Li, H., & Fuster, D. (2021). Time-delayed interactions on acoustically driven bubbly screens. The Journal of the Acoustical Society of America, 150(6), 4219‑4231.](https://doi.org/10.1121/10.0008905). Two interaction type are considered : either the _standard incompressible model_ ("IC") or the newly developped _quasi acoustic model_ ("QA"). In order to optimize computational costs, the quasi acoustic computations are run by using parallelization. The computations are quite heavy because steady state must be achieved, leading to large enough computed times (IC interactions are taking around an hour for 35 microseconds of computed times, while it's around with 15 cores of an Intel 13th gen I7 13700K x24). The displayed results are for each excitation frequency tested the normalized radius oscillation amplitude of each bubble in steady state. \ No newline at end of file diff --git a/examples/bubblyscreen/plot_results.py b/examples/bubblyscreen/plot_results.py new file mode 100644 index 0000000..f98d663 --- /dev/null +++ b/examples/bubblyscreen/plot_results.py @@ -0,0 +1,130 @@ +import os +import numpy as np +import matplotlib.pyplot as plt +from math import pi +from matplotlib.patches import Circle + +fontsize = 12 + +plt.rcParams['font.family']='serif' +plt.rcParams['font.serif']=['Times New Roman'] + plt.rcParams['font.serif'] +plt.rcParams['mathtext.fontset']='stix' +plt.rcParams['font.size']=fontsize + +cm = 1/2.54 + +# This file is designed to gather data in order to reproduce the average radius evolution +# This exemple is a reproduction from the test from Fig.5 in 2021 Fan's article +# DOI : 10.1121/10.0008905 + +######### Step 1 : Retrieving data ################################################################################################################## +interaction_types = ["IC", "QA"] +excitation_w = [0.5, 0.9, 1.0, 1.5] +ratio_D_R0 = [400] + +dic_bubbly_screen = {} +for intype in interaction_types : + dic_bubbly_screen[intype] = {} + for w in excitation_w : + dic_bubbly_screen[intype][w] = {} + for r in ratio_D_R0 : + dic_bubbly_screen[intype][w][r] = np.zeros((51,51),dtype=float) + +for intype in interaction_types : + path = os.path.join(os.getcwd(), intype) + path = os.path.join(path, "results") + for file in os.listdir(path) : + if "_extremum" in file : + data = open(os.path.join(path, file), "r") + lines = data.readlines() + data.close() + + firstline = lines[0].split(" ") + w0 = float(firstline[1]) + fa = float(firstline[3]) + pa = float(firstline[5]) + ratio = int(float(firstline[7])) + + R0 = float(lines[2].split(" ")[4]) + D = ratio * R0 + + w = float("{:.1f}".format(2 * pi * fa / w0)) + + if pa == 10**2 : + for line in lines[2:] : + x = float(line.split(" ")[1]) + y = float(line.split(" ")[2]) + r_amp = (float(line.split(" ")[6]) - float(line.split(" ")[5])) / float(line.split(" ")[4]) + + i = int((y/D)) + 25 + j = int((x/D)) + 25 + + dic_bubbly_screen[intype][w][ratio][i][j] = r_amp + +######### Functions ################################################################################################################################# + +def plot_oscillation_distribution(fig, axs, row, col, nbubbles_x, inttype, ratio_w, ratio_d, order=0, clear=False) : + space = int(0.5 * (nbubbles_x - 1)) + X = [-space + j for j in range(nbubbles_x)] + Y = [-space + i for i in range(nbubbles_x)] + X, Y = np.meshgrid(X, Y) + + axs[row, col].set_title(r"$\omega/\omega_{0}$ = " + "{:.1f}".format(ratio_w)) + cset = plt.pcolormesh(X, Y, dic_bubbly_screen[inttype][ratio_w][ratio_d]*10**(order)) + + # Clearing options to not show pcolormesh (only used for the last plotted distribution on each figure) + if clear : + axs[row, col].clear() + axs[row, col].set_xlabel(r"x/D") + axs[row, col].set_xlim(xmin=-(space + 0.5),xmax=(space + 0.5)) + axs[row, col].set_ylabel(r"y/D") + axs[row, col].set_ylim(ymin=-(space + 0.5),ymax=(space + 0.5)) + axs[row, col].set_title(r"$\omega/\omega_{0}$ = " + "{:.1f}".format(ratio_w)) + axs[row, col].set_aspect("equal") + + clb = fig.colorbar(cset, ax=axs[row, col], shrink=0.7) + if order > 0 : + clb.ax.set_title(r"$|r'| \times 10^{-order}$".replace("order", str(order))) + else : + clb.ax.set_title(r"$|r'|$") + colors = cset.cmap(cset.norm(cset.get_array())) + for i in range(nbubbles_x) : + for j in range(nbubbles_x) : + index = nbubbles_x * i + j + index_color = colors[index] + x = j - space + y = i - space + circle = Circle((x, y), 0.4, facecolor=(index_color[0], index_color[1], index_color[2])) + axs[row, col].add_patch(circle) + +######### Step 2 : Plot results ##################################################################################################################### + +######### D/R0 = 400 : Comparison between QA and IC ############################################### + +nrow = 2 +ncol = 4 +fig, axs = plt.subplots(nrow,ncol,figsize=(55*cm, 27.5*cm)) +for i in range(nrow) : + for j in range(ncol) : + axs[i,j].set_xlabel(r"x/D") + axs[i,j].set_xlim(xmin=-25.5,xmax=25.5) + axs[i,j].set_ylabel(r"y/D") + axs[i,j].set_ylim(ymin=-25.5,ymax=25.5) + axs[i,j].set_aspect("equal") + +### First row : QA ### +plt.figtext(0.5, 0.85, r"QA, $D/R_{0}$ = 400", fontsize=16.5, horizontalalignment="center") +plot_oscillation_distribution(fig, axs, 0, 0, 51, "QA", 0.5, 400) +plot_oscillation_distribution(fig, axs, 0, 1, 51, "QA", 0.9, 400) +plot_oscillation_distribution(fig, axs, 0, 2, 51, "QA", 1.0, 400) +plot_oscillation_distribution(fig, axs, 0, 3, 51, "QA", 1.5, 400) + +### Second row : IC ### +plt.figtext(0.5, 0.5, r"IC, $D/R_{0}$ = 400", fontsize=16.5, horizontalalignment="center") +plot_oscillation_distribution(fig, axs, 1, 0, 51, "IC", 0.5, 400, order=4) +plot_oscillation_distribution(fig, axs, 1, 1, 51, "IC", 0.9, 400, order=3) +plot_oscillation_distribution(fig, axs, 1, 2, 51, "IC", 1.0, 400, order=3) +plot_oscillation_distribution(fig, axs, 1, 3, 51, "IC", 1.5, 400, order=4, clear=True) + +fig.subplots_adjust(hspace=0.05*cm, wspace=0.65*cm) +fig.savefig("bubblyscreen_ComparisonQAIC.pdf", bbox_inches="tight",pad_inches=0.035) \ No newline at end of file diff --git a/examples/bubblyscreen/run_bubblyscreen.sh b/examples/bubblyscreen/run_bubblyscreen.sh new file mode 100755 index 0000000..3d3316a --- /dev/null +++ b/examples/bubblyscreen/run_bubblyscreen.sh @@ -0,0 +1,65 @@ +######### Parameters ################################################################################################################################ + +ncore=15 +nbubbles=2601 + +######### Incompressible computations ############################################################################################################### + +cd IC/build +./compile.sh +cd .. + +f_list=(1.631e06 2.934e06 3.262e06 4.893e06) +for f in "${f_list[@]}" +do + ./build/bubblyscreen_apecss -options run.apecss -freq $f -amp 100.0 -tend 10.0e-6 + python3 gather_results.py +done + +cd .. + +echo "" +echo "Incompressible test cases passed" +echo "" + +######### Quasi acoustic computations ############################################################################################################### + +# cd QA/build +# ./compile.sh +# cd .. + +# cd .. + +# echo "" +# echo "Quasi acoustic test cases passed" +# echo "" + +######### Plotting results ########################################################################################################################## + +python3 plot_results.py + +######### Cleaning ################################################################################################################################## + +cd IC +for ((c=0; c<$nbubbles; c++)) +do + rm -rf Bubble_$c +done +rm -rf bubblyscreen_radii.txt bubblyscreen_extremum.txt +cd .. + +# cd QA +# for ((c=0; c<$nbubbles; c++)) +# do +# rm -rf Bubble_$c +# done +# rm -rf bubblyscreen_radii.txt +# for ((c=0; c<$ncore; c++)) +# do +# rm -rf bubblyscreen_extremum_$c.txt +# done +# cd .. + +echo "" +echo "Cleaning completed" +echo "" \ No newline at end of file From 15da589faac91d270508def9e2cfd163b9323587 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Wed, 17 Jul 2024 16:06:36 -0400 Subject: [PATCH 038/138] spherical cluster interactions ; better file headline --- .../src/sphericalclusterinteractions_apecss.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c b/examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c index d4c6bd5..fb9af24 100644 --- a/examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c +++ b/examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c @@ -12,8 +12,11 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. // ------------------------------------------------------------------- -// APECSS standalone example of acoustically-interacting microbubbles, -// demonstrating a simple parallelization of APECSS. +// APECSS standalone example of acoustically-interacting microbubbles +// in a spherical cluster based on Maeda, K., & Colonius, T. (2019). +// Bubble cloud dynamics in an ultrasound field. Journal of Fluid +// Mechanics, 862, 1105‑1134 +// DOI : https://doi.org/10.1017/jfm.2018.968 // ------------------------------------------------------------------- #include From 4a3dac998483fe9b5096691342878b4d57285088 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 19 Jul 2024 15:29:44 -0400 Subject: [PATCH 039/138] spherical cluster cavitation onset ; new folder --- .../{ => IC}/build/compile.sh | 0 .../IC/run.apecss | 36 +++ .../sphericalclustercavitationonset_apecss.c | 299 ++++++++++++++++++ .../QA/build/compile.sh | 5 + .../{ => QA}/execmpi.sh | 0 .../{ => QA}/run.apecss | 2 - .../sphericalclustercavitationonset_apecss.c | 4 +- .../sphericalclustercavitationonset/README.md | 0 8 files changed, 342 insertions(+), 4 deletions(-) rename examples/sphericalclustercavitationonset/{ => IC}/build/compile.sh (100%) create mode 100644 examples/sphericalclustercavitationonset/IC/run.apecss create mode 100644 examples/sphericalclustercavitationonset/IC/src/sphericalclustercavitationonset_apecss.c create mode 100755 examples/sphericalclustercavitationonset/QA/build/compile.sh rename examples/sphericalclustercavitationonset/{ => QA}/execmpi.sh (100%) rename examples/sphericalclustercavitationonset/{ => QA}/run.apecss (93%) rename examples/sphericalclustercavitationonset/{ => QA}/src/sphericalclustercavitationonset_apecss.c (99%) create mode 100644 examples/sphericalclustercavitationonset/README.md diff --git a/examples/sphericalclustercavitationonset/build/compile.sh b/examples/sphericalclustercavitationonset/IC/build/compile.sh similarity index 100% rename from examples/sphericalclustercavitationonset/build/compile.sh rename to examples/sphericalclustercavitationonset/IC/build/compile.sh diff --git a/examples/sphericalclustercavitationonset/IC/run.apecss b/examples/sphericalclustercavitationonset/IC/run.apecss new file mode 100644 index 0000000..89c4131 --- /dev/null +++ b/examples/sphericalclustercavitationonset/IC/run.apecss @@ -0,0 +1,36 @@ +######################################################### +# # +# APECSS Options File # +# # +######################################################### + +BUBBLE +RPModel KM +Emissions IC 300.0e-6 +PressureAmbient 0.1013e6 +END + +GAS +EoS IG +ReferenceDensity 1.2 +PolytropicExponent 1.4 +END + +LIQUID +ReferencePressure 0.1013e6 +ReferenceDensity 1000.0 +ReferenceSoundSpeed 1500.0 +Viscosity 1.002e-3 +END + +INTERFACE +SurfaceTensionCoeff 0.0728 +END + +RESULTS +Bubble +END + +ODESOLVER +tolerance 1.0e-10 +END diff --git a/examples/sphericalclustercavitationonset/IC/src/sphericalclustercavitationonset_apecss.c b/examples/sphericalclustercavitationonset/IC/src/sphericalclustercavitationonset_apecss.c new file mode 100644 index 0000000..5ddf033 --- /dev/null +++ b/examples/sphericalclustercavitationonset/IC/src/sphericalclustercavitationonset_apecss.c @@ -0,0 +1,299 @@ +// This source file is part of APECSS, an open-source software toolbox +// for the computation of pressure-driven bubble dynamics and acoustic +// emissions in spherical symmetry. +// +// Copyright (C) 2022-2024 The APECSS Developers +// +// The APECSS Developers are listed in the README.md file available in +// the GitHub repository at https://github.com/polycfd/apecss. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// ------------------------------------------------------------------- +// APECSS standalone example of acoustically-interacting microbubbles +// in a spherical cluster with the goal to study cavitation onset +// ------------------------------------------------------------------- + +#include +#include "apecss.h" + +// Declaration of additional case-dependent functions +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); + +// Declaration of the structure holding the interaction variables of each bubble +struct Interaction +{ + APECSS_FLOAT dp_neighbor; +}; + +int main(int argc, char **args) +{ + char OptionsDir[APECSS_STRINGLENGTH]; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Set the case-dependent simulation parameters + const int nBubbles = 2; // Number of bubbles + APECSS_FLOAT bubble_bubble_dist = 200.0e-6; // Bubble-bubble distance + + // Interbubble time-step, defining the frequency with which the neighbor influence is updated + APECSS_FLOAT dt_interbubble = 1.0e-8; + + // Initialize the simulation parameters given by the execution command + double tEnd = 0.0; + double fa = 0.0; + double pa = 0.0; + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + apecss_infoscreen(); + + /* Read commandline options */ + sprintf(OptionsDir, "./run.apecss"); // This is the default + int j = 1; // First argument is the call to the executable + while (j < argc) + { + if (strcmp("-options", args[j]) == 0) + { + sprintf(OptionsDir, "%s", args[j + 1]); + j += 2; + } + else if (strcmp("-tend", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &tEnd); + j += 2; + } + else if (strcmp("-freq", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &fa); + j += 2; + } + else if (strcmp("-amp", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &pa); + j += 2; + } + else if (strcmp("-h", args[j]) == 0) + { + apecss_helpscreen(); + } + else + { + char str[APECSS_STRINGLENGTH_SPRINTF]; + sprintf(str, "Unknown command line options: %s", args[j]); + apecss_erroronscreen(1, str); + ++j; + } + } + + /* Allocate and initialize Bubble structure */ + struct APECSS_Bubble *Bubbles[nBubbles]; + for (register int i = 0; i < nBubbles; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(nBubbles * sizeof(struct APECSS_Bubble)); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initializestruct(Bubbles[i]); + + /* Set default options and read the options for the bubble */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); + + // // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // // Allocate and set bubble-associated variables for the interaction + // for (register int i = 0; i < nBubbles; i++) + // { + // struct Interaction *interaction_data = (struct Interaction *) malloc(sizeof(struct Interaction)); + // interaction_data->dp_neighbor = 0.0; // Pressure excerted by the neighbor bubbles + + // // Hook interaction-structure to the void data pointer + // Bubbles[i]->user_data = interaction_data; + // } + // // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Allocate the structures for the fluid properties and ODE solver parameters */ + struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); + struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); + struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); + struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); + + /* Set the default options for the fluid properties and solver parameters */ + apecss_gas_setdefaultoptions(Gas); + apecss_liquid_setdefaultoptions(Liquid); + apecss_interface_setdefaultoptions(Interface); + apecss_odesolver_setdefaultoptions(NumericsODE); + + /* Read the options file for the fluid properties and solver parameters */ + apecss_gas_readoptions(Gas, OptionsDir); + apecss_liquid_readoptions(Liquid, OptionsDir); + apecss_interface_readoptions(Interface, OptionsDir); + apecss_odesolver_readoptions(NumericsODE, OptionsDir); + + /* Associate the bubble with the relevant fluid properties and solver parameters */ + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Gas = Gas; + Bubbles[i]->Liquid = Liquid; + Bubbles[i]->Interface = Interface; + Bubbles[i]->NumericsODE = NumericsODE; + } + + /* Allocate and set the excitation parameters */ + struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); + Excitation->type = APECSS_EXCITATION_SIN; + Excitation->f = (APECSS_FLOAT) fa; + Excitation->dp = (APECSS_FLOAT) pa; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Excitation = Excitation; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Create individual folders for the results of each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (Bubbles[i]->Results != NULL) + { + sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", i); + struct stat st = {0}; + if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Process all options */ + apecss_gas_processoptions(Gas); + apecss_liquid_processoptions(Liquid); + apecss_interface_processoptions(Interface); + apecss_odesolver_processoptions(NumericsODE); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_processoptions(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Use the revised pressure at infinity, including neighbor contributions + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressure_infinity = interaction_bubble_pressure_infinity; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressurederivative_infinity = interaction_bubble_pressurederivative_infinity; + + // Initialize interaction structure + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); + + // Update interaction structure + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Interaction->nBubbles = nBubbles; + Bubbles[i]->Interaction->dp_neighbor = 0.0; + Bubbles[i]->Interaction->last_t_1 = 0.0; + Bubbles[i]->Interaction->last_t_2 = 0.0; + Bubbles[i]->Interaction->last_p_1 = 0.0; + Bubbles[i]->Interaction->last_p_2 = 0.0; + } + + // Define the size of each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (0 == i) + Bubbles[i]->R0 = 5.0e-6; + else if (1 == i) + Bubbles[i]->R0 = 10.0e-6; + + Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; + } + + // Define center location for each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (0 == i) + { + Bubbles[i]->Interaction->location[0] = 0.0; + Bubbles[i]->Interaction->location[1] = 0.0; + Bubbles[i]->Interaction->location[2] = 0.0; + } + else if (1 == i) + { + Bubbles[i]->Interaction->location[0] = bubble_bubble_dist; + Bubbles[i]->Interaction->location[1] = 0.0; + Bubbles[i]->Interaction->location[2] = 0.0; + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + clock_t starttimebubble = clock(); + APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system + + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->tStart = tSim; + Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; + Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step + } + + /* Initialize the bubble based on the selected options */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initialize(Bubbles[i]); + + /* Initialize */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_initialize(Bubbles[i]); + + /* Solve the bubble dynamics */ + while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered + { + APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); + tSim += dtSim; + + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); + + // for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Update the contribution of the neighbor bubble + apecss_interactions_instantaneous(Bubbles); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; + Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; + + Bubbles[i]->Interaction->last_t_1 = tSim; + Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; + } + } + + /* Finalize the simulation*/ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_finalize(Bubbles[i]); + + char str[APECSS_STRINGLENGTH_SPRINTF]; + for (register int i = 0; i < nBubbles; i++) + { + sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", i, Bubbles[i]->dtNumber, Bubbles[i]->nSubIter, + (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); + apecss_writeonscreen(str); + } + + for (register int i = 0; i < nBubbles; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); + for (register int i = 0; i < nBubbles; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); + + /* Make sure all allocated memory is freed */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_freestruct(Bubbles[i]); + + for (register int i = 0; i < nBubbles; i++) free(Bubbles[i]); + free(Gas); + free(Liquid); + free(Interface); + free(NumericsODE); + free(Excitation); + + return (0); +} + +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * t) + Bubble->Interaction->dp_neighbor); +} + +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + // Approximate numerical computation of p_infinity derivative + APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; + APECSS_FLOAT derivative = -Bubble->Excitation->dp * 2.0 * APECSS_PI * Bubble->Excitation->f * APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * t); + if (delta_t > Bubble->dt) + { + return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) / (Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2))); + } + else + { + return (derivative); + } +} \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/QA/build/compile.sh b/examples/sphericalclustercavitationonset/QA/build/compile.sh new file mode 100755 index 0000000..33147c8 --- /dev/null +++ b/examples/sphericalclustercavitationonset/QA/build/compile.sh @@ -0,0 +1,5 @@ +#!/bin/bash +rm sphericalclustercavitationonset_apecss +cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release +make +rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/execmpi.sh b/examples/sphericalclustercavitationonset/QA/execmpi.sh similarity index 100% rename from examples/sphericalclustercavitationonset/execmpi.sh rename to examples/sphericalclustercavitationonset/QA/execmpi.sh diff --git a/examples/sphericalclustercavitationonset/run.apecss b/examples/sphericalclustercavitationonset/QA/run.apecss similarity index 93% rename from examples/sphericalclustercavitationonset/run.apecss rename to examples/sphericalclustercavitationonset/QA/run.apecss index 04eb3d9..52906a5 100644 --- a/examples/sphericalclustercavitationonset/run.apecss +++ b/examples/sphericalclustercavitationonset/QA/run.apecss @@ -33,6 +33,4 @@ END ODESOLVER tolerance 1.0e-10 -MinTimeStep 1.0e-14 -MaxTimeStep 1.0e-05 END diff --git a/examples/sphericalclustercavitationonset/src/sphericalclustercavitationonset_apecss.c b/examples/sphericalclustercavitationonset/QA/src/sphericalclustercavitationonset_apecss.c similarity index 99% rename from examples/sphericalclustercavitationonset/src/sphericalclustercavitationonset_apecss.c rename to examples/sphericalclustercavitationonset/QA/src/sphericalclustercavitationonset_apecss.c index d86857d..35d37b1 100644 --- a/examples/sphericalclustercavitationonset/src/sphericalclustercavitationonset_apecss.c +++ b/examples/sphericalclustercavitationonset/QA/src/sphericalclustercavitationonset_apecss.c @@ -12,8 +12,8 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. // ------------------------------------------------------------------- -// APECSS standalone example of acoustically-interacting microbubbles, -// demonstrating a simple parallelization of APECSS. +// APECSS standalone example of acoustically-interacting microbubbles +// in a spherical cluster with the goal to study cavitation onset // ------------------------------------------------------------------- #include diff --git a/examples/sphericalclustercavitationonset/README.md b/examples/sphericalclustercavitationonset/README.md new file mode 100644 index 0000000..e69de29 From 18adb0b8a850871659cba45e990787786cefbb9f Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 19 Jul 2024 17:24:25 -0400 Subject: [PATCH 040/138] spherical cluster cavitation onset ; working IC folder --- .../IC/gather_results.py | 47 +++++ .../sphericalclustercavitationonset_apecss.c | 174 +++++++++++++++--- .../sphericalclustercavitationonset/README.md | 1 + .../run_sphericalclustercavitationonset.sh | 41 +++++ 4 files changed, 235 insertions(+), 28 deletions(-) create mode 100644 examples/sphericalclustercavitationonset/IC/gather_results.py create mode 100755 examples/sphericalclustercavitationonset/run_sphericalclustercavitationonset.sh diff --git a/examples/sphericalclustercavitationonset/IC/gather_results.py b/examples/sphericalclustercavitationonset/IC/gather_results.py new file mode 100644 index 0000000..6e44890 --- /dev/null +++ b/examples/sphericalclustercavitationonset/IC/gather_results.py @@ -0,0 +1,47 @@ +import os + +# File designed to recover data for plotting results in cavitation onset case + +file = open("onset_results.txt", "r") +lines = file.readlines() +file.close() + +count = int(lines[0].split(" ")[0]) +png = float(lines[0].split(" ")[5]) +cl_distrib = int(lines[0].split(" ")[7]) + +if cl_distrib == 0 : + # monodispersed spherical cluster + file_name = "mono_{}_{:.4E}.txt".format(count, png) + +else : + # polydispersed spherical cluster + file_name = "poly_{}_{:.4E}.txt".format(count, png) + +working_path = os.getcwd() +results_path = os.path.join(working_path, "results") +file_results = open(os.path.join(results_path, file_name), "w") + +for line in lines : + file_results.write(line) + +file_results.close() + +file_loc = open("bubble_loc.txt", "r") +lines_loc = file_loc.readlines() +file_loc.close() + +if cl_distrib == 0 : + # monodispersed spherical cluster + file_name_loc = "mono_{}_{:.4E}_loc.txt".format(count, png) + +else : + # polydispersed spherical cluster + file_name_loc = "poly_{}_{:.4E}_loc.txt".format(count, png) + +file_loc_results = open(os.path.join(results_path, file_name_loc), "w") + +for line in lines_loc : + file_loc_results.write(line) + +file_loc_results.close() \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/IC/src/sphericalclustercavitationonset_apecss.c b/examples/sphericalclustercavitationonset/IC/src/sphericalclustercavitationonset_apecss.c index 5ddf033..ce62639 100644 --- a/examples/sphericalclustercavitationonset/IC/src/sphericalclustercavitationonset_apecss.c +++ b/examples/sphericalclustercavitationonset/IC/src/sphericalclustercavitationonset_apecss.c @@ -19,6 +19,27 @@ #include #include "apecss.h" +APECSS_FLOAT rand_range(double min, double max) +{ + double random = (drand48()); + double range = (max - min) * random; + double number = min + range; + + return (APECSS_FLOAT) number; +} + +APECSS_FLOAT normal_distribution(double mu, double sigma) +{ + // Generating a normal distribution using Box-Muller transform, with mu as mean and sigma**2 as variance + double u1 = (drand48()); + while (u1 == 0.0) u1 = (drand48()); + double u2 = (drand48()); + + double mag = sigma * APECSS_SQRT(-2.0 * APECSS_LOG(u1)); + double z1 = mag * cos(2 * APECSS_PI * u2) + mu; + return (APECSS_FLOAT) z1; +} + // Declaration of additional case-dependent functions APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); @@ -35,8 +56,9 @@ int main(int argc, char **args) // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // Set the case-dependent simulation parameters - const int nBubbles = 2; // Number of bubbles - APECSS_FLOAT bubble_bubble_dist = 200.0e-6; // Bubble-bubble distance + const int nBubbles = 2500; // Number of bubbles + APECSS_FLOAT bubble_bubble_dist = 100.0e-6; // Bubble-bubble minimal distance + APECSS_FLOAT cluster_radius = 2.5e-3; // Spherical cluster radius // Interbubble time-step, defining the frequency with which the neighbor influence is updated APECSS_FLOAT dt_interbubble = 1.0e-8; @@ -45,6 +67,7 @@ int main(int argc, char **args) double tEnd = 0.0; double fa = 0.0; double pa = 0.0; + int cluster_distrib = 0; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< apecss_infoscreen(); @@ -74,6 +97,11 @@ int main(int argc, char **args) sscanf(args[j + 1], "%le", &pa); j += 2; } + else if (strcmp("-cldistrib", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &cluster_distrib); + j += 2; + } else if (strcmp("-h", args[j]) == 0) { apecss_helpscreen(); @@ -96,18 +124,6 @@ int main(int argc, char **args) for (register int i = 0; i < nBubbles; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); for (register int i = 0; i < nBubbles; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); - // // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // // Allocate and set bubble-associated variables for the interaction - // for (register int i = 0; i < nBubbles; i++) - // { - // struct Interaction *interaction_data = (struct Interaction *) malloc(sizeof(struct Interaction)); - // interaction_data->dp_neighbor = 0.0; // Pressure excerted by the neighbor bubbles - - // // Hook interaction-structure to the void data pointer - // Bubbles[i]->user_data = interaction_data; - // } - // // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - /* Allocate the structures for the fluid properties and ODE solver parameters */ struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); @@ -182,30 +198,75 @@ int main(int argc, char **args) } // Define the size of each bubble - for (register int i = 0; i < nBubbles; i++) + if (cluster_distrib == 0) { - if (0 == i) - Bubbles[i]->R0 = 5.0e-6; - else if (1 == i) + // Monodispersed cluster + for (register int i = 0; i < nBubbles; i++) + { Bubbles[i]->R0 = 10.0e-6; - - Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; + Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; + } + } + else + { + // Polydispersed cluster (radii distribution is following a log normal law) + double mu = 0.0; + double sigma = 0.7; + APECSS_FLOAT radius_ref = 10.0e-6; + for (register int i = 0; i < nBubbles; i++) + { + APECSS_FLOAT radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); + while (radius > 20 * radius_ref) + { + // Small step to ensure no too big bubbles are generated (the distribution is conserved still) + radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); + } + Bubbles[i]->R0 = radius; + Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; + } } // Define center location for each bubble for (register int i = 0; i < nBubbles; i++) { - if (0 == i) + if (i == 0) { Bubbles[i]->Interaction->location[0] = 0.0; Bubbles[i]->Interaction->location[1] = 0.0; Bubbles[i]->Interaction->location[2] = 0.0; } - else if (1 == i) + else { - Bubbles[i]->Interaction->location[0] = bubble_bubble_dist; - Bubbles[i]->Interaction->location[1] = 0.0; - Bubbles[i]->Interaction->location[2] = 0.0; + APECSS_FLOAT x = rand_range((double) -cluster_radius, (double) cluster_radius); + APECSS_FLOAT y = rand_range((double) -cluster_radius, (double) cluster_radius); + APECSS_FLOAT z = rand_range((double) -cluster_radius, (double) cluster_radius); + + APECSS_FLOAT radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); + + while (radius > cluster_radius) + { + x = rand_range((double) -cluster_radius, (double) cluster_radius); + y = rand_range((double) -cluster_radius, (double) cluster_radius); + z = rand_range((double) -cluster_radius, (double) cluster_radius); + + radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); + } + + Bubbles[i]->Interaction->location[0] = x; + Bubbles[i]->Interaction->location[1] = y; + Bubbles[i]->Interaction->location[2] = z; + + for (register int k = 0; k < i; k++) + { + APECSS_FLOAT bubbledist = APECSS_SQRT(APECSS_POW2(Bubbles[i]->Interaction->location[0] - Bubbles[k]->Interaction->location[0]) + + APECSS_POW2(Bubbles[i]->Interaction->location[1] - Bubbles[k]->Interaction->location[1]) + + APECSS_POW2(Bubbles[i]->Interaction->location[2] - Bubbles[k]->Interaction->location[2])); + if (bubbledist < bubble_bubble_dist) + { + i--; + break; + } + } } } // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @@ -226,6 +287,26 @@ int main(int argc, char **args) /* Initialize */ for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_initialize(Bubbles[i]); + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Files to retrieve all valuable information for cavitation onset test case + FILE *file_loc; + file_loc = fopen("bubble_loc.txt", "w"); + fprintf(file_loc, "#number x(m) y(m) z(m)\n"); + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_loc, "%d %e %e %e\n", i, Bubbles[i]->Interaction->location[0], Bubbles[i]->Interaction->location[1], Bubbles[i]->Interaction->location[2]); + } + fclose(file_loc); + + FILE *file_onset; + file_onset = fopen("onset_results.txt", "w"); + fprintf(file_onset, "%d Bubbles p0(pa) %e png(Pa) %e cl_distrib %d\n", nBubbles, Liquid->pref, pa, cluster_distrib); + fprintf(file_onset, "Initial_radii(m)"); + for (register int i = 0; i < nBubbles; i++) fprintf(file_onset, " %e", Bubbles[i]->R0); + fprintf(file_onset, "\n"); + fprintf(file_onset, "#Time(s) R(m) Pt(Pa)\n"); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + /* Solve the bubble dynamics */ while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered { @@ -241,6 +322,20 @@ int main(int argc, char **args) apecss_interactions_instantaneous(Bubbles); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Retrieve data + fprintf(file_onset, "%e", tSim); + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_onset, " %e", Bubbles[i]->R); + } + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_onset, " %e", Bubbles[i]->get_pressure_infinity(Bubbles[i]->t, Bubbles[i])); + } + fprintf(file_onset, "\n"); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + for (register int i = 0; i < nBubbles; i++) { Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; @@ -251,6 +346,8 @@ int main(int argc, char **args) } } + fclose(file_onset); + /* Finalize the simulation*/ for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_finalize(Bubbles[i]); @@ -280,17 +377,38 @@ int main(int argc, char **args) APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { - return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * t) + Bubble->Interaction->dp_neighbor); + APECSS_FLOAT T = 10.0e-06; + if (t < T) + { + return (Bubble->p0 + Bubble->Interaction->dp_neighbor); + } + else if (t > 2 * T) + { + return (Bubble->Excitation->dp + Bubble->Interaction->dp_neighbor); + } + else + { + APECSS_FLOAT W = 0.5 * (1 - APECSS_COS((t + T) * APECSS_PI / T)); + return (Bubble->p0 + W * (Bubble->Excitation->dp - Bubble->p0) + Bubble->Interaction->dp_neighbor); + } } APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { // Approximate numerical computation of p_infinity derivative + APECSS_FLOAT T = 10.0e-06; + APECSS_FLOAT derivative = 0.0; + if ((t >= T) && (t <= 2 * T)) + { + APECSS_FLOAT inv_T = 1 / T; + derivative = 0.5 * APECSS_PI * inv_T * APECSS_SIN(APECSS_PI * (t + T) * inv_T) * (Bubble->Excitation->dp - Bubble->p0); + } + APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; - APECSS_FLOAT derivative = -Bubble->Excitation->dp * 2.0 * APECSS_PI * Bubble->Excitation->f * APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * t); if (delta_t > Bubble->dt) { - return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) / (Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2))); + APECSS_FLOAT inv_delta_t = 1 / delta_t; + return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) * inv_delta_t)); } else { diff --git a/examples/sphericalclustercavitationonset/README.md b/examples/sphericalclustercavitationonset/README.md index e69de29..e543eb3 100644 --- a/examples/sphericalclustercavitationonset/README.md +++ b/examples/sphericalclustercavitationonset/README.md @@ -0,0 +1 @@ +This example builds a standalone APECSS code for a cluster of 2500 interacting bubbles. The cluster can be monodispersed (with 10.0 microns as bubbles initial radius) or polydispersed (with the radii distribution following a log normal law such as $ln(R/R_{0,ref}) \sim N(0,0.7)$, with $R_{0,ref} = 10.0$ microns, as described in [Maeda, K., & Colonius, T. (2019). Bubble cloud dynamics in an ultrasound field. Journal of Fluid Mechanics, 862, 1105‑1134](https://doi.org/10.1017/jfm.2018.968)). The excitation wave is the same as the one described in [Ida, M. (2009). Multibubble cavitation inception. Physics of Fluids, 21(11), 113302.](https://doi.org/10.1063/1.3265547) and used in the example "cavitationonset". The computations can be done using the _standard incompressible model_ ("IC") or the newly developped _quasi acoustic model_ (QA). Since the latter one is a preatty heavy computation, parallelization using *OpenMPI* is adopted (around hours/days on 15 cores of an Intel i7-13700K x24 processor). Concerning the displayed results, the bubbles in the monodispersed cluster are studied based on their location in the cluster (like the "sphericalclusterinteractions" example), while for the polydispersed one, a repartition based on their initial radius is considered. \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/run_sphericalclustercavitationonset.sh b/examples/sphericalclustercavitationonset/run_sphericalclustercavitationonset.sh new file mode 100755 index 0000000..549b02f --- /dev/null +++ b/examples/sphericalclustercavitationonset/run_sphericalclustercavitationonset.sh @@ -0,0 +1,41 @@ +######### Parameters ################################################################################################################################ + +nbubbles=2500 + +######### Incompressible computations ############################################################################################################### + +cd IC/build +./compile.sh +cd .. + +######### Monodispersed system #################################################################### +./build/sphericalclustercavitationonset_apecss -options run.apecss -amp -25325 -tend 25.0e-6 -cldistrib 0 +python3 gather_results.py + +######### Polydispersed system #################################################################### +./build/sphericalclustercavitationonset_apecss -options run.apecss -amp -25325 -tend 25.0e-6 -cldistrib 1 +python3 gather_results.py + +cd .. + +echo "" +echo "Incompressible test cases passed" +echo "" + +######### Incompressible computations ############################################################################################################### + +######### Plot results ############################################################################################################################## + +######### Cleaning ################################################################################################################################## + +cd IC +# rm -rf "onset_results.txt" "bubble_loc.txt" +for ((c=0; c<$nbubbles; c++)) +do + rm -rf Bubble_$c +done +cd .. + +echo "" +echo "Cleaning completed" +echo "" \ No newline at end of file From 8d15c88e3e0ca80edb0674b7c672cf730a624be3 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 19 Jul 2024 17:25:01 -0400 Subject: [PATCH 041/138] spherical cluster interactions ; small update when displaying results --- examples/sphericalclusterinteractions/plot_results.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/sphericalclusterinteractions/plot_results.py b/examples/sphericalclusterinteractions/plot_results.py index f194c9c..3ce41f6 100644 --- a/examples/sphericalclusterinteractions/plot_results.py +++ b/examples/sphericalclusterinteractions/plot_results.py @@ -341,7 +341,7 @@ def savefig(fig, filename="Cluster", format="pdf", path=None) : for k in list(dic_radius_evolution.keys())[1:] : ax.plot(dic_radius_evolution[k][0]*fa, dic_radius_evolution[k][1]/dic_radius_evolution[k][1][0], linestyle=dic_style_key[k], color=dic_color_key[k], linewidth=1.5, label=r"$r/R_{c} \approx$"+"{:.1f}".format(k)) -ax.legend(loc="upper right") +ax.legend(loc="upper left", fontsize=15) savefig(fig, filename="sphericalclusterinteractions_radiievolution") ## Cluster evolution vizualisation ################################################################################################################## From fedd94451e2efceef4535b2297f230e8cadc0f2d Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 22 Jul 2024 15:29:37 -0400 Subject: [PATCH 042/138] bubbly screen ; adding pruning to optimize computational costs for QA case --- examples/bubblyscreen/QA/execmpi.sh | 2 +- .../bubblyscreen/QA/src/bubblyscreen_apecss.c | 98 ++++++++++++++++--- examples/bubblyscreen/plot_results.py | 8 +- examples/bubblyscreen/run_bubblyscreen.sh | 49 ++++++---- 4 files changed, 122 insertions(+), 35 deletions(-) diff --git a/examples/bubblyscreen/QA/execmpi.sh b/examples/bubblyscreen/QA/execmpi.sh index ebcd1ff..08ff9e3 100755 --- a/examples/bubblyscreen/QA/execmpi.sh +++ b/examples/bubblyscreen/QA/execmpi.sh @@ -4,7 +4,7 @@ nbubble=2601 cd build ./compile.sh cd .. -mpiexec -n $ncore ./build/bubblyscreen_apecss -options run.apecss -freq 3.262e6 -amp 100.0 -tend 1.0e-6 +mpiexec -n $ncore ./build/bubblyscreen_apecss -options run.apecss -freq 1.631e6 -amp 100.0 -tend 35.0e-6 -coeff 1.0 python3 gather_results.py for ((c=0; c<$nbubble; c++)) diff --git a/examples/bubblyscreen/QA/src/bubblyscreen_apecss.c b/examples/bubblyscreen/QA/src/bubblyscreen_apecss.c index 756e133..adf575e 100644 --- a/examples/bubblyscreen/QA/src/bubblyscreen_apecss.c +++ b/examples/bubblyscreen/QA/src/bubblyscreen_apecss.c @@ -35,7 +35,9 @@ APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, stru APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubble[], struct APECSS_Parallel_Cluster *RankInfo); int parallel_interactions_proper_cutoffdistance(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo); -int apecss_bubble_new_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble); +int apecss_bubble_new_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble, APECSS_FLOAT coeff); +int apecss_emissions_new_prunelist(struct APECSS_Bubble *Bubble, APECSS_FLOAT coeff); +int apecss_emissions_new_updatelinkedlist(struct APECSS_Bubble *Bubble, APECSS_FLOAT coeff); APECSS_FLOAT maxR; APECSS_FLOAT minR; @@ -63,6 +65,7 @@ int main(int argc, char **args) double tEnd = 0.0; double fa = 0.0; double pa = 0.0; + double coeff_pruning = 1.0; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< apecss_infoscreen(); @@ -92,6 +95,11 @@ int main(int argc, char **args) sscanf(args[j + 1], "%le", &pa); j += 2; } + else if (strcmp("-coeff", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &coeff_pruning); + j += 2; + } else if (strcmp("-h", args[j]) == 0) { apecss_helpscreen(); @@ -279,6 +287,14 @@ int main(int argc, char **args) // Update cut off distance for each bubble parallel_interactions_proper_cutoffdistance(Bubbles, RankInfo); + // Update pruning options + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->Emissions->pruneList = 1; + // Simple allocation to prevent the warning message with no pruning to pop up + Bubbles[i]->Emissions->prune_test = apecss_emissions_prune_no_node; + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< clock_t starttimebubble = clock(); @@ -338,17 +354,11 @@ int main(int argc, char **args) APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); tSim += dtSim; - // See progress during computation - if (RankInfo->rank == 0) - { - printf("D:%le, f:%le, time:%e\n", bubble_bubble_dist, fa, tSim); - } - for (register int i = 0; i < RankInfo->nBubbles_local; i++) { maxR = 0.0; minR = Bubbles[i]->R0; - apecss_bubble_new_solver_run(tSim, tEnd, Bubbles[i]); + apecss_bubble_new_solver_run(tSim, tEnd, Bubbles[i], (APECSS_FLOAT) coeff_pruning); if (maxR > max_radii[i]) { @@ -576,7 +586,7 @@ int parallel_interactions_proper_cutoffdistance(struct APECSS_Bubble *Bubbles[], return (0); } -int apecss_bubble_new_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble) +int apecss_bubble_new_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble, APECSS_FLOAT coeff) { while (Bubble->t < tend - 0.01 * Bubble->NumericsODE->dtMin) { @@ -626,8 +636,8 @@ int apecss_bubble_new_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct AP Bubble->results_emissionsnodeminmax_identify(Bubble); Bubble->results_emissionsnode_alloc(Bubble); - // Acoustic emissions (if applicable) - Bubble->emissions_update(Bubble); + // Acoustic emissions with pruning (if applicable) + apecss_emissions_new_updatelinkedlist(Bubble, coeff); // Store results (if applicable) Bubble->results_rayleighplesset_store(Bubble); @@ -643,5 +653,71 @@ int apecss_bubble_new_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct AP Bubble->progress_update(&(*Bubble).progress, Bubble->t - Bubble->tStart, Bubble->tEnd - Bubble->tStart); } + return (0); +} + +int apecss_emissions_new_prunelist(struct APECSS_Bubble *Bubble, APECSS_FLOAT coeff) +{ + struct APECSS_EmissionNode *Current = Bubble->Emissions->LastNode; + + APECSS_FLOAT inv_nBubbles = 1 / (APECSS_FLOAT) Bubble->Interaction->nBubbles; + APECSS_FLOAT pinfinity = Bubble->get_pressure_infinity(Bubble->t, Bubble); + + APECSS_FLOAT pressure_treshold = coeff * pinfinity * inv_nBubbles; + + while (Current != NULL) + { + if (APECSS_ABS(Current->p - pinfinity) < pressure_treshold) + { + // Delete the node if it satisfies the pruning condition + struct APECSS_EmissionNode *Obsolete = Current; + if ((Current->backward != NULL) && (Current->forward != NULL)) + { + Current->backward->forward = Current->forward; + Current->forward->backward = Current->backward; + Current = Current->backward; + Bubble->Emissions->nNodes -= 1; + } + else if ((Current->backward != NULL) && (Current->forward == NULL)) + { + Current->backward->forward = NULL; + Bubble->Emissions->LastNode = Current->backward; + Current = Current->backward; + Bubble->Emissions->nNodes -= 1; + } + else if ((Current->backward == NULL) && (Current->forward != NULL)) + { + Current->forward->backward = NULL; + Bubble->Emissions->FirstNode = Current->forward; + Current = NULL; + Bubble->Emissions->nNodes -= 1; + } + else + { + Bubble->Emissions->FirstNode = NULL; + Bubble->Emissions->LastNode = NULL; + Bubble->Emissions->nNodes = 0; + Current = NULL; + } + free(Obsolete); + // apecss_emissions_deletenode(Bubble, Current); + } + else + { + // Move to the next node + Current = Current->backward; + } + } + + return (0); +} + +int apecss_emissions_new_updatelinkedlist(struct APECSS_Bubble *Bubble, APECSS_FLOAT coeff) +{ + if (Bubble->Emissions->nNodes) Bubble->Emissions->advance(Bubble); + apecss_emissions_addnode(Bubble); + if (Bubble->Emissions->LastNode->r > Bubble->Emissions->CutOffDistance) apecss_emissions_removenode(Bubble); + if (Bubble->Emissions->pruneList) apecss_emissions_new_prunelist(Bubble, coeff); + return (0); } \ No newline at end of file diff --git a/examples/bubblyscreen/plot_results.py b/examples/bubblyscreen/plot_results.py index f98d663..301f007 100644 --- a/examples/bubblyscreen/plot_results.py +++ b/examples/bubblyscreen/plot_results.py @@ -54,7 +54,7 @@ for line in lines[2:] : x = float(line.split(" ")[1]) y = float(line.split(" ")[2]) - r_amp = (float(line.split(" ")[6]) - float(line.split(" ")[5])) / float(line.split(" ")[4]) + r_amp = (float(line.split(" ")[6]) - float(line.split(" ")[5])) / (2 * float(line.split(" ")[4])) i = int((y/D)) + 25 j = int((x/D)) + 25 @@ -114,10 +114,10 @@ def plot_oscillation_distribution(fig, axs, row, col, nbubbles_x, inttype, rati ### First row : QA ### plt.figtext(0.5, 0.85, r"QA, $D/R_{0}$ = 400", fontsize=16.5, horizontalalignment="center") -plot_oscillation_distribution(fig, axs, 0, 0, 51, "QA", 0.5, 400) -plot_oscillation_distribution(fig, axs, 0, 1, 51, "QA", 0.9, 400) +plot_oscillation_distribution(fig, axs, 0, 0, 51, "QA", 0.5, 400, order=4) +plot_oscillation_distribution(fig, axs, 0, 1, 51, "QA", 0.9, 400, order=3) plot_oscillation_distribution(fig, axs, 0, 2, 51, "QA", 1.0, 400) -plot_oscillation_distribution(fig, axs, 0, 3, 51, "QA", 1.5, 400) +plot_oscillation_distribution(fig, axs, 0, 3, 51, "QA", 1.5, 400, order=4) ### Second row : IC ### plt.figtext(0.5, 0.5, r"IC, $D/R_{0}$ = 400", fontsize=16.5, horizontalalignment="center") diff --git a/examples/bubblyscreen/run_bubblyscreen.sh b/examples/bubblyscreen/run_bubblyscreen.sh index 3d3316a..118c0a9 100755 --- a/examples/bubblyscreen/run_bubblyscreen.sh +++ b/examples/bubblyscreen/run_bubblyscreen.sh @@ -12,7 +12,7 @@ cd .. f_list=(1.631e06 2.934e06 3.262e06 4.893e06) for f in "${f_list[@]}" do - ./build/bubblyscreen_apecss -options run.apecss -freq $f -amp 100.0 -tend 10.0e-6 + ./build/bubblyscreen_apecss -options run.apecss -freq $f -amp 100.0 -tend 35.0e-6 python3 gather_results.py done @@ -24,20 +24,31 @@ echo "" ######### Quasi acoustic computations ############################################################################################################### -# cd QA/build -# ./compile.sh -# cd .. +cd QA/build +./compile.sh +cd .. -# cd .. +f_list=(1.631e06 2.934e06 3.262e06 4.893e06) +for f in "${f_list[@]}" +do + mpiexec -n $ncore ./build/bubblyscreen_apecss -options run.apecss -freq $f -amp 100.0 -tend 35.0e-6 -coeff 0.05 + python3 gather_results.py +done + +cd .. -# echo "" -# echo "Quasi acoustic test cases passed" -# echo "" +echo "" +echo "Quasi acoustic test cases passed" +echo "" ######### Plotting results ########################################################################################################################## python3 plot_results.py +echo "" +echo "Results plotted" +echo "" + ######### Cleaning ################################################################################################################################## cd IC @@ -48,17 +59,17 @@ done rm -rf bubblyscreen_radii.txt bubblyscreen_extremum.txt cd .. -# cd QA -# for ((c=0; c<$nbubbles; c++)) -# do -# rm -rf Bubble_$c -# done -# rm -rf bubblyscreen_radii.txt -# for ((c=0; c<$ncore; c++)) -# do -# rm -rf bubblyscreen_extremum_$c.txt -# done -# cd .. +cd QA +for ((c=0; c<$nbubbles; c++)) +do + rm -rf Bubble_$c +done +rm -rf bubblyscreen_radii.txt +for ((c=0; c<$ncore; c++)) +do + rm -rf bubblyscreen_extremum_$c.txt +done +cd .. echo "" echo "Cleaning completed" From 2f4281955e2070f1c71dba436b8406b4b5880be2 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 22 Jul 2024 15:46:46 -0400 Subject: [PATCH 043/138] spherical cluster cavitation onset ; plot results file and update for the main .sh file --- .../plot_results.py | 203 ++++++++++++++++++ .../run_sphericalclustercavitationonset.sh | 6 +- 2 files changed, 206 insertions(+), 3 deletions(-) create mode 100644 examples/sphericalclustercavitationonset/plot_results.py diff --git a/examples/sphericalclustercavitationonset/plot_results.py b/examples/sphericalclustercavitationonset/plot_results.py new file mode 100644 index 0000000..fd8f5b0 --- /dev/null +++ b/examples/sphericalclustercavitationonset/plot_results.py @@ -0,0 +1,203 @@ +import os +import numpy as np +import matplotlib.pyplot as plt +from math import sqrt + +fontsize = 12 + +plt.rcParams['font.family']='serif' +plt.rcParams['font.serif']=['Times New Roman'] + plt.rcParams['font.serif'] +plt.rcParams['mathtext.fontset']='stix' +plt.rcParams['font.size']=fontsize + +cm = 1/2.54 + +# File designed to plot the results for the cavitation onset test case with a spherical cluster + +######### Step 1 : Retrieving data ################################################################################################################## +interaction_types = ["IC", "QA"] +cluster_types = ["mono", "poly"] + +dic_bubbles = {} +dic_bubbles_loc = {} + +for inttype in interaction_types : + if inttype not in list(dic_bubbles.keys()) : + dic_bubbles[inttype] = {} + for cltype in cluster_types : + if cltype not in list(dic_bubbles[inttype].keys()) : + dic_bubbles[inttype][cltype] = {} + if cltype not in list(dic_bubbles_loc.keys()) : + dic_bubbles_loc[cltype] = {} + +working_path = os.getcwd() +for inttype in interaction_types : + interaction_path = os.path.join(working_path, inttype) + interaction_path = os.path.join(interaction_path, "results") + for file in os.listdir(interaction_path) : + if "_loc.txt" in file : + file_name = file.split("_loc.txt")[0] + + file_loc_path = os.path.join(interaction_path, file) + file_loc = open(file_loc_path, "r") + lines_loc = file_loc.readlines() + file_loc.close() + + file_path = os.path.join(interaction_path, file_name + ".txt") + file_res = open(file_path, "r") + lines_res = file_res.readlines() + file_res.close() + + firstline = lines_res[0].split(" ") + count = int(firstline[0]) + png = float(firstline[5]) + + if "mono" in file_name : + dic_res = dic_bubbles[inttype]["mono"] + dic_loc = dic_bubbles_loc["mono"] + else : + dic_res = dic_bubbles[inttype]["poly"] + dic_loc = dic_bubbles_loc["poly"] + + if count not in list(dic_res.keys()) : + dic_res[count] = {} + if count not in list(dic_loc.keys()) : + dic_loc[count] = {} + + if png not in list(dic_res[count].keys()) : + dic_res[count][png] = [] + if png not in list(dic_loc[count].keys()) : + dic_loc[count][png] = [] + + dic_res[count][png].append([]) + for i in range(count) : + init_radius = float(lines_res[1].split(" ")[1 + i]) + x = float(lines_loc[1 + i].split(" ")[1]) + y = float(lines_loc[1 + i].split(" ")[2]) + z = float(lines_loc[1 + i].split(" ")[3]) + + dic_loc[count][png].append([x, y, z]) + dic_res[count][png].append([init_radius, [], []]) + + for line in lines_res[3:] : + data = line.split(" ") + t = float(data[0]) + dic_res[count][png][0].append(t) + + for i in range(count) : + r = float(data[1 + i]) + p = float(data[1 + count + i]) + dic_res[count][png][i+1][1].append(r) + dic_res[count][png][i+1][2].append(p) + +######### Step 2 : Define bubble distributions ###################################################################################################### + +# For monodispersed cluster, results are plotted based on bubbles locations +cluster_radius = 2.5e-03 +interval_size = 0.20e-03 + +dic_loc_distrib_global = {} +dic_loc_distrib = {0.0 : [], 0.5 : [], 1.0 : []} + +for count in list(dic_bubbles_loc["mono"].keys()) : + if count not in list(dic_loc_distrib_global.keys()) : + dic_loc_distrib_global[count] = {} + + for png in list(dic_bubbles_loc["mono"][count].keys()) : + if png not in list(dic_loc_distrib_global[count].keys()) : + dic_loc_distrib_global[count][png] = dic_loc_distrib + + for i in range(count) : + radius_to_center = sqrt(dic_bubbles_loc["mono"][count][png][i][0]**2 + dic_bubbles_loc["mono"][count][png][i][1]**2 + dic_bubbles_loc["mono"][count][png][i][2]**2) + if radius_to_center < 0.0 * cluster_radius + interval_size : + dic_loc_distrib_global[count][png][0.0].append(i) + elif 0.5 * (cluster_radius - interval_size) < radius_to_center < 0.5 * (cluster_radius + interval_size) : + dic_loc_distrib_global[count][png][0.5].append(i) + elif 1.0 * cluster_radius - interval_size < radius_to_center : + dic_loc_distrib_global[count][png][1.0].append(i) + +# For polydispersed cluster, results are plotted based on bubbles initial radii +n_quantiles = 5 +quantiles_list = [] +for i in range(1, n_quantiles - 1) : + quantiles_list.append(i / n_quantiles) +quantiles_list = np.array(quantiles_list) + +dic_polydisperse = {} + +for inttype in interaction_types : + dic_polydisperse[inttype] = {} + for count in list(dic_bubbles[inttype]["poly"].keys()) : + if count not in list(dic_polydisperse[inttype].keys()) : + dic_polydisperse[inttype][count] = {} + for png in list(dic_bubbles[inttype]["poly"][count].keys()) : + if png not in list(dic_polydisperse[inttype][count].keys()) : + dic_polydisperse[inttype][count][png] = {"quantiles" : []} + for q in quantiles_list : + dic_polydisperse[inttype][count][png][q] = [] + + initial_radius_list = [] + for i in range(count) : + initial_radius_list.append(dic_bubbles[inttype]["poly"][count][png][i][0]) + + quantiles = np.quantile(np.array(initial_radius_list), quantiles_list) + for q in quantiles : dic_polydisperse[inttype][count][png]["quantiles"].append(q) + + for i in range(count) : + initial_radius = dic_bubbles[inttype]["poly"][count][png][i][0] + + index = 0 + while initial_radius > dic_polydisperse[inttype][count][png]["quantiles"][index] : + index += 1 + dic_polydisperse[inttype][count][png][quantiles_list[index]].append(i) + +######### Step 3 : Plot results ##################################################################################################################### + +######### Averaged radius versus time evolution for monodispersed cluster ######################### +count = 2500 +png = -25325 + +nrow = 1 +ncol = 2 +fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) +for i in range(ncol) : + axs[i].set_xlabel(r"t ($\mu$s)") + axs[i].set_ylabel(r"$ / R_{0}$ (-)") + axs[i].set_xlim(xmin=10.0, xmax=60.0) + axs[i].grid() + +axs[0].set_title(r"Incompressible interactions ($N = 2500$, $R_{0}=10.0 \ \mu m$, $p_{ng} / p_{0} = -0.25$)") +axs[1].set_title(r"Quasi acoustic interactions ($N = 2500$, $R_{0}=10.0 \ \mu m$, $p_{ng} / p_{0} = -0.25$)") + +dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} +dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} + +for k in dic_loc_distrib_global[count][png].keys() : + index_list = dic_loc_distrib_global[count][png][k] + + # Incompressible interactions + t_list = np.array(dic_bubbles["IC"]["mono"][count][png][0]) + + r_list_0 = np.array(dic_bubbles["IC"]["mono"][count][png][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["IC"]["mono"][count][png][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + t_list = np.array(dic_bubbles["IC"]["mono"][count][png][0]) + + r_list = np.array(dic_bubbles["IC"]["mono"][count][png][index + 1][1]) + init_r = dic_bubbles["IC"]["mono"][count][png][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[0].plot(t_list*1.0e6, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=r"$r \approx$" + " {:.1f}".format(k) + r"$\times r_{C}$") + + # Quasi acoustic interactions + +axs[0].legend(bbox_to_anchor=(1.15, 1.1), loc="center", fontsize=15, ncol=3, frameon=False) +fig.savefig("sphericalclustercavitationonset_mono_radiusevolution.pdf", bbox_inches='tight',pad_inches=0.35) + +######### Averaged radius versus time evolution for polydispersed cluster ######################### \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/run_sphericalclustercavitationonset.sh b/examples/sphericalclustercavitationonset/run_sphericalclustercavitationonset.sh index 549b02f..f0592a1 100755 --- a/examples/sphericalclustercavitationonset/run_sphericalclustercavitationonset.sh +++ b/examples/sphericalclustercavitationonset/run_sphericalclustercavitationonset.sh @@ -9,11 +9,11 @@ cd IC/build cd .. ######### Monodispersed system #################################################################### -./build/sphericalclustercavitationonset_apecss -options run.apecss -amp -25325 -tend 25.0e-6 -cldistrib 0 +./build/sphericalclustercavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-6 -cldistrib 0 python3 gather_results.py ######### Polydispersed system #################################################################### -./build/sphericalclustercavitationonset_apecss -options run.apecss -amp -25325 -tend 25.0e-6 -cldistrib 1 +./build/sphericalclustercavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-6 -cldistrib 1 python3 gather_results.py cd .. @@ -29,7 +29,7 @@ echo "" ######### Cleaning ################################################################################################################################## cd IC -# rm -rf "onset_results.txt" "bubble_loc.txt" +rm -rf "onset_results.txt" "bubble_loc.txt" for ((c=0; c<$nbubbles; c++)) do rm -rf Bubble_$c From 26f00874e6b2ef92d129a6348cc06d864c639474 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 23 Jul 2024 09:01:31 -0400 Subject: [PATCH 044/138] bubbly screen ; full .sh execution file --- examples/bubblyscreen/run_bubblyscreen.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/bubblyscreen/run_bubblyscreen.sh b/examples/bubblyscreen/run_bubblyscreen.sh index 118c0a9..3f90fe5 100755 --- a/examples/bubblyscreen/run_bubblyscreen.sh +++ b/examples/bubblyscreen/run_bubblyscreen.sh @@ -29,12 +29,12 @@ cd QA/build cd .. f_list=(1.631e06 2.934e06 3.262e06 4.893e06) -for f in "${f_list[@]}" +c_list=(0.0005 0.005 0.05 0.001) +for ((i=0; i<5; i++)) do - mpiexec -n $ncore ./build/bubblyscreen_apecss -options run.apecss -freq $f -amp 100.0 -tend 35.0e-6 -coeff 0.05 + mpiexec -n $ncore ./build/bubblyscreen_apecss -options run.apecss -freq ${f_list[$i]} -amp 100.0 -tend 35.0e-6 -coeff ${c_list[$i]} python3 gather_results.py done - cd .. echo "" From 82dc257e371a510b334080f42b70d5cecbd7e160 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 23 Jul 2024 18:09:49 -0400 Subject: [PATCH 045/138] spherical cluster cavitation onset ; new pressure derivative infinity --- .../sphericalclustercavitationonset_apecss.c | 32 +++++++++++-------- .../sphericalclustercavitationonset_apecss.c | 32 +++++++++++-------- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/examples/sphericalclustercavitationonset/IC/src/sphericalclustercavitationonset_apecss.c b/examples/sphericalclustercavitationonset/IC/src/sphericalclustercavitationonset_apecss.c index ce62639..a3d2c97 100644 --- a/examples/sphericalclustercavitationonset/IC/src/sphericalclustercavitationonset_apecss.c +++ b/examples/sphericalclustercavitationonset/IC/src/sphericalclustercavitationonset_apecss.c @@ -36,7 +36,7 @@ APECSS_FLOAT normal_distribution(double mu, double sigma) double u2 = (drand48()); double mag = sigma * APECSS_SQRT(-2.0 * APECSS_LOG(u1)); - double z1 = mag * cos(2 * APECSS_PI * u2) + mu; + double z1 = mag * APECSS_COS(2 * APECSS_PI * u2) + mu; return (APECSS_FLOAT) z1; } @@ -397,21 +397,27 @@ APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, stru { // Approximate numerical computation of p_infinity derivative APECSS_FLOAT T = 10.0e-06; - APECSS_FLOAT derivative = 0.0; - if ((t >= T) && (t <= 2 * T)) - { - APECSS_FLOAT inv_T = 1 / T; - derivative = 0.5 * APECSS_PI * inv_T * APECSS_SIN(APECSS_PI * (t + T) * inv_T) * (Bubble->Excitation->dp - Bubble->p0); - } - - APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; - if (delta_t > Bubble->dt) + if (t < T) { - APECSS_FLOAT inv_delta_t = 1 / delta_t; - return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) * inv_delta_t)); + return (0.0); } else { - return (derivative); + APECSS_FLOAT derivative = 0.0; + if (t < 2 * T) + { + APECSS_FLOAT inv_T = 1 / T; + derivative = 0.5 * APECSS_PI * inv_T * APECSS_SIN(APECSS_PI * (t + T) * inv_T) * (Bubble->Excitation->dp - Bubble->p0); + } + APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; + if (delta_t > Bubble->dt) + { + APECSS_FLOAT inv_delta_t = 1 / delta_t; + return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) * inv_delta_t)); + } + else + { + return (derivative); + } } } \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/QA/src/sphericalclustercavitationonset_apecss.c b/examples/sphericalclustercavitationonset/QA/src/sphericalclustercavitationonset_apecss.c index 35d37b1..e69205b 100644 --- a/examples/sphericalclustercavitationonset/QA/src/sphericalclustercavitationonset_apecss.c +++ b/examples/sphericalclustercavitationonset/QA/src/sphericalclustercavitationonset_apecss.c @@ -37,7 +37,7 @@ APECSS_FLOAT normal_distribution(double mu, double sigma) double u2 = (drand48()); double mag = sigma * APECSS_SQRT(-2.0 * APECSS_LOG(u1)); - double z1 = mag * cos(2 * APECSS_PI * u2) + mu; + double z1 = mag * APECSS_COS(2 * APECSS_PI * u2) + mu; return (APECSS_FLOAT) z1; } @@ -487,22 +487,28 @@ APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLO { // Approximate numerical computation of p_infinity derivative APECSS_FLOAT T = 10.0e-06; - APECSS_FLOAT derivative = 0.0; - if ((t >= T) && (t <= 2 * T)) - { - APECSS_FLOAT inv_T = 1 / T; - derivative = 0.5 * APECSS_PI * inv_T * APECSS_SIN(APECSS_PI * (t + T) * inv_T) * (Bubble->Excitation->dp - Bubble->p0); - } - - APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; - if (delta_t > Bubble->dt) + if (t < T) { - APECSS_FLOAT inv_delta_t = 1 / delta_t; - return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) * inv_delta_t)); + return (0.0); } else { - return (derivative); + APECSS_FLOAT derivative = 0.0; + if (t < 2 * T) + { + APECSS_FLOAT inv_T = 1 / T; + derivative = 0.5 * APECSS_PI * inv_T * APECSS_SIN(APECSS_PI * (t + T) * inv_T) * (Bubble->Excitation->dp - Bubble->p0); + } + APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; + if (delta_t > Bubble->dt) + { + APECSS_FLOAT inv_delta_t = 1 / delta_t; + return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) * inv_delta_t)); + } + else + { + return (derivative); + } } } From 3de934c0e8d3340c0c6014c7f2d9baeb65d299ac Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 23 Jul 2024 19:44:43 -0400 Subject: [PATCH 046/138] spherical cluster cavitation onset ; completed QA computations + gathering results files --- .../QA/execmpi.sh | 12 ++- .../QA/gather_results.py | 85 +++++++++++++++++++ .../QA/run.apecss | 4 - .../sphericalclustercavitationonset_apecss.c | 65 +++++++++----- 4 files changed, 139 insertions(+), 27 deletions(-) create mode 100644 examples/sphericalclustercavitationonset/QA/gather_results.py diff --git a/examples/sphericalclustercavitationonset/QA/execmpi.sh b/examples/sphericalclustercavitationonset/QA/execmpi.sh index 969f5c1..c0d69a8 100755 --- a/examples/sphericalclustercavitationonset/QA/execmpi.sh +++ b/examples/sphericalclustercavitationonset/QA/execmpi.sh @@ -1,10 +1,18 @@ +nbubbles=2500 +ncores=15 + cd build ./compile.sh cd .. -mpiexec -n 15 ./build/sphericalclustercavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-06 +mpiexec -n $ncores ./build/sphericalclustercavitationonset_apecss -options run.apecss -amp -25325 -tend 5.0e-06 -cldistrib 0 +python3 gather_results.py # rm -rf bubble_loc.txt -# for ((c=0; c<2500; c++)) +# for ((c=0; c<$ncores; c++)) +# do +# rm -rf onset_results_$c.txt +# done +# for ((c=0; c<$nbubbles; c++)) # do # rm -rf Bubble_$c # done \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/QA/gather_results.py b/examples/sphericalclustercavitationonset/QA/gather_results.py new file mode 100644 index 0000000..b23c0c3 --- /dev/null +++ b/examples/sphericalclustercavitationonset/QA/gather_results.py @@ -0,0 +1,85 @@ +import os + +# File designed to recover data for plotting results in cavitation onset case + +count_core = 0 +for file in os.listdir() : + if "onset_results_" in file : + count_core += 1 + +lines_onset = [] +for i in range(count_core) : + file_onset = open("onset_results_{}.txt".format(i), "r") + lines = file_onset.readlines() + file_onset.close() + lines_onset.append(lines) + +firstline = lines_onset[0][0].split(" ") +count = int(firstline[0]) +png = float(firstline[5]) +cl_distrib = int(firstline[7]) + +if cl_distrib == 0 : + # monodispersed spherical cluster + file_name = "mono_{}_{:.4E}.txt".format(count, png) + +else : + # polydispersed spherical cluster + file_name = "poly_{}_{:.4E}.txt".format(count, png) + +working_path = os.getcwd() +results_path = os.path.join(working_path, "results") +file_results = open(os.path.join(results_path, file_name), "w") + +results_onset = open(os.path.join(results_path, file_name), "w") +# Header +for line in lines_onset[0][:3] : + results_onset.write(line) + +# Combining with the good format the values located in the files associated with the cores used for computation +for t in range(3, len(lines_onset[0])) : + time = lines_onset[0][t].split(" ")[0] + r_list = [] + p_list = [] + + for i in range(len(lines_onset)) : + data = lines_onset[i][t].split(" ") + nbubble_core = int((len(data) - 1) / 2) + r_list_file = data[1:nbubble_core+1] + p_list_file = data[nbubble_core+1:2*nbubble_core+1] + + for r in r_list_file : + r_list.append(r) + + for p in p_list_file : + if "\n" in p : + p = p.split("\n")[0] + p_list.append(p) + + results_onset.write(time) + for rad in r_list : + results_onset.write(" {}".format(rad)) + for pres in p_list : + results_onset.write(" {}".format(pres)) + results_onset.write("\n") + +results_onset.close() + +file_loc = open("bubble_loc.txt", "r") +lines_loc = file_loc.readlines() +file_loc.close() + +if cl_distrib == 0 : + # monodispersed spherical cluster + file_name_loc = "mono_{}_{:.4E}_loc.txt".format(count, png) + +else : + # polydispersed spherical cluster + file_name_loc = "poly_{}_{:.4E}_loc.txt".format(count, png) + +file_loc_results = open(os.path.join(results_path, file_name_loc), "w") + +for line in lines_loc : + file_loc_results.write(line) + +file_loc_results.close() \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/QA/run.apecss b/examples/sphericalclustercavitationonset/QA/run.apecss index 52906a5..44da63b 100644 --- a/examples/sphericalclustercavitationonset/QA/run.apecss +++ b/examples/sphericalclustercavitationonset/QA/run.apecss @@ -27,10 +27,6 @@ INTERFACE SurfaceTensionCoeff 0.0728 END -RESULTS -Bubble -END - ODESOLVER tolerance 1.0e-10 END diff --git a/examples/sphericalclustercavitationonset/QA/src/sphericalclustercavitationonset_apecss.c b/examples/sphericalclustercavitationonset/QA/src/sphericalclustercavitationonset_apecss.c index e69205b..26b6158 100644 --- a/examples/sphericalclustercavitationonset/QA/src/sphericalclustercavitationonset_apecss.c +++ b/examples/sphericalclustercavitationonset/QA/src/sphericalclustercavitationonset_apecss.c @@ -265,7 +265,7 @@ int main(int argc, char **args) for (register int n = 0; n < RankInfo->nBubbles_local; n++) { Bubbles[n]->R0 = Bubble_Radius[RankInfo->bubblerank[RankInfo->rank] + n]; - Bubbles[n]->r_hc = Bubbles[n]->R0 / 8.54; + Bubbles[n]->R = Bubble_Radius[RankInfo->bubblerank[RankInfo->rank] + n]; } } @@ -356,20 +356,6 @@ int main(int argc, char **args) // Update cut off distance for each bubble parallel_interactions_proper_cutoffdistance(Bubbles, RankInfo); - - // File to retrieve the locations of bubble centers - if (RankInfo->rank == 0) - { - FILE *file_loc; - file_loc = fopen("bubble_loc.txt", "w"); - fprintf(file_loc, "#number x(m) y(m) z(m)\n"); - for (register int i = 0; i < nBubbles; i++) - { - fprintf(file_loc, "%d %e %e %e\n", i, Bubble_Center[i][0], Bubble_Center[i][1], Bubble_Center[i][2]); - } - fclose(file_loc); - } - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< clock_t starttimebubble = clock(); @@ -391,18 +377,39 @@ int main(int argc, char **args) // Allocate the pressure contribution array RankInfo->sumGU_rank = malloc(2 * RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Files to retrieve all valuable information for cavitation onset test case + // Bubbles locations + FILE *file_loc = fopen("bubble_loc.txt", "w"); + fprintf(file_loc, "#number x(m) y(m) z(m)\n"); + for (register int i = 0; i < RankInfo->nBubbles_global; i++) + { + fprintf(file_loc, "%d %e %e %e\n", i, RankInfo->bubbleglobal_x[i], RankInfo->bubbleglobal_y[i], RankInfo->bubbleglobal_z[i]); + } + fclose(file_loc); + + // Radius and pressure evolution for each bubble during computation + FILE *file_onset; + char file_name[APECSS_STRINGLENGTH_SPRINTF_LONG]; + sprintf(file_name, "onset_results_%d.txt", RankInfo->rank); + file_onset = fopen(file_name, "w"); + + fprintf(file_onset, "%d Bubbles p0(pa) %e png(Pa) %e cl_distrib %d\n", nBubbles, Liquid->pref, pa, cluster_distrib); + fprintf(file_onset, "Initial_radii(m)"); + for (register int i = 0; i < RankInfo->nBubbles_global; i++) + { + fprintf(file_onset, " %e", RankInfo->bubbleglobal_R[i]); + } + fprintf(file_onset, "\n"); + fprintf(file_onset, "#Time(s) R(m) Pt(Pa)\n"); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + /* Solve the bubble dynamics */ while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered { APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); tSim += dtSim; - // To follow computations progress - if (RankInfo->rank == 0) - { - printf("%e\n", tSim); - } - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); // for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; @@ -412,6 +419,20 @@ int main(int argc, char **args) parallel_interactions_quasi_acoustic(Bubbles, RankInfo); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Retrieve data + fprintf(file_onset, "%e", tSim); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + fprintf(file_onset, " %e", Bubbles[i]->R); + } + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + fprintf(file_onset, " %e", Bubbles[i]->get_pressure_infinity(Bubbles[i]->t, Bubbles[i])); + } + fprintf(file_onset, "\n"); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + for (register int i = 0; i < RankInfo->nBubbles_local; i++) { Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; @@ -422,6 +443,8 @@ int main(int argc, char **args) } } + fclose(file_onset); + /* Finalize the simulation*/ for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_finalize(Bubbles[i]); From 71cbba01cbcbcbea8539601a45daada27c753de4 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Thu, 25 Jul 2024 10:15:14 -0400 Subject: [PATCH 047/138] spherical cluster cavitation onset ; corrected IC source file --- .../IC/run.apecss | 4 -- .../sphericalclustercavitationonset_apecss.c | 47 ++++++++++--------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/examples/sphericalclustercavitationonset/IC/run.apecss b/examples/sphericalclustercavitationonset/IC/run.apecss index 89c4131..50eac9b 100644 --- a/examples/sphericalclustercavitationonset/IC/run.apecss +++ b/examples/sphericalclustercavitationonset/IC/run.apecss @@ -27,10 +27,6 @@ INTERFACE SurfaceTensionCoeff 0.0728 END -RESULTS -Bubble -END - ODESOLVER tolerance 1.0e-10 END diff --git a/examples/sphericalclustercavitationonset/IC/src/sphericalclustercavitationonset_apecss.c b/examples/sphericalclustercavitationonset/IC/src/sphericalclustercavitationonset_apecss.c index a3d2c97..ee0bdf3 100644 --- a/examples/sphericalclustercavitationonset/IC/src/sphericalclustercavitationonset_apecss.c +++ b/examples/sphericalclustercavitationonset/IC/src/sphericalclustercavitationonset_apecss.c @@ -204,7 +204,7 @@ int main(int argc, char **args) for (register int i = 0; i < nBubbles; i++) { Bubbles[i]->R0 = 10.0e-6; - Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; + // Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; } } else @@ -216,13 +216,13 @@ int main(int argc, char **args) for (register int i = 0; i < nBubbles; i++) { APECSS_FLOAT radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); - while (radius > 20 * radius_ref) + while ((radius > 20 * radius_ref) || (radius < 0.5 * radius_ref)) { - // Small step to ensure no too big bubbles are generated (the distribution is conserved still) + // Small step to ensure no too big nor too small bubbles are generated (the distribution is conserved still) radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); } Bubbles[i]->R0 = radius; - Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; + // Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; } } @@ -322,6 +322,10 @@ int main(int argc, char **args) apecss_interactions_instantaneous(Bubbles); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + // printf("%e %e %e %e %e\n", tSim, Bubbles[0]->Liquid->get_pressurederivative_bubblewall_expl(Bubbles[0]->ODEsSol, Bubbles[0]->t, Bubbles[0]), + // Bubbles[0]->get_pressurederivative_infinity(Bubbles[0]->t, Bubbles[0]), Bubbles[0]->Interaction->dp_neighbor, + // Bubbles[0]->Interaction->last_p_1 - Bubbles[0]->Interaction->last_p_2); + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // Retrieve data fprintf(file_onset, "%e", tSim); @@ -336,14 +340,14 @@ int main(int argc, char **args) fprintf(file_onset, "\n"); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; - Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; + // for (register int i = 0; i < nBubbles; i++) + // { + // Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; + // Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; - Bubbles[i]->Interaction->last_t_1 = tSim; - Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; - } + // Bubbles[i]->Interaction->last_t_1 = tSim; + // Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; + // } } fclose(file_onset); @@ -409,15 +413,16 @@ APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, stru APECSS_FLOAT inv_T = 1 / T; derivative = 0.5 * APECSS_PI * inv_T * APECSS_SIN(APECSS_PI * (t + T) * inv_T) * (Bubble->Excitation->dp - Bubble->p0); } - APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; - if (delta_t > Bubble->dt) - { - APECSS_FLOAT inv_delta_t = 1 / delta_t; - return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) * inv_delta_t)); - } - else - { - return (derivative); - } + return (derivative); + // APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; + // if ((delta_t > Bubble->dt) && (t > time_treshold)) + // { + // APECSS_FLOAT inv_delta_t = 1 / delta_t; + // return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) * inv_delta_t)); + // } + // else + // { + // return (derivative); + // } } } \ No newline at end of file From 0fa1593da2de080f4e2def0b9e8f8ad8f381485a Mon Sep 17 00:00:00 2001 From: Pierre C Date: Thu, 25 Jul 2024 10:16:02 -0400 Subject: [PATCH 048/138] spherical cluster cavitation onset ; adding a no interaction test case as well --- .../NI/build/compile.sh | 5 + .../NI/gather_results.py | 47 +++ .../NI/run.apecss | 32 ++ .../sphericalclustercavitationonset_apecss.c | 396 ++++++++++++++++++ 4 files changed, 480 insertions(+) create mode 100755 examples/sphericalclustercavitationonset/NI/build/compile.sh create mode 100644 examples/sphericalclustercavitationonset/NI/gather_results.py create mode 100644 examples/sphericalclustercavitationonset/NI/run.apecss create mode 100644 examples/sphericalclustercavitationonset/NI/src/sphericalclustercavitationonset_apecss.c diff --git a/examples/sphericalclustercavitationonset/NI/build/compile.sh b/examples/sphericalclustercavitationonset/NI/build/compile.sh new file mode 100755 index 0000000..33147c8 --- /dev/null +++ b/examples/sphericalclustercavitationonset/NI/build/compile.sh @@ -0,0 +1,5 @@ +#!/bin/bash +rm sphericalclustercavitationonset_apecss +cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release +make +rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/NI/gather_results.py b/examples/sphericalclustercavitationonset/NI/gather_results.py new file mode 100644 index 0000000..6e44890 --- /dev/null +++ b/examples/sphericalclustercavitationonset/NI/gather_results.py @@ -0,0 +1,47 @@ +import os + +# File designed to recover data for plotting results in cavitation onset case + +file = open("onset_results.txt", "r") +lines = file.readlines() +file.close() + +count = int(lines[0].split(" ")[0]) +png = float(lines[0].split(" ")[5]) +cl_distrib = int(lines[0].split(" ")[7]) + +if cl_distrib == 0 : + # monodispersed spherical cluster + file_name = "mono_{}_{:.4E}.txt".format(count, png) + +else : + # polydispersed spherical cluster + file_name = "poly_{}_{:.4E}.txt".format(count, png) + +working_path = os.getcwd() +results_path = os.path.join(working_path, "results") +file_results = open(os.path.join(results_path, file_name), "w") + +for line in lines : + file_results.write(line) + +file_results.close() + +file_loc = open("bubble_loc.txt", "r") +lines_loc = file_loc.readlines() +file_loc.close() + +if cl_distrib == 0 : + # monodispersed spherical cluster + file_name_loc = "mono_{}_{:.4E}_loc.txt".format(count, png) + +else : + # polydispersed spherical cluster + file_name_loc = "poly_{}_{:.4E}_loc.txt".format(count, png) + +file_loc_results = open(os.path.join(results_path, file_name_loc), "w") + +for line in lines_loc : + file_loc_results.write(line) + +file_loc_results.close() \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/NI/run.apecss b/examples/sphericalclustercavitationonset/NI/run.apecss new file mode 100644 index 0000000..50eac9b --- /dev/null +++ b/examples/sphericalclustercavitationonset/NI/run.apecss @@ -0,0 +1,32 @@ +######################################################### +# # +# APECSS Options File # +# # +######################################################### + +BUBBLE +RPModel KM +Emissions IC 300.0e-6 +PressureAmbient 0.1013e6 +END + +GAS +EoS IG +ReferenceDensity 1.2 +PolytropicExponent 1.4 +END + +LIQUID +ReferencePressure 0.1013e6 +ReferenceDensity 1000.0 +ReferenceSoundSpeed 1500.0 +Viscosity 1.002e-3 +END + +INTERFACE +SurfaceTensionCoeff 0.0728 +END + +ODESOLVER +tolerance 1.0e-10 +END diff --git a/examples/sphericalclustercavitationonset/NI/src/sphericalclustercavitationonset_apecss.c b/examples/sphericalclustercavitationonset/NI/src/sphericalclustercavitationonset_apecss.c new file mode 100644 index 0000000..001e26f --- /dev/null +++ b/examples/sphericalclustercavitationonset/NI/src/sphericalclustercavitationonset_apecss.c @@ -0,0 +1,396 @@ +// This source file is part of APECSS, an open-source software toolbox +// for the computation of pressure-driven bubble dynamics and acoustic +// emissions in spherical symmetry. +// +// Copyright (C) 2022-2024 The APECSS Developers +// +// The APECSS Developers are listed in the README.md file available in +// the GitHub repository at https://github.com/polycfd/apecss. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// ------------------------------------------------------------------- +// APECSS standalone example of acoustically-interacting microbubbles +// in a spherical cluster with the goal to study cavitation onset +// ------------------------------------------------------------------- + +#include +#include "apecss.h" + +APECSS_FLOAT rand_range(double min, double max) +{ + double random = (drand48()); + double range = (max - min) * random; + double number = min + range; + + return (APECSS_FLOAT) number; +} + +APECSS_FLOAT normal_distribution(double mu, double sigma) +{ + // Generating a normal distribution using Box-Muller transform, with mu as mean and sigma**2 as variance + double u1 = (drand48()); + while (u1 == 0.0) u1 = (drand48()); + double u2 = (drand48()); + + double mag = sigma * APECSS_SQRT(-2.0 * APECSS_LOG(u1)); + double z1 = mag * APECSS_COS(2 * APECSS_PI * u2) + mu; + return (APECSS_FLOAT) z1; +} + +// Declaration of additional case-dependent functions +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); + +// Declaration of the structure holding the interaction variables of each bubble +struct Interaction +{ + APECSS_FLOAT dp_neighbor; +}; + +int main(int argc, char **args) +{ + char OptionsDir[APECSS_STRINGLENGTH]; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Set the case-dependent simulation parameters + const int nBubbles = 2500; // Number of bubbles + APECSS_FLOAT bubble_bubble_dist = 100.0e-6; // Bubble-bubble minimal distance + APECSS_FLOAT cluster_radius = 2.5e-3; // Spherical cluster radius + + // Interbubble time-step, defining the frequency with which the neighbor influence is updated + APECSS_FLOAT dt_interbubble = 1.0e-8; + + // Initialize the simulation parameters given by the execution command + double tEnd = 0.0; + double fa = 0.0; + double pa = 0.0; + int cluster_distrib = 0; + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + apecss_infoscreen(); + + /* Read commandline options */ + sprintf(OptionsDir, "./run.apecss"); // This is the default + int j = 1; // First argument is the call to the executable + while (j < argc) + { + if (strcmp("-options", args[j]) == 0) + { + sprintf(OptionsDir, "%s", args[j + 1]); + j += 2; + } + else if (strcmp("-tend", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &tEnd); + j += 2; + } + else if (strcmp("-freq", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &fa); + j += 2; + } + else if (strcmp("-amp", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &pa); + j += 2; + } + else if (strcmp("-cldistrib", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &cluster_distrib); + j += 2; + } + else if (strcmp("-h", args[j]) == 0) + { + apecss_helpscreen(); + } + else + { + char str[APECSS_STRINGLENGTH_SPRINTF]; + sprintf(str, "Unknown command line options: %s", args[j]); + apecss_erroronscreen(1, str); + ++j; + } + } + + /* Allocate and initialize Bubble structure */ + struct APECSS_Bubble *Bubbles[nBubbles]; + for (register int i = 0; i < nBubbles; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(nBubbles * sizeof(struct APECSS_Bubble)); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initializestruct(Bubbles[i]); + + /* Set default options and read the options for the bubble */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); + + /* Allocate the structures for the fluid properties and ODE solver parameters */ + struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); + struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); + struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); + struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); + + /* Set the default options for the fluid properties and solver parameters */ + apecss_gas_setdefaultoptions(Gas); + apecss_liquid_setdefaultoptions(Liquid); + apecss_interface_setdefaultoptions(Interface); + apecss_odesolver_setdefaultoptions(NumericsODE); + + /* Read the options file for the fluid properties and solver parameters */ + apecss_gas_readoptions(Gas, OptionsDir); + apecss_liquid_readoptions(Liquid, OptionsDir); + apecss_interface_readoptions(Interface, OptionsDir); + apecss_odesolver_readoptions(NumericsODE, OptionsDir); + + /* Associate the bubble with the relevant fluid properties and solver parameters */ + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Gas = Gas; + Bubbles[i]->Liquid = Liquid; + Bubbles[i]->Interface = Interface; + Bubbles[i]->NumericsODE = NumericsODE; + } + + /* Allocate and set the excitation parameters */ + struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); + Excitation->type = APECSS_EXCITATION_SIN; + Excitation->f = (APECSS_FLOAT) fa; + Excitation->dp = (APECSS_FLOAT) pa; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Excitation = Excitation; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Create individual folders for the results of each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (Bubbles[i]->Results != NULL) + { + sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", i); + struct stat st = {0}; + if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Process all options */ + apecss_gas_processoptions(Gas); + apecss_liquid_processoptions(Liquid); + apecss_interface_processoptions(Interface); + apecss_odesolver_processoptions(NumericsODE); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_processoptions(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Use the revised pressure at infinity, including neighbor contributions + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressure_infinity = interaction_bubble_pressure_infinity; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressurederivative_infinity = interaction_bubble_pressurederivative_infinity; + + // Initialize interaction structure + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); + + // Update interaction structure + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Interaction->nBubbles = nBubbles; + Bubbles[i]->Interaction->dp_neighbor = 0.0; + Bubbles[i]->Interaction->last_t_1 = 0.0; + Bubbles[i]->Interaction->last_t_2 = 0.0; + Bubbles[i]->Interaction->last_p_1 = 0.0; + Bubbles[i]->Interaction->last_p_2 = 0.0; + } + + // Define the size of each bubble + if (cluster_distrib == 0) + { + // Monodispersed cluster + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->R0 = 10.0e-6; + } + } + else + { + // Polydispersed cluster (radii distribution is following a log normal law) + double mu = 0.0; + double sigma = 0.7; + APECSS_FLOAT radius_ref = 10.0e-6; + for (register int i = 0; i < nBubbles; i++) + { + APECSS_FLOAT radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); + while ((radius > 20 * radius_ref) || (radius < 0.5 * radius_ref)) + { + // Small step to ensure no too big nor too small bubbles are generated (the distribution is conserved still) + radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); + } + Bubbles[i]->R0 = radius; + } + } + + // Define center location for each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (i == 0) + { + Bubbles[i]->Interaction->location[0] = 0.0; + Bubbles[i]->Interaction->location[1] = 0.0; + Bubbles[i]->Interaction->location[2] = 0.0; + } + else + { + APECSS_FLOAT x = rand_range((double) -cluster_radius, (double) cluster_radius); + APECSS_FLOAT y = rand_range((double) -cluster_radius, (double) cluster_radius); + APECSS_FLOAT z = rand_range((double) -cluster_radius, (double) cluster_radius); + + APECSS_FLOAT radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); + + while (radius > cluster_radius) + { + x = rand_range((double) -cluster_radius, (double) cluster_radius); + y = rand_range((double) -cluster_radius, (double) cluster_radius); + z = rand_range((double) -cluster_radius, (double) cluster_radius); + + radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); + } + + Bubbles[i]->Interaction->location[0] = x; + Bubbles[i]->Interaction->location[1] = y; + Bubbles[i]->Interaction->location[2] = z; + + for (register int k = 0; k < i; k++) + { + APECSS_FLOAT bubbledist = APECSS_SQRT(APECSS_POW2(Bubbles[i]->Interaction->location[0] - Bubbles[k]->Interaction->location[0]) + + APECSS_POW2(Bubbles[i]->Interaction->location[1] - Bubbles[k]->Interaction->location[1]) + + APECSS_POW2(Bubbles[i]->Interaction->location[2] - Bubbles[k]->Interaction->location[2])); + if (bubbledist < bubble_bubble_dist) + { + i--; + break; + } + } + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + clock_t starttimebubble = clock(); + APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system + + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->tStart = tSim; + Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; + Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step + } + + /* Initialize the bubble based on the selected options */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initialize(Bubbles[i]); + + /* Initialize */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_initialize(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Files to retrieve all valuable information for cavitation onset test case + FILE *file_loc; + file_loc = fopen("bubble_loc.txt", "w"); + fprintf(file_loc, "#number x(m) y(m) z(m)\n"); + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_loc, "%d %e %e %e\n", i, Bubbles[i]->Interaction->location[0], Bubbles[i]->Interaction->location[1], Bubbles[i]->Interaction->location[2]); + } + fclose(file_loc); + + FILE *file_onset; + file_onset = fopen("onset_results.txt", "w"); + fprintf(file_onset, "%d Bubbles p0(pa) %e png(Pa) %e cl_distrib %d\n", nBubbles, Liquid->pref, pa, cluster_distrib); + fprintf(file_onset, "Initial_radii(m)"); + for (register int i = 0; i < nBubbles; i++) fprintf(file_onset, " %e", Bubbles[i]->R0); + fprintf(file_onset, "\n"); + fprintf(file_onset, "#Time(s) R(m) Pt(Pa)\n"); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Solve the bubble dynamics */ + while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered + { + APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); + tSim += dtSim; + + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Retrieve data + fprintf(file_onset, "%e", tSim); + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_onset, " %e", Bubbles[i]->R); + } + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_onset, " %e", Bubbles[i]->get_pressure_infinity(Bubbles[i]->t, Bubbles[i])); + } + fprintf(file_onset, "\n"); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + } + + fclose(file_onset); + + /* Finalize the simulation*/ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_finalize(Bubbles[i]); + + char str[APECSS_STRINGLENGTH_SPRINTF]; + for (register int i = 0; i < nBubbles; i++) + { + sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", i, Bubbles[i]->dtNumber, Bubbles[i]->nSubIter, + (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); + apecss_writeonscreen(str); + } + + for (register int i = 0; i < nBubbles; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); + for (register int i = 0; i < nBubbles; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); + + /* Make sure all allocated memory is freed */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_freestruct(Bubbles[i]); + + for (register int i = 0; i < nBubbles; i++) free(Bubbles[i]); + free(Gas); + free(Liquid); + free(Interface); + free(NumericsODE); + free(Excitation); + + return (0); +} + +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + APECSS_FLOAT T = 10.0e-06; + if (t < T) + { + return (Bubble->p0 + Bubble->Interaction->dp_neighbor); + } + else if (t > 2 * T) + { + return (Bubble->Excitation->dp + Bubble->Interaction->dp_neighbor); + } + else + { + APECSS_FLOAT W = 0.5 * (1 - APECSS_COS((t + T) * APECSS_PI / T)); + return (Bubble->p0 + W * (Bubble->Excitation->dp - Bubble->p0) + Bubble->Interaction->dp_neighbor); + } +} + +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + // Approximate numerical computation of p_infinity derivative + APECSS_FLOAT T = 10.0e-06; + if (t < T) + { + return (0.0); + } + else + { + APECSS_FLOAT derivative = 0.0; + if (t < 2 * T) + { + APECSS_FLOAT inv_T = 1 / T; + derivative = 0.5 * APECSS_PI * inv_T * APECSS_SIN(APECSS_PI * (t + T) * inv_T) * (Bubble->Excitation->dp - Bubble->p0); + } + return (derivative); + } +} \ No newline at end of file From 4d8f967456d7225eb1da5737996fb32601dde83f Mon Sep 17 00:00:00 2001 From: Pierre C Date: Thu, 25 Jul 2024 10:17:12 -0400 Subject: [PATCH 049/138] spherical cluster cavitation onset ; adding new plots and completing .sh run file --- .../plot_results.py | 78 ++++++++++++++++--- .../run_sphericalclustercavitationonset.sh | 43 ++++++++++ 2 files changed, 109 insertions(+), 12 deletions(-) diff --git a/examples/sphericalclustercavitationonset/plot_results.py b/examples/sphericalclustercavitationonset/plot_results.py index fd8f5b0..e35d9e3 100644 --- a/examples/sphericalclustercavitationonset/plot_results.py +++ b/examples/sphericalclustercavitationonset/plot_results.py @@ -3,7 +3,7 @@ import matplotlib.pyplot as plt from math import sqrt -fontsize = 12 +fontsize = 15 plt.rcParams['font.family']='serif' plt.rcParams['font.serif']=['Times New Roman'] + plt.rcParams['font.serif'] @@ -15,7 +15,7 @@ # File designed to plot the results for the cavitation onset test case with a spherical cluster ######### Step 1 : Retrieving data ################################################################################################################## -interaction_types = ["IC", "QA"] +interaction_types = ["IC"] cluster_types = ["mono", "poly"] dic_bubbles = {} @@ -118,8 +118,10 @@ # For polydispersed cluster, results are plotted based on bubbles initial radii n_quantiles = 5 +quantile_name_dic = {4 : "quartile", 5 : "quintile"} +quantile_name = quantile_name_dic[n_quantiles] quantiles_list = [] -for i in range(1, n_quantiles - 1) : +for i in range(1, n_quantiles + 1) : quantiles_list.append(i / n_quantiles) quantiles_list = np.array(quantiles_list) @@ -161,13 +163,13 @@ ncol = 2 fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) for i in range(ncol) : - axs[i].set_xlabel(r"t ($\mu$s)") - axs[i].set_ylabel(r"$ / R_{0}$ (-)") + axs[i].set_xlabel(r"t ($\mu$s)", fontsize=15) + axs[i].set_ylabel(r"$ / R_{0}$ (-)", fontsize=15) axs[i].set_xlim(xmin=10.0, xmax=60.0) axs[i].grid() -axs[0].set_title(r"Incompressible interactions ($N = 2500$, $R_{0}=10.0 \ \mu m$, $p_{ng} / p_{0} = -0.25$)") -axs[1].set_title(r"Quasi acoustic interactions ($N = 2500$, $R_{0}=10.0 \ \mu m$, $p_{ng} / p_{0} = -0.25$)") +axs[0].set_title(r"Incompressible interactions" + "\n" +r"($N = 2500$, $R_{0}=10.0 \ \mu m$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) +axs[1].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 2500$, $R_{0}=10.0 \ \mu m$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} @@ -185,19 +187,71 @@ for i in range(1, len(index_list)) : index = index_list[i] - t_list = np.array(dic_bubbles["IC"]["mono"][count][png][0]) - r_list = np.array(dic_bubbles["IC"]["mono"][count][png][index + 1][1]) init_r = dic_bubbles["IC"]["mono"][count][png][index + 1][0] avg_radius = avg_radius + np.array(r_list) / init_r avg_radius = (1 / len(index_list)) * avg_radius - axs[0].plot(t_list*1.0e6, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=r"$r \approx$" + " {:.1f}".format(k) + r"$\times r_{C}$") + axs[0].plot(t_list*1.0e6, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=r"$r/R_{C} \approx$" + " {:.1f}".format(k)) # Quasi acoustic interactions -axs[0].legend(bbox_to_anchor=(1.15, 1.1), loc="center", fontsize=15, ncol=3, frameon=False) +axs[0].legend(bbox_to_anchor=(1.15, 1.175), loc="center", fontsize=15, ncol=3, frameon=False) fig.savefig("sphericalclustercavitationonset_mono_radiusevolution.pdf", bbox_inches='tight',pad_inches=0.35) -######### Averaged radius versus time evolution for polydispersed cluster ######################### \ No newline at end of file +######### Averaged radius versus time evolution for polydispersed cluster ######################### + +count = 2500 +png = -25325 + +nrow = 1 +ncol = 2 +fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) +for i in range(ncol) : + axs[i].set_xlabel(r"t ($\mu$s)", fontsize=15) + axs[i].set_ylabel(r"$$ (-)", fontsize=15) + axs[i].set_xlim(xmin=10.0, xmax=60.0) + axs[i].grid() + +axs[0].set_title(r"Incompressible interactions" + "\n" +r"($N = 2500$, $R_{0, ref}=10.0 \ \mu m$, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) +axs[1].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 2500$, $R_{0, ref}=10.0 \ \mu m$, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) + +color_list = ["black", "magenta", "blue", "green", "red"] +dic_color_q = {} +dic_label_q = {} +for i in range(n_quantiles) : + quantile = quantiles_list[i] + dic_color_q[quantile] = color_list[i] + + dic_label_q[quantile] = "{}th-{}".format(i+1, quantile_name) + if i == 0 : + dic_label_q[quantile] = "1st-{}".format(quantile_name) + elif i == 1 : + dic_label_q[quantile] = "2nd-{}".format(quantile_name) + elif i == 2 : + dic_label_q[quantile] = "3rd-{}".format(quantile_name) + +# Incompressible interactions +for q in list(dic_polydisperse["IC"][count][png].keys())[1:] : + index_list = dic_polydisperse["IC"][count][png][q] + + t_list = np.array(dic_bubbles["IC"]["poly"][count][png][0]) + + r_list_0 = np.array(dic_bubbles["IC"]["poly"][count][png][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["IC"]["poly"][count][png][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["IC"]["poly"][count][png][index + 1][1]) + init_r = dic_bubbles["IC"]["poly"][count][png][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[0].plot(t_list*1.0e6, avg_radius, linewidth=1.5, linestyle="solid", color=dic_color_q[q], label=dic_label_q[q]) + +axs[0].legend(bbox_to_anchor=(1.1, 1.175), loc="center", fontsize=15, ncol=n_quantiles, frameon=False) +fig.savefig("sphericalclustercavitationonset_poly_radiusevolution.pdf", bbox_inches='tight',pad_inches=0.35) \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/run_sphericalclustercavitationonset.sh b/examples/sphericalclustercavitationonset/run_sphericalclustercavitationonset.sh index f0592a1..2ed1c5c 100755 --- a/examples/sphericalclustercavitationonset/run_sphericalclustercavitationonset.sh +++ b/examples/sphericalclustercavitationonset/run_sphericalclustercavitationonset.sh @@ -1,7 +1,28 @@ ######### Parameters ################################################################################################################################ +ncores=17 nbubbles=2500 +######### No interaction computations ############################################################################################################### + +cd NI/build +./compile.sh +cd .. + +######### Monodispersed system #################################################################### +./build/sphericalclustercavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-6 -cldistrib 0 +python3 gather_results.py + +######### Polydispersed system #################################################################### +./build/sphericalclustercavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-6 -cldistrib 1 +python3 gather_results.py + +cd .. + +echo "" +echo "No interaction test cases passed" +echo "" + ######### Incompressible computations ############################################################################################################### cd IC/build @@ -26,8 +47,18 @@ echo "" ######### Plot results ############################################################################################################################## +python3 plot_results.py + ######### Cleaning ################################################################################################################################## +cd NI +rm -rf "onset_results.txt" "bubble_loc.txt" +for ((c=0; c<$nbubbles; c++)) +do + rm -rf Bubble_$c +done +cd .. + cd IC rm -rf "onset_results.txt" "bubble_loc.txt" for ((c=0; c<$nbubbles; c++)) @@ -36,6 +67,18 @@ do done cd .. +cd QA +rm -rf "bubble_loc.txt" +for ((c=0; c<$ncores; c++)) +do + rm -rf onset_results_$c.txt +done +for ((c=0; c<$nbubbles; c++)) +do + rm -rf Bubble_$c +done +cd .. + echo "" echo "Cleaning completed" echo "" \ No newline at end of file From a19424e4fe1b7701ab8f3758c6487f963f64c69d Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 26 Jul 2024 10:11:32 -0400 Subject: [PATCH 050/138] sherical cluster cavitation onset ; adding no interaction and pressure evolution plots --- .../plot_results.py | 206 ++++++++++++++++-- 1 file changed, 192 insertions(+), 14 deletions(-) diff --git a/examples/sphericalclustercavitationonset/plot_results.py b/examples/sphericalclustercavitationonset/plot_results.py index e35d9e3..8511b54 100644 --- a/examples/sphericalclustercavitationonset/plot_results.py +++ b/examples/sphericalclustercavitationonset/plot_results.py @@ -15,7 +15,7 @@ # File designed to plot the results for the cavitation onset test case with a spherical cluster ######### Step 1 : Retrieving data ################################################################################################################## -interaction_types = ["IC"] +interaction_types = ["NI", "IC"] cluster_types = ["mono", "poly"] dic_bubbles = {} @@ -160,16 +160,17 @@ png = -25325 nrow = 1 -ncol = 2 +ncol = 3 fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) for i in range(ncol) : axs[i].set_xlabel(r"t ($\mu$s)", fontsize=15) axs[i].set_ylabel(r"$ / R_{0}$ (-)", fontsize=15) - axs[i].set_xlim(xmin=10.0, xmax=60.0) + axs[i].set_xlim(xmin=10.0, xmax=150.0) axs[i].grid() -axs[0].set_title(r"Incompressible interactions" + "\n" +r"($N = 2500$, $R_{0}=10.0 \ \mu m$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) -axs[1].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 2500$, $R_{0}=10.0 \ \mu m$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) +axs[0].set_title(r"No interaction" + "\n" +r"($N = 2500$, $R_{0}=10.0 \ \mu m$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) +axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 2500$, $R_{0}=10.0 \ \mu m$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) +axs[2].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 2500$, $R_{0}=10.0 \ \mu m$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} @@ -177,6 +178,24 @@ for k in dic_loc_distrib_global[count][png].keys() : index_list = dic_loc_distrib_global[count][png][k] + # No interaction + t_list = np.array(dic_bubbles["NI"]["mono"][count][png][0]) + + r_list_0 = np.array(dic_bubbles["NI"]["mono"][count][png][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["NI"]["mono"][count][png][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["NI"]["mono"][count][png][index + 1][1]) + init_r = dic_bubbles["NI"]["mono"][count][png][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[0].plot(t_list*1.0e6, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) + # Incompressible interactions t_list = np.array(dic_bubbles["IC"]["mono"][count][png][0]) @@ -193,11 +212,11 @@ avg_radius = (1 / len(index_list)) * avg_radius - axs[0].plot(t_list*1.0e6, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=r"$r/R_{C} \approx$" + " {:.1f}".format(k)) + axs[1].plot(t_list*1.0e6, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=r"$r/R_{C} \approx$" + " {:.1f}".format(k)) # Quasi acoustic interactions -axs[0].legend(bbox_to_anchor=(1.15, 1.175), loc="center", fontsize=15, ncol=3, frameon=False) +axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=3, frameon=False) fig.savefig("sphericalclustercavitationonset_mono_radiusevolution.pdf", bbox_inches='tight',pad_inches=0.35) ######### Averaged radius versus time evolution for polydispersed cluster ######################### @@ -206,16 +225,17 @@ png = -25325 nrow = 1 -ncol = 2 +ncol = 3 fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) for i in range(ncol) : axs[i].set_xlabel(r"t ($\mu$s)", fontsize=15) axs[i].set_ylabel(r"$$ (-)", fontsize=15) - axs[i].set_xlim(xmin=10.0, xmax=60.0) + axs[i].set_xlim(xmin=10.0, xmax=150.0) axs[i].grid() -axs[0].set_title(r"Incompressible interactions" + "\n" +r"($N = 2500$, $R_{0, ref}=10.0 \ \mu m$, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) -axs[1].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 2500$, $R_{0, ref}=10.0 \ \mu m$, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) +axs[0].set_title(r"No interaction" + "\n" +r"($N = 2500$, $R_{0, ref}=10.0 \ \mu m$, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) +axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 2500$, $R_{0, ref}=10.0 \ \mu m$, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) +axs[2].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 2500$, $R_{0, ref}=10.0 \ \mu m$, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) color_list = ["black", "magenta", "blue", "green", "red"] dic_color_q = {} @@ -232,6 +252,27 @@ elif i == 2 : dic_label_q[quantile] = "3rd-{}".format(quantile_name) +# No interaction +for q in list(dic_polydisperse["NI"][count][png].keys())[1:] : + index_list = dic_polydisperse["NI"][count][png][q] + + t_list = np.array(dic_bubbles["NI"]["poly"][count][png][0]) + + r_list_0 = np.array(dic_bubbles["NI"]["poly"][count][png][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["NI"]["poly"][count][png][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["NI"]["poly"][count][png][index + 1][1]) + init_r = dic_bubbles["NI"]["poly"][count][png][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[0].plot(t_list*1.0e6, avg_radius, linewidth=1.5, linestyle="solid", color=dic_color_q[q]) + # Incompressible interactions for q in list(dic_polydisperse["IC"][count][png].keys())[1:] : index_list = dic_polydisperse["IC"][count][png][q] @@ -251,7 +292,144 @@ avg_radius = (1 / len(index_list)) * avg_radius - axs[0].plot(t_list*1.0e6, avg_radius, linewidth=1.5, linestyle="solid", color=dic_color_q[q], label=dic_label_q[q]) + axs[1].plot(t_list*1.0e6, avg_radius, linewidth=1.5, linestyle="solid", color=dic_color_q[q], label=dic_label_q[q]) + +axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=n_quantiles, frameon=False) +fig.savefig("sphericalclustercavitationonset_poly_radiusevolution.pdf", bbox_inches='tight',pad_inches=0.35) + +######### Averaged pressure infinity versus time evolution for monodispersed clusters ############# + +count = 2500 +png = -25325 +p0 = 101.3e3 + +nrow = 1 +ncol = 3 +fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) +for i in range(ncol) : + axs[i].set_xlabel(r"t ($\mu$s)", fontsize=15) + axs[i].set_ylabel(r"$ / p_{0}$ (-)", fontsize=15) + axs[i].set_xlim(xmin=10.0, xmax=90.0) + axs[i].grid() + +axs[0].set_title(r"No interaction" + "\n" +r"($N = 2500$, $R_{0}=10.0 \ \mu m$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) +axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 2500$, $R_{0}=10.0 \ \mu m$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) +axs[2].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 2500$, $R_{0}=10.0 \ \mu m$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) + +dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} +dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} + +for k in dic_loc_distrib_global[count][png].keys() : + index_list = dic_loc_distrib_global[count][png][k] + + # No interaction + t_list = np.array(dic_bubbles["NI"]["mono"][count][png][0]) + + p_list_0 = np.array(dic_bubbles["NI"]["mono"][count][png][index_list[0] + 1][2]) + avg_pressure = p_list_0 / p0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + p_list = np.array(dic_bubbles["NI"]["mono"][count][png][index + 1][2]) + avg_pressure = avg_pressure + np.array(p_list) / p0 + + avg_pressure = (1 / len(index_list)) * avg_pressure + + axs[0].plot(t_list*1.0e6, avg_pressure, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) + + # Incompressible interactions + t_list = np.array(dic_bubbles["IC"]["mono"][count][png][0]) + + p_list_0 = np.array(dic_bubbles["IC"]["mono"][count][png][index_list[0] + 1][2]) + avg_pressure = p_list_0 / p0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + p_list = np.array(dic_bubbles["IC"]["mono"][count][png][index + 1][2]) + avg_pressure = avg_pressure + np.array(p_list) / p0 + + avg_pressure = (1 / len(index_list)) * avg_pressure + + axs[1].plot(t_list*1.0e6, avg_pressure, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=r"$r/R_{C} \approx$" + " {:.1f}".format(k)) + + # Quasi acoustic interactions + +axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=3, frameon=False) +fig.savefig("sphericalclustercavitationonset_mono_pressureevolution.pdf", bbox_inches='tight',pad_inches=0.35) + +######### Averaged pressure infinity versus time evolution for monodispersed clusters ############# + +count = 2500 +png = -25325 +p0 = 101.3e3 + +nrow = 1 +ncol = 3 +fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) +for i in range(ncol) : + axs[i].set_xlabel(r"t ($\mu$s)", fontsize=15) + axs[i].set_ylabel(r"$/p_{0}$ (-)", fontsize=15) + axs[i].set_xlim(xmin=10.0, xmax=90.0) + axs[i].grid() + +axs[0].set_title(r"No interaction" + "\n" +r"($N = 2500$, $R_{0, ref}=10.0 \ \mu m$, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) +axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 2500$, $R_{0, ref}=10.0 \ \mu m$, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) +axs[2].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 2500$, $R_{0, ref}=10.0 \ \mu m$, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) + +color_list = ["black", "magenta", "blue", "green", "red"] +dic_color_q = {} +dic_label_q = {} +for i in range(n_quantiles) : + quantile = quantiles_list[i] + dic_color_q[quantile] = color_list[i] + + dic_label_q[quantile] = "{}th-{}".format(i+1, quantile_name) + if i == 0 : + dic_label_q[quantile] = "1st-{}".format(quantile_name) + elif i == 1 : + dic_label_q[quantile] = "2nd-{}".format(quantile_name) + elif i == 2 : + dic_label_q[quantile] = "3rd-{}".format(quantile_name) + +# No interaction +for q in list(dic_polydisperse["NI"][count][png].keys())[1:] : + index_list = dic_polydisperse["NI"][count][png][q] + + t_list = np.array(dic_bubbles["NI"]["poly"][count][png][0]) + + p_list_0 = np.array(dic_bubbles["NI"]["poly"][count][png][index_list[0] + 1][2]) + avg_pressure = p_list_0 / p0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + p_list = np.array(dic_bubbles["NI"]["poly"][count][png][index + 1][2]) + avg_pressure = avg_pressure + np.array(p_list) / p0 + + avg_pressure = (1 / len(index_list)) * avg_pressure + + axs[0].plot(t_list*1.0e6, avg_pressure, linewidth=1.5, linestyle="solid", color=dic_color_q[q]) + +# Incompressible interactions +for q in list(dic_polydisperse["IC"][count][png].keys())[1:] : + index_list = dic_polydisperse["IC"][count][png][q] + + t_list = np.array(dic_bubbles["IC"]["poly"][count][png][0]) + + p_list_0 = np.array(dic_bubbles["IC"]["poly"][count][png][index_list[0] + 1][2]) + avg_pressure = p_list_0 / p0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + p_list = np.array(dic_bubbles["IC"]["poly"][count][png][index + 1][2]) + avg_pressure = avg_pressure + np.array(p_list) / p0 + + avg_pressure = (1 / len(index_list)) * avg_pressure + + axs[1].plot(t_list*1.0e6, avg_pressure, linewidth=1.5, linestyle="solid", color=dic_color_q[q], label=dic_label_q[q]) -axs[0].legend(bbox_to_anchor=(1.1, 1.175), loc="center", fontsize=15, ncol=n_quantiles, frameon=False) -fig.savefig("sphericalclustercavitationonset_poly_radiusevolution.pdf", bbox_inches='tight',pad_inches=0.35) \ No newline at end of file +axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=n_quantiles, frameon=False) +fig.savefig("sphericalclustercavitationonset_poly_pressureevolution.pdf", bbox_inches='tight',pad_inches=0.35) \ No newline at end of file From 5b899af1bc88bef2627e5ebe43d1493a49f3fd2b Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 26 Jul 2024 10:11:59 -0400 Subject: [PATCH 051/138] interactions ; changing sign for least contributuve term --- src/interactions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interactions.c b/src/interactions.c index 6f691c7..50830dc 100644 --- a/src/interactions.c +++ b/src/interactions.c @@ -74,7 +74,7 @@ int apecss_interactions_instantaneous(struct APECSS_Bubble *Bubbles[]) APECSS_FLOAT dp = Liquid->rhoref * 2.0 * Bubbles[j]->R * APECSS_POW2(Bubbles[j]->U) * (1 / interbubble_dist); dp += Liquid->rhoref * APECSS_POW2(Bubbles[j]->R) * Bubbles[j]->ode[0](Bubbles[j]->ODEsSol, Bubbles[j]->t, Bubbles[j]) * (1 / interbubble_dist); - dp += Liquid->rhoref * APECSS_POW4(Bubbles[j]->R) * APECSS_POW2(Bubbles[j]->U) * (1 / (2 * APECSS_POW4(interbubble_dist))); + dp += -Liquid->rhoref * APECSS_POW4(Bubbles[j]->R) * APECSS_POW2(Bubbles[j]->U) * (1 / (2 * APECSS_POW4(interbubble_dist))); // if ((i == 0) && (j == 1)) // printf(" %e %e %e", 2.0 * Bubbles[j]->R * APECSS_POW2(Bubbles[j]->U) * (1 / interbubble_dist), From 594aad4011f60525c53e270d398d823ef3e39aa9 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 26 Jul 2024 12:15:44 -0400 Subject: [PATCH 052/138] spherical cluster interactions ; change in excitation pressure --- .../sphericalclusterinteractions/execmpi.sh | 12 +++---- .../src/sphericalclusterinteractions_apecss.c | 36 ++++++++++++++++--- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/examples/sphericalclusterinteractions/execmpi.sh b/examples/sphericalclusterinteractions/execmpi.sh index a159a5d..7a2edfd 100755 --- a/examples/sphericalclusterinteractions/execmpi.sh +++ b/examples/sphericalclusterinteractions/execmpi.sh @@ -1,10 +1,10 @@ cd build ./compile.sh cd .. -mpiexec -n 15 ./build/sphericalclusterinteractions_apecss -options run.apecss -freq 50.0e03 -amp -2.5e5 -tend 5.0e-07 +mpiexec -n 15 ./build/sphericalclusterinteractions_apecss -options run.apecss -freq 50.0e03 -amp -2.5e5 -tend 30.0e-06 -rm -rf bubble_loc.txt -for ((c=0; c<2500; c++)) -do - rm -rf Bubble_$c -done \ No newline at end of file +# rm -rf bubble_loc.txt +# for ((c=0; c<2500; c++)) +# do +# rm -rf Bubble_$c +# done \ No newline at end of file diff --git a/examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c b/examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c index fb9af24..6536b7d 100644 --- a/examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c +++ b/examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c @@ -424,15 +424,41 @@ int main(int argc, char **args) APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { - return (Bubble->p0 - - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * (t - Bubble->Interaction->location[0] / Bubble->Liquid->cref)) + - Bubble->Interaction->dp_neighbor); + // return (Bubble->p0 - + // Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * (t - Bubble->Interaction->location[0] / Bubble->Liquid->cref)) + + // Bubble->Interaction->dp_neighbor); + APECSS_FLOAT wavelength = Bubble->Liquid->cref / Bubble->Excitation->f; + APECSS_FLOAT wavefront = Bubble->Liquid->cref * t - 2.5e-03; + APECSS_FLOAT p_infty = Bubble->p0 + Bubble->Interaction->dp_neighbor; + + if (Bubble->Interaction->location[0] > wavefront) + { + return (p_infty); + } + else if (Bubble->Interaction->location[0] < wavefront - wavelength) + { + return (p_infty); + } + else + { + return (p_infty + Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * (wavefront - Bubble->Interaction->location[0]) / wavelength)); + } } APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { - APECSS_FLOAT derivative = -2.0 * APECSS_PI * Bubble->Excitation->f * Bubble->Excitation->dp * - APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * (t - Bubble->Interaction->location[0] / Bubble->Liquid->cref)); + APECSS_FLOAT wavelength = Bubble->Liquid->cref / Bubble->Excitation->f; + APECSS_FLOAT wavefront = Bubble->Liquid->cref * t - 2.5e-03; + APECSS_FLOAT derivative = 0.0; + if ((Bubble->Interaction->location[0] > wavefront - wavelength) && (Bubble->Interaction->location[0] < wavefront)) + { + APECSS_FLOAT inv_wavelength = 1 / wavelength; + derivative += 2.0 * APECSS_PI * inv_wavelength * Bubble->Excitation->dp * + APECSS_COS(2.0 * APECSS_PI * inv_wavelength * (wavefront - Bubble->Interaction->location[0])); + } + + // APECSS_FLOAT derivative = -2.0 * APECSS_PI * Bubble->Excitation->f * Bubble->Excitation->dp * + // APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * (t - Bubble->Interaction->location[0] / Bubble->Liquid->cref)); APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; if (delta_t > Bubble->dt) From 32fd605795d01fed16be6647c9bbb44952cdd4a6 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 26 Jul 2024 17:35:12 -0400 Subject: [PATCH 053/138] bubbly screen ; removing one term in the pressure derivative infinity for IC interactions --- .../bubblyscreen/IC/src/bubblyscreen_apecss.c | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/examples/bubblyscreen/IC/src/bubblyscreen_apecss.c b/examples/bubblyscreen/IC/src/bubblyscreen_apecss.c index f2aaf78..165b6de 100644 --- a/examples/bubblyscreen/IC/src/bubblyscreen_apecss.c +++ b/examples/bubblyscreen/IC/src/bubblyscreen_apecss.c @@ -175,7 +175,7 @@ int main(int argc, char **args) for (register int i = 0; i < nBubbles; i++) { Bubbles[i]->R0 = 1.0e-6; - Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; + // Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; } // Define center location for each bubble @@ -279,14 +279,14 @@ int main(int argc, char **args) } fprintf(file_radii, "\n"); - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; - Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; + // for (register int i = 0; i < nBubbles; i++) + // { + // Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; + // Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; - Bubbles[i]->Interaction->last_t_1 = tSim; - Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; - } + // Bubbles[i]->Interaction->last_t_1 = tSim; + // Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; + // } } /* Complete results file */ @@ -334,16 +334,17 @@ APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_ APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { // Approximate numerical computation of p_infinity derivative - APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; + // APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; APECSS_FLOAT derivative = -Bubble->Excitation->dp * 2.0 * APECSS_PI * Bubble->Excitation->f * APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * t); - if (delta_t > Bubble->dt) - { - return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) / (Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2))); - } - else - { - return (derivative); - } + return (derivative); + // if (delta_t > Bubble->dt) + // { + // return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) / (Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2))); + // } + // else + // { + // return (derivative); + // } } int apecss_bubble_new_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble) From a9b7cfc4af89ffa7b4562274df72b94ad9eced5c Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 29 Jul 2024 13:20:31 -0400 Subject: [PATCH 054/138] spherical cluster cavitation onset ; small changes in files --- .../IC/gather_results.py | 10 ++++- .../sphericalclustercavitationonset_apecss.c | 6 +-- .../plot_results.py | 41 ++++++++++++++++--- 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/examples/sphericalclustercavitationonset/IC/gather_results.py b/examples/sphericalclustercavitationonset/IC/gather_results.py index 6e44890..570d247 100644 --- a/examples/sphericalclustercavitationonset/IC/gather_results.py +++ b/examples/sphericalclustercavitationonset/IC/gather_results.py @@ -22,8 +22,14 @@ results_path = os.path.join(working_path, "results") file_results = open(os.path.join(results_path, file_name), "w") -for line in lines : - file_results.write(line) +# for line in lines : +# if "nan" not in line : +# file_results.write(line) + +index = 0 +while index < len(lines) and "nan" not in lines[index] : + file_results.write(lines[index]) + index += 1 file_results.close() diff --git a/examples/sphericalclustercavitationonset/QA/src/sphericalclustercavitationonset_apecss.c b/examples/sphericalclustercavitationonset/QA/src/sphericalclustercavitationonset_apecss.c index 26b6158..def6f99 100644 --- a/examples/sphericalclustercavitationonset/QA/src/sphericalclustercavitationonset_apecss.c +++ b/examples/sphericalclustercavitationonset/QA/src/sphericalclustercavitationonset_apecss.c @@ -241,7 +241,7 @@ int main(int argc, char **args) for (register int i = 0; i < RankInfo->nBubbles_local; i++) { Bubbles[i]->R0 = 10.0e-6; - Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; + Bubbles[i]->R = Bubbles[i]->R0; } } else @@ -254,9 +254,9 @@ int main(int argc, char **args) for (register int i = 0; i < nBubbles; i++) { APECSS_FLOAT radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); - while (radius > 20 * radius_ref) + while ((radius > 20 * radius_ref) || (radius < 0.5 * radius_ref)) { - // Small step to ensure no too big bubbles are generated (the distribution is conserved still) + // Small step to ensure no too big bubbles nor too small are generated (the distribution is conserved still) radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); } Bubble_Radius[i] = radius; diff --git a/examples/sphericalclustercavitationonset/plot_results.py b/examples/sphericalclustercavitationonset/plot_results.py index 8511b54..73200d4 100644 --- a/examples/sphericalclustercavitationonset/plot_results.py +++ b/examples/sphericalclustercavitationonset/plot_results.py @@ -15,7 +15,7 @@ # File designed to plot the results for the cavitation onset test case with a spherical cluster ######### Step 1 : Retrieving data ################################################################################################################## -interaction_types = ["NI", "IC"] +interaction_types = ["NI", "IC", "QA"] cluster_types = ["mono", "poly"] dic_bubbles = {} @@ -165,7 +165,7 @@ for i in range(ncol) : axs[i].set_xlabel(r"t ($\mu$s)", fontsize=15) axs[i].set_ylabel(r"$ / R_{0}$ (-)", fontsize=15) - axs[i].set_xlim(xmin=10.0, xmax=150.0) + axs[i].set_xlim(xmin=10.0, xmax=60.0) axs[i].grid() axs[0].set_title(r"No interaction" + "\n" +r"($N = 2500$, $R_{0}=10.0 \ \mu m$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) @@ -215,6 +215,23 @@ axs[1].plot(t_list*1.0e6, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=r"$r/R_{C} \approx$" + " {:.1f}".format(k)) # Quasi acoustic interactions + t_list = np.array(dic_bubbles["QA"]["mono"][count][png][0]) + + r_list_0 = np.array(dic_bubbles["QA"]["mono"][count][png][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["QA"]["mono"][count][png][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["QA"]["mono"][count][png][index + 1][1]) + init_r = dic_bubbles["QA"]["mono"][count][png][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[2].plot(t_list*1.0e6, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) + axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=3, frameon=False) fig.savefig("sphericalclustercavitationonset_mono_radiusevolution.pdf", bbox_inches='tight',pad_inches=0.35) @@ -230,7 +247,7 @@ for i in range(ncol) : axs[i].set_xlabel(r"t ($\mu$s)", fontsize=15) axs[i].set_ylabel(r"$$ (-)", fontsize=15) - axs[i].set_xlim(xmin=10.0, xmax=150.0) + axs[i].set_xlim(xmin=10.0, xmax=60.0) axs[i].grid() axs[0].set_title(r"No interaction" + "\n" +r"($N = 2500$, $R_{0, ref}=10.0 \ \mu m$, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) @@ -309,7 +326,7 @@ for i in range(ncol) : axs[i].set_xlabel(r"t ($\mu$s)", fontsize=15) axs[i].set_ylabel(r"$ / p_{0}$ (-)", fontsize=15) - axs[i].set_xlim(xmin=10.0, xmax=90.0) + axs[i].set_xlim(xmin=10.0, xmax=60.0) axs[i].grid() axs[0].set_title(r"No interaction" + "\n" +r"($N = 2500$, $R_{0}=10.0 \ \mu m$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) @@ -355,6 +372,20 @@ axs[1].plot(t_list*1.0e6, avg_pressure, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=r"$r/R_{C} \approx$" + " {:.1f}".format(k)) # Quasi acoustic interactions + t_list = np.array(dic_bubbles["QA"]["mono"][count][png][0]) + + p_list_0 = np.array(dic_bubbles["QA"]["mono"][count][png][index_list[0] + 1][2]) + avg_pressure = p_list_0 / p0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + p_list = np.array(dic_bubbles["QA"]["mono"][count][png][index + 1][2]) + avg_pressure = avg_pressure + np.array(p_list) / p0 + + avg_pressure = (1 / len(index_list)) * avg_pressure + + axs[2].plot(t_list*1.0e6, avg_pressure, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=3, frameon=False) fig.savefig("sphericalclustercavitationonset_mono_pressureevolution.pdf", bbox_inches='tight',pad_inches=0.35) @@ -371,7 +402,7 @@ for i in range(ncol) : axs[i].set_xlabel(r"t ($\mu$s)", fontsize=15) axs[i].set_ylabel(r"$/p_{0}$ (-)", fontsize=15) - axs[i].set_xlim(xmin=10.0, xmax=90.0) + axs[i].set_xlim(xmin=10.0, xmax=60.0) axs[i].grid() axs[0].set_title(r"No interaction" + "\n" +r"($N = 2500$, $R_{0, ref}=10.0 \ \mu m$, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) From b55342ae79026624cd5743cf2fc25492248cc209 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 29 Jul 2024 13:21:24 -0400 Subject: [PATCH 055/138] spherical cluster tension wave ; new IC framework --- .../IC/build/compile.sh | 5 ++ .../IC/gather_results.py | 53 +++++++++++++++++++ .../sphericalclustertensionwave/IC/run.apecss | 32 +++++++++++ 3 files changed, 90 insertions(+) create mode 100755 examples/sphericalclustertensionwave/IC/build/compile.sh create mode 100644 examples/sphericalclustertensionwave/IC/gather_results.py create mode 100644 examples/sphericalclustertensionwave/IC/run.apecss diff --git a/examples/sphericalclustertensionwave/IC/build/compile.sh b/examples/sphericalclustertensionwave/IC/build/compile.sh new file mode 100755 index 0000000..33147c8 --- /dev/null +++ b/examples/sphericalclustertensionwave/IC/build/compile.sh @@ -0,0 +1,5 @@ +#!/bin/bash +rm sphericalclustercavitationonset_apecss +cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release +make +rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/sphericalclustertensionwave/IC/gather_results.py b/examples/sphericalclustertensionwave/IC/gather_results.py new file mode 100644 index 0000000..570d247 --- /dev/null +++ b/examples/sphericalclustertensionwave/IC/gather_results.py @@ -0,0 +1,53 @@ +import os + +# File designed to recover data for plotting results in cavitation onset case + +file = open("onset_results.txt", "r") +lines = file.readlines() +file.close() + +count = int(lines[0].split(" ")[0]) +png = float(lines[0].split(" ")[5]) +cl_distrib = int(lines[0].split(" ")[7]) + +if cl_distrib == 0 : + # monodispersed spherical cluster + file_name = "mono_{}_{:.4E}.txt".format(count, png) + +else : + # polydispersed spherical cluster + file_name = "poly_{}_{:.4E}.txt".format(count, png) + +working_path = os.getcwd() +results_path = os.path.join(working_path, "results") +file_results = open(os.path.join(results_path, file_name), "w") + +# for line in lines : +# if "nan" not in line : +# file_results.write(line) + +index = 0 +while index < len(lines) and "nan" not in lines[index] : + file_results.write(lines[index]) + index += 1 + +file_results.close() + +file_loc = open("bubble_loc.txt", "r") +lines_loc = file_loc.readlines() +file_loc.close() + +if cl_distrib == 0 : + # monodispersed spherical cluster + file_name_loc = "mono_{}_{:.4E}_loc.txt".format(count, png) + +else : + # polydispersed spherical cluster + file_name_loc = "poly_{}_{:.4E}_loc.txt".format(count, png) + +file_loc_results = open(os.path.join(results_path, file_name_loc), "w") + +for line in lines_loc : + file_loc_results.write(line) + +file_loc_results.close() \ No newline at end of file diff --git a/examples/sphericalclustertensionwave/IC/run.apecss b/examples/sphericalclustertensionwave/IC/run.apecss new file mode 100644 index 0000000..50eac9b --- /dev/null +++ b/examples/sphericalclustertensionwave/IC/run.apecss @@ -0,0 +1,32 @@ +######################################################### +# # +# APECSS Options File # +# # +######################################################### + +BUBBLE +RPModel KM +Emissions IC 300.0e-6 +PressureAmbient 0.1013e6 +END + +GAS +EoS IG +ReferenceDensity 1.2 +PolytropicExponent 1.4 +END + +LIQUID +ReferencePressure 0.1013e6 +ReferenceDensity 1000.0 +ReferenceSoundSpeed 1500.0 +Viscosity 1.002e-3 +END + +INTERFACE +SurfaceTensionCoeff 0.0728 +END + +ODESOLVER +tolerance 1.0e-10 +END From 913f9b99d0b40c8f407ed9c33584b4ed41915ac8 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 29 Jul 2024 13:24:06 -0400 Subject: [PATCH 056/138] spherical cluster tension wave ; source file for IC computation --- .../sphericalclustercavitationonset_apecss.c | 428 ++++++++++++++++++ 1 file changed, 428 insertions(+) create mode 100644 examples/sphericalclustertensionwave/IC/src/sphericalclustercavitationonset_apecss.c diff --git a/examples/sphericalclustertensionwave/IC/src/sphericalclustercavitationonset_apecss.c b/examples/sphericalclustertensionwave/IC/src/sphericalclustercavitationonset_apecss.c new file mode 100644 index 0000000..ee0bdf3 --- /dev/null +++ b/examples/sphericalclustertensionwave/IC/src/sphericalclustercavitationonset_apecss.c @@ -0,0 +1,428 @@ +// This source file is part of APECSS, an open-source software toolbox +// for the computation of pressure-driven bubble dynamics and acoustic +// emissions in spherical symmetry. +// +// Copyright (C) 2022-2024 The APECSS Developers +// +// The APECSS Developers are listed in the README.md file available in +// the GitHub repository at https://github.com/polycfd/apecss. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// ------------------------------------------------------------------- +// APECSS standalone example of acoustically-interacting microbubbles +// in a spherical cluster with the goal to study cavitation onset +// ------------------------------------------------------------------- + +#include +#include "apecss.h" + +APECSS_FLOAT rand_range(double min, double max) +{ + double random = (drand48()); + double range = (max - min) * random; + double number = min + range; + + return (APECSS_FLOAT) number; +} + +APECSS_FLOAT normal_distribution(double mu, double sigma) +{ + // Generating a normal distribution using Box-Muller transform, with mu as mean and sigma**2 as variance + double u1 = (drand48()); + while (u1 == 0.0) u1 = (drand48()); + double u2 = (drand48()); + + double mag = sigma * APECSS_SQRT(-2.0 * APECSS_LOG(u1)); + double z1 = mag * APECSS_COS(2 * APECSS_PI * u2) + mu; + return (APECSS_FLOAT) z1; +} + +// Declaration of additional case-dependent functions +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); + +// Declaration of the structure holding the interaction variables of each bubble +struct Interaction +{ + APECSS_FLOAT dp_neighbor; +}; + +int main(int argc, char **args) +{ + char OptionsDir[APECSS_STRINGLENGTH]; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Set the case-dependent simulation parameters + const int nBubbles = 2500; // Number of bubbles + APECSS_FLOAT bubble_bubble_dist = 100.0e-6; // Bubble-bubble minimal distance + APECSS_FLOAT cluster_radius = 2.5e-3; // Spherical cluster radius + + // Interbubble time-step, defining the frequency with which the neighbor influence is updated + APECSS_FLOAT dt_interbubble = 1.0e-8; + + // Initialize the simulation parameters given by the execution command + double tEnd = 0.0; + double fa = 0.0; + double pa = 0.0; + int cluster_distrib = 0; + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + apecss_infoscreen(); + + /* Read commandline options */ + sprintf(OptionsDir, "./run.apecss"); // This is the default + int j = 1; // First argument is the call to the executable + while (j < argc) + { + if (strcmp("-options", args[j]) == 0) + { + sprintf(OptionsDir, "%s", args[j + 1]); + j += 2; + } + else if (strcmp("-tend", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &tEnd); + j += 2; + } + else if (strcmp("-freq", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &fa); + j += 2; + } + else if (strcmp("-amp", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &pa); + j += 2; + } + else if (strcmp("-cldistrib", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &cluster_distrib); + j += 2; + } + else if (strcmp("-h", args[j]) == 0) + { + apecss_helpscreen(); + } + else + { + char str[APECSS_STRINGLENGTH_SPRINTF]; + sprintf(str, "Unknown command line options: %s", args[j]); + apecss_erroronscreen(1, str); + ++j; + } + } + + /* Allocate and initialize Bubble structure */ + struct APECSS_Bubble *Bubbles[nBubbles]; + for (register int i = 0; i < nBubbles; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(nBubbles * sizeof(struct APECSS_Bubble)); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initializestruct(Bubbles[i]); + + /* Set default options and read the options for the bubble */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); + + /* Allocate the structures for the fluid properties and ODE solver parameters */ + struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); + struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); + struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); + struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); + + /* Set the default options for the fluid properties and solver parameters */ + apecss_gas_setdefaultoptions(Gas); + apecss_liquid_setdefaultoptions(Liquid); + apecss_interface_setdefaultoptions(Interface); + apecss_odesolver_setdefaultoptions(NumericsODE); + + /* Read the options file for the fluid properties and solver parameters */ + apecss_gas_readoptions(Gas, OptionsDir); + apecss_liquid_readoptions(Liquid, OptionsDir); + apecss_interface_readoptions(Interface, OptionsDir); + apecss_odesolver_readoptions(NumericsODE, OptionsDir); + + /* Associate the bubble with the relevant fluid properties and solver parameters */ + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Gas = Gas; + Bubbles[i]->Liquid = Liquid; + Bubbles[i]->Interface = Interface; + Bubbles[i]->NumericsODE = NumericsODE; + } + + /* Allocate and set the excitation parameters */ + struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); + Excitation->type = APECSS_EXCITATION_SIN; + Excitation->f = (APECSS_FLOAT) fa; + Excitation->dp = (APECSS_FLOAT) pa; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Excitation = Excitation; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Create individual folders for the results of each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (Bubbles[i]->Results != NULL) + { + sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", i); + struct stat st = {0}; + if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Process all options */ + apecss_gas_processoptions(Gas); + apecss_liquid_processoptions(Liquid); + apecss_interface_processoptions(Interface); + apecss_odesolver_processoptions(NumericsODE); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_processoptions(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Use the revised pressure at infinity, including neighbor contributions + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressure_infinity = interaction_bubble_pressure_infinity; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressurederivative_infinity = interaction_bubble_pressurederivative_infinity; + + // Initialize interaction structure + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); + + // Update interaction structure + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Interaction->nBubbles = nBubbles; + Bubbles[i]->Interaction->dp_neighbor = 0.0; + Bubbles[i]->Interaction->last_t_1 = 0.0; + Bubbles[i]->Interaction->last_t_2 = 0.0; + Bubbles[i]->Interaction->last_p_1 = 0.0; + Bubbles[i]->Interaction->last_p_2 = 0.0; + } + + // Define the size of each bubble + if (cluster_distrib == 0) + { + // Monodispersed cluster + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->R0 = 10.0e-6; + // Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; + } + } + else + { + // Polydispersed cluster (radii distribution is following a log normal law) + double mu = 0.0; + double sigma = 0.7; + APECSS_FLOAT radius_ref = 10.0e-6; + for (register int i = 0; i < nBubbles; i++) + { + APECSS_FLOAT radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); + while ((radius > 20 * radius_ref) || (radius < 0.5 * radius_ref)) + { + // Small step to ensure no too big nor too small bubbles are generated (the distribution is conserved still) + radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); + } + Bubbles[i]->R0 = radius; + // Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; + } + } + + // Define center location for each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (i == 0) + { + Bubbles[i]->Interaction->location[0] = 0.0; + Bubbles[i]->Interaction->location[1] = 0.0; + Bubbles[i]->Interaction->location[2] = 0.0; + } + else + { + APECSS_FLOAT x = rand_range((double) -cluster_radius, (double) cluster_radius); + APECSS_FLOAT y = rand_range((double) -cluster_radius, (double) cluster_radius); + APECSS_FLOAT z = rand_range((double) -cluster_radius, (double) cluster_radius); + + APECSS_FLOAT radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); + + while (radius > cluster_radius) + { + x = rand_range((double) -cluster_radius, (double) cluster_radius); + y = rand_range((double) -cluster_radius, (double) cluster_radius); + z = rand_range((double) -cluster_radius, (double) cluster_radius); + + radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); + } + + Bubbles[i]->Interaction->location[0] = x; + Bubbles[i]->Interaction->location[1] = y; + Bubbles[i]->Interaction->location[2] = z; + + for (register int k = 0; k < i; k++) + { + APECSS_FLOAT bubbledist = APECSS_SQRT(APECSS_POW2(Bubbles[i]->Interaction->location[0] - Bubbles[k]->Interaction->location[0]) + + APECSS_POW2(Bubbles[i]->Interaction->location[1] - Bubbles[k]->Interaction->location[1]) + + APECSS_POW2(Bubbles[i]->Interaction->location[2] - Bubbles[k]->Interaction->location[2])); + if (bubbledist < bubble_bubble_dist) + { + i--; + break; + } + } + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + clock_t starttimebubble = clock(); + APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system + + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->tStart = tSim; + Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; + Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step + } + + /* Initialize the bubble based on the selected options */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initialize(Bubbles[i]); + + /* Initialize */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_initialize(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Files to retrieve all valuable information for cavitation onset test case + FILE *file_loc; + file_loc = fopen("bubble_loc.txt", "w"); + fprintf(file_loc, "#number x(m) y(m) z(m)\n"); + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_loc, "%d %e %e %e\n", i, Bubbles[i]->Interaction->location[0], Bubbles[i]->Interaction->location[1], Bubbles[i]->Interaction->location[2]); + } + fclose(file_loc); + + FILE *file_onset; + file_onset = fopen("onset_results.txt", "w"); + fprintf(file_onset, "%d Bubbles p0(pa) %e png(Pa) %e cl_distrib %d\n", nBubbles, Liquid->pref, pa, cluster_distrib); + fprintf(file_onset, "Initial_radii(m)"); + for (register int i = 0; i < nBubbles; i++) fprintf(file_onset, " %e", Bubbles[i]->R0); + fprintf(file_onset, "\n"); + fprintf(file_onset, "#Time(s) R(m) Pt(Pa)\n"); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Solve the bubble dynamics */ + while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered + { + APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); + tSim += dtSim; + + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); + + // for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Update the contribution of the neighbor bubble + apecss_interactions_instantaneous(Bubbles); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + // printf("%e %e %e %e %e\n", tSim, Bubbles[0]->Liquid->get_pressurederivative_bubblewall_expl(Bubbles[0]->ODEsSol, Bubbles[0]->t, Bubbles[0]), + // Bubbles[0]->get_pressurederivative_infinity(Bubbles[0]->t, Bubbles[0]), Bubbles[0]->Interaction->dp_neighbor, + // Bubbles[0]->Interaction->last_p_1 - Bubbles[0]->Interaction->last_p_2); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Retrieve data + fprintf(file_onset, "%e", tSim); + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_onset, " %e", Bubbles[i]->R); + } + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_onset, " %e", Bubbles[i]->get_pressure_infinity(Bubbles[i]->t, Bubbles[i])); + } + fprintf(file_onset, "\n"); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + // for (register int i = 0; i < nBubbles; i++) + // { + // Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; + // Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; + + // Bubbles[i]->Interaction->last_t_1 = tSim; + // Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; + // } + } + + fclose(file_onset); + + /* Finalize the simulation*/ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_finalize(Bubbles[i]); + + char str[APECSS_STRINGLENGTH_SPRINTF]; + for (register int i = 0; i < nBubbles; i++) + { + sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", i, Bubbles[i]->dtNumber, Bubbles[i]->nSubIter, + (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); + apecss_writeonscreen(str); + } + + for (register int i = 0; i < nBubbles; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); + for (register int i = 0; i < nBubbles; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); + + /* Make sure all allocated memory is freed */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_freestruct(Bubbles[i]); + + for (register int i = 0; i < nBubbles; i++) free(Bubbles[i]); + free(Gas); + free(Liquid); + free(Interface); + free(NumericsODE); + free(Excitation); + + return (0); +} + +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + APECSS_FLOAT T = 10.0e-06; + if (t < T) + { + return (Bubble->p0 + Bubble->Interaction->dp_neighbor); + } + else if (t > 2 * T) + { + return (Bubble->Excitation->dp + Bubble->Interaction->dp_neighbor); + } + else + { + APECSS_FLOAT W = 0.5 * (1 - APECSS_COS((t + T) * APECSS_PI / T)); + return (Bubble->p0 + W * (Bubble->Excitation->dp - Bubble->p0) + Bubble->Interaction->dp_neighbor); + } +} + +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + // Approximate numerical computation of p_infinity derivative + APECSS_FLOAT T = 10.0e-06; + if (t < T) + { + return (0.0); + } + else + { + APECSS_FLOAT derivative = 0.0; + if (t < 2 * T) + { + APECSS_FLOAT inv_T = 1 / T; + derivative = 0.5 * APECSS_PI * inv_T * APECSS_SIN(APECSS_PI * (t + T) * inv_T) * (Bubble->Excitation->dp - Bubble->p0); + } + return (derivative); + // APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; + // if ((delta_t > Bubble->dt) && (t > time_treshold)) + // { + // APECSS_FLOAT inv_delta_t = 1 / delta_t; + // return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) * inv_delta_t)); + // } + // else + // { + // return (derivative); + // } + } +} \ No newline at end of file From d44d94e6d58904b47a0413710dd8458f835c80cb Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 29 Jul 2024 14:04:33 -0400 Subject: [PATCH 057/138] CMakeLists not ignored anymore --- .gitignore | 1 + examples/bubblyscreen/IC/build/CMakeLists.txt | 41 +++++++++++++++++++ examples/bubblyscreen/QA/build/CMakeLists.txt | 41 +++++++++++++++++++ .../IC/build/CMakeLists.txt | 41 +++++++++++++++++++ .../NI/build/CMakeLists.txt | 41 +++++++++++++++++++ .../QA/build/CMakeLists.txt | 41 +++++++++++++++++++ .../build/CMakeLists.txt | 41 +++++++++++++++++++ .../IC/build/CMakeLists.txt | 41 +++++++++++++++++++ 8 files changed, 288 insertions(+) create mode 100644 examples/bubblyscreen/IC/build/CMakeLists.txt create mode 100644 examples/bubblyscreen/QA/build/CMakeLists.txt create mode 100644 examples/sphericalclustercavitationonset/IC/build/CMakeLists.txt create mode 100644 examples/sphericalclustercavitationonset/NI/build/CMakeLists.txt create mode 100644 examples/sphericalclustercavitationonset/QA/build/CMakeLists.txt create mode 100644 examples/sphericalclusterinteractions/build/CMakeLists.txt create mode 100644 examples/sphericalclustertensionwave/IC/build/CMakeLists.txt diff --git a/.gitignore b/.gitignore index f1d2ab7..0d119a2 100644 --- a/.gitignore +++ b/.gitignore @@ -82,5 +82,6 @@ Makefile # Results *.txt +!CMakeLists.txt *.pdf *.png \ No newline at end of file diff --git a/examples/bubblyscreen/IC/build/CMakeLists.txt b/examples/bubblyscreen/IC/build/CMakeLists.txt new file mode 100644 index 0000000..b7b74a5 --- /dev/null +++ b/examples/bubblyscreen/IC/build/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.12) + +project (bubblyscreen_apecss) +set(CMAKE_C_COMPILER /usr/bin/gcc) + +include_directories($ENV{APECSS_DIR}/include) +FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) + +set (mylibs m apecss) +link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) + +foreach(arg ${myincludes}) + IF (arg MATCHES "-I") + STRING(REGEX REPLACE "-I" "" myinc ${arg}) + message("Additional include: ${myinc}") + include_directories(${myinc}) + ENDIF(arg MATCHES "-I") +endforeach(arg ${myincludes}) + +foreach(arg ${mylibs}) + STRING(REGEX REPLACE "lib" "" myl1 ${arg}) + STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) + set(mylibs ${myl2} ${mylibs} ${myl2}) +endforeach(arg ${mylibs}) + +if(NOT CMAKE_BUILD_TYPE) + message(STATUS "Optimization: No optimization specified.") + set(CMAKE_BUILD_TYPE Release) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + message(STATUS "Optimization: Debug") + set(CMAKE_C_FLAGS_DEBUG "-Wall -g") +elseif(CMAKE_BUILD_TYPE STREQUAL "Release") + message(STATUS "Optimization: Release") + add_definitions(-DNDEBUG) + set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") +endif() + +add_executable(bubblyscreen_apecss ${myfiles}) +target_link_libraries(bubblyscreen_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/bubblyscreen/QA/build/CMakeLists.txt b/examples/bubblyscreen/QA/build/CMakeLists.txt new file mode 100644 index 0000000..2335399 --- /dev/null +++ b/examples/bubblyscreen/QA/build/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.12) + +project (bubblyscreen_apecss) +set(CMAKE_C_COMPILER mpicc) + +include_directories($ENV{APECSS_DIR}/include) +FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) + +set (mylibs m apecss) +link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) + +foreach(arg ${myincludes}) + IF (arg MATCHES "-I") + STRING(REGEX REPLACE "-I" "" myinc ${arg}) + message("Additional include: ${myinc}") + include_directories(${myinc}) + ENDIF(arg MATCHES "-I") +endforeach(arg ${myincludes}) + +foreach(arg ${mylibs}) + STRING(REGEX REPLACE "lib" "" myl1 ${arg}) + STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) + set(mylibs ${myl2} ${mylibs} ${myl2}) +endforeach(arg ${mylibs}) + +if(NOT CMAKE_BUILD_TYPE) + message(STATUS "Optimization: No optimization specified.") + set(CMAKE_BUILD_TYPE Release) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + message(STATUS "Optimization: Debug") + set(CMAKE_C_FLAGS_DEBUG "-Wall -g") +elseif(CMAKE_BUILD_TYPE STREQUAL "Release") + message(STATUS "Optimization: Release") + add_definitions(-DNDEBUG) + set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") +endif() + +add_executable(bubblyscreen_apecss ${myfiles}) +target_link_libraries(bubblyscreen_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/IC/build/CMakeLists.txt b/examples/sphericalclustercavitationonset/IC/build/CMakeLists.txt new file mode 100644 index 0000000..ff672ba --- /dev/null +++ b/examples/sphericalclustercavitationonset/IC/build/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.12) + +project (sphericalclustercavitationonset_apecss) +set(CMAKE_C_COMPILER /usr/bin/gcc) + +include_directories($ENV{APECSS_DIR}/include) +FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) + +set (mylibs m apecss) +link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) + +foreach(arg ${myincludes}) + IF (arg MATCHES "-I") + STRING(REGEX REPLACE "-I" "" myinc ${arg}) + message("Additional include: ${myinc}") + include_directories(${myinc}) + ENDIF(arg MATCHES "-I") +endforeach(arg ${myincludes}) + +foreach(arg ${mylibs}) + STRING(REGEX REPLACE "lib" "" myl1 ${arg}) + STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) + set(mylibs ${myl2} ${mylibs} ${myl2}) +endforeach(arg ${mylibs}) + +if(NOT CMAKE_BUILD_TYPE) + message(STATUS "Optimization: No optimization specified.") + set(CMAKE_BUILD_TYPE Release) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + message(STATUS "Optimization: Debug") + set(CMAKE_C_FLAGS_DEBUG "-Wall -g") +elseif(CMAKE_BUILD_TYPE STREQUAL "Release") + message(STATUS "Optimization: Release") + add_definitions(-DNDEBUG) + set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") +endif() + +add_executable(sphericalclustercavitationonset_apecss ${myfiles}) +target_link_libraries(sphericalclustercavitationonset_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/NI/build/CMakeLists.txt b/examples/sphericalclustercavitationonset/NI/build/CMakeLists.txt new file mode 100644 index 0000000..ff672ba --- /dev/null +++ b/examples/sphericalclustercavitationonset/NI/build/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.12) + +project (sphericalclustercavitationonset_apecss) +set(CMAKE_C_COMPILER /usr/bin/gcc) + +include_directories($ENV{APECSS_DIR}/include) +FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) + +set (mylibs m apecss) +link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) + +foreach(arg ${myincludes}) + IF (arg MATCHES "-I") + STRING(REGEX REPLACE "-I" "" myinc ${arg}) + message("Additional include: ${myinc}") + include_directories(${myinc}) + ENDIF(arg MATCHES "-I") +endforeach(arg ${myincludes}) + +foreach(arg ${mylibs}) + STRING(REGEX REPLACE "lib" "" myl1 ${arg}) + STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) + set(mylibs ${myl2} ${mylibs} ${myl2}) +endforeach(arg ${mylibs}) + +if(NOT CMAKE_BUILD_TYPE) + message(STATUS "Optimization: No optimization specified.") + set(CMAKE_BUILD_TYPE Release) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + message(STATUS "Optimization: Debug") + set(CMAKE_C_FLAGS_DEBUG "-Wall -g") +elseif(CMAKE_BUILD_TYPE STREQUAL "Release") + message(STATUS "Optimization: Release") + add_definitions(-DNDEBUG) + set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") +endif() + +add_executable(sphericalclustercavitationonset_apecss ${myfiles}) +target_link_libraries(sphericalclustercavitationonset_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/QA/build/CMakeLists.txt b/examples/sphericalclustercavitationonset/QA/build/CMakeLists.txt new file mode 100644 index 0000000..6fece97 --- /dev/null +++ b/examples/sphericalclustercavitationonset/QA/build/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.12) + +project (sphericalclustercavitationonset_apecss) +set(CMAKE_C_COMPILER mpicc) + +include_directories($ENV{APECSS_DIR}/include) +FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) + +set (mylibs m apecss) +link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) + +foreach(arg ${myincludes}) + IF (arg MATCHES "-I") + STRING(REGEX REPLACE "-I" "" myinc ${arg}) + message("Additional include: ${myinc}") + include_directories(${myinc}) + ENDIF(arg MATCHES "-I") +endforeach(arg ${myincludes}) + +foreach(arg ${mylibs}) + STRING(REGEX REPLACE "lib" "" myl1 ${arg}) + STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) + set(mylibs ${myl2} ${mylibs} ${myl2}) +endforeach(arg ${mylibs}) + +if(NOT CMAKE_BUILD_TYPE) + message(STATUS "Optimization: No optimization specified.") + set(CMAKE_BUILD_TYPE Release) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + message(STATUS "Optimization: Debug") + set(CMAKE_C_FLAGS_DEBUG "-Wall -g") +elseif(CMAKE_BUILD_TYPE STREQUAL "Release") + message(STATUS "Optimization: Release") + add_definitions(-DNDEBUG) + set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") +endif() + +add_executable(sphericalclustercavitationonset_apecss ${myfiles}) +target_link_libraries(sphericalclustercavitationonset_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/sphericalclusterinteractions/build/CMakeLists.txt b/examples/sphericalclusterinteractions/build/CMakeLists.txt new file mode 100644 index 0000000..937ef70 --- /dev/null +++ b/examples/sphericalclusterinteractions/build/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.12) + +project (sphericalclusterinteractions_apecss) +set(CMAKE_C_COMPILER mpicc) + +include_directories($ENV{APECSS_DIR}/include) +FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) + +set (mylibs m apecss) +link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) + +foreach(arg ${myincludes}) + IF (arg MATCHES "-I") + STRING(REGEX REPLACE "-I" "" myinc ${arg}) + message("Additional include: ${myinc}") + include_directories(${myinc}) + ENDIF(arg MATCHES "-I") +endforeach(arg ${myincludes}) + +foreach(arg ${mylibs}) + STRING(REGEX REPLACE "lib" "" myl1 ${arg}) + STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) + set(mylibs ${myl2} ${mylibs} ${myl2}) +endforeach(arg ${mylibs}) + +if(NOT CMAKE_BUILD_TYPE) + message(STATUS "Optimization: No optimization specified.") + set(CMAKE_BUILD_TYPE Release) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + message(STATUS "Optimization: Debug") + set(CMAKE_C_FLAGS_DEBUG "-Wall -g") +elseif(CMAKE_BUILD_TYPE STREQUAL "Release") + message(STATUS "Optimization: Release") + add_definitions(-DNDEBUG) + set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") +endif() + +add_executable(sphericalclusterinteractions_apecss ${myfiles}) +target_link_libraries(sphericalclusterinteractions_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/sphericalclustertensionwave/IC/build/CMakeLists.txt b/examples/sphericalclustertensionwave/IC/build/CMakeLists.txt new file mode 100644 index 0000000..ff672ba --- /dev/null +++ b/examples/sphericalclustertensionwave/IC/build/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.12) + +project (sphericalclustercavitationonset_apecss) +set(CMAKE_C_COMPILER /usr/bin/gcc) + +include_directories($ENV{APECSS_DIR}/include) +FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) + +set (mylibs m apecss) +link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) + +foreach(arg ${myincludes}) + IF (arg MATCHES "-I") + STRING(REGEX REPLACE "-I" "" myinc ${arg}) + message("Additional include: ${myinc}") + include_directories(${myinc}) + ENDIF(arg MATCHES "-I") +endforeach(arg ${myincludes}) + +foreach(arg ${mylibs}) + STRING(REGEX REPLACE "lib" "" myl1 ${arg}) + STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) + set(mylibs ${myl2} ${mylibs} ${myl2}) +endforeach(arg ${mylibs}) + +if(NOT CMAKE_BUILD_TYPE) + message(STATUS "Optimization: No optimization specified.") + set(CMAKE_BUILD_TYPE Release) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + message(STATUS "Optimization: Debug") + set(CMAKE_C_FLAGS_DEBUG "-Wall -g") +elseif(CMAKE_BUILD_TYPE STREQUAL "Release") + message(STATUS "Optimization: Release") + add_definitions(-DNDEBUG) + set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") +endif() + +add_executable(sphericalclustercavitationonset_apecss ${myfiles}) +target_link_libraries(sphericalclustercavitationonset_apecss ${mylibs}) \ No newline at end of file From 510063deb222455cdb8d1ab675bea094920595d5 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 29 Jul 2024 17:55:03 -0400 Subject: [PATCH 058/138] Spherical cluster tension wave ; no interaction framework --- .../NI/build/CMakeLists.txt | 41 ++ .../NI/build/compile.sh | 5 + .../NI/gather_results.py | 53 +++ .../sphericalclustertensionwave/NI/run.apecss | 37 ++ .../src/sphericalclustertensionwave_apecss.c | 385 ++++++++++++++++++ 5 files changed, 521 insertions(+) create mode 100644 examples/sphericalclustertensionwave/NI/build/CMakeLists.txt create mode 100755 examples/sphericalclustertensionwave/NI/build/compile.sh create mode 100644 examples/sphericalclustertensionwave/NI/gather_results.py create mode 100644 examples/sphericalclustertensionwave/NI/run.apecss create mode 100644 examples/sphericalclustertensionwave/NI/src/sphericalclustertensionwave_apecss.c diff --git a/examples/sphericalclustertensionwave/NI/build/CMakeLists.txt b/examples/sphericalclustertensionwave/NI/build/CMakeLists.txt new file mode 100644 index 0000000..254078c --- /dev/null +++ b/examples/sphericalclustertensionwave/NI/build/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.12) + +project (sphericalclustertensionwave_apecss) +set(CMAKE_C_COMPILER /usr/bin/gcc) + +include_directories($ENV{APECSS_DIR}/include) +FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) + +set (mylibs m apecss) +link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) + +foreach(arg ${myincludes}) + IF (arg MATCHES "-I") + STRING(REGEX REPLACE "-I" "" myinc ${arg}) + message("Additional include: ${myinc}") + include_directories(${myinc}) + ENDIF(arg MATCHES "-I") +endforeach(arg ${myincludes}) + +foreach(arg ${mylibs}) + STRING(REGEX REPLACE "lib" "" myl1 ${arg}) + STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) + set(mylibs ${myl2} ${mylibs} ${myl2}) +endforeach(arg ${mylibs}) + +if(NOT CMAKE_BUILD_TYPE) + message(STATUS "Optimization: No optimization specified.") + set(CMAKE_BUILD_TYPE Release) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + message(STATUS "Optimization: Debug") + set(CMAKE_C_FLAGS_DEBUG "-Wall -g") +elseif(CMAKE_BUILD_TYPE STREQUAL "Release") + message(STATUS "Optimization: Release") + add_definitions(-DNDEBUG) + set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") +endif() + +add_executable(sphericalclustertensionwave_apecss ${myfiles}) +target_link_libraries(sphericalclustertensionwave_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/sphericalclustertensionwave/NI/build/compile.sh b/examples/sphericalclustertensionwave/NI/build/compile.sh new file mode 100755 index 0000000..564c7a4 --- /dev/null +++ b/examples/sphericalclustertensionwave/NI/build/compile.sh @@ -0,0 +1,5 @@ +#!/bin/bash +rm sphericalclustertensionwave_apecss +cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release +make +rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/sphericalclustertensionwave/NI/gather_results.py b/examples/sphericalclustertensionwave/NI/gather_results.py new file mode 100644 index 0000000..92ecd08 --- /dev/null +++ b/examples/sphericalclustertensionwave/NI/gather_results.py @@ -0,0 +1,53 @@ +import os + +# File designed to recover data for plotting results in cavitation onset case + +file = open("tension_results.txt", "r") +lines = file.readlines() +file.close() + +count = int(lines[0].split(" ")[0]) +p1 = float(lines[0].split(" ")[5]) +cl_distrib = int(lines[0].split(" ")[7]) + +if cl_distrib == 0 : + # monodispersed spherical cluster + file_name = "mono_{}_{:.4E}.txt".format(count, p1) + +else : + # polydispersed spherical cluster + file_name = "poly_{}_{:.4E}.txt".format(count, p1) + +working_path = os.getcwd() +results_path = os.path.join(working_path, "results") +file_results = open(os.path.join(results_path, file_name), "w") + +# for line in lines : +# if "nan" not in line : +# file_results.write(line) + +index = 0 +while index < len(lines) and "nan" not in lines[index] : + file_results.write(lines[index]) + index += 1 + +file_results.close() + +file_loc = open("bubble_loc.txt", "r") +lines_loc = file_loc.readlines() +file_loc.close() + +if cl_distrib == 0 : + # monodispersed spherical cluster + file_name_loc = "mono_{}_{:.4E}_loc.txt".format(count, p1) + +else : + # polydispersed spherical cluster + file_name_loc = "poly_{}_{:.4E}_loc.txt".format(count, p1) + +file_loc_results = open(os.path.join(results_path, file_name_loc), "w") + +for line in lines_loc : + file_loc_results.write(line) + +file_loc_results.close() \ No newline at end of file diff --git a/examples/sphericalclustertensionwave/NI/run.apecss b/examples/sphericalclustertensionwave/NI/run.apecss new file mode 100644 index 0000000..44bbe03 --- /dev/null +++ b/examples/sphericalclustertensionwave/NI/run.apecss @@ -0,0 +1,37 @@ +######################################################### +# # +# APECSS Options File # +# # +######################################################### + +BUBBLE +RPModel KM +Emissions IC 300.0e-6 +PressureAmbient 1.0e5 +END + +GAS +EoS IG +ReferenceDensity 1.2 +PolytropicExponent 1.4 +END + +LIQUID +ReferencePressure 1.0e5 +ReferenceDensity 1000.0 +ReferenceSoundSpeed 1500.0 +Viscosity 1.002e-3 +END + +INTERFACE +SurfaceTensionCoeff 0.0728 +END + +RESULTS +Bubble +END + +ODESOLVER +tolerance 1.0e-10 +MinTimeStep 1.0e-10 +END diff --git a/examples/sphericalclustertensionwave/NI/src/sphericalclustertensionwave_apecss.c b/examples/sphericalclustertensionwave/NI/src/sphericalclustertensionwave_apecss.c new file mode 100644 index 0000000..d4a725e --- /dev/null +++ b/examples/sphericalclustertensionwave/NI/src/sphericalclustertensionwave_apecss.c @@ -0,0 +1,385 @@ +// This source file is part of APECSS, an open-source software toolbox +// for the computation of pressure-driven bubble dynamics and acoustic +// emissions in spherical symmetry. +// +// Copyright (C) 2022-2024 The APECSS Developers +// +// The APECSS Developers are listed in the README.md file available in +// the GitHub repository at https://github.com/polycfd/apecss. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// ------------------------------------------------------------------- +// APECSS standalone example of acoustically-interacting microbubbles +// in a spherical cluster with the goal to study cavitation onset +// ------------------------------------------------------------------- + +#include +#include "apecss.h" + +APECSS_FLOAT rand_range(double min, double max) +{ + double random = (drand48()); + double range = (max - min) * random; + double number = min + range; + + return (APECSS_FLOAT) number; +} + +APECSS_FLOAT normal_distribution(double mu, double sigma) +{ + // Generating a normal distribution using Box-Muller transform, with mu as mean and sigma**2 as variance + double u1 = (drand48()); + while (u1 == 0.0) u1 = (drand48()); + double u2 = (drand48()); + + double mag = sigma * APECSS_SQRT(-2.0 * APECSS_LOG(u1)); + double z1 = mag * APECSS_COS(2 * APECSS_PI * u2) + mu; + return (APECSS_FLOAT) z1; +} + +// Declaration of additional case-dependent functions +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); + +// Declaration of the structure holding the interaction variables of each bubble +struct Interaction +{ + APECSS_FLOAT dp_neighbor; +}; + +int main(int argc, char **args) +{ + char OptionsDir[APECSS_STRINGLENGTH]; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Set the case-dependent simulation parameters + const int nBubbles = 250; // Number of bubbles + APECSS_FLOAT bubble_bubble_dist = 20.0e-6; // Bubble-bubble minimal distance + APECSS_FLOAT cluster_radius = 232e-6; // Spherical cluster radius + + // Interbubble time-step, defining the frequency with which the neighbor influence is updated + APECSS_FLOAT dt_interbubble = 1.0e-8; + + // Initialize the simulation parameters given by the execution command + double tEnd = 0.0; + double fa = 0.0; + double pa = 0.0; + int cluster_distrib = 0; + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + apecss_infoscreen(); + + /* Read commandline options */ + sprintf(OptionsDir, "./run.apecss"); // This is the default + int j = 1; // First argument is the call to the executable + while (j < argc) + { + if (strcmp("-options", args[j]) == 0) + { + sprintf(OptionsDir, "%s", args[j + 1]); + j += 2; + } + else if (strcmp("-tend", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &tEnd); + j += 2; + } + else if (strcmp("-freq", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &fa); + j += 2; + } + else if (strcmp("-amp", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &pa); + j += 2; + } + else if (strcmp("-cldistrib", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &cluster_distrib); + j += 2; + } + else if (strcmp("-h", args[j]) == 0) + { + apecss_helpscreen(); + } + else + { + char str[APECSS_STRINGLENGTH_SPRINTF]; + sprintf(str, "Unknown command line options: %s", args[j]); + apecss_erroronscreen(1, str); + ++j; + } + } + + /* Allocate and initialize Bubble structure */ + struct APECSS_Bubble *Bubbles[nBubbles]; + for (register int i = 0; i < nBubbles; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(nBubbles * sizeof(struct APECSS_Bubble)); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initializestruct(Bubbles[i]); + + /* Set default options and read the options for the bubble */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); + + /* Allocate the structures for the fluid properties and ODE solver parameters */ + struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); + struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); + struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); + struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); + + /* Set the default options for the fluid properties and solver parameters */ + apecss_gas_setdefaultoptions(Gas); + apecss_liquid_setdefaultoptions(Liquid); + apecss_interface_setdefaultoptions(Interface); + apecss_odesolver_setdefaultoptions(NumericsODE); + + /* Read the options file for the fluid properties and solver parameters */ + apecss_gas_readoptions(Gas, OptionsDir); + apecss_liquid_readoptions(Liquid, OptionsDir); + apecss_interface_readoptions(Interface, OptionsDir); + apecss_odesolver_readoptions(NumericsODE, OptionsDir); + + /* Associate the bubble with the relevant fluid properties and solver parameters */ + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Gas = Gas; + Bubbles[i]->Liquid = Liquid; + Bubbles[i]->Interface = Interface; + Bubbles[i]->NumericsODE = NumericsODE; + } + + /* Allocate and set the excitation parameters */ + struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); + Excitation->type = APECSS_EXCITATION_SIN; + Excitation->f = (APECSS_FLOAT) fa; + Excitation->dp = (APECSS_FLOAT) pa; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Excitation = Excitation; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Create individual folders for the results of each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (Bubbles[i]->Results != NULL) + { + sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", i); + struct stat st = {0}; + if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Process all options */ + apecss_gas_processoptions(Gas); + apecss_liquid_processoptions(Liquid); + apecss_interface_processoptions(Interface); + apecss_odesolver_processoptions(NumericsODE); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_processoptions(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Use the revised pressure at infinity, including neighbor contributions + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressure_infinity = interaction_bubble_pressure_infinity; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressurederivative_infinity = interaction_bubble_pressurederivative_infinity; + + // Initialize interaction structure + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); + + // Update interaction structure + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Interaction->nBubbles = nBubbles; + Bubbles[i]->Interaction->dp_neighbor = 0.0; + Bubbles[i]->Interaction->last_t_1 = 0.0; + Bubbles[i]->Interaction->last_t_2 = 0.0; + Bubbles[i]->Interaction->last_p_1 = 0.0; + Bubbles[i]->Interaction->last_p_2 = 0.0; + } + + // Define the size of each bubble + if (cluster_distrib == 0) + { + // Monodispersed cluster + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->R0 = 2.0e-6; + } + } + else + { + // Polydispersed cluster (radii distribution is following a log normal law) + double mu = 0.0; + double sigma = 0.7; + APECSS_FLOAT radius_ref = 2.0e-6; + for (register int i = 0; i < nBubbles; i++) + { + APECSS_FLOAT radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); + // while ((radius > 20 * radius_ref) || (radius < 0.5 * radius_ref)) + while (radius > 20 * radius_ref) + { + // Small step to ensure no too big nor too small bubbles are generated (the distribution is conserved still) + radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); + } + Bubbles[i]->R0 = radius; + } + } + + // Define center location for each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (i == 0) + { + Bubbles[i]->Interaction->location[0] = 0.0; + Bubbles[i]->Interaction->location[1] = 0.0; + Bubbles[i]->Interaction->location[2] = 0.0; + } + else + { + APECSS_FLOAT x = rand_range((double) -cluster_radius, (double) cluster_radius); + APECSS_FLOAT y = rand_range((double) -cluster_radius, (double) cluster_radius); + APECSS_FLOAT z = rand_range((double) -cluster_radius, (double) cluster_radius); + + APECSS_FLOAT radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); + + while (radius > cluster_radius) + { + x = rand_range((double) -cluster_radius, (double) cluster_radius); + y = rand_range((double) -cluster_radius, (double) cluster_radius); + z = rand_range((double) -cluster_radius, (double) cluster_radius); + + radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); + } + + Bubbles[i]->Interaction->location[0] = x; + Bubbles[i]->Interaction->location[1] = y; + Bubbles[i]->Interaction->location[2] = z; + + for (register int k = 0; k < i; k++) + { + APECSS_FLOAT bubbledist = APECSS_SQRT(APECSS_POW2(Bubbles[i]->Interaction->location[0] - Bubbles[k]->Interaction->location[0]) + + APECSS_POW2(Bubbles[i]->Interaction->location[1] - Bubbles[k]->Interaction->location[1]) + + APECSS_POW2(Bubbles[i]->Interaction->location[2] - Bubbles[k]->Interaction->location[2])); + if (bubbledist < bubble_bubble_dist) + { + i--; + break; + } + } + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + clock_t starttimebubble = clock(); + APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system + + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->tStart = tSim; + Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; + Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step + } + + /* Initialize the bubble based on the selected options */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initialize(Bubbles[i]); + + /* Initialize */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_initialize(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Files to retrieve all valuable information for cavitation onset test case + FILE *file_loc; + file_loc = fopen("bubble_loc.txt", "w"); + fprintf(file_loc, "#number x(m) y(m) z(m)\n"); + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_loc, "%d %e %e %e\n", i, Bubbles[i]->Interaction->location[0], Bubbles[i]->Interaction->location[1], Bubbles[i]->Interaction->location[2]); + } + fclose(file_loc); + + FILE *file_tension; + file_tension = fopen("tension_results.txt", "w"); + fprintf(file_tension, "%d Bubbles p0(pa) %e p1(Pa) %e cl_distrib %d\n", nBubbles, Liquid->pref, pa, cluster_distrib); + fprintf(file_tension, "Initial_radii(m)"); + for (register int i = 0; i < nBubbles; i++) fprintf(file_tension, " %e", Bubbles[i]->R0); + fprintf(file_tension, "\n"); + fprintf(file_tension, "#Time(s) R(m) Pt(Pa)\n"); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Solve the bubble dynamics */ + while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered + { + APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); + tSim += dtSim; + + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Retrieve data + fprintf(file_tension, "%e", tSim); + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_tension, " %e", Bubbles[i]->R); + } + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_tension, " %e", Bubbles[i]->get_pressure_infinity(Bubbles[i]->t, Bubbles[i])); + } + fprintf(file_tension, "\n"); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + } + + fclose(file_tension); + + /* Finalize the simulation*/ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_finalize(Bubbles[i]); + + char str[APECSS_STRINGLENGTH_SPRINTF]; + for (register int i = 0; i < nBubbles; i++) + { + sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", i, Bubbles[i]->dtNumber, Bubbles[i]->nSubIter, + (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); + apecss_writeonscreen(str); + } + + for (register int i = 0; i < nBubbles; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); + for (register int i = 0; i < nBubbles; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); + + /* Make sure all allocated memory is freed */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_freestruct(Bubbles[i]); + + for (register int i = 0; i < nBubbles; i++) free(Bubbles[i]); + free(Gas); + free(Liquid); + free(Interface); + free(NumericsODE); + free(Excitation); + + return (0); +} + +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + APECSS_FLOAT tau = 1.75e-6; + if (t < tau) + { + return (Bubble->p0 - (Bubble->p0 - Bubble->Excitation->dp) * APECSS_POW2(APECSS_SIN(APECSS_PI * t / tau)) + Bubble->Interaction->dp_neighbor); + } + else + { + return (Bubble->p0 + Bubble->Interaction->dp_neighbor); + } +} + +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + APECSS_FLOAT tau = 1.75e-6; + if (t < tau) + { + return (-2.0 * (APECSS_PI / tau) * (Bubble->p0 - Bubble->Excitation->dp) * APECSS_COS(APECSS_PI * t / tau) * APECSS_SIN(APECSS_PI * t / tau)); + } + else + { + return (0.0); + } +} \ No newline at end of file From be9cdfc6490849b55a00941b2da23728ece5f14c Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 29 Jul 2024 17:55:28 -0400 Subject: [PATCH 059/138] Spherical cluster tension wave ; IC framework --- .../IC/build/CMakeLists.txt | 6 +- .../IC/build/compile.sh | 2 +- .../IC/gather_results.py | 12 +- .../sphericalclustertensionwave/IC/run.apecss | 9 +- .../src/sphericalclustertensionwave_apecss.c | 390 ++++++++++++++++++ 5 files changed, 407 insertions(+), 12 deletions(-) create mode 100644 examples/sphericalclustertensionwave/IC/src/sphericalclustertensionwave_apecss.c diff --git a/examples/sphericalclustertensionwave/IC/build/CMakeLists.txt b/examples/sphericalclustertensionwave/IC/build/CMakeLists.txt index ff672ba..254078c 100644 --- a/examples/sphericalclustertensionwave/IC/build/CMakeLists.txt +++ b/examples/sphericalclustertensionwave/IC/build/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.12) -project (sphericalclustercavitationonset_apecss) +project (sphericalclustertensionwave_apecss) set(CMAKE_C_COMPILER /usr/bin/gcc) include_directories($ENV{APECSS_DIR}/include) @@ -37,5 +37,5 @@ elseif(CMAKE_BUILD_TYPE STREQUAL "Release") set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") endif() -add_executable(sphericalclustercavitationonset_apecss ${myfiles}) -target_link_libraries(sphericalclustercavitationonset_apecss ${mylibs}) \ No newline at end of file +add_executable(sphericalclustertensionwave_apecss ${myfiles}) +target_link_libraries(sphericalclustertensionwave_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/sphericalclustertensionwave/IC/build/compile.sh b/examples/sphericalclustertensionwave/IC/build/compile.sh index 33147c8..564c7a4 100755 --- a/examples/sphericalclustertensionwave/IC/build/compile.sh +++ b/examples/sphericalclustertensionwave/IC/build/compile.sh @@ -1,5 +1,5 @@ #!/bin/bash -rm sphericalclustercavitationonset_apecss +rm sphericalclustertensionwave_apecss cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release make rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/sphericalclustertensionwave/IC/gather_results.py b/examples/sphericalclustertensionwave/IC/gather_results.py index 570d247..92ecd08 100644 --- a/examples/sphericalclustertensionwave/IC/gather_results.py +++ b/examples/sphericalclustertensionwave/IC/gather_results.py @@ -2,21 +2,21 @@ # File designed to recover data for plotting results in cavitation onset case -file = open("onset_results.txt", "r") +file = open("tension_results.txt", "r") lines = file.readlines() file.close() count = int(lines[0].split(" ")[0]) -png = float(lines[0].split(" ")[5]) +p1 = float(lines[0].split(" ")[5]) cl_distrib = int(lines[0].split(" ")[7]) if cl_distrib == 0 : # monodispersed spherical cluster - file_name = "mono_{}_{:.4E}.txt".format(count, png) + file_name = "mono_{}_{:.4E}.txt".format(count, p1) else : # polydispersed spherical cluster - file_name = "poly_{}_{:.4E}.txt".format(count, png) + file_name = "poly_{}_{:.4E}.txt".format(count, p1) working_path = os.getcwd() results_path = os.path.join(working_path, "results") @@ -39,11 +39,11 @@ if cl_distrib == 0 : # monodispersed spherical cluster - file_name_loc = "mono_{}_{:.4E}_loc.txt".format(count, png) + file_name_loc = "mono_{}_{:.4E}_loc.txt".format(count, p1) else : # polydispersed spherical cluster - file_name_loc = "poly_{}_{:.4E}_loc.txt".format(count, png) + file_name_loc = "poly_{}_{:.4E}_loc.txt".format(count, p1) file_loc_results = open(os.path.join(results_path, file_name_loc), "w") diff --git a/examples/sphericalclustertensionwave/IC/run.apecss b/examples/sphericalclustertensionwave/IC/run.apecss index 50eac9b..44bbe03 100644 --- a/examples/sphericalclustertensionwave/IC/run.apecss +++ b/examples/sphericalclustertensionwave/IC/run.apecss @@ -7,7 +7,7 @@ BUBBLE RPModel KM Emissions IC 300.0e-6 -PressureAmbient 0.1013e6 +PressureAmbient 1.0e5 END GAS @@ -17,7 +17,7 @@ PolytropicExponent 1.4 END LIQUID -ReferencePressure 0.1013e6 +ReferencePressure 1.0e5 ReferenceDensity 1000.0 ReferenceSoundSpeed 1500.0 Viscosity 1.002e-3 @@ -27,6 +27,11 @@ INTERFACE SurfaceTensionCoeff 0.0728 END +RESULTS +Bubble +END + ODESOLVER tolerance 1.0e-10 +MinTimeStep 1.0e-10 END diff --git a/examples/sphericalclustertensionwave/IC/src/sphericalclustertensionwave_apecss.c b/examples/sphericalclustertensionwave/IC/src/sphericalclustertensionwave_apecss.c new file mode 100644 index 0000000..cc28962 --- /dev/null +++ b/examples/sphericalclustertensionwave/IC/src/sphericalclustertensionwave_apecss.c @@ -0,0 +1,390 @@ +// This source file is part of APECSS, an open-source software toolbox +// for the computation of pressure-driven bubble dynamics and acoustic +// emissions in spherical symmetry. +// +// Copyright (C) 2022-2024 The APECSS Developers +// +// The APECSS Developers are listed in the README.md file available in +// the GitHub repository at https://github.com/polycfd/apecss. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// ------------------------------------------------------------------- +// APECSS standalone example of acoustically-interacting microbubbles +// in a spherical cluster with the goal to study cavitation onset +// ------------------------------------------------------------------- + +#include +#include "apecss.h" + +APECSS_FLOAT rand_range(double min, double max) +{ + double random = (drand48()); + double range = (max - min) * random; + double number = min + range; + + return (APECSS_FLOAT) number; +} + +APECSS_FLOAT normal_distribution(double mu, double sigma) +{ + // Generating a normal distribution using Box-Muller transform, with mu as mean and sigma**2 as variance + double u1 = (drand48()); + while (u1 == 0.0) u1 = (drand48()); + double u2 = (drand48()); + + double mag = sigma * APECSS_SQRT(-2.0 * APECSS_LOG(u1)); + double z1 = mag * APECSS_COS(2 * APECSS_PI * u2) + mu; + return (APECSS_FLOAT) z1; +} + +// Declaration of additional case-dependent functions +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); + +// Declaration of the structure holding the interaction variables of each bubble +struct Interaction +{ + APECSS_FLOAT dp_neighbor; +}; + +int main(int argc, char **args) +{ + char OptionsDir[APECSS_STRINGLENGTH]; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Set the case-dependent simulation parameters + const int nBubbles = 250; // Number of bubbles + APECSS_FLOAT bubble_bubble_dist = 20.0e-6; // Bubble-bubble minimal distance + APECSS_FLOAT cluster_radius = 232e-6; // Spherical cluster radius + + // Interbubble time-step, defining the frequency with which the neighbor influence is updated + APECSS_FLOAT dt_interbubble = 1.0e-8; + + // Initialize the simulation parameters given by the execution command + double tEnd = 0.0; + double fa = 0.0; + double pa = 0.0; + int cluster_distrib = 0; + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + apecss_infoscreen(); + + /* Read commandline options */ + sprintf(OptionsDir, "./run.apecss"); // This is the default + int j = 1; // First argument is the call to the executable + while (j < argc) + { + if (strcmp("-options", args[j]) == 0) + { + sprintf(OptionsDir, "%s", args[j + 1]); + j += 2; + } + else if (strcmp("-tend", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &tEnd); + j += 2; + } + else if (strcmp("-freq", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &fa); + j += 2; + } + else if (strcmp("-amp", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &pa); + j += 2; + } + else if (strcmp("-cldistrib", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &cluster_distrib); + j += 2; + } + else if (strcmp("-h", args[j]) == 0) + { + apecss_helpscreen(); + } + else + { + char str[APECSS_STRINGLENGTH_SPRINTF]; + sprintf(str, "Unknown command line options: %s", args[j]); + apecss_erroronscreen(1, str); + ++j; + } + } + + /* Allocate and initialize Bubble structure */ + struct APECSS_Bubble *Bubbles[nBubbles]; + for (register int i = 0; i < nBubbles; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(nBubbles * sizeof(struct APECSS_Bubble)); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initializestruct(Bubbles[i]); + + /* Set default options and read the options for the bubble */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); + + /* Allocate the structures for the fluid properties and ODE solver parameters */ + struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); + struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); + struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); + struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); + + /* Set the default options for the fluid properties and solver parameters */ + apecss_gas_setdefaultoptions(Gas); + apecss_liquid_setdefaultoptions(Liquid); + apecss_interface_setdefaultoptions(Interface); + apecss_odesolver_setdefaultoptions(NumericsODE); + + /* Read the options file for the fluid properties and solver parameters */ + apecss_gas_readoptions(Gas, OptionsDir); + apecss_liquid_readoptions(Liquid, OptionsDir); + apecss_interface_readoptions(Interface, OptionsDir); + apecss_odesolver_readoptions(NumericsODE, OptionsDir); + + /* Associate the bubble with the relevant fluid properties and solver parameters */ + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Gas = Gas; + Bubbles[i]->Liquid = Liquid; + Bubbles[i]->Interface = Interface; + Bubbles[i]->NumericsODE = NumericsODE; + } + + /* Allocate and set the excitation parameters */ + struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); + Excitation->type = APECSS_EXCITATION_SIN; + Excitation->f = (APECSS_FLOAT) fa; + Excitation->dp = (APECSS_FLOAT) pa; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Excitation = Excitation; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Create individual folders for the results of each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (Bubbles[i]->Results != NULL) + { + sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", i); + struct stat st = {0}; + if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Process all options */ + apecss_gas_processoptions(Gas); + apecss_liquid_processoptions(Liquid); + apecss_interface_processoptions(Interface); + apecss_odesolver_processoptions(NumericsODE); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_processoptions(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Use the revised pressure at infinity, including neighbor contributions + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressure_infinity = interaction_bubble_pressure_infinity; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressurederivative_infinity = interaction_bubble_pressurederivative_infinity; + + // Initialize interaction structure + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); + + // Update interaction structure + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Interaction->nBubbles = nBubbles; + Bubbles[i]->Interaction->dp_neighbor = 0.0; + Bubbles[i]->Interaction->last_t_1 = 0.0; + Bubbles[i]->Interaction->last_t_2 = 0.0; + Bubbles[i]->Interaction->last_p_1 = 0.0; + Bubbles[i]->Interaction->last_p_2 = 0.0; + } + + // Define the size of each bubble + if (cluster_distrib == 0) + { + // Monodispersed cluster + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->R0 = 2.0e-6; + } + } + else + { + // Polydispersed cluster (radii distribution is following a log normal law) + double mu = 0.0; + double sigma = 0.7; + APECSS_FLOAT radius_ref = 2.0e-6; + for (register int i = 0; i < nBubbles; i++) + { + APECSS_FLOAT radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); + // while ((radius > 20 * radius_ref) || (radius < 0.5 * radius_ref)) + while (radius > 20 * radius_ref) + { + // Small step to ensure no too big nor too small bubbles are generated (the distribution is conserved still) + radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); + } + Bubbles[i]->R0 = radius; + } + } + + // Define center location for each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (i == 0) + { + Bubbles[i]->Interaction->location[0] = 0.0; + Bubbles[i]->Interaction->location[1] = 0.0; + Bubbles[i]->Interaction->location[2] = 0.0; + } + else + { + APECSS_FLOAT x = rand_range((double) -cluster_radius, (double) cluster_radius); + APECSS_FLOAT y = rand_range((double) -cluster_radius, (double) cluster_radius); + APECSS_FLOAT z = rand_range((double) -cluster_radius, (double) cluster_radius); + + APECSS_FLOAT radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); + + while (radius > cluster_radius) + { + x = rand_range((double) -cluster_radius, (double) cluster_radius); + y = rand_range((double) -cluster_radius, (double) cluster_radius); + z = rand_range((double) -cluster_radius, (double) cluster_radius); + + radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); + } + + Bubbles[i]->Interaction->location[0] = x; + Bubbles[i]->Interaction->location[1] = y; + Bubbles[i]->Interaction->location[2] = z; + + for (register int k = 0; k < i; k++) + { + APECSS_FLOAT bubbledist = APECSS_SQRT(APECSS_POW2(Bubbles[i]->Interaction->location[0] - Bubbles[k]->Interaction->location[0]) + + APECSS_POW2(Bubbles[i]->Interaction->location[1] - Bubbles[k]->Interaction->location[1]) + + APECSS_POW2(Bubbles[i]->Interaction->location[2] - Bubbles[k]->Interaction->location[2])); + if (bubbledist < bubble_bubble_dist) + { + i--; + break; + } + } + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + clock_t starttimebubble = clock(); + APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system + + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->tStart = tSim; + Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; + Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step + } + + /* Initialize the bubble based on the selected options */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initialize(Bubbles[i]); + + /* Initialize */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_initialize(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Files to retrieve all valuable information for cavitation onset test case + FILE *file_loc; + file_loc = fopen("bubble_loc.txt", "w"); + fprintf(file_loc, "#number x(m) y(m) z(m)\n"); + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_loc, "%d %e %e %e\n", i, Bubbles[i]->Interaction->location[0], Bubbles[i]->Interaction->location[1], Bubbles[i]->Interaction->location[2]); + } + fclose(file_loc); + + FILE *file_tension; + file_tension = fopen("tension_results.txt", "w"); + fprintf(file_tension, "%d Bubbles p0(pa) %e p1(Pa) %e cl_distrib %d\n", nBubbles, Liquid->pref, pa, cluster_distrib); + fprintf(file_tension, "Initial_radii(m)"); + for (register int i = 0; i < nBubbles; i++) fprintf(file_tension, " %e", Bubbles[i]->R0); + fprintf(file_tension, "\n"); + fprintf(file_tension, "#Time(s) R(m) Pt(Pa)\n"); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Solve the bubble dynamics */ + while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered + { + APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); + tSim += dtSim; + + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Update the contribution of the neighbor bubble + apecss_interactions_instantaneous(Bubbles); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Retrieve data + fprintf(file_tension, "%e", tSim); + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_tension, " %e", Bubbles[i]->R); + } + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_tension, " %e", Bubbles[i]->get_pressure_infinity(Bubbles[i]->t, Bubbles[i])); + } + fprintf(file_tension, "\n"); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + } + + fclose(file_tension); + + /* Finalize the simulation*/ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_finalize(Bubbles[i]); + + char str[APECSS_STRINGLENGTH_SPRINTF]; + for (register int i = 0; i < nBubbles; i++) + { + sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", i, Bubbles[i]->dtNumber, Bubbles[i]->nSubIter, + (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); + apecss_writeonscreen(str); + } + + for (register int i = 0; i < nBubbles; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); + for (register int i = 0; i < nBubbles; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); + + /* Make sure all allocated memory is freed */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_freestruct(Bubbles[i]); + + for (register int i = 0; i < nBubbles; i++) free(Bubbles[i]); + free(Gas); + free(Liquid); + free(Interface); + free(NumericsODE); + free(Excitation); + + return (0); +} + +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + APECSS_FLOAT tau = 1.75e-6; + if (t < tau) + { + return (Bubble->p0 - (Bubble->p0 - Bubble->Excitation->dp) * APECSS_POW2(APECSS_SIN(APECSS_PI * t / tau)) + Bubble->Interaction->dp_neighbor); + } + else + { + return (Bubble->p0 + Bubble->Interaction->dp_neighbor); + } +} + +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + APECSS_FLOAT tau = 1.75e-6; + if (t < tau) + { + return (-2.0 * (APECSS_PI / tau) * (Bubble->p0 - Bubble->Excitation->dp) * APECSS_COS(APECSS_PI * t / tau) * APECSS_SIN(APECSS_PI * t / tau)); + } + else + { + return (0.0); + } +} \ No newline at end of file From c2744337a21c69575f7812c77b0a9163d362830e Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 29 Jul 2024 17:56:22 -0400 Subject: [PATCH 060/138] Spherical cluster tension wave ; general files to run and plot results --- .../sphericalclustercavitationonset_apecss.c | 428 -------------- .../plot_results.py | 527 ++++++++++++++++++ .../run_sphericalclustertensionwave.sh | 84 +++ 3 files changed, 611 insertions(+), 428 deletions(-) delete mode 100644 examples/sphericalclustertensionwave/IC/src/sphericalclustercavitationonset_apecss.c create mode 100644 examples/sphericalclustertensionwave/plot_results.py create mode 100755 examples/sphericalclustertensionwave/run_sphericalclustertensionwave.sh diff --git a/examples/sphericalclustertensionwave/IC/src/sphericalclustercavitationonset_apecss.c b/examples/sphericalclustertensionwave/IC/src/sphericalclustercavitationonset_apecss.c deleted file mode 100644 index ee0bdf3..0000000 --- a/examples/sphericalclustertensionwave/IC/src/sphericalclustercavitationonset_apecss.c +++ /dev/null @@ -1,428 +0,0 @@ -// This source file is part of APECSS, an open-source software toolbox -// for the computation of pressure-driven bubble dynamics and acoustic -// emissions in spherical symmetry. -// -// Copyright (C) 2022-2024 The APECSS Developers -// -// The APECSS Developers are listed in the README.md file available in -// the GitHub repository at https://github.com/polycfd/apecss. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// ------------------------------------------------------------------- -// APECSS standalone example of acoustically-interacting microbubbles -// in a spherical cluster with the goal to study cavitation onset -// ------------------------------------------------------------------- - -#include -#include "apecss.h" - -APECSS_FLOAT rand_range(double min, double max) -{ - double random = (drand48()); - double range = (max - min) * random; - double number = min + range; - - return (APECSS_FLOAT) number; -} - -APECSS_FLOAT normal_distribution(double mu, double sigma) -{ - // Generating a normal distribution using Box-Muller transform, with mu as mean and sigma**2 as variance - double u1 = (drand48()); - while (u1 == 0.0) u1 = (drand48()); - double u2 = (drand48()); - - double mag = sigma * APECSS_SQRT(-2.0 * APECSS_LOG(u1)); - double z1 = mag * APECSS_COS(2 * APECSS_PI * u2) + mu; - return (APECSS_FLOAT) z1; -} - -// Declaration of additional case-dependent functions -APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); - -// Declaration of the structure holding the interaction variables of each bubble -struct Interaction -{ - APECSS_FLOAT dp_neighbor; -}; - -int main(int argc, char **args) -{ - char OptionsDir[APECSS_STRINGLENGTH]; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Set the case-dependent simulation parameters - const int nBubbles = 2500; // Number of bubbles - APECSS_FLOAT bubble_bubble_dist = 100.0e-6; // Bubble-bubble minimal distance - APECSS_FLOAT cluster_radius = 2.5e-3; // Spherical cluster radius - - // Interbubble time-step, defining the frequency with which the neighbor influence is updated - APECSS_FLOAT dt_interbubble = 1.0e-8; - - // Initialize the simulation parameters given by the execution command - double tEnd = 0.0; - double fa = 0.0; - double pa = 0.0; - int cluster_distrib = 0; - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - apecss_infoscreen(); - - /* Read commandline options */ - sprintf(OptionsDir, "./run.apecss"); // This is the default - int j = 1; // First argument is the call to the executable - while (j < argc) - { - if (strcmp("-options", args[j]) == 0) - { - sprintf(OptionsDir, "%s", args[j + 1]); - j += 2; - } - else if (strcmp("-tend", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &tEnd); - j += 2; - } - else if (strcmp("-freq", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &fa); - j += 2; - } - else if (strcmp("-amp", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &pa); - j += 2; - } - else if (strcmp("-cldistrib", args[j]) == 0) - { - sscanf(args[j + 1], "%d", &cluster_distrib); - j += 2; - } - else if (strcmp("-h", args[j]) == 0) - { - apecss_helpscreen(); - } - else - { - char str[APECSS_STRINGLENGTH_SPRINTF]; - sprintf(str, "Unknown command line options: %s", args[j]); - apecss_erroronscreen(1, str); - ++j; - } - } - - /* Allocate and initialize Bubble structure */ - struct APECSS_Bubble *Bubbles[nBubbles]; - for (register int i = 0; i < nBubbles; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(nBubbles * sizeof(struct APECSS_Bubble)); - for (register int i = 0; i < nBubbles; i++) apecss_bubble_initializestruct(Bubbles[i]); - - /* Set default options and read the options for the bubble */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); - for (register int i = 0; i < nBubbles; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); - - /* Allocate the structures for the fluid properties and ODE solver parameters */ - struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); - struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); - struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); - struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); - - /* Set the default options for the fluid properties and solver parameters */ - apecss_gas_setdefaultoptions(Gas); - apecss_liquid_setdefaultoptions(Liquid); - apecss_interface_setdefaultoptions(Interface); - apecss_odesolver_setdefaultoptions(NumericsODE); - - /* Read the options file for the fluid properties and solver parameters */ - apecss_gas_readoptions(Gas, OptionsDir); - apecss_liquid_readoptions(Liquid, OptionsDir); - apecss_interface_readoptions(Interface, OptionsDir); - apecss_odesolver_readoptions(NumericsODE, OptionsDir); - - /* Associate the bubble with the relevant fluid properties and solver parameters */ - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->Gas = Gas; - Bubbles[i]->Liquid = Liquid; - Bubbles[i]->Interface = Interface; - Bubbles[i]->NumericsODE = NumericsODE; - } - - /* Allocate and set the excitation parameters */ - struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); - Excitation->type = APECSS_EXCITATION_SIN; - Excitation->f = (APECSS_FLOAT) fa; - Excitation->dp = (APECSS_FLOAT) pa; - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Excitation = Excitation; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Create individual folders for the results of each bubble - for (register int i = 0; i < nBubbles; i++) - { - if (Bubbles[i]->Results != NULL) - { - sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", i); - struct stat st = {0}; - if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); - } - } - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - /* Process all options */ - apecss_gas_processoptions(Gas); - apecss_liquid_processoptions(Liquid); - apecss_interface_processoptions(Interface); - apecss_odesolver_processoptions(NumericsODE); - for (register int i = 0; i < nBubbles; i++) apecss_bubble_processoptions(Bubbles[i]); - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Use the revised pressure at infinity, including neighbor contributions - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressure_infinity = interaction_bubble_pressure_infinity; - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressurederivative_infinity = interaction_bubble_pressurederivative_infinity; - - // Initialize interaction structure - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); - - // Update interaction structure - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->Interaction->nBubbles = nBubbles; - Bubbles[i]->Interaction->dp_neighbor = 0.0; - Bubbles[i]->Interaction->last_t_1 = 0.0; - Bubbles[i]->Interaction->last_t_2 = 0.0; - Bubbles[i]->Interaction->last_p_1 = 0.0; - Bubbles[i]->Interaction->last_p_2 = 0.0; - } - - // Define the size of each bubble - if (cluster_distrib == 0) - { - // Monodispersed cluster - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->R0 = 10.0e-6; - // Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; - } - } - else - { - // Polydispersed cluster (radii distribution is following a log normal law) - double mu = 0.0; - double sigma = 0.7; - APECSS_FLOAT radius_ref = 10.0e-6; - for (register int i = 0; i < nBubbles; i++) - { - APECSS_FLOAT radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); - while ((radius > 20 * radius_ref) || (radius < 0.5 * radius_ref)) - { - // Small step to ensure no too big nor too small bubbles are generated (the distribution is conserved still) - radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); - } - Bubbles[i]->R0 = radius; - // Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; - } - } - - // Define center location for each bubble - for (register int i = 0; i < nBubbles; i++) - { - if (i == 0) - { - Bubbles[i]->Interaction->location[0] = 0.0; - Bubbles[i]->Interaction->location[1] = 0.0; - Bubbles[i]->Interaction->location[2] = 0.0; - } - else - { - APECSS_FLOAT x = rand_range((double) -cluster_radius, (double) cluster_radius); - APECSS_FLOAT y = rand_range((double) -cluster_radius, (double) cluster_radius); - APECSS_FLOAT z = rand_range((double) -cluster_radius, (double) cluster_radius); - - APECSS_FLOAT radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); - - while (radius > cluster_radius) - { - x = rand_range((double) -cluster_radius, (double) cluster_radius); - y = rand_range((double) -cluster_radius, (double) cluster_radius); - z = rand_range((double) -cluster_radius, (double) cluster_radius); - - radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); - } - - Bubbles[i]->Interaction->location[0] = x; - Bubbles[i]->Interaction->location[1] = y; - Bubbles[i]->Interaction->location[2] = z; - - for (register int k = 0; k < i; k++) - { - APECSS_FLOAT bubbledist = APECSS_SQRT(APECSS_POW2(Bubbles[i]->Interaction->location[0] - Bubbles[k]->Interaction->location[0]) + - APECSS_POW2(Bubbles[i]->Interaction->location[1] - Bubbles[k]->Interaction->location[1]) + - APECSS_POW2(Bubbles[i]->Interaction->location[2] - Bubbles[k]->Interaction->location[2])); - if (bubbledist < bubble_bubble_dist) - { - i--; - break; - } - } - } - } - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - clock_t starttimebubble = clock(); - APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system - - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->tStart = tSim; - Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; - Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step - } - - /* Initialize the bubble based on the selected options */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_initialize(Bubbles[i]); - - /* Initialize */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_initialize(Bubbles[i]); - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Files to retrieve all valuable information for cavitation onset test case - FILE *file_loc; - file_loc = fopen("bubble_loc.txt", "w"); - fprintf(file_loc, "#number x(m) y(m) z(m)\n"); - for (register int i = 0; i < nBubbles; i++) - { - fprintf(file_loc, "%d %e %e %e\n", i, Bubbles[i]->Interaction->location[0], Bubbles[i]->Interaction->location[1], Bubbles[i]->Interaction->location[2]); - } - fclose(file_loc); - - FILE *file_onset; - file_onset = fopen("onset_results.txt", "w"); - fprintf(file_onset, "%d Bubbles p0(pa) %e png(Pa) %e cl_distrib %d\n", nBubbles, Liquid->pref, pa, cluster_distrib); - fprintf(file_onset, "Initial_radii(m)"); - for (register int i = 0; i < nBubbles; i++) fprintf(file_onset, " %e", Bubbles[i]->R0); - fprintf(file_onset, "\n"); - fprintf(file_onset, "#Time(s) R(m) Pt(Pa)\n"); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - /* Solve the bubble dynamics */ - while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered - { - APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); - tSim += dtSim; - - for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); - - // for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Update the contribution of the neighbor bubble - apecss_interactions_instantaneous(Bubbles); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - // printf("%e %e %e %e %e\n", tSim, Bubbles[0]->Liquid->get_pressurederivative_bubblewall_expl(Bubbles[0]->ODEsSol, Bubbles[0]->t, Bubbles[0]), - // Bubbles[0]->get_pressurederivative_infinity(Bubbles[0]->t, Bubbles[0]), Bubbles[0]->Interaction->dp_neighbor, - // Bubbles[0]->Interaction->last_p_1 - Bubbles[0]->Interaction->last_p_2); - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Retrieve data - fprintf(file_onset, "%e", tSim); - for (register int i = 0; i < nBubbles; i++) - { - fprintf(file_onset, " %e", Bubbles[i]->R); - } - for (register int i = 0; i < nBubbles; i++) - { - fprintf(file_onset, " %e", Bubbles[i]->get_pressure_infinity(Bubbles[i]->t, Bubbles[i])); - } - fprintf(file_onset, "\n"); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - // for (register int i = 0; i < nBubbles; i++) - // { - // Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; - // Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; - - // Bubbles[i]->Interaction->last_t_1 = tSim; - // Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; - // } - } - - fclose(file_onset); - - /* Finalize the simulation*/ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_finalize(Bubbles[i]); - - char str[APECSS_STRINGLENGTH_SPRINTF]; - for (register int i = 0; i < nBubbles; i++) - { - sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", i, Bubbles[i]->dtNumber, Bubbles[i]->nSubIter, - (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); - apecss_writeonscreen(str); - } - - for (register int i = 0; i < nBubbles; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); - for (register int i = 0; i < nBubbles; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); - - /* Make sure all allocated memory is freed */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_freestruct(Bubbles[i]); - - for (register int i = 0; i < nBubbles; i++) free(Bubbles[i]); - free(Gas); - free(Liquid); - free(Interface); - free(NumericsODE); - free(Excitation); - - return (0); -} - -APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - APECSS_FLOAT T = 10.0e-06; - if (t < T) - { - return (Bubble->p0 + Bubble->Interaction->dp_neighbor); - } - else if (t > 2 * T) - { - return (Bubble->Excitation->dp + Bubble->Interaction->dp_neighbor); - } - else - { - APECSS_FLOAT W = 0.5 * (1 - APECSS_COS((t + T) * APECSS_PI / T)); - return (Bubble->p0 + W * (Bubble->Excitation->dp - Bubble->p0) + Bubble->Interaction->dp_neighbor); - } -} - -APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - // Approximate numerical computation of p_infinity derivative - APECSS_FLOAT T = 10.0e-06; - if (t < T) - { - return (0.0); - } - else - { - APECSS_FLOAT derivative = 0.0; - if (t < 2 * T) - { - APECSS_FLOAT inv_T = 1 / T; - derivative = 0.5 * APECSS_PI * inv_T * APECSS_SIN(APECSS_PI * (t + T) * inv_T) * (Bubble->Excitation->dp - Bubble->p0); - } - return (derivative); - // APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; - // if ((delta_t > Bubble->dt) && (t > time_treshold)) - // { - // APECSS_FLOAT inv_delta_t = 1 / delta_t; - // return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) * inv_delta_t)); - // } - // else - // { - // return (derivative); - // } - } -} \ No newline at end of file diff --git a/examples/sphericalclustertensionwave/plot_results.py b/examples/sphericalclustertensionwave/plot_results.py new file mode 100644 index 0000000..21753be --- /dev/null +++ b/examples/sphericalclustertensionwave/plot_results.py @@ -0,0 +1,527 @@ +import os +import numpy as np +import matplotlib.pyplot as plt +from math import sqrt + +fontsize = 15 + +plt.rcParams['font.family']='serif' +plt.rcParams['font.serif']=['Times New Roman'] + plt.rcParams['font.serif'] +plt.rcParams['mathtext.fontset']='stix' +plt.rcParams['font.size']=fontsize + +cm = 1/2.54 + +# File designed to plot the results for the cavitation onset test case with a spherical cluster + +######### Step 1 : Retrieving data ################################################################################################################## +interaction_types = ["NI", "IC", "QA"] +cluster_types = ["mono", "poly"] + +dic_bubbles = {} +dic_bubbles_loc = {} + +for inttype in interaction_types : + if inttype not in list(dic_bubbles.keys()) : + dic_bubbles[inttype] = {} + for cltype in cluster_types : + if cltype not in list(dic_bubbles[inttype].keys()) : + dic_bubbles[inttype][cltype] = {} + if cltype not in list(dic_bubbles_loc.keys()) : + dic_bubbles_loc[cltype] = {} + +working_path = os.getcwd() +for inttype in interaction_types : + interaction_path = os.path.join(working_path, inttype) + interaction_path = os.path.join(interaction_path, "results") + for file in os.listdir(interaction_path) : + if "_loc.txt" in file : + file_name = file.split("_loc.txt")[0] + + file_loc_path = os.path.join(interaction_path, file) + file_loc = open(file_loc_path, "r") + lines_loc = file_loc.readlines() + file_loc.close() + + file_path = os.path.join(interaction_path, file_name + ".txt") + file_res = open(file_path, "r") + lines_res = file_res.readlines() + file_res.close() + + firstline = lines_res[0].split(" ") + count = int(firstline[0]) + p1 = float(firstline[5]) + + if "mono" in file_name : + dic_res = dic_bubbles[inttype]["mono"] + dic_loc = dic_bubbles_loc["mono"] + else : + dic_res = dic_bubbles[inttype]["poly"] + dic_loc = dic_bubbles_loc["poly"] + + if count not in list(dic_res.keys()) : + dic_res[count] = {} + if count not in list(dic_loc.keys()) : + dic_loc[count] = {} + + if p1 not in list(dic_res[count].keys()) : + dic_res[count][p1] = [] + if p1 not in list(dic_loc[count].keys()) : + dic_loc[count][p1] = [] + + dic_res[count][p1].append([]) + for i in range(count) : + init_radius = float(lines_res[1].split(" ")[1 + i]) + x = float(lines_loc[1 + i].split(" ")[1]) + y = float(lines_loc[1 + i].split(" ")[2]) + z = float(lines_loc[1 + i].split(" ")[3]) + + dic_loc[count][p1].append([x, y, z]) + dic_res[count][p1].append([init_radius, [], []]) + + for line in lines_res[3:] : + data = line.split(" ") + t = float(data[0]) + dic_res[count][p1][0].append(t) + + for i in range(count) : + r = float(data[1 + i]) + p = float(data[1 + count + i]) + dic_res[count][p1][i+1][1].append(r) + dic_res[count][p1][i+1][2].append(p) + +######### Step 2 : Define bubble distributions ###################################################################################################### + +# For monodispersed cluster, results are plotted based on bubbles locations +cluster_radius = 232.0e-6 +interval_size = cluster_radius / 10 + +dic_loc_distrib_global = {} +dic_loc_distrib = {0.0 : [], 0.5 : [], 1.0 : []} + +for count in list(dic_bubbles_loc["mono"].keys()) : + if count not in list(dic_loc_distrib_global.keys()) : + dic_loc_distrib_global[count] = {} + + for p1 in list(dic_bubbles_loc["mono"][count].keys()) : + if p1 not in list(dic_loc_distrib_global[count].keys()) : + dic_loc_distrib_global[count][p1] = dic_loc_distrib + + for i in range(count) : + radius_to_center = sqrt(dic_bubbles_loc["mono"][count][p1][i][0]**2 + dic_bubbles_loc["mono"][count][p1][i][1]**2 + dic_bubbles_loc["mono"][count][p1][i][2]**2) + if radius_to_center < 0.0 * cluster_radius + interval_size : + dic_loc_distrib_global[count][p1][0.0].append(i) + elif 0.5 * (cluster_radius - interval_size) < radius_to_center < 0.5 * (cluster_radius + interval_size) : + dic_loc_distrib_global[count][p1][0.5].append(i) + elif 1.0 * cluster_radius - interval_size < radius_to_center : + dic_loc_distrib_global[count][p1][1.0].append(i) + +dic_loc_label = {1.0 : "{:.1f}".format(1.0 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f}".format(1.0), + 0.5 : "{:.1f}".format(0.5 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f}".format(0.5 + interval_size/cluster_radius), + 0.0 : "{:.1f}".format(0.0) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f}".format(interval_size/cluster_radius)} + +# For polydispersed cluster, results are plotted based on bubbles initial radii +n_quantiles = 5 +quantile_name_dic = {4 : "quartile", 5 : "quintile"} +quantile_name = quantile_name_dic[n_quantiles] +quantiles_list = [] +for i in range(1, n_quantiles + 1) : + quantiles_list.append(i / n_quantiles) +quantiles_list = np.array(quantiles_list) + +dic_polydisperse = {} + +for inttype in interaction_types : + dic_polydisperse[inttype] = {} + for count in list(dic_bubbles[inttype]["poly"].keys()) : + if count not in list(dic_polydisperse[inttype].keys()) : + dic_polydisperse[inttype][count] = {} + for p1 in list(dic_bubbles[inttype]["poly"][count].keys()) : + if p1 not in list(dic_polydisperse[inttype][count].keys()) : + dic_polydisperse[inttype][count][p1] = {"quantiles" : []} + for q in quantiles_list : + dic_polydisperse[inttype][count][p1][q] = [] + + initial_radius_list = [] + for i in range(count) : + initial_radius_list.append(dic_bubbles[inttype]["poly"][count][p1][i][0]) + + quantiles = np.quantile(np.array(initial_radius_list), quantiles_list) + for q in quantiles : dic_polydisperse[inttype][count][p1]["quantiles"].append(q) + + for i in range(count) : + initial_radius = dic_bubbles[inttype]["poly"][count][p1][i][0] + + index = 0 + while initial_radius > dic_polydisperse[inttype][count][p1]["quantiles"][index] : + index += 1 + dic_polydisperse[inttype][count][p1][quantiles_list[index]].append(i) + +######### Step 3 : Plot results ##################################################################################################################### + +#### General parameters ##### +rho_l = 1000.0 +r_ref = 2.0e-6 +p0 = 1.0e5 +mu = 0.0 +sigma = 0.7 + +######### Radius and minimum distance between bubbles in both configurations ###################### +p1 = -3.0e4 + +for cluster in cluster_types : + dic_loc = dic_bubbles_loc[cluster] + + for count in list(dic_loc.keys()) : + min_dist = cluster_radius + loc_list = dic_loc[count][p1] + for i in range(count) : + x_i = loc_list[i][0] + y_i = loc_list[i][1] + z_i = loc_list[i][2] + min_dist_bubble = cluster_radius + + for j in range(count) : + if (i != j) : + x_j = loc_list[j][0] + y_j = loc_list[j][1] + z_j = loc_list[j][2] + dist = sqrt((x_i - x_j)**2 + (y_i - y_j)**2 + (z_i - z_j)**2) + if dist < min_dist_bubble : + min_dist_bubble = dist + + if min_dist_bubble < min_dist : + min_dist = min_dist_bubble + + print("{} cluster with N={} bubbles, minimum distance between bubbles equal {:.2f} microns".format(cluster, count, min_dist*1.0e6)) + +fig, ax = plt.subplots(1, 1, figsize=(17.5*cm, 12.5*cm)) +ax.set_xlabel(r"$ / R_{0,ref}$ (-)", fontsize=15) +ax.grid() + +for count in list(dic_bubbles["NI"]["poly"].keys()) : + init_r_list = [] + for i in range(count) : + init_r_list.append(dic_bubbles["NI"]["poly"][count][p1][i][0] / r_ref) + count, bins, ignored = ax.hist(init_r_list, 100, density=True, align='mid', label="{} bubbles".format(count)) + +x = np.linspace(min(bins), max(bins), 10000) +pdf = (np.exp(-(np.log(x) - mu)**2 / (2 * sigma**2)) / (x * sigma * np.sqrt(2 * np.pi))) +ax.plot(x, pdf, color="red", linewidth=1.5, linestyle="solid") + +ax.legend(loc="upper right") +fig.savefig("sphericalclustertensionwave_poly_radiidistribution.pdf", bbox_inches='tight',pad_inches=0.35) + +######### Averaged radius versus time evolution for monodispersed cluster ######################### +count = 250 +p1 = -3.0e4 +t_i = r_ref * sqrt(rho_l / (p0 - p1)) + +nrow = 1 +ncol = 3 +fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) +for i in range(ncol) : + axs[i].set_xlabel(r"$ t / t_{i}$ (-)", fontsize=15) + axs[i].set_ylabel(r"$ / R_{0}$ (-)", fontsize=15) + # axs[i].set_xlim(xmin=10.0, xmax=60.0) + axs[i].grid() + +axs[0].set_title(r"No interaction" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[2].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) + +dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} +dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} + +for k in dic_loc_distrib_global[count][p1].keys() : + index_list = dic_loc_distrib_global[count][p1][k] + + # No interaction + t_list = (1/t_i) * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) + + r_list_0 = np.array(dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["NI"]["mono"][count][p1][index + 1][1]) + init_r = dic_bubbles["NI"]["mono"][count][p1][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[0].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) + + # Incompressible interactions + t_list = (1/t_i) * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) + + r_list_0 = np.array(dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["IC"]["mono"][count][p1][index + 1][1]) + init_r = dic_bubbles["IC"]["mono"][count][p1][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[1].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) + + # # Quasi acoustic interactions + # t_list = (1/t_i) * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) + + # r_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][1]) + # init_r_0 = dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][0] + # avg_radius = r_list_0 / init_r_0 + + # for i in range(1, len(index_list)) : + # index = index_list[i] + + # r_list = np.array(dic_bubbles["QA"]["mono"][count][p1][index + 1][1]) + # init_r = dic_bubbles["QA"]["mono"][count][p1][index + 1][0] + # avg_radius = avg_radius + np.array(r_list) / init_r + + # avg_radius = (1 / len(index_list)) * avg_radius + + # axs[2].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) + + +axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=3, frameon=False) +fig.savefig("sphericalclustertensionwave_mono_radiusevolution.pdf", bbox_inches='tight',pad_inches=0.35) + +######### Averaged radius versus time evolution for polydispersed cluster ######################### + +count = 250 +p1 = -3.0e4 +t_i = r_ref * sqrt(rho_l / (p0 - p1)) + +nrow = 1 +ncol = 3 +fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) +for i in range(ncol) : + axs[i].set_xlabel(r"$ t / t_{i}$ (-)", fontsize=15) + axs[i].set_ylabel(r"$$ (-)", fontsize=15) + # axs[i].set_xlim(xmin=10.0, xmax=60.0) + axs[i].grid() + +axs[0].set_title(r"No interaction" + "\n" +r"($N = 250$, $R_{0, ref}=10.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0, ref}=10.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[2].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=10.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) + +color_list = ["black", "magenta", "blue", "green", "red"] +dic_color_q = {} +dic_label_q = {} +for i in range(n_quantiles) : + quantile = quantiles_list[i] + dic_color_q[quantile] = color_list[i] + + dic_label_q[quantile] = "{}th-{}".format(i+1, quantile_name) + if i == 0 : + dic_label_q[quantile] = "1st-{}".format(quantile_name) + elif i == 1 : + dic_label_q[quantile] = "2nd-{}".format(quantile_name) + elif i == 2 : + dic_label_q[quantile] = "3rd-{}".format(quantile_name) + +# No interaction +for q in list(dic_polydisperse["NI"][count][p1].keys())[1:] : + index_list = dic_polydisperse["NI"][count][p1][q] + + t_list = (1/t_i) * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) + + r_list_0 = np.array(dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["NI"]["poly"][count][p1][index + 1][1]) + init_r = dic_bubbles["NI"]["poly"][count][p1][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[0].plot(t_list, avg_radius, linewidth=1.5, linestyle="solid", color=dic_color_q[q]) + +# Incompressible interactions +for q in list(dic_polydisperse["IC"][count][p1].keys())[1:] : + index_list = dic_polydisperse["IC"][count][p1][q] + + t_list = (1/t_i) * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) + + r_list_0 = np.array(dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["IC"]["poly"][count][p1][index + 1][1]) + init_r = dic_bubbles["IC"]["poly"][count][p1][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[1].plot(t_list, avg_radius, linewidth=1.5, linestyle="solid", color=dic_color_q[q], label=dic_label_q[q]) + +axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=n_quantiles, frameon=False) +fig.savefig("sphericalclustertensionwave_poly_radiusevolution.pdf", bbox_inches='tight',pad_inches=0.35) + +######### Averaged pressure infinity versus time evolution for monodispersed clusters ############# + +count = 250 +p1 = -3.0e4 +p0 = 1.0e5 +t_i = r_ref * sqrt(rho_l / (p0 - p1)) + +nrow = 1 +ncol = 3 +fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) +for i in range(ncol) : + axs[i].set_xlabel(r"$ t / t_{i}$ (-)", fontsize=15) + axs[i].set_ylabel(r"$ / p_{0}$ (-)", fontsize=15) + # axs[i].set_xlim(xmin=10.0, xmax=60.0) + axs[i].grid() + +axs[0].set_title(r"No interaction" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[2].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) + +dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} +dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} + +for k in dic_loc_distrib_global[count][p1].keys() : + index_list = dic_loc_distrib_global[count][p1][k] + + # No interaction + t_list = (1/t_i) * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) + + p_list_0 = np.array(dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][2]) + avg_pressure = p_list_0 / p0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + p_list = np.array(dic_bubbles["NI"]["mono"][count][p1][index + 1][2]) + avg_pressure = avg_pressure + np.array(p_list) / p0 + + avg_pressure = (1 / len(index_list)) * avg_pressure + + axs[0].plot(t_list, avg_pressure, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) + + # Incompressible interactions + t_list = (1/t_i) * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) + + p_list_0 = np.array(dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][2]) + avg_pressure = p_list_0 / p0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + p_list = np.array(dic_bubbles["IC"]["mono"][count][p1][index + 1][2]) + avg_pressure = avg_pressure + np.array(p_list) / p0 + + avg_pressure = (1 / len(index_list)) * avg_pressure + + axs[1].plot(t_list, avg_pressure, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) + + # # Quasi acoustic interactions + # t_list = (1/t_i) * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) + + # p_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][2]) + # avg_pressure = p_list_0 / p0 + + # for i in range(1, len(index_list)) : + # index = index_list[i] + + # p_list = np.array(dic_bubbles["QA"]["mono"][count][p1][index + 1][2]) + # avg_pressure = avg_pressure + np.array(p_list) / p0 + + # avg_pressure = (1 / len(index_list)) * avg_pressure + + # axs[2].plot(t_list, avg_pressure, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) + +axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=3, frameon=False) +fig.savefig("sphericalclustertensionwave_mono_pressureevolution.pdf", bbox_inches='tight',pad_inches=0.35) + +######### Averaged pressure infinity versus time evolution for monodispersed clusters ############# + +count = 250 +p1 = -3.0e4 +p0 = 1.0e5 +t_i = r_ref * sqrt(rho_l / (p0 - p1)) + +nrow = 1 +ncol = 3 +fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) +for i in range(ncol) : + axs[i].set_xlabel(r"$ t / t_{i}$ (-)", fontsize=15) + axs[i].set_ylabel(r"$/p_{0}$ (-)", fontsize=15) + # axs[i].set_xlim(xmin=10.0, xmax=60.0) + axs[i].grid() + +axs[0].set_title(r"No interaction" + "\n" +r"($N = 250$, $R_{0, ref}=10.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0, ref}=10.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[2].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=10.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) + +color_list = ["black", "magenta", "blue", "green", "red"] +dic_color_q = {} +dic_label_q = {} +for i in range(n_quantiles) : + quantile = quantiles_list[i] + dic_color_q[quantile] = color_list[i] + + dic_label_q[quantile] = "{}th-{}".format(i+1, quantile_name) + if i == 0 : + dic_label_q[quantile] = "1st-{}".format(quantile_name) + elif i == 1 : + dic_label_q[quantile] = "2nd-{}".format(quantile_name) + elif i == 2 : + dic_label_q[quantile] = "3rd-{}".format(quantile_name) + +# No interaction +for q in list(dic_polydisperse["NI"][count][p1].keys())[1:] : + index_list = dic_polydisperse["NI"][count][p1][q] + + t_list = (1/t_i) * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) + + p_list_0 = np.array(dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][2]) + avg_pressure = p_list_0 / p0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + p_list = np.array(dic_bubbles["NI"]["poly"][count][p1][index + 1][2]) + avg_pressure = avg_pressure + np.array(p_list) / p0 + + avg_pressure = (1 / len(index_list)) * avg_pressure + + axs[0].plot(t_list, avg_pressure, linewidth=1.5, linestyle="solid", color=dic_color_q[q]) + +# Incompressible interactions +for q in list(dic_polydisperse["IC"][count][p1].keys())[1:] : + index_list = dic_polydisperse["IC"][count][p1][q] + + t_list = (1/t_i) * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) + + p_list_0 = np.array(dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][2]) + avg_pressure = p_list_0 / p0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + p_list = np.array(dic_bubbles["IC"]["poly"][count][p1][index + 1][2]) + avg_pressure = avg_pressure + np.array(p_list) / p0 + + avg_pressure = (1 / len(index_list)) * avg_pressure + + axs[1].plot(t_list, avg_pressure, linewidth=1.5, linestyle="solid", color=dic_color_q[q], label=dic_label_q[q]) + +axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=n_quantiles, frameon=False) +fig.savefig("sphericalclustertensionwave_poly_pressureevolution.pdf", bbox_inches='tight',pad_inches=0.35) \ No newline at end of file diff --git a/examples/sphericalclustertensionwave/run_sphericalclustertensionwave.sh b/examples/sphericalclustertensionwave/run_sphericalclustertensionwave.sh new file mode 100755 index 0000000..b8bc6de --- /dev/null +++ b/examples/sphericalclustertensionwave/run_sphericalclustertensionwave.sh @@ -0,0 +1,84 @@ +######### Parameters ################################################################################################################################ + +ncores=10 +nbubbles=250 + +######### No interaction computations ############################################################################################################### + +cd NI/build +./compile.sh +cd .. + +######### Monodispersed system #################################################################### +./build/sphericalclustertensionwave_apecss -options run.apecss -amp -3.0e4 -tend 15.0e-6 -cldistrib 0 +python3 gather_results.py + +# ######### Polydispersed system #################################################################### +./build/sphericalclustertensionwave_apecss -options run.apecss -amp -3.0e4 -tend 50.0e-6 -cldistrib 1 +python3 gather_results.py + +cd .. + +echo "" +echo "No interaction test cases passed" +echo "" + +######### Incompressible computations ############################################################################################################### + +cd IC/build +./compile.sh +cd .. + +######### Monodispersed system #################################################################### +./build/sphericalclustertensionwave_apecss -options run.apecss -amp -3.0e4 -tend 15.0e-6 -cldistrib 0 +python3 gather_results.py + +######### Polydispersed system #################################################################### +./build/sphericalclustertensionwave_apecss -options run.apecss -amp -3.0e4 -tend 60.0e-6 -cldistrib 1 +python3 gather_results.py + +cd .. + +echo "" +echo "Incompressible test cases passed" +echo "" + +######### Quasi acoustic computations ############################################################################################################### + +######### Plot results ############################################################################################################################## + +python3 plot_results.py + +######### Cleaning ################################################################################################################################## + +cd NI +rm -rf "tension_results.txt" "bubble_loc.txt" +for ((c=0; c<$nbubbles; c++)) +do + rm -rf Bubble_$c +done +cd .. + +cd IC +rm -rf "tension_results.txt" "bubble_loc.txt" +for ((c=0; c<$nbubbles; c++)) +do + rm -rf Bubble_$c +done +cd .. + +# # # cd QA +# # # rm -rf "bubble_loc.txt" +# # # for ((c=0; c<$ncores; c++)) +# # # do +# # # rm -rf tension_results_$c.txt +# # # done +# # # for ((c=0; c<$nbubbles; c++)) +# # # do +# # # rm -rf Bubble_$c +# # # done +# # # cd .. + +echo "" +echo "Cleaning completed" +echo "" \ No newline at end of file From 9cc8860e7902d34f3142abc8454e90c1471b3287 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 30 Jul 2024 08:55:26 -0400 Subject: [PATCH 061/138] Spherical cluster tension wave ; adding preliminary QA framework --- .../QA/build/CMakeLists.txt | 41 ++ .../QA/build/compile.sh | 5 + .../sphericalclustertensionwave/QA/execmpi.sh | 18 + .../QA/gather_results.py | 85 +++ .../sphericalclustertensionwave/QA/run.apecss | 32 + .../src/sphericalclustertensionwave_apecss.c | 655 ++++++++++++++++++ 6 files changed, 836 insertions(+) create mode 100644 examples/sphericalclustertensionwave/QA/build/CMakeLists.txt create mode 100755 examples/sphericalclustertensionwave/QA/build/compile.sh create mode 100755 examples/sphericalclustertensionwave/QA/execmpi.sh create mode 100644 examples/sphericalclustertensionwave/QA/gather_results.py create mode 100644 examples/sphericalclustertensionwave/QA/run.apecss create mode 100644 examples/sphericalclustertensionwave/QA/src/sphericalclustertensionwave_apecss.c diff --git a/examples/sphericalclustertensionwave/QA/build/CMakeLists.txt b/examples/sphericalclustertensionwave/QA/build/CMakeLists.txt new file mode 100644 index 0000000..6fece97 --- /dev/null +++ b/examples/sphericalclustertensionwave/QA/build/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.12) + +project (sphericalclustercavitationonset_apecss) +set(CMAKE_C_COMPILER mpicc) + +include_directories($ENV{APECSS_DIR}/include) +FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) + +set (mylibs m apecss) +link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) + +foreach(arg ${myincludes}) + IF (arg MATCHES "-I") + STRING(REGEX REPLACE "-I" "" myinc ${arg}) + message("Additional include: ${myinc}") + include_directories(${myinc}) + ENDIF(arg MATCHES "-I") +endforeach(arg ${myincludes}) + +foreach(arg ${mylibs}) + STRING(REGEX REPLACE "lib" "" myl1 ${arg}) + STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) + set(mylibs ${myl2} ${mylibs} ${myl2}) +endforeach(arg ${mylibs}) + +if(NOT CMAKE_BUILD_TYPE) + message(STATUS "Optimization: No optimization specified.") + set(CMAKE_BUILD_TYPE Release) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + message(STATUS "Optimization: Debug") + set(CMAKE_C_FLAGS_DEBUG "-Wall -g") +elseif(CMAKE_BUILD_TYPE STREQUAL "Release") + message(STATUS "Optimization: Release") + add_definitions(-DNDEBUG) + set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") +endif() + +add_executable(sphericalclustercavitationonset_apecss ${myfiles}) +target_link_libraries(sphericalclustercavitationonset_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/sphericalclustertensionwave/QA/build/compile.sh b/examples/sphericalclustertensionwave/QA/build/compile.sh new file mode 100755 index 0000000..33147c8 --- /dev/null +++ b/examples/sphericalclustertensionwave/QA/build/compile.sh @@ -0,0 +1,5 @@ +#!/bin/bash +rm sphericalclustercavitationonset_apecss +cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release +make +rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/sphericalclustertensionwave/QA/execmpi.sh b/examples/sphericalclustertensionwave/QA/execmpi.sh new file mode 100755 index 0000000..09cb14d --- /dev/null +++ b/examples/sphericalclustertensionwave/QA/execmpi.sh @@ -0,0 +1,18 @@ +nbubbles=2500 +ncores=20 + +cd build +./compile.sh +cd .. +mpiexec -n $ncores ./build/sphericalclustercavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-06 -cldistrib 1 +python3 gather_results.py + +# rm -rf bubble_loc.txt +# for ((c=0; c<$ncores; c++)) +# do +# rm -rf onset_results_$c.txt +# done +# for ((c=0; c<$nbubbles; c++)) +# do +# rm -rf Bubble_$c +# done \ No newline at end of file diff --git a/examples/sphericalclustertensionwave/QA/gather_results.py b/examples/sphericalclustertensionwave/QA/gather_results.py new file mode 100644 index 0000000..b23c0c3 --- /dev/null +++ b/examples/sphericalclustertensionwave/QA/gather_results.py @@ -0,0 +1,85 @@ +import os + +# File designed to recover data for plotting results in cavitation onset case + +count_core = 0 +for file in os.listdir() : + if "onset_results_" in file : + count_core += 1 + +lines_onset = [] +for i in range(count_core) : + file_onset = open("onset_results_{}.txt".format(i), "r") + lines = file_onset.readlines() + file_onset.close() + lines_onset.append(lines) + +firstline = lines_onset[0][0].split(" ") +count = int(firstline[0]) +png = float(firstline[5]) +cl_distrib = int(firstline[7]) + +if cl_distrib == 0 : + # monodispersed spherical cluster + file_name = "mono_{}_{:.4E}.txt".format(count, png) + +else : + # polydispersed spherical cluster + file_name = "poly_{}_{:.4E}.txt".format(count, png) + +working_path = os.getcwd() +results_path = os.path.join(working_path, "results") +file_results = open(os.path.join(results_path, file_name), "w") + +results_onset = open(os.path.join(results_path, file_name), "w") +# Header +for line in lines_onset[0][:3] : + results_onset.write(line) + +# Combining with the good format the values located in the files associated with the cores used for computation +for t in range(3, len(lines_onset[0])) : + time = lines_onset[0][t].split(" ")[0] + r_list = [] + p_list = [] + + for i in range(len(lines_onset)) : + data = lines_onset[i][t].split(" ") + nbubble_core = int((len(data) - 1) / 2) + r_list_file = data[1:nbubble_core+1] + p_list_file = data[nbubble_core+1:2*nbubble_core+1] + + for r in r_list_file : + r_list.append(r) + + for p in p_list_file : + if "\n" in p : + p = p.split("\n")[0] + p_list.append(p) + + results_onset.write(time) + for rad in r_list : + results_onset.write(" {}".format(rad)) + for pres in p_list : + results_onset.write(" {}".format(pres)) + results_onset.write("\n") + +results_onset.close() + +file_loc = open("bubble_loc.txt", "r") +lines_loc = file_loc.readlines() +file_loc.close() + +if cl_distrib == 0 : + # monodispersed spherical cluster + file_name_loc = "mono_{}_{:.4E}_loc.txt".format(count, png) + +else : + # polydispersed spherical cluster + file_name_loc = "poly_{}_{:.4E}_loc.txt".format(count, png) + +file_loc_results = open(os.path.join(results_path, file_name_loc), "w") + +for line in lines_loc : + file_loc_results.write(line) + +file_loc_results.close() \ No newline at end of file diff --git a/examples/sphericalclustertensionwave/QA/run.apecss b/examples/sphericalclustertensionwave/QA/run.apecss new file mode 100644 index 0000000..44da63b --- /dev/null +++ b/examples/sphericalclustertensionwave/QA/run.apecss @@ -0,0 +1,32 @@ +######################################################### +# # +# APECSS Options File # +# # +######################################################### + +BUBBLE +RPModel KM +Emissions QA 250.0e-6 +PressureAmbient 0.1013e6 +END + +GAS +EoS IG +ReferenceDensity 1.2 +PolytropicExponent 1.4 +END + +LIQUID +ReferencePressure 0.1013e6 +ReferenceDensity 1000.0 +ReferenceSoundSpeed 1500.0 +Viscosity 1.002e-3 +END + +INTERFACE +SurfaceTensionCoeff 0.0728 +END + +ODESOLVER +tolerance 1.0e-10 +END diff --git a/examples/sphericalclustertensionwave/QA/src/sphericalclustertensionwave_apecss.c b/examples/sphericalclustertensionwave/QA/src/sphericalclustertensionwave_apecss.c new file mode 100644 index 0000000..def6f99 --- /dev/null +++ b/examples/sphericalclustertensionwave/QA/src/sphericalclustertensionwave_apecss.c @@ -0,0 +1,655 @@ +// This source file is part of APECSS, an open-source software toolbox +// for the computation of pressure-driven bubble dynamics and acoustic +// emissions in spherical symmetry. +// +// Copyright (C) 2022-2024 The APECSS Developers +// +// The APECSS Developers are listed in the README.md file available in +// the GitHub repository at https://github.com/polycfd/apecss. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// ------------------------------------------------------------------- +// APECSS standalone example of acoustically-interacting microbubbles +// in a spherical cluster with the goal to study cavitation onset +// ------------------------------------------------------------------- + +#include +#include +#include "apecss.h" + +APECSS_FLOAT rand_range(double min, double max) +{ + double random = (drand48()); + double range = (max - min) * random; + double number = min + range; + + return (APECSS_FLOAT) number; +} + +APECSS_FLOAT normal_distribution(double mu, double sigma) +{ + // Generating a normal distribution using Box-Muller transform, with mu as mean and sigma**2 as variance + double u1 = (drand48()); + while (u1 == 0.0) u1 = (drand48()); + double u2 = (drand48()); + + double mag = sigma * APECSS_SQRT(-2.0 * APECSS_LOG(u1)); + double z1 = mag * APECSS_COS(2 * APECSS_PI * u2) + mu; + return (APECSS_FLOAT) z1; +} + +struct APECSS_Parallel_Cluster +{ + int rank, size; + int nBubbles_local, nBubbles_global; + + int *bubblerank; // max id of bubbles for each rank + APECSS_FLOAT *bubbleglobal_R, *bubbleglobal_x, *bubbleglobal_y, *bubbleglobal_z; // Radius and x,y,z location of all bubbles + APECSS_FLOAT *sumGU_rank; // Contributions from local bubbles to all bubbles +}; + +// Declaration of additional case-dependent functions +APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); + +int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubble[], struct APECSS_Parallel_Cluster *RankInfo); +int parallel_interactions_proper_cutoffdistance(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo); + +int main(int argc, char **args) +{ + /* Initialize MPI */ + int mpi_rank, mpi_size; + MPI_Init(&argc, &args); + MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); + MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); + + char OptionsDir[APECSS_STRINGLENGTH]; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Set the case-dependent simulation parameters + const int nBubbles = 2500; // Number of bubbles + APECSS_FLOAT bubble_bubble_dist = 100.0e-6; // Bubble-bubble minimal distance + APECSS_FLOAT cluster_radius = 2.5e-3; // Spherical cluster radius + + // Interbubble time-step, defining the frequency with which the neighbor influence is updated + APECSS_FLOAT dt_interbubble = 1.0e-8; + + // Initialize the simulation parameters given by the execution command + double tEnd = 0.0; + double fa = 0.0; + double pa = 0.0; + int cluster_distrib = 0; + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + apecss_infoscreen(); + + /* Read commandline options */ + sprintf(OptionsDir, "./run.apecss"); // This is the default + int j = 1; // First argument is the call to the executable + while (j < argc) + { + if (strcmp("-options", args[j]) == 0) + { + sprintf(OptionsDir, "%s", args[j + 1]); + j += 2; + } + else if (strcmp("-tend", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &tEnd); + j += 2; + } + else if (strcmp("-freq", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &fa); + j += 2; + } + else if (strcmp("-amp", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &pa); + j += 2; + } + else if (strcmp("-cldistrib", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &cluster_distrib); + j += 2; + } + else if (strcmp("-h", args[j]) == 0) + { + apecss_helpscreen(); + } + else + { + char str[APECSS_STRINGLENGTH_SPRINTF]; + sprintf(str, "Unknown command line options: %s", args[j]); + apecss_erroronscreen(1, str); + ++j; + } + } + + /* Allocate structure for parallel data */ + struct APECSS_Parallel_Cluster *RankInfo = (struct APECSS_Parallel_Cluster *) malloc(sizeof(struct APECSS_Parallel_Cluster)); + RankInfo->rank = mpi_rank; + RankInfo->size = mpi_size; + + /* Determine the number of bubbles per rank */ + int max_per_rank = ceil((double) nBubbles / (double) mpi_size); + RankInfo->nBubbles_local = APECSS_MAX(0, APECSS_MIN(max_per_rank, nBubbles - mpi_rank * max_per_rank)); + + /* Share the parallel distribution of bubbles with all ranks */ + RankInfo->bubblerank = malloc((RankInfo->size + 1) * sizeof(int)); + + RankInfo->nBubbles_global = 0; + RankInfo->bubblerank[0] = 0; + for (int r = 0; r < RankInfo->size; r++) + { + int temp = RankInfo->nBubbles_local; + MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); + RankInfo->bubblerank[r + 1] = RankInfo->bubblerank[r] + temp; + RankInfo->nBubbles_global += temp; + } + + /* Allocate and initialize Bubble structure */ + struct APECSS_Bubble *Bubbles[RankInfo->nBubbles_local]; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(sizeof(struct APECSS_Bubble)); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_initializestruct(Bubbles[i]); + + /* Set default options and read the options for the bubble */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); + + /* Allocate the structures for the fluid properties and ODE solver parameters */ + struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); + struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); + struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); + struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); + + /* Set the default options for the fluid properties and solver parameters */ + apecss_gas_setdefaultoptions(Gas); + apecss_liquid_setdefaultoptions(Liquid); + apecss_interface_setdefaultoptions(Interface); + apecss_odesolver_setdefaultoptions(NumericsODE); + + /* Read the options file for the fluid properties and solver parameters */ + apecss_gas_readoptions(Gas, OptionsDir); + apecss_liquid_readoptions(Liquid, OptionsDir); + apecss_interface_readoptions(Interface, OptionsDir); + apecss_odesolver_readoptions(NumericsODE, OptionsDir); + + /* Associate the bubble with the relevant fluid properties and solver parameters */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->Gas = Gas; + Bubbles[i]->Liquid = Liquid; + Bubbles[i]->Interface = Interface; + Bubbles[i]->NumericsODE = NumericsODE; + } + + /* Allocate and set the excitation parameters */ + struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); + Excitation->type = APECSS_EXCITATION_SIN; + Excitation->f = (APECSS_FLOAT) fa; + Excitation->dp = (APECSS_FLOAT) pa; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Excitation = Excitation; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Create individual folders for the results of each bubble + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + if (Bubbles[i]->Results != NULL) + { + sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", RankInfo->bubblerank[RankInfo->rank] + i); + struct stat st = {0}; + if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Process all options */ + apecss_gas_processoptions(Gas); + apecss_liquid_processoptions(Liquid); + apecss_interface_processoptions(Interface); + apecss_odesolver_processoptions(NumericsODE); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_processoptions(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Use the revised pressure at infinity, including neighbor contributions + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->get_pressure_infinity = parallel_interactions_bubble_pressure_infinity; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + Bubbles[i]->get_pressurederivative_infinity = parallel_interactions_bubble_pressurederivative_infinity; + + // Allocate interaction structure + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); + Bubbles[i]->Interaction->dp_neighbor = 0.0; + Bubbles[i]->Interaction->last_t_1 = 0.0; + Bubbles[i]->Interaction->last_t_2 = 0.0; + Bubbles[i]->Interaction->last_p_1 = 0.0; + Bubbles[i]->Interaction->last_p_2 = 0.0; + } + + // Update interaction structure + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->nBubbles = nBubbles; // Not used? + + // Define the size of each bubble + if (cluster_distrib == 0) + { + // Monodispersed cluster + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->R0 = 10.0e-6; + Bubbles[i]->R = Bubbles[i]->R0; + } + } + else + { + // Polydispersed cluster (radii distribution is following a log normal law) + double mu = 0.0; + double sigma = 0.7; + APECSS_FLOAT radius_ref = 10.0e-6; + APECSS_FLOAT Bubble_Radius[nBubbles]; + for (register int i = 0; i < nBubbles; i++) + { + APECSS_FLOAT radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); + while ((radius > 20 * radius_ref) || (radius < 0.5 * radius_ref)) + { + // Small step to ensure no too big bubbles nor too small are generated (the distribution is conserved still) + radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); + } + Bubble_Radius[i] = radius; + } + + for (register int n = 0; n < RankInfo->nBubbles_local; n++) + { + Bubbles[n]->R0 = Bubble_Radius[RankInfo->bubblerank[RankInfo->rank] + n]; + Bubbles[n]->R = Bubble_Radius[RankInfo->bubblerank[RankInfo->rank] + n]; + } + } + + // Define center location for each bubble + APECSS_FLOAT Bubble_Center[nBubbles][3]; + + for (register int i = 0; i < nBubbles; i++) + { + if (i == 0) + { + Bubble_Center[i][0] = 0.0; + Bubble_Center[i][1] = 0.0; + Bubble_Center[i][2] = 0.0; + } + else + { + APECSS_FLOAT x = rand_range((double) -cluster_radius, (double) cluster_radius); + APECSS_FLOAT y = rand_range((double) -cluster_radius, (double) cluster_radius); + APECSS_FLOAT z = rand_range((double) -cluster_radius, (double) cluster_radius); + + APECSS_FLOAT radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); + + while (radius > cluster_radius) + { + x = rand_range((double) -cluster_radius, (double) cluster_radius); + y = rand_range((double) -cluster_radius, (double) cluster_radius); + z = rand_range((double) -cluster_radius, (double) cluster_radius); + + radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); + } + + Bubble_Center[i][0] = x; + Bubble_Center[i][1] = y; + Bubble_Center[i][2] = z; + + for (register int k = 0; k < i; k++) + { + APECSS_FLOAT bubbledist = APECSS_SQRT(APECSS_POW2(Bubble_Center[i][0] - Bubble_Center[k][0]) + APECSS_POW2(Bubble_Center[i][1] - Bubble_Center[k][1]) + + APECSS_POW2(Bubble_Center[i][2] - Bubble_Center[k][2])); + if (bubbledist < bubble_bubble_dist) + { + i--; + break; + } + } + } + } + + for (register int n = 0; n < RankInfo->nBubbles_local; n++) + { + Bubbles[n]->Interaction->location[0] = Bubble_Center[RankInfo->bubblerank[RankInfo->rank] + n][0]; + Bubbles[n]->Interaction->location[1] = Bubble_Center[RankInfo->bubblerank[RankInfo->rank] + n][1]; + Bubbles[n]->Interaction->location[2] = Bubble_Center[RankInfo->bubblerank[RankInfo->rank] + n][2]; + } + + // Share the location of each bubble with all ranks + + RankInfo->bubbleglobal_R = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + RankInfo->bubbleglobal_x = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + RankInfo->bubbleglobal_y = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + RankInfo->bubbleglobal_z = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + + for (int r = 0; r < RankInfo->size; r++) + { + int temp = RankInfo->nBubbles_local; + MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); + + APECSS_FLOAT temp_array[4]; + + for (int i = 0; i < temp; i++) + { + if (r == RankInfo->rank) + { + temp_array[0] = Bubbles[i]->Interaction->location[0]; + temp_array[1] = Bubbles[i]->Interaction->location[1]; + temp_array[2] = Bubbles[i]->Interaction->location[2]; + temp_array[3] = Bubbles[i]->R; + } + + MPI_Bcast(temp_array, 4, MPI_DOUBLE, r, MPI_COMM_WORLD); + + RankInfo->bubbleglobal_x[RankInfo->bubblerank[r] + i] = temp_array[0]; + RankInfo->bubbleglobal_y[RankInfo->bubblerank[r] + i] = temp_array[1]; + RankInfo->bubbleglobal_z[RankInfo->bubblerank[r] + i] = temp_array[2]; + RankInfo->bubbleglobal_R[RankInfo->bubblerank[r] + i] = temp_array[3]; + } + } + + // Update cut off distance for each bubble + parallel_interactions_proper_cutoffdistance(Bubbles, RankInfo); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + clock_t starttimebubble = clock(); + APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->tStart = tSim; + Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; + Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step + } + + /* Initialize the bubble based on the selected options */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_initialize(Bubbles[i]); + + /* Initialize */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_initialize(Bubbles[i]); + + // Allocate the pressure contribution array + RankInfo->sumGU_rank = malloc(2 * RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Files to retrieve all valuable information for cavitation onset test case + // Bubbles locations + FILE *file_loc = fopen("bubble_loc.txt", "w"); + fprintf(file_loc, "#number x(m) y(m) z(m)\n"); + for (register int i = 0; i < RankInfo->nBubbles_global; i++) + { + fprintf(file_loc, "%d %e %e %e\n", i, RankInfo->bubbleglobal_x[i], RankInfo->bubbleglobal_y[i], RankInfo->bubbleglobal_z[i]); + } + fclose(file_loc); + + // Radius and pressure evolution for each bubble during computation + FILE *file_onset; + char file_name[APECSS_STRINGLENGTH_SPRINTF_LONG]; + sprintf(file_name, "onset_results_%d.txt", RankInfo->rank); + file_onset = fopen(file_name, "w"); + + fprintf(file_onset, "%d Bubbles p0(pa) %e png(Pa) %e cl_distrib %d\n", nBubbles, Liquid->pref, pa, cluster_distrib); + fprintf(file_onset, "Initial_radii(m)"); + for (register int i = 0; i < RankInfo->nBubbles_global; i++) + { + fprintf(file_onset, " %e", RankInfo->bubbleglobal_R[i]); + } + fprintf(file_onset, "\n"); + fprintf(file_onset, "#Time(s) R(m) Pt(Pa)\n"); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Solve the bubble dynamics */ + while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered + { + APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); + tSim += dtSim; + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); + + // for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Update the contribution of the neighbor bubble + parallel_interactions_quasi_acoustic(Bubbles, RankInfo); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Retrieve data + fprintf(file_onset, "%e", tSim); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + fprintf(file_onset, " %e", Bubbles[i]->R); + } + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + fprintf(file_onset, " %e", Bubbles[i]->get_pressure_infinity(Bubbles[i]->t, Bubbles[i])); + } + fprintf(file_onset, "\n"); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; + Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; + + Bubbles[i]->Interaction->last_t_1 = tSim; + Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; + } + } + + fclose(file_onset); + + /* Finalize the simulation*/ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_finalize(Bubbles[i]); + + char str[APECSS_STRINGLENGTH_SPRINTF]; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", RankInfo->bubblerank[RankInfo->rank] + i, Bubbles[i]->dtNumber, + Bubbles[i]->nSubIter, (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); + apecss_writeonscreen(str); + } + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); + + /* Make sure all allocated memory is freed */ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_freestruct(Bubbles[i]); + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) free(Bubbles[i]); + free(Gas); + free(Liquid); + free(Interface); + free(NumericsODE); + free(Excitation); + + free(RankInfo->bubblerank); + RankInfo->bubblerank = NULL; + free(RankInfo->bubbleglobal_R); + RankInfo->bubbleglobal_R = NULL; + free(RankInfo->bubbleglobal_x); + RankInfo->bubbleglobal_x = NULL; + free(RankInfo->bubbleglobal_y); + RankInfo->bubbleglobal_y = NULL; + free(RankInfo->bubbleglobal_z); + RankInfo->bubbleglobal_z = NULL; + free(RankInfo->sumGU_rank); + RankInfo->sumGU_rank = NULL; + free(RankInfo); + + MPI_Finalize(); + + return (0); +} + +APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + APECSS_FLOAT T = 10.0e-06; + if (t < T) + { + return (Bubble->p0 + Bubble->Interaction->dp_neighbor); + } + else if (t > 2 * T) + { + return (Bubble->Excitation->dp + Bubble->Interaction->dp_neighbor); + } + else + { + APECSS_FLOAT W = 0.5 * (1 - APECSS_COS((t + T) * APECSS_PI / T)); + return (Bubble->p0 + W * (Bubble->Excitation->dp - Bubble->p0) + Bubble->Interaction->dp_neighbor); + } +} + +APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + // Approximate numerical computation of p_infinity derivative + APECSS_FLOAT T = 10.0e-06; + if (t < T) + { + return (0.0); + } + else + { + APECSS_FLOAT derivative = 0.0; + if (t < 2 * T) + { + APECSS_FLOAT inv_T = 1 / T; + derivative = 0.5 * APECSS_PI * inv_T * APECSS_SIN(APECSS_PI * (t + T) * inv_T) * (Bubble->Excitation->dp - Bubble->p0); + } + APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; + if (delta_t > Bubble->dt) + { + APECSS_FLOAT inv_delta_t = 1 / delta_t; + return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) * inv_delta_t)); + } + else + { + return (derivative); + } + } +} + +int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo) +{ + // All bubbles are supposed to be in the same liquid + struct APECSS_Liquid *Liquid = Bubbles[0]->Liquid; + + // Update bubble radii info + APECSS_FLOAT *tempR = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + for (register int j = 0; j < RankInfo->nBubbles_global; j++) tempR[j] = 0.0; + for (register int i = 0; i < RankInfo->nBubbles_local; i++) tempR[RankInfo->bubblerank[RankInfo->rank] + i] = Bubbles[i]->R; + MPI_Allreduce(tempR, RankInfo->bubbleglobal_R, RankInfo->nBubbles_global, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + free(tempR); + + // Reset pressure contributions of the neighours + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; + + // Locally compute the contribution to each bubble + for (register int j = 0; j < RankInfo->nBubbles_global; j++) + { + APECSS_FLOAT x_j = RankInfo->bubbleglobal_x[j]; + APECSS_FLOAT y_j = RankInfo->bubbleglobal_y[j]; + APECSS_FLOAT z_j = RankInfo->bubbleglobal_z[j]; + + RankInfo->sumGU_rank[j] = 0.0; + RankInfo->sumGU_rank[j + RankInfo->nBubbles_global] = 0.0; + + double R_j = RankInfo->bubbleglobal_R[j]; + + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + if (j != RankInfo->bubblerank[RankInfo->rank] + i) + { + APECSS_FLOAT sumU_bubble = 0.0; + APECSS_FLOAT sumG_bubble = 0.0; + int nodecount_bubble = 0; + + APECSS_FLOAT x_i = Bubbles[i]->Interaction->location[0]; + APECSS_FLOAT y_i = Bubbles[i]->Interaction->location[1]; + APECSS_FLOAT z_i = Bubbles[i]->Interaction->location[2]; + + APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); + + // The loop over the emission nodes begins with the most far away from the emitting bubble + struct APECSS_EmissionNode *Current = Bubbles[i]->Emissions->LastNode; + while (Current != NULL) + { + if (Current->r < interbubble_dist - R_j) + { + // The following emission nodes have not yet reached the bubble of interest + Current = NULL; + } + else if (Current->r > interbubble_dist + R_j) + { + // The bubble of interest is still not reached + Current = Current->backward; + } + else + { + // The current emission node is located inside the bubble of interest + APECSS_FLOAT gr = Current->g / Current->r; + sumU_bubble += (Current->f / APECSS_POW2(Current->r)) + gr / Liquid->cref; + sumG_bubble += gr; + nodecount_bubble++; + Current = Current->backward; + } + } + + if (nodecount_bubble) + { + APECSS_FLOAT inv_nodecount = 1.0 / (APECSS_FLOAT) nodecount_bubble; + RankInfo->sumGU_rank[j] += sumG_bubble * inv_nodecount; + RankInfo->sumGU_rank[j + RankInfo->nBubbles_global] += sumU_bubble * inv_nodecount; + } + } + } + } + + APECSS_FLOAT *sumGU_all = malloc(2 * RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); + MPI_Allreduce(RankInfo->sumGU_rank, sumGU_all, 2 * RankInfo->nBubbles_global, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + + // Compute the total pressure contributions of the neighbours for all local bubbles + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + Bubbles[i]->Interaction->dp_neighbor = + Liquid->rhoref * (sumGU_all[RankInfo->bubblerank[RankInfo->rank] + i] - + 0.5 * APECSS_POW2(sumGU_all[RankInfo->nBubbles_global + RankInfo->bubblerank[RankInfo->rank] + i])); + } + + free(sumGU_all); + + return (0); +} + +int parallel_interactions_proper_cutoffdistance(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo) +{ + for (register int i = 0; i < RankInfo->nBubbles_local; i++) + { + APECSS_FLOAT x_i = Bubbles[i]->Interaction->location[0]; + APECSS_FLOAT y_i = Bubbles[i]->Interaction->location[1]; + APECSS_FLOAT z_i = Bubbles[i]->Interaction->location[2]; + APECSS_FLOAT dist = 0.0; + + for (register int j = 0; j < RankInfo->nBubbles_global; j++) + { + APECSS_FLOAT x_j = RankInfo->bubbleglobal_x[j]; + APECSS_FLOAT y_j = RankInfo->bubbleglobal_y[j]; + APECSS_FLOAT z_j = RankInfo->bubbleglobal_z[j]; + + APECSS_FLOAT dist_ij = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); + + if (dist_ij > dist) + { + dist = dist_ij; + } + } + if (Bubbles[i]->Emissions != NULL) Bubbles[i]->Emissions->CutOffDistance = 1.25 * dist; + } + return (0); +} \ No newline at end of file From e2accf21d3316f98caf6382602c25663f4b1b0ff Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 30 Jul 2024 09:55:31 -0400 Subject: [PATCH 062/138] Spherical cluster tension wave ; working QA framework --- .../QA/build/CMakeLists.txt | 6 +- .../QA/build/compile.sh | 2 +- .../sphericalclustertensionwave/QA/execmpi.sh | 24 +++--- .../QA/gather_results.py | 48 +++++------ .../sphericalclustertensionwave/QA/run.apecss | 9 +- .../src/sphericalclustertensionwave_apecss.c | 86 ++++++++----------- 6 files changed, 83 insertions(+), 92 deletions(-) diff --git a/examples/sphericalclustertensionwave/QA/build/CMakeLists.txt b/examples/sphericalclustertensionwave/QA/build/CMakeLists.txt index 6fece97..3c801ed 100644 --- a/examples/sphericalclustertensionwave/QA/build/CMakeLists.txt +++ b/examples/sphericalclustertensionwave/QA/build/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.12) -project (sphericalclustercavitationonset_apecss) +project (sphericalclustertensionwave_apecss) set(CMAKE_C_COMPILER mpicc) include_directories($ENV{APECSS_DIR}/include) @@ -37,5 +37,5 @@ elseif(CMAKE_BUILD_TYPE STREQUAL "Release") set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") endif() -add_executable(sphericalclustercavitationonset_apecss ${myfiles}) -target_link_libraries(sphericalclustercavitationonset_apecss ${mylibs}) \ No newline at end of file +add_executable(sphericalclustertensionwave_apecss ${myfiles}) +target_link_libraries(sphericalclustertensionwave_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/sphericalclustertensionwave/QA/build/compile.sh b/examples/sphericalclustertensionwave/QA/build/compile.sh index 33147c8..564c7a4 100755 --- a/examples/sphericalclustertensionwave/QA/build/compile.sh +++ b/examples/sphericalclustertensionwave/QA/build/compile.sh @@ -1,5 +1,5 @@ #!/bin/bash -rm sphericalclustercavitationonset_apecss +rm sphericalclustertensionwave_apecss cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release make rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/sphericalclustertensionwave/QA/execmpi.sh b/examples/sphericalclustertensionwave/QA/execmpi.sh index 09cb14d..c1bbf3c 100755 --- a/examples/sphericalclustertensionwave/QA/execmpi.sh +++ b/examples/sphericalclustertensionwave/QA/execmpi.sh @@ -1,18 +1,18 @@ -nbubbles=2500 -ncores=20 +nbubbles=250 +ncores=10 cd build ./compile.sh cd .. -mpiexec -n $ncores ./build/sphericalclustercavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-06 -cldistrib 1 +mpiexec -n $ncores ./build/sphericalclustertensionwave_apecss -options run.apecss -amp -3.0e4 -tend 25.0e-06 -cldistrib 0 python3 gather_results.py -# rm -rf bubble_loc.txt -# for ((c=0; c<$ncores; c++)) -# do -# rm -rf onset_results_$c.txt -# done -# for ((c=0; c<$nbubbles; c++)) -# do -# rm -rf Bubble_$c -# done \ No newline at end of file +rm -rf bubble_loc.txt +for ((c=0; c<$ncores; c++)) +do + rm -rf tension_results_$c.txt +done +for ((c=0; c<$nbubbles; c++)) +do + rm -rf Bubble_$c +done \ No newline at end of file diff --git a/examples/sphericalclustertensionwave/QA/gather_results.py b/examples/sphericalclustertensionwave/QA/gather_results.py index b23c0c3..7567636 100644 --- a/examples/sphericalclustertensionwave/QA/gather_results.py +++ b/examples/sphericalclustertensionwave/QA/gather_results.py @@ -4,46 +4,46 @@ count_core = 0 for file in os.listdir() : - if "onset_results_" in file : + if "tension_results_" in file : count_core += 1 -lines_onset = [] +lines_tension = [] for i in range(count_core) : - file_onset = open("onset_results_{}.txt".format(i), "r") - lines = file_onset.readlines() - file_onset.close() - lines_onset.append(lines) + file_tension = open("tension_results_{}.txt".format(i), "r") + lines = file_tension.readlines() + file_tension.close() + lines_tension.append(lines) -firstline = lines_onset[0][0].split(" ") +firstline = lines_tension[0][0].split(" ") count = int(firstline[0]) -png = float(firstline[5]) +p1 = float(firstline[5]) cl_distrib = int(firstline[7]) if cl_distrib == 0 : # monodispersed spherical cluster - file_name = "mono_{}_{:.4E}.txt".format(count, png) + file_name = "mono_{}_{:.4E}.txt".format(count, p1) else : # polydispersed spherical cluster - file_name = "poly_{}_{:.4E}.txt".format(count, png) + file_name = "poly_{}_{:.4E}.txt".format(count, p1) working_path = os.getcwd() results_path = os.path.join(working_path, "results") file_results = open(os.path.join(results_path, file_name), "w") -results_onset = open(os.path.join(results_path, file_name), "w") +results_tension = open(os.path.join(results_path, file_name), "w") # Header -for line in lines_onset[0][:3] : - results_onset.write(line) +for line in lines_tension[0][:3] : + results_tension.write(line) # Combining with the good format the values located in the files associated with the cores used for computation -for t in range(3, len(lines_onset[0])) : - time = lines_onset[0][t].split(" ")[0] +for t in range(3, len(lines_tension[0])) : + time = lines_tension[0][t].split(" ")[0] r_list = [] p_list = [] - for i in range(len(lines_onset)) : - data = lines_onset[i][t].split(" ") + for i in range(len(lines_tension)) : + data = lines_tension[i][t].split(" ") nbubble_core = int((len(data) - 1) / 2) r_list_file = data[1:nbubble_core+1] p_list_file = data[nbubble_core+1:2*nbubble_core+1] @@ -56,14 +56,14 @@ p = p.split("\n")[0] p_list.append(p) - results_onset.write(time) + results_tension.write(time) for rad in r_list : - results_onset.write(" {}".format(rad)) + results_tension.write(" {}".format(rad)) for pres in p_list : - results_onset.write(" {}".format(pres)) - results_onset.write("\n") + results_tension.write(" {}".format(pres)) + results_tension.write("\n") -results_onset.close() +results_tension.close() file_loc = open("bubble_loc.txt", "r") lines_loc = file_loc.readlines() @@ -71,11 +71,11 @@ if cl_distrib == 0 : # monodispersed spherical cluster - file_name_loc = "mono_{}_{:.4E}_loc.txt".format(count, png) + file_name_loc = "mono_{}_{:.4E}_loc.txt".format(count, p1) else : # polydispersed spherical cluster - file_name_loc = "poly_{}_{:.4E}_loc.txt".format(count, png) + file_name_loc = "poly_{}_{:.4E}_loc.txt".format(count, p1) file_loc_results = open(os.path.join(results_path, file_name_loc), "w") diff --git a/examples/sphericalclustertensionwave/QA/run.apecss b/examples/sphericalclustertensionwave/QA/run.apecss index 44da63b..5a2c1d6 100644 --- a/examples/sphericalclustertensionwave/QA/run.apecss +++ b/examples/sphericalclustertensionwave/QA/run.apecss @@ -7,7 +7,7 @@ BUBBLE RPModel KM Emissions QA 250.0e-6 -PressureAmbient 0.1013e6 +PressureAmbient 1.0e5 END GAS @@ -17,7 +17,7 @@ PolytropicExponent 1.4 END LIQUID -ReferencePressure 0.1013e6 +ReferencePressure 1.0e5 ReferenceDensity 1000.0 ReferenceSoundSpeed 1500.0 Viscosity 1.002e-3 @@ -27,6 +27,11 @@ INTERFACE SurfaceTensionCoeff 0.0728 END +RESULTS +Bubble +END + ODESOLVER tolerance 1.0e-10 +MinTimeStep 1.0e-10 END diff --git a/examples/sphericalclustertensionwave/QA/src/sphericalclustertensionwave_apecss.c b/examples/sphericalclustertensionwave/QA/src/sphericalclustertensionwave_apecss.c index def6f99..1dbaa2f 100644 --- a/examples/sphericalclustertensionwave/QA/src/sphericalclustertensionwave_apecss.c +++ b/examples/sphericalclustertensionwave/QA/src/sphericalclustertensionwave_apecss.c @@ -70,12 +70,12 @@ int main(int argc, char **args) // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // Set the case-dependent simulation parameters - const int nBubbles = 2500; // Number of bubbles - APECSS_FLOAT bubble_bubble_dist = 100.0e-6; // Bubble-bubble minimal distance - APECSS_FLOAT cluster_radius = 2.5e-3; // Spherical cluster radius + const int nBubbles = 250; // Number of bubbles + APECSS_FLOAT bubble_bubble_dist = 20.0e-6; // Bubble-bubble minimal distance + APECSS_FLOAT cluster_radius = 232e-6; // Spherical cluster radius // Interbubble time-step, defining the frequency with which the neighbor influence is updated - APECSS_FLOAT dt_interbubble = 1.0e-8; + APECSS_FLOAT dt_interbubble = 1.0e-9; // Initialize the simulation parameters given by the execution command double tEnd = 0.0; @@ -240,7 +240,7 @@ int main(int argc, char **args) // Monodispersed cluster for (register int i = 0; i < RankInfo->nBubbles_local; i++) { - Bubbles[i]->R0 = 10.0e-6; + Bubbles[i]->R0 = 2.0e-6; Bubbles[i]->R = Bubbles[i]->R0; } } @@ -249,12 +249,12 @@ int main(int argc, char **args) // Polydispersed cluster (radii distribution is following a log normal law) double mu = 0.0; double sigma = 0.7; - APECSS_FLOAT radius_ref = 10.0e-6; + APECSS_FLOAT radius_ref = 2.0e-6; APECSS_FLOAT Bubble_Radius[nBubbles]; for (register int i = 0; i < nBubbles; i++) { APECSS_FLOAT radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); - while ((radius > 20 * radius_ref) || (radius < 0.5 * radius_ref)) + while (radius > 20 * radius_ref) { // Small step to ensure no too big bubbles nor too small are generated (the distribution is conserved still) radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); @@ -389,19 +389,19 @@ int main(int argc, char **args) fclose(file_loc); // Radius and pressure evolution for each bubble during computation - FILE *file_onset; + FILE *file_tension; char file_name[APECSS_STRINGLENGTH_SPRINTF_LONG]; - sprintf(file_name, "onset_results_%d.txt", RankInfo->rank); - file_onset = fopen(file_name, "w"); + sprintf(file_name, "tension_results_%d.txt", RankInfo->rank); + file_tension = fopen(file_name, "w"); - fprintf(file_onset, "%d Bubbles p0(pa) %e png(Pa) %e cl_distrib %d\n", nBubbles, Liquid->pref, pa, cluster_distrib); - fprintf(file_onset, "Initial_radii(m)"); + fprintf(file_tension, "%d Bubbles p0(pa) %e p1(Pa) %e cl_distrib %d\n", nBubbles, Liquid->pref, pa, cluster_distrib); + fprintf(file_tension, "Initial_radii(m)"); for (register int i = 0; i < RankInfo->nBubbles_global; i++) { - fprintf(file_onset, " %e", RankInfo->bubbleglobal_R[i]); + fprintf(file_tension, " %e", RankInfo->bubbleglobal_R[i]); } - fprintf(file_onset, "\n"); - fprintf(file_onset, "#Time(s) R(m) Pt(Pa)\n"); + fprintf(file_tension, "\n"); + fprintf(file_tension, "#Time(s) R(m) Pt(Pa)\n"); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< /* Solve the bubble dynamics */ @@ -412,8 +412,6 @@ int main(int argc, char **args) for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); - // for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // Update the contribution of the neighbor bubble parallel_interactions_quasi_acoustic(Bubbles, RankInfo); @@ -421,16 +419,16 @@ int main(int argc, char **args) // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // Retrieve data - fprintf(file_onset, "%e", tSim); + fprintf(file_tension, "%e", tSim); for (register int i = 0; i < RankInfo->nBubbles_local; i++) { - fprintf(file_onset, " %e", Bubbles[i]->R); + fprintf(file_tension, " %e", Bubbles[i]->R); } for (register int i = 0; i < RankInfo->nBubbles_local; i++) { - fprintf(file_onset, " %e", Bubbles[i]->get_pressure_infinity(Bubbles[i]->t, Bubbles[i])); + fprintf(file_tension, " %e", Bubbles[i]->get_pressure_infinity(Bubbles[i]->t, Bubbles[i])); } - fprintf(file_onset, "\n"); + fprintf(file_tension, "\n"); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< for (register int i = 0; i < RankInfo->nBubbles_local; i++) @@ -443,7 +441,7 @@ int main(int argc, char **args) } } - fclose(file_onset); + fclose(file_tension); /* Finalize the simulation*/ for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_finalize(Bubbles[i]); @@ -490,48 +488,36 @@ int main(int argc, char **args) APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { - APECSS_FLOAT T = 10.0e-06; - if (t < T) - { - return (Bubble->p0 + Bubble->Interaction->dp_neighbor); - } - else if (t > 2 * T) + APECSS_FLOAT tau = 1.75e-6; + if (t < tau) { - return (Bubble->Excitation->dp + Bubble->Interaction->dp_neighbor); + return (Bubble->p0 - (Bubble->p0 - Bubble->Excitation->dp) * APECSS_POW2(APECSS_SIN(APECSS_PI * t / tau)) + Bubble->Interaction->dp_neighbor); } else { - APECSS_FLOAT W = 0.5 * (1 - APECSS_COS((t + T) * APECSS_PI / T)); - return (Bubble->p0 + W * (Bubble->Excitation->dp - Bubble->p0) + Bubble->Interaction->dp_neighbor); + return (Bubble->p0 + Bubble->Interaction->dp_neighbor); } } APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { // Approximate numerical computation of p_infinity derivative - APECSS_FLOAT T = 10.0e-06; - if (t < T) + APECSS_FLOAT tau = 1.75e-6; + APECSS_FLOAT derivative = 0.0; + if (t < tau) + { + APECSS_FLOAT inv_tau = 1 / tau; + derivative = -2.0 * APECSS_PI * inv_tau * (Bubble->p0 - Bubble->Excitation->dp) * APECSS_COS(APECSS_PI * t * inv_tau) * APECSS_SIN(APECSS_PI * t * inv_tau); + } + APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; + if (delta_t > Bubble->dt) { - return (0.0); + APECSS_FLOAT inv_delta_t = 1 / delta_t; + return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) * inv_delta_t)); } else { - APECSS_FLOAT derivative = 0.0; - if (t < 2 * T) - { - APECSS_FLOAT inv_T = 1 / T; - derivative = 0.5 * APECSS_PI * inv_T * APECSS_SIN(APECSS_PI * (t + T) * inv_T) * (Bubble->Excitation->dp - Bubble->p0); - } - APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; - if (delta_t > Bubble->dt) - { - APECSS_FLOAT inv_delta_t = 1 / delta_t; - return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) * inv_delta_t)); - } - else - { - return (derivative); - } + return (derivative); } } From b774372bd960b5a0126c950fb9a5f91e8f3ed1c4 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 30 Jul 2024 15:01:49 -0400 Subject: [PATCH 063/138] bubbly screen ; small changes for displaying results --- examples/bubblyscreen/plot_results.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/bubblyscreen/plot_results.py b/examples/bubblyscreen/plot_results.py index 301f007..011042e 100644 --- a/examples/bubblyscreen/plot_results.py +++ b/examples/bubblyscreen/plot_results.py @@ -4,7 +4,7 @@ from math import pi from matplotlib.patches import Circle -fontsize = 12 +fontsize = 16.5 plt.rcParams['font.family']='serif' plt.rcParams['font.serif']=['Times New Roman'] + plt.rcParams['font.serif'] @@ -106,25 +106,25 @@ def plot_oscillation_distribution(fig, axs, row, col, nbubbles_x, inttype, rati fig, axs = plt.subplots(nrow,ncol,figsize=(55*cm, 27.5*cm)) for i in range(nrow) : for j in range(ncol) : - axs[i,j].set_xlabel(r"x/D") + axs[i,j].set_xlabel(r"y/D") axs[i,j].set_xlim(xmin=-25.5,xmax=25.5) - axs[i,j].set_ylabel(r"y/D") + axs[i,j].set_ylabel(r"z/D") axs[i,j].set_ylim(ymin=-25.5,ymax=25.5) axs[i,j].set_aspect("equal") ### First row : QA ### -plt.figtext(0.5, 0.85, r"QA, $D/R_{0}$ = 400", fontsize=16.5, horizontalalignment="center") +plt.figtext(0.5, 0.875, r"QA, $D/R_{0}$ = 400", fontsize=20.0, horizontalalignment="center") plot_oscillation_distribution(fig, axs, 0, 0, 51, "QA", 0.5, 400, order=4) plot_oscillation_distribution(fig, axs, 0, 1, 51, "QA", 0.9, 400, order=3) -plot_oscillation_distribution(fig, axs, 0, 2, 51, "QA", 1.0, 400) +plot_oscillation_distribution(fig, axs, 0, 2, 51, "QA", 1.0, 400, order=2) plot_oscillation_distribution(fig, axs, 0, 3, 51, "QA", 1.5, 400, order=4) ### Second row : IC ### -plt.figtext(0.5, 0.5, r"IC, $D/R_{0}$ = 400", fontsize=16.5, horizontalalignment="center") +plt.figtext(0.5, 0.5, r"IC, $D/R_{0}$ = 400", fontsize=20.0, horizontalalignment="center") plot_oscillation_distribution(fig, axs, 1, 0, 51, "IC", 0.5, 400, order=4) plot_oscillation_distribution(fig, axs, 1, 1, 51, "IC", 0.9, 400, order=3) plot_oscillation_distribution(fig, axs, 1, 2, 51, "IC", 1.0, 400, order=3) plot_oscillation_distribution(fig, axs, 1, 3, 51, "IC", 1.5, 400, order=4, clear=True) -fig.subplots_adjust(hspace=0.05*cm, wspace=0.65*cm) +fig.subplots_adjust(hspace=0.01*cm, wspace=0.60*cm) fig.savefig("bubblyscreen_ComparisonQAIC.pdf", bbox_inches="tight",pad_inches=0.035) \ No newline at end of file From 96c48181d009e68cfdf210f8a494f906e3a49379 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 30 Jul 2024 15:02:52 -0400 Subject: [PATCH 064/138] spherical cluster tension wave ; efficienter way to compute pderivative infinity for IC and NI test cases --- .../IC/src/sphericalclustertensionwave_apecss.c | 3 ++- .../NI/src/sphericalclustertensionwave_apecss.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/sphericalclustertensionwave/IC/src/sphericalclustertensionwave_apecss.c b/examples/sphericalclustertensionwave/IC/src/sphericalclustertensionwave_apecss.c index cc28962..ffe6ef1 100644 --- a/examples/sphericalclustertensionwave/IC/src/sphericalclustertensionwave_apecss.c +++ b/examples/sphericalclustertensionwave/IC/src/sphericalclustertensionwave_apecss.c @@ -381,7 +381,8 @@ APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, stru APECSS_FLOAT tau = 1.75e-6; if (t < tau) { - return (-2.0 * (APECSS_PI / tau) * (Bubble->p0 - Bubble->Excitation->dp) * APECSS_COS(APECSS_PI * t / tau) * APECSS_SIN(APECSS_PI * t / tau)); + APECSS_FLOAT inv_tau = 1 / tau; + return (-2.0 * APECSS_PI * inv_tau * (Bubble->p0 - Bubble->Excitation->dp) * APECSS_COS(APECSS_PI * t * inv_tau) * APECSS_SIN(APECSS_PI * t * inv_tau)); } else { diff --git a/examples/sphericalclustertensionwave/NI/src/sphericalclustertensionwave_apecss.c b/examples/sphericalclustertensionwave/NI/src/sphericalclustertensionwave_apecss.c index d4a725e..22dfb7d 100644 --- a/examples/sphericalclustertensionwave/NI/src/sphericalclustertensionwave_apecss.c +++ b/examples/sphericalclustertensionwave/NI/src/sphericalclustertensionwave_apecss.c @@ -376,7 +376,8 @@ APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, stru APECSS_FLOAT tau = 1.75e-6; if (t < tau) { - return (-2.0 * (APECSS_PI / tau) * (Bubble->p0 - Bubble->Excitation->dp) * APECSS_COS(APECSS_PI * t / tau) * APECSS_SIN(APECSS_PI * t / tau)); + APECSS_FLOAT inv_tau = 1 / tau; + return (-2.0 * APECSS_PI * inv_tau * (Bubble->p0 - Bubble->Excitation->dp) * APECSS_COS(APECSS_PI * t * inv_tau) * APECSS_SIN(APECSS_PI * t * inv_tau)); } else { From 0a270030990a396255a0d1d7a5d3263d0d8ac749 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 30 Jul 2024 15:04:13 -0400 Subject: [PATCH 065/138] spherical cluster tension wave ; adding QA runs in .sh and improving results plotted --- .../plot_results.py | 257 +++++++++++++++--- .../run_sphericalclustertensionwave.sh | 44 ++- 2 files changed, 244 insertions(+), 57 deletions(-) diff --git a/examples/sphericalclustertensionwave/plot_results.py b/examples/sphericalclustertensionwave/plot_results.py index 21753be..0d2bd23 100644 --- a/examples/sphericalclustertensionwave/plot_results.py +++ b/examples/sphericalclustertensionwave/plot_results.py @@ -147,6 +147,7 @@ initial_radius_list.append(dic_bubbles[inttype]["poly"][count][p1][i][0]) quantiles = np.quantile(np.array(initial_radius_list), quantiles_list) + print(count, quantiles) for q in quantiles : dic_polydisperse[inttype][count][p1]["quantiles"].append(q) for i in range(count) : @@ -157,6 +158,26 @@ index += 1 dic_polydisperse[inttype][count][p1][quantiles_list[index]].append(i) +# It's possible also for polydispersed cluster to plot results based on bubbles locations +dic_loc_distrib_global_poly = {} + +for count in list(dic_bubbles_loc["poly"].keys()) : + if count not in list(dic_loc_distrib_global.keys()) : + dic_loc_distrib_global[count] = {} + + for p1 in list(dic_bubbles_loc["poly"][count].keys()) : + if p1 not in list(dic_loc_distrib_global[count].keys()) : + dic_loc_distrib_global[count][p1] = dic_loc_distrib + + for i in range(count) : + radius_to_center = sqrt(dic_bubbles_loc["poly"][count][p1][i][0]**2 + dic_bubbles_loc["poly"][count][p1][i][1]**2 + dic_bubbles_loc["poly"][count][p1][i][2]**2) + if radius_to_center < 0.0 * cluster_radius + interval_size : + dic_loc_distrib_global[count][p1][0.0].append(i) + elif 0.5 * (cluster_radius - interval_size) < radius_to_center < 0.5 * (cluster_radius + interval_size) : + dic_loc_distrib_global[count][p1][0.5].append(i) + elif 1.0 * cluster_radius - interval_size < radius_to_center : + dic_loc_distrib_global[count][p1][1.0].append(i) + ######### Step 3 : Plot results ##################################################################################################################### #### General parameters ##### @@ -196,13 +217,14 @@ print("{} cluster with N={} bubbles, minimum distance between bubbles equal {:.2f} microns".format(cluster, count, min_dist*1.0e6)) fig, ax = plt.subplots(1, 1, figsize=(17.5*cm, 12.5*cm)) -ax.set_xlabel(r"$ / R_{0,ref}$ (-)", fontsize=15) +ax.set_xlabel(r"$ / R_{0,ref}$ [-]", fontsize=15) ax.grid() for count in list(dic_bubbles["NI"]["poly"].keys()) : init_r_list = [] for i in range(count) : init_r_list.append(dic_bubbles["NI"]["poly"][count][p1][i][0] / r_ref) + print("poly cluster with N={} bubbles, minimum initial radius equal {:.2E} m".format(count, np.min(init_r_list) * r_ref)) count, bins, ignored = ax.hist(init_r_list, 100, density=True, align='mid', label="{} bubbles".format(count)) x = np.linspace(min(bins), max(bins), 10000) @@ -221,9 +243,9 @@ ncol = 3 fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) for i in range(ncol) : - axs[i].set_xlabel(r"$ t / t_{i}$ (-)", fontsize=15) - axs[i].set_ylabel(r"$ / R_{0}$ (-)", fontsize=15) - # axs[i].set_xlim(xmin=10.0, xmax=60.0) + axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=15) + axs[i].set_ylabel(r"$ / R_{0}$ [-]", fontsize=15) + axs[i].set_xlim(xmin=0.0, xmax=80.0) axs[i].grid() axs[0].set_title(r"No interaction" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) @@ -272,23 +294,23 @@ axs[1].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) - # # Quasi acoustic interactions - # t_list = (1/t_i) * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) + # Quasi acoustic interactions + t_list = (1/t_i) * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) - # r_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][1]) - # init_r_0 = dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][0] - # avg_radius = r_list_0 / init_r_0 + r_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 - # for i in range(1, len(index_list)) : - # index = index_list[i] + for i in range(1, len(index_list)) : + index = index_list[i] - # r_list = np.array(dic_bubbles["QA"]["mono"][count][p1][index + 1][1]) - # init_r = dic_bubbles["QA"]["mono"][count][p1][index + 1][0] - # avg_radius = avg_radius + np.array(r_list) / init_r + r_list = np.array(dic_bubbles["QA"]["mono"][count][p1][index + 1][1]) + init_r = dic_bubbles["QA"]["mono"][count][p1][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r - # avg_radius = (1 / len(index_list)) * avg_radius + avg_radius = (1 / len(index_list)) * avg_radius - # axs[2].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) + axs[2].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=3, frameon=False) @@ -304,21 +326,25 @@ ncol = 3 fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) for i in range(ncol) : - axs[i].set_xlabel(r"$ t / t_{i}$ (-)", fontsize=15) - axs[i].set_ylabel(r"$$ (-)", fontsize=15) + axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=15) + axs[i].set_ylabel(r"$$ [-]", fontsize=15) # axs[i].set_xlim(xmin=10.0, xmax=60.0) axs[i].grid() -axs[0].set_title(r"No interaction" + "\n" +r"($N = 250$, $R_{0, ref}=10.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) -axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0, ref}=10.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) -axs[2].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=10.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[0].set_title(r"No interaction" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[2].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) color_list = ["black", "magenta", "blue", "green", "red"] +# linestyle_list = [(0, (1, 1)), (5, (10, 3)), (0, (5, 5)), (0, (3, 5, 1, 5)), (0, (3, 1, 1, 1, 1, 1))] +linestyle_list = ["solid" for i in range(5)] dic_color_q = {} +dic_linestyle_q = {} dic_label_q = {} for i in range(n_quantiles) : quantile = quantiles_list[i] dic_color_q[quantile] = color_list[i] + dic_linestyle_q[quantile] = linestyle_list[i] dic_label_q[quantile] = "{}th-{}".format(i+1, quantile_name) if i == 0 : @@ -329,6 +355,13 @@ dic_label_q[quantile] = "3rd-{}".format(quantile_name) # No interaction +axs[0].set_xlim(xmin=0.0,xmax=250.0) +axs[0].set_ylim(ymin=0.95,ymax=1.6) + +zm = axs[0].inset_axes([0.25, 0.25, 0.7, 0.7]) +zm.grid() +zm.set_xlim(xmax=50.0) + for q in list(dic_polydisperse["NI"][count][p1].keys())[1:] : index_list = dic_polydisperse["NI"][count][p1][q] @@ -347,9 +380,18 @@ avg_radius = (1 / len(index_list)) * avg_radius - axs[0].plot(t_list, avg_radius, linewidth=1.5, linestyle="solid", color=dic_color_q[q]) + axs[0].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) + + zm.plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) # Incompressible interactions +axs[1].set_xlim(xmin=-10.0,xmax=800.0) +axs[1].set_ylim(ymin=0.925,ymax=1.25) + +zm = axs[1].inset_axes([0.25, 0.5, 0.7, 0.45]) +zm.grid() +zm.set_xlim(xmax=200.0) + for q in list(dic_polydisperse["IC"][count][p1].keys())[1:] : index_list = dic_polydisperse["IC"][count][p1][q] @@ -368,11 +410,119 @@ avg_radius = (1 / len(index_list)) * avg_radius - axs[1].plot(t_list, avg_radius, linewidth=1.5, linestyle="solid", color=dic_color_q[q], label=dic_label_q[q]) + axs[1].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q], label=dic_label_q[q]) + + zm.plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) + +# Quasi acoustic interactions +for q in list(dic_polydisperse["QA"][count][p1].keys())[1:] : + index_list = dic_polydisperse["QA"][count][p1][q] + + t_list = (1/t_i) * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) + + r_list_0 = np.array(dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["QA"]["poly"][count][p1][index + 1][1]) + init_r = dic_bubbles["QA"]["poly"][count][p1][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[2].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=n_quantiles, frameon=False) fig.savefig("sphericalclustertensionwave_poly_radiusevolution.pdf", bbox_inches='tight',pad_inches=0.35) +######### Averaged radius versus time for polydispersed cluster based on location ################# +count = 250 +p1 = -3.0e4 +t_i = r_ref * sqrt(rho_l / (p0 - p1)) + +nrow = 1 +ncol = 3 +fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) +for i in range(ncol) : + axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=15) + axs[i].set_ylabel(r"$ / R_{0}$ [-]", fontsize=15) + # axs[i].set_xlim(xmin=10.0, xmax=60.0) + axs[i].grid() + +axs[0].set_title(r"No interaction" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[2].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) + +dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} +dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} + +axs[0].set_xlim(xmin=0.0, xmax=250.0) +axs[1].set_xlim(xmin=-10.0, xmax=800.0) + +for k in dic_loc_distrib_global[count][p1].keys() : + index_list = dic_loc_distrib_global[count][p1][k] + + # No interaction + t_list = (1/t_i) * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) + + r_list_0 = np.array(dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["NI"]["poly"][count][p1][index + 1][1]) + init_r = dic_bubbles["NI"]["poly"][count][p1][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[0].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) + + # Incompressible interactions + t_list = (1/t_i) * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) + + r_list_0 = np.array(dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["IC"]["poly"][count][p1][index + 1][1]) + init_r = dic_bubbles["IC"]["poly"][count][p1][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[1].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) + + # Quasi acoustic interactions + t_list = (1/t_i) * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) + + r_list_0 = np.array(dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["QA"]["poly"][count][p1][index + 1][1]) + init_r = dic_bubbles["QA"]["poly"][count][p1][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[2].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) + + +axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=3, frameon=False) +fig.savefig("sphericalclustertensionwave_poly_radiusevolution_bis.pdf", bbox_inches='tight',pad_inches=0.35) + ######### Averaged pressure infinity versus time evolution for monodispersed clusters ############# count = 250 @@ -384,9 +534,9 @@ ncol = 3 fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) for i in range(ncol) : - axs[i].set_xlabel(r"$ t / t_{i}$ (-)", fontsize=15) - axs[i].set_ylabel(r"$ / p_{0}$ (-)", fontsize=15) - # axs[i].set_xlim(xmin=10.0, xmax=60.0) + axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=15) + axs[i].set_ylabel(r"$ / p_{0}$ [-]", fontsize=15) + axs[i].set_xlim(xmin=0.0, xmax=80.0) axs[i].grid() axs[0].set_title(r"No interaction" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) @@ -431,26 +581,26 @@ axs[1].plot(t_list, avg_pressure, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) - # # Quasi acoustic interactions - # t_list = (1/t_i) * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) + # Quasi acoustic interactions + t_list = (1/t_i) * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) - # p_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][2]) - # avg_pressure = p_list_0 / p0 + p_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][2]) + avg_pressure = p_list_0 / p0 - # for i in range(1, len(index_list)) : - # index = index_list[i] + for i in range(1, len(index_list)) : + index = index_list[i] - # p_list = np.array(dic_bubbles["QA"]["mono"][count][p1][index + 1][2]) - # avg_pressure = avg_pressure + np.array(p_list) / p0 + p_list = np.array(dic_bubbles["QA"]["mono"][count][p1][index + 1][2]) + avg_pressure = avg_pressure + np.array(p_list) / p0 - # avg_pressure = (1 / len(index_list)) * avg_pressure + avg_pressure = (1 / len(index_list)) * avg_pressure - # axs[2].plot(t_list, avg_pressure, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) + axs[2].plot(t_list, avg_pressure, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=3, frameon=False) fig.savefig("sphericalclustertensionwave_mono_pressureevolution.pdf", bbox_inches='tight',pad_inches=0.35) -######### Averaged pressure infinity versus time evolution for monodispersed clusters ############# +######### Averaged pressure infinity versus time evolution for polydispersed clusters ############# count = 250 p1 = -3.0e4 @@ -461,14 +611,14 @@ ncol = 3 fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) for i in range(ncol) : - axs[i].set_xlabel(r"$ t / t_{i}$ (-)", fontsize=15) - axs[i].set_ylabel(r"$/p_{0}$ (-)", fontsize=15) + axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=15) + axs[i].set_ylabel(r"$/p_{0}$ [-]", fontsize=15) # axs[i].set_xlim(xmin=10.0, xmax=60.0) axs[i].grid() -axs[0].set_title(r"No interaction" + "\n" +r"($N = 250$, $R_{0, ref}=10.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) -axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0, ref}=10.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) -axs[2].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=10.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[0].set_title(r"No interaction" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[2].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) color_list = ["black", "magenta", "blue", "green", "red"] dic_color_q = {} @@ -502,7 +652,7 @@ avg_pressure = (1 / len(index_list)) * avg_pressure - axs[0].plot(t_list, avg_pressure, linewidth=1.5, linestyle="solid", color=dic_color_q[q]) + axs[0].plot(t_list, avg_pressure, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) # Incompressible interactions for q in list(dic_polydisperse["IC"][count][p1].keys())[1:] : @@ -521,7 +671,26 @@ avg_pressure = (1 / len(index_list)) * avg_pressure - axs[1].plot(t_list, avg_pressure, linewidth=1.5, linestyle="solid", color=dic_color_q[q], label=dic_label_q[q]) + axs[1].plot(t_list, avg_pressure, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q], label=dic_label_q[q]) + +# Quasi acoustic interactions +for q in list(dic_polydisperse["QA"][count][p1].keys())[1:] : + index_list = dic_polydisperse["QA"][count][p1][q] + + t_list = (1/t_i) * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) + + p_list_0 = np.array(dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][2]) + avg_pressure = p_list_0 / p0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + p_list = np.array(dic_bubbles["QA"]["poly"][count][p1][index + 1][2]) + avg_pressure = avg_pressure + np.array(p_list) / p0 + + avg_pressure = (1 / len(index_list)) * avg_pressure + + axs[2].plot(t_list, avg_pressure, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=n_quantiles, frameon=False) fig.savefig("sphericalclustertensionwave_poly_pressureevolution.pdf", bbox_inches='tight',pad_inches=0.35) \ No newline at end of file diff --git a/examples/sphericalclustertensionwave/run_sphericalclustertensionwave.sh b/examples/sphericalclustertensionwave/run_sphericalclustertensionwave.sh index b8bc6de..8a3996b 100755 --- a/examples/sphericalclustertensionwave/run_sphericalclustertensionwave.sh +++ b/examples/sphericalclustertensionwave/run_sphericalclustertensionwave.sh @@ -1,6 +1,6 @@ ######### Parameters ################################################################################################################################ -ncores=10 +ncores=12 nbubbles=250 ######### No interaction computations ############################################################################################################### @@ -34,7 +34,7 @@ cd .. python3 gather_results.py ######### Polydispersed system #################################################################### -./build/sphericalclustertensionwave_apecss -options run.apecss -amp -3.0e4 -tend 60.0e-6 -cldistrib 1 +./build/sphericalclustertensionwave_apecss -options run.apecss -amp -3.0e4 -tend 150.0e-6 -cldistrib 1 python3 gather_results.py cd .. @@ -45,6 +45,24 @@ echo "" ######### Quasi acoustic computations ############################################################################################################### +cd QA/build +./compile.sh +cd .. + +######### Monodispersed system #################################################################### +mpiexec -n $ncores ./build/sphericalclustertensionwave_apecss -options run.apecss -amp -3.0e4 -tend 25.0e-06 -cldistrib 0 +python3 gather_results.py + +######### Polydispersed system #################################################################### +mpiexec -n $ncores ./build/sphericalclustertensionwave_apecss -options run.apecss -amp -3.0e4 -tend 200.0e-06 -cldistrib 1 +python3 gather_results.py + +cd .. + +echo "" +echo "Quasi acoustic test cases passed" +echo "" + ######### Plot results ############################################################################################################################## python3 plot_results.py @@ -67,17 +85,17 @@ do done cd .. -# # # cd QA -# # # rm -rf "bubble_loc.txt" -# # # for ((c=0; c<$ncores; c++)) -# # # do -# # # rm -rf tension_results_$c.txt -# # # done -# # # for ((c=0; c<$nbubbles; c++)) -# # # do -# # # rm -rf Bubble_$c -# # # done -# # # cd .. +cd QA +rm -rf "bubble_loc.txt" +for ((c=0; c<$ncores; c++)) +do + rm -rf tension_results_$c.txt +done +for ((c=0; c<$nbubbles; c++)) +do + rm -rf Bubble_$c +done +cd .. echo "" echo "Cleaning completed" From 94b4e60c6229e9d37713746dc57abcb60dbbad03 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Wed, 31 Jul 2024 11:25:06 -0400 Subject: [PATCH 066/138] spherical cluster tension wave ; new plots for article --- .../plot_results.py | 234 +++++++++++++++++- 1 file changed, 232 insertions(+), 2 deletions(-) diff --git a/examples/sphericalclustertensionwave/plot_results.py b/examples/sphericalclustertensionwave/plot_results.py index 0d2bd23..28e38dc 100644 --- a/examples/sphericalclustertensionwave/plot_results.py +++ b/examples/sphericalclustertensionwave/plot_results.py @@ -214,7 +214,7 @@ if min_dist_bubble < min_dist : min_dist = min_dist_bubble - print("{} cluster with N={} bubbles, minimum distance between bubbles equal {:.2f} microns".format(cluster, count, min_dist*1.0e6)) + print("{} cluster with N={} bubbles, minimum distance between bubbles equals {:.2f} microns".format(cluster, count, min_dist*1.0e6)) fig, ax = plt.subplots(1, 1, figsize=(17.5*cm, 12.5*cm)) ax.set_xlabel(r"$ / R_{0,ref}$ [-]", fontsize=15) @@ -224,7 +224,7 @@ init_r_list = [] for i in range(count) : init_r_list.append(dic_bubbles["NI"]["poly"][count][p1][i][0] / r_ref) - print("poly cluster with N={} bubbles, minimum initial radius equal {:.2E} m".format(count, np.min(init_r_list) * r_ref)) + print("poly cluster with N={} bubbles, minimum initial radius equals {:.2E} m".format(count, np.min(init_r_list) * r_ref)) count, bins, ignored = ax.hist(init_r_list, 100, density=True, align='mid', label="{} bubbles".format(count)) x = np.linspace(min(bins), max(bins), 10000) @@ -316,6 +316,91 @@ axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=3, frameon=False) fig.savefig("sphericalclustertensionwave_mono_radiusevolution.pdf", bbox_inches='tight',pad_inches=0.35) +######### Averaged radius versus time evolution for monodispersed cluster (article) ############### +count = 250 +p1 = -3.0e4 +t_i = r_ref * sqrt(rho_l / (p0 - p1)) + +nrow = 1 +ncol = 3 +fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) +for i in range(ncol) : + axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=27.5) + if i == 0 : axs[i].set_ylabel(r"$ / R_{0}$ [-]", fontsize=27.5) + axs[i].set_xlim(xmin=0.0, xmax=80.0) + axs[i].tick_params(axis="both", labelsize=25) + axs[i].grid() + +plt.subplots_adjust(wspace=0.35*cm) + +axs[0].set_title(r"No interaction", fontsize=27.5) +axs[1].set_title(r"Incompressible interactions", fontsize=27.5) +axs[2].set_title(r"Quasi acoustic interactions", fontsize=27.5) + +dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} +dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} + +for k in dic_loc_distrib_global[count][p1].keys() : + index_list = dic_loc_distrib_global[count][p1][k] + + # No interaction + t_list = (1/t_i) * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) + + r_list_0 = np.array(dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["NI"]["mono"][count][p1][index + 1][1]) + init_r = dic_bubbles["NI"]["mono"][count][p1][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[0].plot(t_list, avg_radius, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) + + # Incompressible interactions + t_list = (1/t_i) * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) + + r_list_0 = np.array(dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["IC"]["mono"][count][p1][index + 1][1]) + init_r = dic_bubbles["IC"]["mono"][count][p1][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[1].plot(t_list, avg_radius, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) + + # Quasi acoustic interactions + t_list = (1/t_i) * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) + + r_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["QA"]["mono"][count][p1][index + 1][1]) + init_r = dic_bubbles["QA"]["mono"][count][p1][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[2].plot(t_list, avg_radius, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) + + +axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=26.5, ncol=3, frameon=False) +fig.savefig("sphericalclustertensionwave_mono_radiusevolution_article.pdf", bbox_inches='tight',pad_inches=0.35) + ######### Averaged radius versus time evolution for polydispersed cluster ######################### count = 250 @@ -415,6 +500,13 @@ zm.plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) # Quasi acoustic interactions +axs[2].set_xlim(xmin=-10.0,xmax=1000.0) +axs[2].set_ylim(ymin=0.925,ymax=1.25) + +zm = axs[2].inset_axes([0.25, 0.5, 0.7, 0.45]) +zm.grid() +zm.set_xlim(xmax=250.0) + for q in list(dic_polydisperse["QA"][count][p1].keys())[1:] : index_list = dic_polydisperse["QA"][count][p1][q] @@ -435,9 +527,147 @@ axs[2].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) + zm.plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) + axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=n_quantiles, frameon=False) fig.savefig("sphericalclustertensionwave_poly_radiusevolution.pdf", bbox_inches='tight',pad_inches=0.35) +######### Averaged radius versus time evolution for polydispersed cluster (article) ############### + +count = 250 +p1 = -3.0e4 +t_i = r_ref * sqrt(rho_l / (p0 - p1)) + +nrow = 1 +ncol = 3 +fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) +for i in range(ncol) : + axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=27.5) + if i == 0 : axs[i].set_ylabel(r"$$ [-]", fontsize=27.5) + # axs[i].set_xlim(xmin=10.0, xmax=60.0) + axs[i].tick_params(axis="both", labelsize=25) + axs[i].grid() +plt.subplots_adjust(wspace=0.35*cm) + +axs[0].set_title(r"No interaction", fontsize=27.5) +axs[1].set_title(r"Incompressible interactions", fontsize=27.5) +axs[2].set_title(r"Quasi acoustic interactions", fontsize=27.5) + +color_list = ["black", "magenta", "blue", "green", "red"] +# linestyle_list = [(0, (1, 1)), (5, (10, 3)), (0, (5, 5)), (0, (3, 5, 1, 5)), (0, (3, 1, 1, 1, 1, 1))] +linestyle_list = ["solid" for i in range(5)] +dic_color_q = {} +dic_linestyle_q = {} +dic_label_q = {} +for i in range(n_quantiles) : + quantile = quantiles_list[i] + dic_color_q[quantile] = color_list[i] + dic_linestyle_q[quantile] = linestyle_list[i] + + dic_label_q[quantile] = "{}th-{}".format(i+1, quantile_name) + if i == 0 : + dic_label_q[quantile] = "1st-{}".format(quantile_name) + elif i == 1 : + dic_label_q[quantile] = "2nd-{}".format(quantile_name) + elif i == 2 : + dic_label_q[quantile] = "3rd-{}".format(quantile_name) + +# No interaction +axs[0].set_xlim(xmin=0.0,xmax=250.0) +axs[0].set_ylim(ymin=0.95,ymax=1.6) + +zm = axs[0].inset_axes([0.25, 0.25, 0.7, 0.7]) +zm.grid() +zm.set_xlim(xmin=0.0, xmax=50.0) +zm.tick_params(axis="both", labelsize=25) + +for q in list(dic_polydisperse["NI"][count][p1].keys())[1:] : + index_list = dic_polydisperse["NI"][count][p1][q] + + t_list = (1/t_i) * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) + + r_list_0 = np.array(dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["NI"]["poly"][count][p1][index + 1][1]) + init_r = dic_bubbles["NI"]["poly"][count][p1][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[0].plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) + + zm.plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) + +# Incompressible interactions +axs[1].set_xlim(xmin=-10.0,xmax=800.0) +axs[1].set_ylim(ymin=0.925,ymax=1.25) + +zm = axs[1].inset_axes([0.25, 0.5, 0.7, 0.45]) +zm.grid() +zm.set_xlim(xmax=200.0) +zm.tick_params(axis="both", labelsize=25) + +for q in list(dic_polydisperse["IC"][count][p1].keys())[1:] : + index_list = dic_polydisperse["IC"][count][p1][q] + + t_list = (1/t_i) * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) + + r_list_0 = np.array(dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["IC"]["poly"][count][p1][index + 1][1]) + init_r = dic_bubbles["IC"]["poly"][count][p1][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[1].plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q], label=dic_label_q[q]) + + zm.plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) + +# Quasi acoustic interactions +axs[2].set_xlim(xmin=-10.0,xmax=1000.0) +axs[2].set_ylim(ymin=0.925,ymax=1.25) + +zm = axs[2].inset_axes([0.25, 0.5, 0.7, 0.45]) +zm.grid() +zm.set_xlim(xmax=250.0) +zm.tick_params(axis="both", labelsize=25) + +for q in list(dic_polydisperse["QA"][count][p1].keys())[1:] : + index_list = dic_polydisperse["QA"][count][p1][q] + + t_list = (1/t_i) * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) + + r_list_0 = np.array(dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["QA"]["poly"][count][p1][index + 1][1]) + init_r = dic_bubbles["QA"]["poly"][count][p1][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[2].plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) + + zm.plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) + +axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=26.5, ncol=n_quantiles, frameon=False) +fig.savefig("sphericalclustertensionwave_poly_radiusevolution_article.pdf", bbox_inches='tight',pad_inches=0.35) + ######### Averaged radius versus time for polydispersed cluster based on location ################# count = 250 p1 = -3.0e4 From 9bc3ca432d9bd4120a6e6eed08feb0c6b4c84693 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Wed, 31 Jul 2024 13:29:06 -0400 Subject: [PATCH 067/138] cavitation onset ; rework of the plots for better lisibility in the article --- examples/cavitationonset/plot_results.py | 148 ++++++++++++----------- 1 file changed, 75 insertions(+), 73 deletions(-) diff --git a/examples/cavitationonset/plot_results.py b/examples/cavitationonset/plot_results.py index 75de18e..30abe54 100644 --- a/examples/cavitationonset/plot_results.py +++ b/examples/cavitationonset/plot_results.py @@ -6,7 +6,7 @@ plt.rcParams['font.family']='serif' plt.rcParams['font.serif']=['Times New Roman'] + plt.rcParams['font.serif'] plt.rcParams['mathtext.fontset']='stix' -plt.rcParams['font.size']=12.5 +plt.rcParams['font.size']=25 color_names = list(mcolors.XKCD_COLORS) @@ -92,30 +92,30 @@ plt.subplots_adjust(wspace=0.5*cm, hspace=0.5*cm) axs[0].set_title("Pressure time history (" + r"$T$ = " + "{:.1f} ".format(T*1.0e06) + r"$\mu$s)") -axs[0].set_xlabel(r"t ($\mu$s)") +axs[0].set_xlabel(r"t ($\mu$s)", fontsize=27.5) axs[0].set_xlim(xmin=0.0, xmax=60.0) -axs[0].set_ylabel(r"$p_{\infty}$/$p_{0}$ (-)") +axs[0].set_ylabel(r"$p_{\infty}$/$p_{0}$ (-)", fontsize=27.5) axs[0].grid() t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][1]) * 1.0e6 p_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][3]) / P0 -axs[0].plot(t_list, p_list, color="black") +axs[0].plot(t_list, p_list, color="black", linewidth=2.5) axs[1].set_title("Evolution of radius without interaction") -axs[1].set_xlabel(r"t ($\mu$s)") +axs[1].set_xlabel(r"t ($\mu$s)", fontsize=27.5) axs[1].set_xlim(xmin=0.0, xmax=60.0) -axs[1].set_ylabel(r"$R$ ($\mu$m)") +axs[1].set_ylabel(r"$R$ ($\mu$m)", fontsize=27.5) axs[1].grid() t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][1]) * 1.0e6 r_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][2]) * 1.0e6 -axs[1].plot(t_list, r_list, color="blue", label=r"$R_{1,0}$ = 2.0 $\mu$m") +axs[1].plot(t_list, r_list, color="blue", label=r"$R_{1,0}$ = 2.0 $\mu$m", linewidth=2.5) t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][1][1]) * 1.0e6 r_list = np.array(dic_2_bubbles["NI"][-25325][15.0][1][2]) * 1.0e6 -axs[1].plot(t_list, r_list, color="magenta", label=r"$R_{2,0}$ = 20.0 $\mu$m") +axs[1].plot(t_list, r_list, color="magenta", linestyle="dashed", label=r"$R_{2,0}$ = 20.0 $\mu$m", linewidth=2.5) -axs[1].legend(loc="upper left") +axs[1].legend(loc="upper left", frameon=False) fig.savefig("cavitationonset_pressurehistory_radiusevolutionNI.pdf", bbox_inches='tight',pad_inches=0.35) @@ -129,10 +129,10 @@ png_list = [-17221, -17725.5, -18353.2, -18770.3] -ax.set_title("Cavitation inception of a single bubble depending on " + r"$p_{ng}$/$p_{0}$ ($R_{0}$ = 2 $\mu$m)") -ax.set_xlabel(r"t ($\mu$s)") +ax.set_title("Cavitation inception of a single bubble \n depending on " + r"$p_{ng}$/$p_{0}$ ($R_{0}$ = 2 $\mu$m)") +ax.set_xlabel(r"t ($\mu$s)", fontsize=27.5) ax.set_xlim(xmin=10.0, xmax=60.0) -ax.set_ylabel(r"$R$ ($\mu$m)") +ax.set_ylabel(r"$R$ ($\mu$m)", fontsize=27.5) ax.set_ylim(ymin=0.0, ymax=14.0) ax.grid() @@ -140,12 +140,12 @@ t_list = np.array(dic_2_bubbles["NI"][png][15.0][0][1]) * 1.0e6 r_list = np.array(dic_2_bubbles["NI"][png][15.0][0][2]) * 1.0e6 - ax.plot(t_list, r_list, color="blue") + ax.plot(t_list, r_list, color="blue", linewidth=2.5) -ax.text(25.0, 3.50, r"$-0.17$") +ax.text(25.0, 3.00, r"$-0.17$") ax.text(31.0, 6.25, r"$-0.175$") ax.text(28.0, 9.00, r"$-0.176$") -ax.text(22.5, 13.0, r"$-0.18$") +ax.text(21.0, 13.0, r"$-0.18$") fig.savefig("cavitationonset_singlebubble.pdf", bbox_inches='tight',pad_inches=0.35) @@ -155,74 +155,74 @@ ncol = 2 fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm))) -plt.subplots_adjust(wspace=0.5*cm, hspace=0.5*cm) +plt.subplots_adjust(wspace=0.35*cm, hspace=0.5*cm) dist_list = [10, 12, 12.1, 12.5, 15, 20] -axs[0].set_title(r"Incompressible interactions ($p_{ng}$/$p_{0}$ = -0.25)") -axs[0].set_xlabel(r"t ($\mu$s)") +axs[0].set_title(r"Incompressible interactions" + "\n" +r"($p_{ng}$/$p_{0}$ = -0.25)") +axs[0].set_xlabel(r"t ($\mu$s)", fontsize=27.5) axs[0].set_xlim(xmin=0.0, xmax=60.0) -axs[0].set_ylabel(r"$R$ ($\mu$m)") -axs[0].set_ylim(ymin=0.0, ymax=80.0) +axs[0].set_ylabel(r"$R$ ($\mu$m)", fontsize=27.5) +axs[0].set_ylim(ymin=-5.0, ymax=80.0) axs[0].grid() for dist in dist_list : t_list = np.array(dic_2_bubbles["IC"][-25325][dist][0][1]) * 1.0e6 r_list = np.array(dic_2_bubbles["IC"][-25325][dist][0][2]) * 1.0e6 - axs[0].plot(t_list, r_list, color="blue") + axs[0].plot(t_list, r_list, color="blue", linewidth=2.5) t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][1]) * 1.0e6 r_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][2]) * 1.0e6 -axs[0].plot(t_list, r_list, color="blue") +axs[0].plot(t_list, r_list, color="blue", linewidth=2.5) t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][1][1]) * 1.0e6 r_list = np.array(dic_2_bubbles["NI"][-25325][15.0][1][2]) * 1.0e6 -axs[0].plot(t_list, r_list, color="magenta") +axs[0].plot(t_list, r_list, color="magenta", linestyle="dashed", linewidth=2.5) -axs[0].text(0.5, 5.0, r"$R_{1,0}$ = 2.0 $\mu$m", color="blue") -axs[0].text(0.5, 25.0, r"$R_{2,0}$ = 20.0 $\mu$m", color="magenta") +axs[0].text(0.5, 5.0, r"$R_{1,0}$", color="blue") +axs[0].text(0.5, 25.0, r"$R_{2,0}$", color="magenta") -axs[0].text(38.0, 75.0, r"$\infty$", color="blue") -axs[0].text(45.0, 75.0, r"20", color="blue") -axs[0].text(50.0, 75.0, r"15", color="blue") -axs[0].text(55.0, 55.0, r"12.5", color="blue") +axs[0].text(36.5, 73.5, r"$\infty$", color="blue") +axs[0].text(42.5, 73.5, r"20", color="blue") +axs[0].text(54.0, 73.5, r"15", color="blue") +axs[0].text(50.0, 54.0, r"12.5", color="blue") axs[0].text(45.0, 15.0, r"12.1", color="blue") -axs[0].text(35.0, 7.0, r"12", color="blue") -axs[0].text(25.0, 0.5, r"10", color="blue") +axs[0].text(37.0, 6.5, r"12", color="blue") +axs[0].text(25.0, -2.5, r"10", color="blue") dist_list = [10, 11.9, 12, 15, 20] -axs[1].set_title(r"Quasi acoustic interactions ($p_{ng}$/$p_{0}$ = -0.25)") -axs[1].set_xlabel(r"t ($\mu$s)") +axs[1].set_title(r"Quasi acoustic interactions" + "\n" +r"($p_{ng}$/$p_{0}$ = -0.25)") +axs[1].set_xlabel(r"t ($\mu$s)", fontsize=27.5) axs[1].set_xlim(xmin=0.0, xmax=60.0) -axs[1].set_ylabel(r"$R$ ($\mu$m)") -axs[1].set_ylim(ymin=0.0, ymax=80.0) +# axs[1].set_ylabel(r"$R$ ($\mu$m)") +axs[1].set_ylim(ymin=-5.0, ymax=80.0) axs[1].grid() for dist in dist_list : t_list = np.array(dic_2_bubbles["QA"][-25325][dist][0][1]) * 1.0e6 r_list = np.array(dic_2_bubbles["QA"][-25325][dist][0][2]) * 1.0e6 - axs[1].plot(t_list, r_list, color="blue") + axs[1].plot(t_list, r_list, color="blue", linewidth=2.5) t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][1]) * 1.0e6 r_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][2]) * 1.0e6 -axs[1].plot(t_list, r_list, color="blue") +axs[1].plot(t_list, r_list, color="blue", linewidth=2.5) t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][1][1]) * 1.0e6 r_list = np.array(dic_2_bubbles["NI"][-25325][15.0][1][2]) * 1.0e6 -axs[1].plot(t_list, r_list, color="magenta") +axs[1].plot(t_list, r_list, color="magenta", linestyle="dashed", linewidth=2.5) -axs[1].text(0.5, 5.0, r"$R_{1,0}$ = 2.0 $\mu$m", color="blue") -axs[1].text(0.5, 25.0, r"$R_{2,0}$ = 20.0 $\mu$m", color="magenta") +axs[1].text(0.5, 5.0, r"$R_{1,0}$", color="blue") +axs[1].text(0.5, 25.0, r"$R_{2,0}$", color="magenta") -axs[1].text(38.0, 75.0, r"$\infty$", color="blue") -axs[1].text(45.0, 75.0, r"20", color="blue") -axs[1].text(50.0, 75.0, r"15", color="blue") -axs[1].text(51.0, 35.0, r"12", color="blue") +axs[1].text(36.5, 73.5, r"$\infty$", color="blue") +axs[1].text(42.5, 73.5, r"20", color="blue") +axs[1].text(54.0, 73.5, r"15", color="blue") +axs[1].text(51.0, 36.0, r"12", color="blue") axs[1].text(40.0, 10.0, r"11.9", color="blue") -axs[1].text(25.0, 0.5, r"10", color="blue") +axs[1].text(25.0, -2.5, r"10", color="blue") fig.savefig("cavitationonset_varyingdistance.pdf", bbox_inches='tight',pad_inches=0.35) @@ -232,14 +232,14 @@ ncol = 2 fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm))) -plt.subplots_adjust(wspace=0.5*cm, hspace=0.5*cm) +plt.subplots_adjust(wspace=0.35*cm, hspace=0.5*cm) png_list = [-25325, -27351, -27958.8, -29377] -axs[0].set_title(r"Incompressible interactions ($\Delta x_{12}$ = 10[$R_{1,0}$ + $R_{2,0}$])") -axs[0].set_xlabel(r"t ($\mu$s)") +axs[0].set_title(r"Incompressible interactions" + "\n" +r"($\Delta x_{12}$ = 10[$R_{1,0}$ + $R_{2,0}$])") +axs[0].set_xlabel(r"t ($\mu$s)", fontsize=27.5) axs[0].set_xlim(xmin=0.0, xmax=60.0) -axs[0].set_ylabel(r"$R$ ($\mu$m)") +axs[0].set_ylabel(r"$R_{1}$ ($\mu$m)", fontsize=27.5) axs[0].set_ylim(ymin=0.0, ymax=40.0) axs[0].grid() @@ -247,21 +247,21 @@ t_list = np.array(dic_2_bubbles["IC"][png][10.0][0][1]) * 1.0e6 r_list = np.array(dic_2_bubbles["IC"][png][10.0][0][2]) * 1.0e6 - axs[0].plot(t_list, r_list, color="blue") + axs[0].plot(t_list, r_list, color="blue", linewidth=2.5) -axs[0].text(0.5, 3.0, r"$R_{1,0}$ = 2.0 $\mu$m", color="blue") +axs[0].text(0.5, 3.0, r"$R_{1,0}$", color="blue") -axs[0].text(36.0, 37.5, r"-0.29", color="blue") +axs[0].text(32.0, 37.5, r"-0.29", color="blue") axs[0].text(45.0, 25.5, r"-0.276", color="blue") axs[0].text(30.0, 8.0, r"-0.27", color="blue") -axs[0].text(25.0, 1.0, r"-0.25", color="blue") +axs[0].text(23.0, 0.5, r"-0.25", color="blue") png_list = [-25325, -27351, -27958.8, -27654.9, -29377] -axs[1].set_title(r"Quasi acoustic interactions ($\Delta x_{12}$ = 10[$R_{1,0}$ + $R_{2,0}$])") -axs[1].set_xlabel(r"t ($\mu$s)") +axs[1].set_title(r"Quasi acoustic interactions" + "\n" +r"($\Delta x_{12}$ = 10[$R_{1,0}$ + $R_{2,0}$])") +axs[1].set_xlabel(r"t ($\mu$s)", fontsize=27.5) axs[1].set_xlim(xmin=0.0, xmax=60.0) -axs[1].set_ylabel(r"$R$ ($\mu$m)") +# axs[1].set_ylabel(r"$R$ ($\mu$m)") axs[1].set_ylim(ymin=0.0, ymax=40.0) axs[1].grid() @@ -269,15 +269,15 @@ t_list = np.array(dic_2_bubbles["QA"][png][10.0][0][1]) * 1.0e6 r_list = np.array(dic_2_bubbles["QA"][png][10.0][0][2]) * 1.0e6 - axs[1].plot(t_list, r_list, color="blue") + axs[1].plot(t_list, r_list, color="blue", linewidth=2.5) -axs[1].text(0.5, 3.0, r"$R_{1,0}$ = 2.0 $\mu$m", color="blue") +axs[1].text(0.5, 3.0, r"$R_{1,0}$", color="blue") -axs[1].text(34.5, 37.5, r"-0.29", color="blue") +axs[1].text(30.5, 37.5, r"-0.29", color="blue") axs[1].text(48.5, 37.5, r"-0.276", color="blue") -axs[1].text(54.0, 31.0, r"-0.273", color="blue") +axs[1].text(50.0, 28.0, r"-0.273", color="blue") axs[1].text(36.5, 8.0, r"-0.27", color="blue") -axs[1].text(25.0, 1.0, r"-0.25", color="blue") +axs[1].text(25.0, 0.5, r"-0.25", color="blue") fig.savefig("cavitationonset_varyingpressure.pdf", bbox_inches='tight',pad_inches=0.35) @@ -287,25 +287,27 @@ ncol = 2 fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm)), sharex=True) -plt.subplots_adjust(wspace=0.25*cm, hspace=0.25*cm) +plt.subplots_adjust(wspace=0.35*cm, hspace=0.25*cm) dic_color = {1 : "black", 2 : "red", 3 : "magenta", 4 : "blue", 8 : "green"} nbubble_list = [1, 2, 3, 4, 8] dic_shape = {1 : "single bubble", 2 : "Line of 2 bubbles", 3 : "3 bubbles-regular triangle", 4 : "4 bubbles-regular tetragon", 8 : "8 bubbles-regular hexaedron"} +dic_linestyle = {1 : "solid", 2 : "dashed", 3 : "-.", 4 : "dotted", 8 : "dashdot"} +dic_marker = {1 : "*", 2 : "s", 3 : "X", 4 : "^", 8 : "D"} for i in range(2) : for j in range(2) : axs[i, j].grid() axs[i, j].set_xlim(xmin=10.0, xmax=60.0) -axs[0, 0].set_title(r"Incompressible interactions ($p_{ng}$/$p_{0}$ = -0.25, $\Delta x_{12}$ = 20$R_{1,0}$)") -axs[0, 1].set_title(r"Quasi acoustic interactions ($p_{ng}$/$p_{0}$ = -0.25, $\Delta x_{12}$ = 20$R_{1,0}$)") +axs[0, 0].set_title(r"Incompressible interactions" + "\n" +r"($p_{ng}$/$p_{0}$ = -0.25, $\Delta x_{12}$ = 20$R_{1,0}$)") +axs[0, 1].set_title(r"Quasi acoustic interactions" + "\n" +r"($p_{ng}$/$p_{0}$ = -0.25, $\Delta x_{12}$ = 20$R_{1,0}$)") -axs[1, 0].set_xlabel(r"t ($\mu$s)") -axs[1, 1].set_xlabel(r"t ($\mu$s)") +axs[1, 0].set_xlabel(r"t ($\mu$s)", fontsize=27.5) +axs[1, 1].set_xlabel(r"t ($\mu$s)", fontsize=27.5) -axs[0, 0].set_ylabel(r"$R_{1}$ ($\mu$m)") -axs[1, 0].set_ylabel(r"$P_{1, \infty}$/$P_{0}$ (-)") +axs[0, 0].set_ylabel(r"$R_{1}$ ($\mu$m)", fontsize=27.5) +axs[1, 0].set_ylabel(r"$P_{1, \infty}$/$P_{0}$ (-)", fontsize=27.5) axs[1, 0].set_ylim(ymin=-0.255, ymax=0.0) axs[1, 1].set_ylim(ymin=-0.255, ymax=0.0) @@ -314,16 +316,16 @@ r_list = np.array(dic_n_bubbles["IC"][nbubble][0][2]) * 1.0e6 p_list = np.array(dic_n_bubbles["IC"][nbubble][0][3]) / P0 - axs[0, 0].plot(t_list, r_list, color=dic_color[nbubble], label=dic_shape[nbubble]) - axs[1, 0].plot(t_list, p_list, color=dic_color[nbubble]) + axs[0, 0].plot(t_list, r_list, color=dic_color[nbubble], label=dic_shape[nbubble], marker=dic_marker[nbubble], markevery=600, markersize=10.0, linewidth=2.5) + axs[1, 0].plot(t_list, p_list, color=dic_color[nbubble], marker=dic_marker[nbubble], markevery=600, markersize=10.0, linewidth=2.5) t_list = np.array(dic_n_bubbles["QA"][nbubble][0][1]) * 1.0e6 r_list = np.array(dic_n_bubbles["QA"][nbubble][0][2]) * 1.0e6 p_list = np.array(dic_n_bubbles["QA"][nbubble][0][3]) / P0 - axs[0, 1].plot(t_list, r_list, color=dic_color[nbubble]) - axs[1, 1].plot(t_list, p_list, color=dic_color[nbubble]) + axs[0, 1].plot(t_list, r_list, color=dic_color[nbubble], marker=dic_marker[nbubble], markevery=600, markersize=10.0, linewidth=2.5) + axs[1, 1].plot(t_list, p_list, color=dic_color[nbubble], marker=dic_marker[nbubble], markevery=600, markersize=12.5, linewidth=2.5) -axs[0, 0].legend(loc="upper left") +axs[0, 0].legend(bbox_to_anchor=(1.1, 1.175), loc="lower center", ncol=2, frameon=False) fig.savefig("cavitationonset_monodispersedclusters.pdf", bbox_inches='tight',pad_inches=0.35) \ No newline at end of file From 2982388c35ac6965e7efb9ad674d287c77e1d5ec Mon Sep 17 00:00:00 2001 From: Pierre C Date: Wed, 31 Jul 2024 14:39:19 -0400 Subject: [PATCH 068/138] better plots for bubbly screens and cavitation onset test cases --- examples/bubblyscreen/plot_results.py | 14 ++++----- examples/cavitationonset/plot_results.py | 36 ++++++++++++------------ 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/examples/bubblyscreen/plot_results.py b/examples/bubblyscreen/plot_results.py index 011042e..8a0a18f 100644 --- a/examples/bubblyscreen/plot_results.py +++ b/examples/bubblyscreen/plot_results.py @@ -4,7 +4,7 @@ from math import pi from matplotlib.patches import Circle -fontsize = 16.5 +fontsize = 20.5 plt.rcParams['font.family']='serif' plt.rcParams['font.serif']=['Times New Roman'] + plt.rcParams['font.serif'] @@ -82,11 +82,11 @@ def plot_oscillation_distribution(fig, axs, row, col, nbubbles_x, inttype, rati axs[row, col].set_title(r"$\omega/\omega_{0}$ = " + "{:.1f}".format(ratio_w)) axs[row, col].set_aspect("equal") - clb = fig.colorbar(cset, ax=axs[row, col], shrink=0.7) + clb = fig.colorbar(cset, ax=axs[row, col], pad=0.025, shrink=0.665) if order > 0 : - clb.ax.set_title(r"$|r'| \times 10^{-order}$".replace("order", str(order))) + clb.ax.set_title(r"$|r'| \times 10^{-order}$".replace("order", str(order)), fontsize=fontsize+1.0) else : - clb.ax.set_title(r"$|r'|$") + clb.ax.set_title(r"$|r'|$", fontsize=fontsize+1.0) colors = cset.cmap(cset.norm(cset.get_array())) for i in range(nbubbles_x) : for j in range(nbubbles_x) : @@ -113,18 +113,18 @@ def plot_oscillation_distribution(fig, axs, row, col, nbubbles_x, inttype, rati axs[i,j].set_aspect("equal") ### First row : QA ### -plt.figtext(0.5, 0.875, r"QA, $D/R_{0}$ = 400", fontsize=20.0, horizontalalignment="center") +plt.figtext(0.5, 0.875, r"QA, $D/R_{0}$ = 400", fontsize=25.0, horizontalalignment="center") plot_oscillation_distribution(fig, axs, 0, 0, 51, "QA", 0.5, 400, order=4) plot_oscillation_distribution(fig, axs, 0, 1, 51, "QA", 0.9, 400, order=3) plot_oscillation_distribution(fig, axs, 0, 2, 51, "QA", 1.0, 400, order=2) plot_oscillation_distribution(fig, axs, 0, 3, 51, "QA", 1.5, 400, order=4) ### Second row : IC ### -plt.figtext(0.5, 0.5, r"IC, $D/R_{0}$ = 400", fontsize=20.0, horizontalalignment="center") +plt.figtext(0.5, 0.475, r"IC, $D/R_{0}$ = 400", fontsize=25.0, horizontalalignment="center") plot_oscillation_distribution(fig, axs, 1, 0, 51, "IC", 0.5, 400, order=4) plot_oscillation_distribution(fig, axs, 1, 1, 51, "IC", 0.9, 400, order=3) plot_oscillation_distribution(fig, axs, 1, 2, 51, "IC", 1.0, 400, order=3) plot_oscillation_distribution(fig, axs, 1, 3, 51, "IC", 1.5, 400, order=4, clear=True) -fig.subplots_adjust(hspace=0.01*cm, wspace=0.60*cm) +fig.subplots_adjust(hspace=0.01*cm, wspace=0.95*cm) fig.savefig("bubblyscreen_ComparisonQAIC.pdf", bbox_inches="tight",pad_inches=0.035) \ No newline at end of file diff --git a/examples/cavitationonset/plot_results.py b/examples/cavitationonset/plot_results.py index 30abe54..de91906 100644 --- a/examples/cavitationonset/plot_results.py +++ b/examples/cavitationonset/plot_results.py @@ -92,9 +92,9 @@ plt.subplots_adjust(wspace=0.5*cm, hspace=0.5*cm) axs[0].set_title("Pressure time history (" + r"$T$ = " + "{:.1f} ".format(T*1.0e06) + r"$\mu$s)") -axs[0].set_xlabel(r"t ($\mu$s)", fontsize=27.5) +axs[0].set_xlabel(r"t [$\mu$s]", fontsize=27.5) axs[0].set_xlim(xmin=0.0, xmax=60.0) -axs[0].set_ylabel(r"$p_{\infty}$/$p_{0}$ (-)", fontsize=27.5) +axs[0].set_ylabel(r"$p_{\infty}$/$p_{0}$ [-]", fontsize=27.5) axs[0].grid() t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][1]) * 1.0e6 @@ -102,9 +102,9 @@ axs[0].plot(t_list, p_list, color="black", linewidth=2.5) axs[1].set_title("Evolution of radius without interaction") -axs[1].set_xlabel(r"t ($\mu$s)", fontsize=27.5) +axs[1].set_xlabel(r"t [$\mu$s]", fontsize=27.5) axs[1].set_xlim(xmin=0.0, xmax=60.0) -axs[1].set_ylabel(r"$R$ ($\mu$m)", fontsize=27.5) +axs[1].set_ylabel(r"$R$ [$\mu$m]", fontsize=27.5) axs[1].grid() t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][1]) * 1.0e6 @@ -130,9 +130,9 @@ png_list = [-17221, -17725.5, -18353.2, -18770.3] ax.set_title("Cavitation inception of a single bubble \n depending on " + r"$p_{ng}$/$p_{0}$ ($R_{0}$ = 2 $\mu$m)") -ax.set_xlabel(r"t ($\mu$s)", fontsize=27.5) +ax.set_xlabel(r"t [$\mu$s]", fontsize=27.5) ax.set_xlim(xmin=10.0, xmax=60.0) -ax.set_ylabel(r"$R$ ($\mu$m)", fontsize=27.5) +ax.set_ylabel(r"$R$ [$\mu$m]", fontsize=27.5) ax.set_ylim(ymin=0.0, ymax=14.0) ax.grid() @@ -160,9 +160,9 @@ dist_list = [10, 12, 12.1, 12.5, 15, 20] axs[0].set_title(r"Incompressible interactions" + "\n" +r"($p_{ng}$/$p_{0}$ = -0.25)") -axs[0].set_xlabel(r"t ($\mu$s)", fontsize=27.5) +axs[0].set_xlabel(r"t [$\mu$s]", fontsize=27.5) axs[0].set_xlim(xmin=0.0, xmax=60.0) -axs[0].set_ylabel(r"$R$ ($\mu$m)", fontsize=27.5) +axs[0].set_ylabel(r"$R$ [$\mu$m]", fontsize=27.5) axs[0].set_ylim(ymin=-5.0, ymax=80.0) axs[0].grid() @@ -194,9 +194,9 @@ dist_list = [10, 11.9, 12, 15, 20] axs[1].set_title(r"Quasi acoustic interactions" + "\n" +r"($p_{ng}$/$p_{0}$ = -0.25)") -axs[1].set_xlabel(r"t ($\mu$s)", fontsize=27.5) +axs[1].set_xlabel(r"t [$\mu$s]", fontsize=27.5) axs[1].set_xlim(xmin=0.0, xmax=60.0) -# axs[1].set_ylabel(r"$R$ ($\mu$m)") +# axs[1].set_ylabel(r"$R$ [$\mu$m]") axs[1].set_ylim(ymin=-5.0, ymax=80.0) axs[1].grid() @@ -237,9 +237,9 @@ png_list = [-25325, -27351, -27958.8, -29377] axs[0].set_title(r"Incompressible interactions" + "\n" +r"($\Delta x_{12}$ = 10[$R_{1,0}$ + $R_{2,0}$])") -axs[0].set_xlabel(r"t ($\mu$s)", fontsize=27.5) +axs[0].set_xlabel(r"t [$\mu$s]", fontsize=27.5) axs[0].set_xlim(xmin=0.0, xmax=60.0) -axs[0].set_ylabel(r"$R_{1}$ ($\mu$m)", fontsize=27.5) +axs[0].set_ylabel(r"$R_{1}$ [$\mu$m]", fontsize=27.5) axs[0].set_ylim(ymin=0.0, ymax=40.0) axs[0].grid() @@ -259,9 +259,9 @@ png_list = [-25325, -27351, -27958.8, -27654.9, -29377] axs[1].set_title(r"Quasi acoustic interactions" + "\n" +r"($\Delta x_{12}$ = 10[$R_{1,0}$ + $R_{2,0}$])") -axs[1].set_xlabel(r"t ($\mu$s)", fontsize=27.5) +axs[1].set_xlabel(r"t [$\mu$s]", fontsize=27.5) axs[1].set_xlim(xmin=0.0, xmax=60.0) -# axs[1].set_ylabel(r"$R$ ($\mu$m)") +# axs[1].set_ylabel(r"$R$ [$\mu$m]") axs[1].set_ylim(ymin=0.0, ymax=40.0) axs[1].grid() @@ -303,11 +303,11 @@ axs[0, 0].set_title(r"Incompressible interactions" + "\n" +r"($p_{ng}$/$p_{0}$ = -0.25, $\Delta x_{12}$ = 20$R_{1,0}$)") axs[0, 1].set_title(r"Quasi acoustic interactions" + "\n" +r"($p_{ng}$/$p_{0}$ = -0.25, $\Delta x_{12}$ = 20$R_{1,0}$)") -axs[1, 0].set_xlabel(r"t ($\mu$s)", fontsize=27.5) -axs[1, 1].set_xlabel(r"t ($\mu$s)", fontsize=27.5) +axs[1, 0].set_xlabel(r"t [$\mu$s]", fontsize=27.5) +axs[1, 1].set_xlabel(r"t [$\mu$s]", fontsize=27.5) -axs[0, 0].set_ylabel(r"$R_{1}$ ($\mu$m)", fontsize=27.5) -axs[1, 0].set_ylabel(r"$P_{1, \infty}$/$P_{0}$ (-)", fontsize=27.5) +axs[0, 0].set_ylabel(r"$R_{1}$ [$\mu$m]", fontsize=27.5) +axs[1, 0].set_ylabel(r"$P_{1, \infty}$/$P_{0}$ [-]", fontsize=27.5) axs[1, 0].set_ylim(ymin=-0.255, ymax=0.0) axs[1, 1].set_ylim(ymin=-0.255, ymax=0.0) From 52e07cc6fa953eb7958ee95cb928aa2b97dc43d5 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Wed, 31 Jul 2024 17:29:01 -0400 Subject: [PATCH 069/138] spherical cluster tension wave ; adding clearer plots for pressure evolution --- .../plot_results.py | 204 +++++++++++++++++- 1 file changed, 201 insertions(+), 3 deletions(-) diff --git a/examples/sphericalclustertensionwave/plot_results.py b/examples/sphericalclustertensionwave/plot_results.py index 28e38dc..bda8d85 100644 --- a/examples/sphericalclustertensionwave/plot_results.py +++ b/examples/sphericalclustertensionwave/plot_results.py @@ -635,12 +635,12 @@ zm.plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) # Quasi acoustic interactions -axs[2].set_xlim(xmin=-10.0,xmax=1000.0) +axs[2].set_xlim(xmin=-10.0,xmax=800.0) axs[2].set_ylim(ymin=0.925,ymax=1.25) zm = axs[2].inset_axes([0.25, 0.5, 0.7, 0.45]) zm.grid() -zm.set_xlim(xmax=250.0) +zm.set_xlim(xmax=200.0) zm.tick_params(axis="both", labelsize=25) for q in list(dic_polydisperse["QA"][count][p1].keys())[1:] : @@ -830,6 +830,106 @@ axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=3, frameon=False) fig.savefig("sphericalclustertensionwave_mono_pressureevolution.pdf", bbox_inches='tight',pad_inches=0.35) +######### Averaged pressure infinity versus time evolution for monodispersed clusters (article) ### + +count = 250 +p1 = -3.0e4 +p0 = 1.0e5 +t_i = r_ref * sqrt(rho_l / (p0 - p1)) + +nrow = 1 +ncol = 3 +fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) +for i in range(ncol) : + axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=27.5) + if i == 0 : axs[i].set_ylabel(r"$ / p_{0}$ [-]", fontsize=27.5) + axs[i].set_xlim(xmin=0.0, xmax=80.0) + axs[i].tick_params(axis="both", labelsize=25) + axs[i].grid() + +plt.subplots_adjust(wspace=0.35*cm) + +axs[0].set_title(r"No interaction", fontsize=27.5) +axs[1].set_title(r"Incompressible interactions", fontsize=27.5) +axs[2].set_title(r"Quasi acoustic interactions", fontsize=27.5) + +dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} +dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} + +zm_IC = axs[1].inset_axes([0.35, 0.35, 0.60, 0.60]) +zm_IC.grid() +zm_IC.set_xlim(xmin=0.0,xmax=20.0) +zm_IC.set_ylim(ymin=-0.5,ymax=2.0) +zm_IC.set_yticks([-0.267, 0.0, 1.0, 2.0]) +zm_IC.set_yticklabels([r"$p_{\mathrm{C}}$", 0, 1, 2]) +zm_IC.tick_params(axis="both", labelsize=25) + +zm_QA = axs[2].inset_axes([0.30, 0.4, 0.65, 0.55]) +zm_QA.grid() +zm_QA.set_xlim(xmin=0.0,xmax=20.0) +zm_QA.set_ylim(ymin=-0.5,ymax=2.0) +zm_QA.set_yticks([-0.267, 0.0, 1.0, 2.0]) +zm_QA.set_yticklabels([r"$p_{\mathrm{C}}$", 0, 1, 2]) +zm_QA.tick_params(axis="both", labelsize=25) + +for k in dic_loc_distrib_global[count][p1].keys() : + index_list = dic_loc_distrib_global[count][p1][k] + + # No interaction + t_list = (1/t_i) * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) + + p_list_0 = np.array(dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][2]) + avg_pressure = p_list_0 / p0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + p_list = np.array(dic_bubbles["NI"]["mono"][count][p1][index + 1][2]) + avg_pressure = avg_pressure + np.array(p_list) / p0 + + avg_pressure = (1 / len(index_list)) * avg_pressure + + axs[0].plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) + + # Incompressible interactions + t_list = (1/t_i) * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) + + p_list_0 = np.array(dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][2]) + avg_pressure = p_list_0 / p0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + p_list = np.array(dic_bubbles["IC"]["mono"][count][p1][index + 1][2]) + avg_pressure = avg_pressure + np.array(p_list) / p0 + + avg_pressure = (1 / len(index_list)) * avg_pressure + + axs[1].plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) + + zm_IC.plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) + + # Quasi acoustic interactions + t_list = (1/t_i) * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) + + p_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][2]) + avg_pressure = p_list_0 / p0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + p_list = np.array(dic_bubbles["QA"]["mono"][count][p1][index + 1][2]) + avg_pressure = avg_pressure + np.array(p_list) / p0 + + avg_pressure = (1 / len(index_list)) * avg_pressure + + axs[2].plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) + + zm_QA.plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) + +axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=26.5, ncol=3, frameon=False) +fig.savefig("sphericalclustertensionwave_mono_pressureevolution_article.pdf", bbox_inches='tight',pad_inches=0.35) + ######### Averaged pressure infinity versus time evolution for polydispersed clusters ############# count = 250 @@ -923,4 +1023,102 @@ axs[2].plot(t_list, avg_pressure, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=n_quantiles, frameon=False) -fig.savefig("sphericalclustertensionwave_poly_pressureevolution.pdf", bbox_inches='tight',pad_inches=0.35) \ No newline at end of file +fig.savefig("sphericalclustertensionwave_poly_pressureevolution.pdf", bbox_inches='tight',pad_inches=0.35) + +######### Averaged pressure infinity versus time evolution for polydispersed clusters (article) ### + +count = 250 +p1 = -3.0e4 +p0 = 1.0e5 +t_i = r_ref * sqrt(rho_l / (p0 - p1)) + +nrow = 1 +ncol = 3 +fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) +for i in range(ncol) : + axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=27.5) + if i == 0 : axs[i].set_ylabel(r"$/p_{0}$ [-]", fontsize=27.5) + # axs[i].set_xlim(xmin=10.0, xmax=60.0) + axs[i].tick_params(axis="both", labelsize=25) + axs[i].grid() + +plt.subplots_adjust(wspace=0.35*cm) + +axs[0].set_title(r"No interaction", fontsize=27.5) +axs[1].set_title(r"Incompressible interactions", fontsize=27.5) +axs[2].set_title(r"Quasi acoustic interactions", fontsize=27.5) + +color_list = ["black", "magenta", "blue", "green", "red"] +dic_color_q = {} +dic_label_q = {} +for i in range(n_quantiles) : + quantile = quantiles_list[i] + dic_color_q[quantile] = color_list[i] + + dic_label_q[quantile] = "{}th-{}".format(i+1, quantile_name) + if i == 0 : + dic_label_q[quantile] = "1st-{}".format(quantile_name) + elif i == 1 : + dic_label_q[quantile] = "2nd-{}".format(quantile_name) + elif i == 2 : + dic_label_q[quantile] = "3rd-{}".format(quantile_name) + +# No interaction +for q in list(dic_polydisperse["NI"][count][p1].keys())[1:] : + index_list = dic_polydisperse["NI"][count][p1][q] + + t_list = (1/t_i) * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) + + p_list_0 = np.array(dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][2]) + avg_pressure = p_list_0 / p0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + p_list = np.array(dic_bubbles["NI"]["poly"][count][p1][index + 1][2]) + avg_pressure = avg_pressure + np.array(p_list) / p0 + + avg_pressure = (1 / len(index_list)) * avg_pressure + + axs[0].plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) + +# Incompressible interactions +for q in list(dic_polydisperse["IC"][count][p1].keys())[1:] : + index_list = dic_polydisperse["IC"][count][p1][q] + + t_list = (1/t_i) * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) + + p_list_0 = np.array(dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][2]) + avg_pressure = p_list_0 / p0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + p_list = np.array(dic_bubbles["IC"]["poly"][count][p1][index + 1][2]) + avg_pressure = avg_pressure + np.array(p_list) / p0 + + avg_pressure = (1 / len(index_list)) * avg_pressure + + axs[1].plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q], label=dic_label_q[q]) + +# Quasi acoustic interactions +for q in list(dic_polydisperse["QA"][count][p1].keys())[1:] : + index_list = dic_polydisperse["QA"][count][p1][q] + + t_list = (1/t_i) * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) + + p_list_0 = np.array(dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][2]) + avg_pressure = p_list_0 / p0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + p_list = np.array(dic_bubbles["QA"]["poly"][count][p1][index + 1][2]) + avg_pressure = avg_pressure + np.array(p_list) / p0 + + avg_pressure = (1 / len(index_list)) * avg_pressure + + axs[2].plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) + +axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=26.5, ncol=n_quantiles, frameon=False) +fig.savefig("sphericalclustertensionwave_poly_pressureevolution_article.pdf", bbox_inches='tight',pad_inches=0.35) \ No newline at end of file From deedf90fb7b1f8a44f60d2196fa9ca8dc958fcf3 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Wed, 31 Jul 2024 17:29:25 -0400 Subject: [PATCH 070/138] spherical cluster interactions ; better displayed results --- .../plot_results.py | 48 ++++++++++++------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/examples/sphericalclusterinteractions/plot_results.py b/examples/sphericalclusterinteractions/plot_results.py index 3ce41f6..a1cf40d 100644 --- a/examples/sphericalclusterinteractions/plot_results.py +++ b/examples/sphericalclusterinteractions/plot_results.py @@ -8,7 +8,7 @@ plt.rcParams['font.family']='serif' plt.rcParams['font.serif']=['Times New Roman'] + plt.rcParams['font.serif'] plt.rcParams['mathtext.fontset']='stix' -plt.rcParams['font.size']=10 +plt.rcParams['font.size']=25 color_names = list(mcolors.XKCD_COLORS) @@ -49,6 +49,8 @@ file_loc.close() +print("Data retrieved\n") + ######### Step 1 : Functions ######################################################################################################################## ### signal sampling (for signal with non uniform timestep) ######################################## @@ -274,6 +276,7 @@ def savefig(fig, filename="Cluster", format="pdf", path=None) : interval_size = 0.20e-03 cluster_radius = 2.5e-03 +interval_size = cluster_radius / 10 fa = 50e03 max_radius_to_center = 0.0 @@ -290,14 +293,18 @@ def savefig(fig, filename="Cluster", format="pdf", path=None) : if radius_to_center > max_radius_to_center : max_radius_to_center = radius_to_center +print("Repartition of bubbles done\n") + dic_color_key = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} dic_style_key = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} +dic_label_key = {1.0 : "{:.1f}".format(1.0 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f}".format(1.0), + 0.5 : "{:.1f}".format(0.5 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f} (average)".format(0.5 + interval_size/cluster_radius), + 0.0 : "{:.1f}".format(0.0) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f} (average)".format(interval_size/cluster_radius)} -fig = plt.figure(figsize=(20*cm, 15*cm)) +fig = plt.figure(figsize=(20*cm, 12.5*cm)) ax = fig.add_subplot(1, 1, 1) -ax.set_xlabel(r"$t^{*}$", fontsize=15) -ax.set_ylabel(r"$/R_{0}$", fontsize=15) -ax.set_title("Spherical cluster with " + r"$N=$" + "{} bubbles".format(count), fontsize=15) +ax.set_xlabel(r"$t^{*}$", fontsize=27.5) +ax.set_ylabel(r"$R/R_{0}$", fontsize=27.5) ax.grid() dic_radius_evolution = {1.0 : [], 0.5 : [], 0.0 : []} @@ -305,6 +312,7 @@ def savefig(fig, filename="Cluster", format="pdf", path=None) : for k in list(dic_radii.keys()) : index_list = dic_radii[k] for i in range(len(index_list)) : + print("{}, {}".format(k, i)) index = index_list[i] t_uni, r_uni = _sample(Bubbles[index][:, 1], Bubbles[index][:, 3], 8, False) if i == 0 : @@ -315,6 +323,8 @@ def savefig(fig, filename="Cluster", format="pdf", path=None) : dic_radius_evolution[k].append(np.array(t_uni)) dic_radius_evolution[k].append(avg_radii / len(index_list)) +print("Sampling and averaging completed") + label_edge_front = 0 label_edge_back = 0 @@ -329,23 +339,27 @@ def savefig(fig, filename="Cluster", format="pdf", path=None) : # index_list = dic_radii[k] # if len(index_list) > 1 : # for i in index_list[1:] : -# ax.plot(Bubbles[i][:, 1]*fa, Bubbles[i][:, 3]/Bubbles[i][:, 3][0], linestyle=dic_style_key[k], color=dic_color_key[k], linewidth=1.5) -# ax.plot(Bubbles[index_list[0]][:, 1]*fa, Bubbles[index_list[0]][:, 3]/Bubbles[i][:, 3][0], linestyle=dic_style_key[k], color=dic_color_key[k], linewidth=1.5, label=r"$r/R_{c} \approx$"+"{:.1f}".format(k)) +# ax.plot(Bubbles[i][:, 1]*fa, Bubbles[i][:, 3]/Bubbles[i][:, 3][0], linestyle=dic_style_key[k], color=dic_color_key[k], linewidth=3.0) +# ax.plot(Bubbles[index_list[0]][:, 1]*fa, Bubbles[index_list[0]][:, 3]/Bubbles[i][:, 3][0], linestyle=dic_style_key[k], color=dic_color_key[k], linewidth=3.0, label=r"$r/R_{c} \approx$"+"{:.1f}".format(k)) # else : # for i in index_list : -# ax.plot(Bubbles[i][:, 1]*fa, Bubbles[i][:, 3]/Bubbles[i][:, 3][0], linestyle=dic_style_key[k], color=dic_color_key[k], linewidth=1.5, label=r"$r/R_{c} \approx$"+"{:.1f}".format(k)) +# ax.plot(Bubbles[i][:, 1]*fa, Bubbles[i][:, 3]/Bubbles[i][:, 3][0], linestyle=dic_style_key[k], color=dic_color_key[k], linewidth=3.0, label=r"$r/R_{c} \approx$"+"{:.1f}".format(k)) -ax.plot(Bubbles[label_edge_front][:, 1]*fa, Bubbles[label_edge_front][:, 3]/Bubbles[label_edge_front][:, 3][0], linestyle="solid", color="black", linewidth=1.5, label=r"$r/R_{c} \approx 1.0$ (front)") -ax.plot(Bubbles[label_edge_back][:, 1]*fa, Bubbles[label_edge_back][:, 3]/Bubbles[label_edge_back][:, 3][0], linestyle="solid", color="grey", linewidth=1.5, label=r"$r/R_{c} \approx 1.0$ (back)") +ax.plot(Bubbles[label_edge_front][:, 1]*fa, Bubbles[label_edge_front][:, 3]/Bubbles[label_edge_front][:, 3][0], linestyle="solid", color="black", + marker="*", markersize=7.5, markevery=2500, linewidth=3.0, label="{:.1f}".format(1.0 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f} (one bubble, front)".format(1.0)) +ax.plot(Bubbles[label_edge_back][:, 1]*fa, Bubbles[label_edge_back][:, 3]/Bubbles[label_edge_back][:, 3][0], linestyle="solid", color="grey", + marker="D", markersize=7.5, markevery=2500, linewidth=3.0, label="{:.1f}".format(1.0 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f} (one bubble, back)".format(1.0)) for k in list(dic_radius_evolution.keys())[1:] : - ax.plot(dic_radius_evolution[k][0]*fa, dic_radius_evolution[k][1]/dic_radius_evolution[k][1][0], linestyle=dic_style_key[k], color=dic_color_key[k], linewidth=1.5, label=r"$r/R_{c} \approx$"+"{:.1f}".format(k)) + ax.plot(dic_radius_evolution[k][0]*fa, dic_radius_evolution[k][1]/dic_radius_evolution[k][1][0], linestyle=dic_style_key[k], color=dic_color_key[k], linewidth=3.0, label=dic_label_key[k]) -ax.legend(loc="upper left", fontsize=15) +ax.legend(bbox_to_anchor=(1.005, 0.75),loc="upper left", ncol=1, fontsize=26.5, frameon=False) savefig(fig, filename="sphericalclusterinteractions_radiievolution") +print("Radius evolution plotted") + ## Cluster evolution vizualisation ################################################################################################################## -plt.rcParams['font.size']=15 +plt.rcParams['font.size']=27.5 fig = plt.figure(figsize=(4*15*cm,15*cm)) plt.subplots_adjust(wspace=0, hspace=0) @@ -359,7 +373,7 @@ def savefig(fig, filename="Cluster", format="pdf", path=None) : ax.set_axis_off() ax.set_title(r"$t^{*}$ = " + "{:.2f}".format(t_star)) -t_star = 0.75 +t_star = 0.5 ax = fig.add_subplot(1, 4, 2, projection='3d') plot_cluster(ax, Bubbles, Bubbles_loc, t=t_star/fa, figtitle="", grid="False", radius_vis="False") ax.view_init(elev=90, azim=-90) @@ -377,7 +391,7 @@ def savefig(fig, filename="Cluster", format="pdf", path=None) : ax.set_axis_off() ax.set_title(r"$t^{*}$ = " + "{:.2f}".format(t_star)) -t_star = 1.25 +t_star = 1.5 ax = fig.add_subplot(1, 4, 4, projection='3d') plot_cluster(ax, Bubbles, Bubbles_loc, t=t_star/fa, figtitle="", grid="False", radius_vis="False") ax.view_init(elev=90, azim=-90) @@ -387,4 +401,6 @@ def savefig(fig, filename="Cluster", format="pdf", path=None) : ax.set_title(r"$t^{*}$ = " + "{:.2f}".format(t_star)) # plot_cluster(fig, Bubbles, Bubbles_loc) -savefig(fig, filename="sphericalclusterinteractions_clusterevolution", format="png") \ No newline at end of file +savefig(fig, filename="sphericalclusterinteractions_clusterevolution", format="png") + +print("Cluster temporal evolution plotted\n") \ No newline at end of file From f45e8f93902fa0f4eab6288a06d8d6f78cd292d7 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Thu, 1 Aug 2024 11:48:02 -0400 Subject: [PATCH 071/138] spherical cluster interactions ; small additional changes for better plots --- .../plot_results.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/examples/sphericalclusterinteractions/plot_results.py b/examples/sphericalclusterinteractions/plot_results.py index a1cf40d..32cd794 100644 --- a/examples/sphericalclusterinteractions/plot_results.py +++ b/examples/sphericalclusterinteractions/plot_results.py @@ -301,9 +301,10 @@ def savefig(fig, filename="Cluster", format="pdf", path=None) : 0.5 : "{:.1f}".format(0.5 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f} (average)".format(0.5 + interval_size/cluster_radius), 0.0 : "{:.1f}".format(0.0) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f} (average)".format(interval_size/cluster_radius)} -fig = plt.figure(figsize=(20*cm, 12.5*cm)) +fig = plt.figure(figsize=(37*cm, 17.5*cm)) ax = fig.add_subplot(1, 1, 1) ax.set_xlabel(r"$t^{*}$", fontsize=27.5) +ax.set_xlim(xmin=0.0, xmax=1.5) ax.set_ylabel(r"$R/R_{0}$", fontsize=27.5) ax.grid() @@ -346,14 +347,14 @@ def savefig(fig, filename="Cluster", format="pdf", path=None) : # ax.plot(Bubbles[i][:, 1]*fa, Bubbles[i][:, 3]/Bubbles[i][:, 3][0], linestyle=dic_style_key[k], color=dic_color_key[k], linewidth=3.0, label=r"$r/R_{c} \approx$"+"{:.1f}".format(k)) ax.plot(Bubbles[label_edge_front][:, 1]*fa, Bubbles[label_edge_front][:, 3]/Bubbles[label_edge_front][:, 3][0], linestyle="solid", color="black", - marker="*", markersize=7.5, markevery=2500, linewidth=3.0, label="{:.1f}".format(1.0 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f} (one bubble, front)".format(1.0)) + marker="*", markersize=11.5, markevery=2500, linewidth=3.0, label="{:.1f}".format(1.0 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f} (one bubble, front)".format(1.0)) ax.plot(Bubbles[label_edge_back][:, 1]*fa, Bubbles[label_edge_back][:, 3]/Bubbles[label_edge_back][:, 3][0], linestyle="solid", color="grey", - marker="D", markersize=7.5, markevery=2500, linewidth=3.0, label="{:.1f}".format(1.0 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f} (one bubble, back)".format(1.0)) + marker="D", markersize=11.5, markevery=2500, linewidth=3.0, label="{:.1f}".format(1.0 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f} (one bubble, back)".format(1.0)) for k in list(dic_radius_evolution.keys())[1:] : ax.plot(dic_radius_evolution[k][0]*fa, dic_radius_evolution[k][1]/dic_radius_evolution[k][1][0], linestyle=dic_style_key[k], color=dic_color_key[k], linewidth=3.0, label=dic_label_key[k]) -ax.legend(bbox_to_anchor=(1.005, 0.75),loc="upper left", ncol=1, fontsize=26.5, frameon=False) +ax.legend(bbox_to_anchor=(0.5, 1.175),loc="center", ncol=2, fontsize=26.5, frameon=False) savefig(fig, filename="sphericalclusterinteractions_radiievolution") print("Radius evolution plotted") @@ -371,7 +372,7 @@ def savefig(fig, filename="Cluster", format="pdf", path=None) : ax.set_aspect('equal') ax.set_box_aspect(None, zoom=1.5) ax.set_axis_off() -ax.set_title(r"$t^{*}$ = " + "{:.2f}".format(t_star)) +ax.set_title(r"$t^{*}$ = " + "{:.1f}".format(t_star)) t_star = 0.5 ax = fig.add_subplot(1, 4, 2, projection='3d') @@ -380,7 +381,7 @@ def savefig(fig, filename="Cluster", format="pdf", path=None) : ax.set_aspect('equal') ax.set_box_aspect(None, zoom=1.5) ax.set_axis_off() -ax.set_title(r"$t^{*}$ = " + "{:.2f}".format(t_star)) +ax.set_title(r"$t^{*}$ = " + "{:.1f}".format(t_star)) t_star = 1.0 ax = fig.add_subplot(1, 4, 3, projection='3d') @@ -389,7 +390,7 @@ def savefig(fig, filename="Cluster", format="pdf", path=None) : ax.set_aspect('equal') ax.set_box_aspect(None, zoom=1.5) ax.set_axis_off() -ax.set_title(r"$t^{*}$ = " + "{:.2f}".format(t_star)) +ax.set_title(r"$t^{*}$ = " + "{:.1f}".format(t_star)) t_star = 1.5 ax = fig.add_subplot(1, 4, 4, projection='3d') @@ -398,7 +399,7 @@ def savefig(fig, filename="Cluster", format="pdf", path=None) : ax.set_aspect('equal') ax.set_box_aspect(None, zoom=1.5) ax.set_axis_off() -ax.set_title(r"$t^{*}$ = " + "{:.2f}".format(t_star)) +ax.set_title(r"$t^{*}$ = " + "{:.1f}".format(t_star)) # plot_cluster(fig, Bubbles, Bubbles_loc) savefig(fig, filename="sphericalclusterinteractions_clusterevolution", format="png") From 9fa2318c978aca35cf4f142d8fe49b557f68281d Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 2 Aug 2024 15:29:31 -0400 Subject: [PATCH 072/138] spherical cluster tension wave ; adding new plots with higher excitation pressure --- .../plot_results.py | 327 +++++++++++++++++- 1 file changed, 326 insertions(+), 1 deletion(-) diff --git a/examples/sphericalclustertensionwave/plot_results.py b/examples/sphericalclustertensionwave/plot_results.py index bda8d85..38e017c 100644 --- a/examples/sphericalclustertensionwave/plot_results.py +++ b/examples/sphericalclustertensionwave/plot_results.py @@ -1121,4 +1121,329 @@ axs[2].plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=26.5, ncol=n_quantiles, frameon=False) -fig.savefig("sphericalclustertensionwave_poly_pressureevolution_article.pdf", bbox_inches='tight',pad_inches=0.35) \ No newline at end of file +fig.savefig("sphericalclustertensionwave_poly_pressureevolution_article.pdf", bbox_inches='tight',pad_inches=0.35) + +######### Averaged radius versus time evolution for monodispersed cluster (article) ############### +######### More excitation pressure ################################################################ + +count = 250 +p1 = -1.0e5 +t_i = r_ref * sqrt(rho_l / (p0 - p1)) + +nrow = 1 +ncol = 3 +fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) +for i in range(ncol) : + axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=27.5) + if i == 0 : axs[i].set_ylabel(r"$ / R_{0}$ [-]", fontsize=27.5) + axs[i].set_xlim(xmin=0.0, xmax=80.0) + axs[i].tick_params(axis="both", labelsize=25) + axs[i].grid() + +plt.subplots_adjust(wspace=0.35*cm) + +axs[0].set_title(r"No interaction", fontsize=27.5) +axs[1].set_title(r"Incompressible interactions", fontsize=27.5) +axs[2].set_title(r"Quasi acoustic interactions", fontsize=27.5) + +dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} +dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} + +for k in dic_loc_distrib_global[count][p1].keys() : + index_list = dic_loc_distrib_global[count][p1][k] + + # No interaction + t_list = (1/t_i) * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) + + r_list_0 = np.array(dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["NI"]["mono"][count][p1][index + 1][1]) + init_r = dic_bubbles["NI"]["mono"][count][p1][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[0].plot(t_list, avg_radius, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) + + # Incompressible interactions + t_list = (1/t_i) * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) + + r_list_0 = np.array(dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["IC"]["mono"][count][p1][index + 1][1]) + init_r = dic_bubbles["IC"]["mono"][count][p1][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[1].plot(t_list, avg_radius, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) + + # Quasi acoustic interactions + t_list = (1/t_i) * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) + + r_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["QA"]["mono"][count][p1][index + 1][1]) + init_r = dic_bubbles["QA"]["mono"][count][p1][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[2].plot(t_list, avg_radius, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) + + +axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=26.5, ncol=3, frameon=False) +fig.savefig("sphericalclustertensionwave_mono_radiusevolution_morepress_article.pdf", bbox_inches='tight',pad_inches=0.35) + +######### Averaged pressure infinity versus time evolution for monodispersed clusters (article) ### +######### More excitation pressure ################################################################ + +count = 250 +p1 = -1.0e5 +p0 = 1.0e5 +t_i = r_ref * sqrt(rho_l / (p0 - p1)) + +nrow = 1 +ncol = 3 +fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) +for i in range(ncol) : + axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=27.5) + if i == 0 : axs[i].set_ylabel(r"$ / p_{0}$ [-]", fontsize=27.5) + axs[i].set_xlim(xmin=0.0, xmax=80.0) + axs[i].tick_params(axis="both", labelsize=25) + axs[i].grid() + +plt.subplots_adjust(wspace=0.35*cm) + +axs[0].set_title(r"No interaction", fontsize=27.5) +axs[1].set_title(r"Incompressible interactions", fontsize=27.5) +axs[2].set_title(r"Quasi acoustic interactions", fontsize=27.5) + +dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} +dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} + +zm_IC = axs[1].inset_axes([0.35, 0.35, 0.60, 0.60]) +zm_IC.grid() +zm_IC.set_xlim(xmin=0.0,xmax=20.0) +zm_IC.set_ylim(ymin=-0.5,ymax=2.0) +zm_IC.set_yticks([-0.267, 0.0, 1.0, 2.0]) +zm_IC.set_yticklabels([r"$p_{\mathrm{C}}$", 0, 1, 2]) +zm_IC.tick_params(axis="both", labelsize=25) + +zm_QA = axs[2].inset_axes([0.30, 0.4, 0.65, 0.55]) +zm_QA.grid() +zm_QA.set_xlim(xmin=0.0,xmax=20.0) +zm_QA.set_ylim(ymin=-0.5,ymax=2.0) +zm_QA.set_yticks([-0.267, 0.0, 1.0, 2.0]) +zm_QA.set_yticklabels([r"$p_{\mathrm{C}}$", 0, 1, 2]) +zm_QA.tick_params(axis="both", labelsize=25) + +for k in dic_loc_distrib_global[count][p1].keys() : + index_list = dic_loc_distrib_global[count][p1][k] + + # No interaction + t_list = (1/t_i) * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) + + p_list_0 = np.array(dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][2]) + avg_pressure = p_list_0 / p0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + p_list = np.array(dic_bubbles["NI"]["mono"][count][p1][index + 1][2]) + avg_pressure = avg_pressure + np.array(p_list) / p0 + + avg_pressure = (1 / len(index_list)) * avg_pressure + + axs[0].plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) + + # Incompressible interactions + t_list = (1/t_i) * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) + + p_list_0 = np.array(dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][2]) + avg_pressure = p_list_0 / p0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + p_list = np.array(dic_bubbles["IC"]["mono"][count][p1][index + 1][2]) + avg_pressure = avg_pressure + np.array(p_list) / p0 + + avg_pressure = (1 / len(index_list)) * avg_pressure + + axs[1].plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) + + zm_IC.plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) + + # Quasi acoustic interactions + t_list = (1/t_i) * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) + + p_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][2]) + avg_pressure = p_list_0 / p0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + p_list = np.array(dic_bubbles["QA"]["mono"][count][p1][index + 1][2]) + avg_pressure = avg_pressure + np.array(p_list) / p0 + + avg_pressure = (1 / len(index_list)) * avg_pressure + + axs[2].plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) + + zm_QA.plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) + +axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=26.5, ncol=3, frameon=False) +fig.savefig("sphericalclustertensionwave_mono_pressureevolution_morepress_article.pdf", bbox_inches='tight',pad_inches=0.35) + +######### Averaged radius versus time evolution for polydispersed cluster (article) ############### +######### More excitation pressure ################################################################ + +count = 250 +p1 = -1.0e5 +t_i = r_ref * sqrt(rho_l / (p0 - p1)) + +nrow = 1 +ncol = 3 +fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) +for i in range(ncol) : + axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=27.5) + if i == 0 : axs[i].set_ylabel(r"$$ [-]", fontsize=27.5) + # axs[i].set_xlim(xmin=10.0, xmax=60.0) + axs[i].tick_params(axis="both", labelsize=25) + axs[i].grid() +plt.subplots_adjust(wspace=0.35*cm) + +axs[0].set_title(r"No interaction", fontsize=27.5) +axs[1].set_title(r"Incompressible interactions", fontsize=27.5) +axs[2].set_title(r"Quasi acoustic interactions", fontsize=27.5) + +color_list = ["black", "magenta", "blue", "green", "red"] +# linestyle_list = [(0, (1, 1)), (5, (10, 3)), (0, (5, 5)), (0, (3, 5, 1, 5)), (0, (3, 1, 1, 1, 1, 1))] +linestyle_list = ["solid" for i in range(5)] +dic_color_q = {} +dic_linestyle_q = {} +dic_label_q = {} +for i in range(n_quantiles) : + quantile = quantiles_list[i] + dic_color_q[quantile] = color_list[i] + dic_linestyle_q[quantile] = linestyle_list[i] + + dic_label_q[quantile] = "{}th-{}".format(i+1, quantile_name) + if i == 0 : + dic_label_q[quantile] = "1st-{}".format(quantile_name) + elif i == 1 : + dic_label_q[quantile] = "2nd-{}".format(quantile_name) + elif i == 2 : + dic_label_q[quantile] = "3rd-{}".format(quantile_name) + +# No interaction +axs[0].set_xlim(xmin=0.0,xmax=250.0) +axs[0].set_ylim(ymin=0.95,ymax=3.0) + +zm = axs[0].inset_axes([0.25, 0.25, 0.7, 0.7]) +zm.grid() +zm.set_xlim(xmin=0.0, xmax=50.0) +zm.tick_params(axis="both", labelsize=25) + +for q in list(dic_polydisperse["NI"][count][p1].keys())[1:] : + index_list = dic_polydisperse["NI"][count][p1][q] + + t_list = (1/t_i) * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) + + r_list_0 = np.array(dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["NI"]["poly"][count][p1][index + 1][1]) + init_r = dic_bubbles["NI"]["poly"][count][p1][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[0].plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) + + zm.plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) + +# Incompressible interactions +axs[1].set_xlim(xmin=-10.0,xmax=800.0) +axs[1].set_ylim(ymin=0.925,ymax=1.50) + +zm = axs[1].inset_axes([0.25, 0.5, 0.7, 0.45]) +zm.grid() +zm.set_xlim(xmax=200.0) +zm.tick_params(axis="both", labelsize=25) + +for q in list(dic_polydisperse["IC"][count][p1].keys())[1:] : + index_list = dic_polydisperse["IC"][count][p1][q] + + t_list = (1/t_i) * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) + + r_list_0 = np.array(dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["IC"]["poly"][count][p1][index + 1][1]) + init_r = dic_bubbles["IC"]["poly"][count][p1][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[1].plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q], label=dic_label_q[q]) + + zm.plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) + +# Quasi acoustic interactions +axs[2].set_xlim(xmin=-10.0,xmax=800.0) +axs[2].set_ylim(ymin=0.925,ymax=1.50) + +zm = axs[2].inset_axes([0.25, 0.5, 0.7, 0.45]) +zm.grid() +zm.set_xlim(xmax=200.0) +zm.tick_params(axis="both", labelsize=25) + +for q in list(dic_polydisperse["QA"][count][p1].keys())[1:] : + index_list = dic_polydisperse["QA"][count][p1][q] + + t_list = (1/t_i) * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) + + r_list_0 = np.array(dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][1]) + init_r_0 = dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][0] + avg_radius = r_list_0 / init_r_0 + + for i in range(1, len(index_list)) : + index = index_list[i] + + r_list = np.array(dic_bubbles["QA"]["poly"][count][p1][index + 1][1]) + init_r = dic_bubbles["QA"]["poly"][count][p1][index + 1][0] + avg_radius = avg_radius + np.array(r_list) / init_r + + avg_radius = (1 / len(index_list)) * avg_radius + + axs[2].plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) + + zm.plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) + +axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=26.5, ncol=n_quantiles, frameon=False) +fig.savefig("sphericalclustertensionwave_poly_radiusevolution_morepress_article.pdf", bbox_inches='tight',pad_inches=0.35) \ No newline at end of file From dcbcfa4b2f4e43bd71305b02e588d2e3d99754d0 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 2 Aug 2024 15:54:42 -0400 Subject: [PATCH 073/138] small typo changes in plots --- examples/cavitationonset/plot_results.py | 14 +++--- .../plot_results.py | 48 +++++++++---------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/examples/cavitationonset/plot_results.py b/examples/cavitationonset/plot_results.py index de91906..e9ea27b 100644 --- a/examples/cavitationonset/plot_results.py +++ b/examples/cavitationonset/plot_results.py @@ -159,7 +159,7 @@ dist_list = [10, 12, 12.1, 12.5, 15, 20] -axs[0].set_title(r"Incompressible interactions" + "\n" +r"($p_{ng}$/$p_{0}$ = -0.25)") +axs[0].set_title(r"Incompressible interactions") axs[0].set_xlabel(r"t [$\mu$s]", fontsize=27.5) axs[0].set_xlim(xmin=0.0, xmax=60.0) axs[0].set_ylabel(r"$R$ [$\mu$m]", fontsize=27.5) @@ -193,7 +193,7 @@ dist_list = [10, 11.9, 12, 15, 20] -axs[1].set_title(r"Quasi acoustic interactions" + "\n" +r"($p_{ng}$/$p_{0}$ = -0.25)") +axs[1].set_title(r"Quasi-acoustic interactions") axs[1].set_xlabel(r"t [$\mu$s]", fontsize=27.5) axs[1].set_xlim(xmin=0.0, xmax=60.0) # axs[1].set_ylabel(r"$R$ [$\mu$m]") @@ -236,7 +236,7 @@ png_list = [-25325, -27351, -27958.8, -29377] -axs[0].set_title(r"Incompressible interactions" + "\n" +r"($\Delta x_{12}$ = 10[$R_{1,0}$ + $R_{2,0}$])") +axs[0].set_title(r"Incompressible interactions") axs[0].set_xlabel(r"t [$\mu$s]", fontsize=27.5) axs[0].set_xlim(xmin=0.0, xmax=60.0) axs[0].set_ylabel(r"$R_{1}$ [$\mu$m]", fontsize=27.5) @@ -258,7 +258,7 @@ png_list = [-25325, -27351, -27958.8, -27654.9, -29377] -axs[1].set_title(r"Quasi acoustic interactions" + "\n" +r"($\Delta x_{12}$ = 10[$R_{1,0}$ + $R_{2,0}$])") +axs[1].set_title(r"Quasi-acoustic interactions") axs[1].set_xlabel(r"t [$\mu$s]", fontsize=27.5) axs[1].set_xlim(xmin=0.0, xmax=60.0) # axs[1].set_ylabel(r"$R$ [$\mu$m]") @@ -300,8 +300,8 @@ axs[i, j].grid() axs[i, j].set_xlim(xmin=10.0, xmax=60.0) -axs[0, 0].set_title(r"Incompressible interactions" + "\n" +r"($p_{ng}$/$p_{0}$ = -0.25, $\Delta x_{12}$ = 20$R_{1,0}$)") -axs[0, 1].set_title(r"Quasi acoustic interactions" + "\n" +r"($p_{ng}$/$p_{0}$ = -0.25, $\Delta x_{12}$ = 20$R_{1,0}$)") +axs[0, 0].set_title(r"Incompressible interactions") +axs[0, 1].set_title(r"Quasi-acoustic interactions") axs[1, 0].set_xlabel(r"t [$\mu$s]", fontsize=27.5) axs[1, 1].set_xlabel(r"t [$\mu$s]", fontsize=27.5) @@ -326,6 +326,6 @@ axs[0, 1].plot(t_list, r_list, color=dic_color[nbubble], marker=dic_marker[nbubble], markevery=600, markersize=10.0, linewidth=2.5) axs[1, 1].plot(t_list, p_list, color=dic_color[nbubble], marker=dic_marker[nbubble], markevery=600, markersize=12.5, linewidth=2.5) -axs[0, 0].legend(bbox_to_anchor=(1.1, 1.175), loc="lower center", ncol=2, frameon=False) +axs[0, 0].legend(bbox_to_anchor=(1.1, 1.05), loc="lower center", ncol=2, frameon=False) fig.savefig("cavitationonset_monodispersedclusters.pdf", bbox_inches='tight',pad_inches=0.35) \ No newline at end of file diff --git a/examples/sphericalclustertensionwave/plot_results.py b/examples/sphericalclustertensionwave/plot_results.py index 38e017c..ff0dcd7 100644 --- a/examples/sphericalclustertensionwave/plot_results.py +++ b/examples/sphericalclustertensionwave/plot_results.py @@ -250,7 +250,7 @@ axs[0].set_title(r"No interaction" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) -axs[2].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} @@ -294,7 +294,7 @@ axs[1].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) - # Quasi acoustic interactions + # Quasi-acoustic interactions t_list = (1/t_i) * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) r_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][1]) @@ -335,7 +335,7 @@ axs[0].set_title(r"No interaction", fontsize=27.5) axs[1].set_title(r"Incompressible interactions", fontsize=27.5) -axs[2].set_title(r"Quasi acoustic interactions", fontsize=27.5) +axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} @@ -379,7 +379,7 @@ axs[1].plot(t_list, avg_radius, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) - # Quasi acoustic interactions + # Quasi-acoustic interactions t_list = (1/t_i) * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) r_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][1]) @@ -418,7 +418,7 @@ axs[0].set_title(r"No interaction" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) -axs[2].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) color_list = ["black", "magenta", "blue", "green", "red"] # linestyle_list = [(0, (1, 1)), (5, (10, 3)), (0, (5, 5)), (0, (3, 5, 1, 5)), (0, (3, 1, 1, 1, 1, 1))] @@ -499,7 +499,7 @@ zm.plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) -# Quasi acoustic interactions +# Quasi-acoustic interactions axs[2].set_xlim(xmin=-10.0,xmax=1000.0) axs[2].set_ylim(ymin=0.925,ymax=1.25) @@ -551,7 +551,7 @@ axs[0].set_title(r"No interaction", fontsize=27.5) axs[1].set_title(r"Incompressible interactions", fontsize=27.5) -axs[2].set_title(r"Quasi acoustic interactions", fontsize=27.5) +axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) color_list = ["black", "magenta", "blue", "green", "red"] # linestyle_list = [(0, (1, 1)), (5, (10, 3)), (0, (5, 5)), (0, (3, 5, 1, 5)), (0, (3, 1, 1, 1, 1, 1))] @@ -634,7 +634,7 @@ zm.plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) -# Quasi acoustic interactions +# Quasi-acoustic interactions axs[2].set_xlim(xmin=-10.0,xmax=800.0) axs[2].set_ylim(ymin=0.925,ymax=1.25) @@ -684,7 +684,7 @@ axs[0].set_title(r"No interaction" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) -axs[2].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} @@ -731,7 +731,7 @@ axs[1].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) - # Quasi acoustic interactions + # Quasi-acoustic interactions t_list = (1/t_i) * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) r_list_0 = np.array(dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][1]) @@ -771,7 +771,7 @@ axs[0].set_title(r"No interaction" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) -axs[2].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} @@ -811,7 +811,7 @@ axs[1].plot(t_list, avg_pressure, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) - # Quasi acoustic interactions + # Quasi-acoustic interactions t_list = (1/t_i) * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) p_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][2]) @@ -851,7 +851,7 @@ axs[0].set_title(r"No interaction", fontsize=27.5) axs[1].set_title(r"Incompressible interactions", fontsize=27.5) -axs[2].set_title(r"Quasi acoustic interactions", fontsize=27.5) +axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} @@ -909,7 +909,7 @@ zm_IC.plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) - # Quasi acoustic interactions + # Quasi-acoustic interactions t_list = (1/t_i) * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) p_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][2]) @@ -948,7 +948,7 @@ axs[0].set_title(r"No interaction" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) -axs[2].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) color_list = ["black", "magenta", "blue", "green", "red"] dic_color_q = {} @@ -1003,7 +1003,7 @@ axs[1].plot(t_list, avg_pressure, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q], label=dic_label_q[q]) -# Quasi acoustic interactions +# Quasi-acoustic interactions for q in list(dic_polydisperse["QA"][count][p1].keys())[1:] : index_list = dic_polydisperse["QA"][count][p1][q] @@ -1046,7 +1046,7 @@ axs[0].set_title(r"No interaction", fontsize=27.5) axs[1].set_title(r"Incompressible interactions", fontsize=27.5) -axs[2].set_title(r"Quasi acoustic interactions", fontsize=27.5) +axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) color_list = ["black", "magenta", "blue", "green", "red"] dic_color_q = {} @@ -1101,7 +1101,7 @@ axs[1].plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q], label=dic_label_q[q]) -# Quasi acoustic interactions +# Quasi-acoustic interactions for q in list(dic_polydisperse["QA"][count][p1].keys())[1:] : index_list = dic_polydisperse["QA"][count][p1][q] @@ -1144,7 +1144,7 @@ axs[0].set_title(r"No interaction", fontsize=27.5) axs[1].set_title(r"Incompressible interactions", fontsize=27.5) -axs[2].set_title(r"Quasi acoustic interactions", fontsize=27.5) +axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} @@ -1188,7 +1188,7 @@ axs[1].plot(t_list, avg_radius, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) - # Quasi acoustic interactions + # Quasi-acoustic interactions t_list = (1/t_i) * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) r_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][1]) @@ -1232,7 +1232,7 @@ axs[0].set_title(r"No interaction", fontsize=27.5) axs[1].set_title(r"Incompressible interactions", fontsize=27.5) -axs[2].set_title(r"Quasi acoustic interactions", fontsize=27.5) +axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} @@ -1290,7 +1290,7 @@ zm_IC.plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) - # Quasi acoustic interactions + # Quasi-acoustic interactions t_list = (1/t_i) * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) p_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][2]) @@ -1331,7 +1331,7 @@ axs[0].set_title(r"No interaction", fontsize=27.5) axs[1].set_title(r"Incompressible interactions", fontsize=27.5) -axs[2].set_title(r"Quasi acoustic interactions", fontsize=27.5) +axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) color_list = ["black", "magenta", "blue", "green", "red"] # linestyle_list = [(0, (1, 1)), (5, (10, 3)), (0, (5, 5)), (0, (3, 5, 1, 5)), (0, (3, 1, 1, 1, 1, 1))] @@ -1414,7 +1414,7 @@ zm.plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) -# Quasi acoustic interactions +# Quasi-acoustic interactions axs[2].set_xlim(xmin=-10.0,xmax=800.0) axs[2].set_ylim(ymin=0.925,ymax=1.50) From 25b14db1403b513c30d21b1bb917042a84ec60b1 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 5 Aug 2024 12:13:14 -0400 Subject: [PATCH 074/138] bubbly screen ; adding a new plot for radius versus time evolution --- examples/bubblyscreen/plot_results.py | 53 ++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/examples/bubblyscreen/plot_results.py b/examples/bubblyscreen/plot_results.py index 8a0a18f..ba591a3 100644 --- a/examples/bubblyscreen/plot_results.py +++ b/examples/bubblyscreen/plot_results.py @@ -23,12 +23,16 @@ ratio_D_R0 = [400] dic_bubbly_screen = {} +dic_radii = {} for intype in interaction_types : dic_bubbly_screen[intype] = {} + dic_radii[intype] = {} for w in excitation_w : dic_bubbly_screen[intype][w] = {} + dic_radii[intype][w] = {} for r in ratio_D_R0 : dic_bubbly_screen[intype][w][r] = np.zeros((51,51),dtype=float) + dic_radii[intype][w][r] = [[] for i in range(51*51 + 1)] for intype in interaction_types : path = os.path.join(os.getcwd(), intype) @@ -60,6 +64,33 @@ j = int((x/D)) + 25 dic_bubbly_screen[intype][w][ratio][i][j] = r_amp + + if "_radii" in file : + print(file) + data = open(os.path.join(path, file), "r") + lines = data.readlines() + data.close() + + firstline = lines[0].split(" ") + w0 = float(firstline[1]) + fa = float(firstline[3]) + pa = float(firstline[5]) + ratio = int(float(firstline[7])) + + R0 = float(lines[2].split(" ")[1]) + D = ratio * R0 + + w = float("{:.1f}".format(2 * pi * fa / w0)) + + if pa == 10**2 : + for i in range(2, len(lines), 25) : + line = lines[i] + t = float(line.split(" ")[0]) + dic_radii[intype][w][ratio][0].append(t) + + for i in range(51*51) : + r = (float(line.split(" ")[i + 1]) - R0) / R0 + dic_radii[intype][w][ratio][i + 1].append(r) ######### Functions ################################################################################################################################# @@ -127,4 +158,24 @@ def plot_oscillation_distribution(fig, axs, row, col, nbubbles_x, inttype, rati plot_oscillation_distribution(fig, axs, 1, 3, 51, "IC", 1.5, 400, order=4, clear=True) fig.subplots_adjust(hspace=0.01*cm, wspace=0.95*cm) -fig.savefig("bubblyscreen_ComparisonQAIC.pdf", bbox_inches="tight",pad_inches=0.035) \ No newline at end of file +fig.savefig("bubblyscreen_ComparisonQAIC.pdf", bbox_inches="tight",pad_inches=0.035) + +######### D/R0 = 400 : Radius evolution ########################################################### + +fig, ax = plt.subplots(1, 1, figsize=(27.5*cm, 12.5*cm)) +ax.set_xlabel(r"t [$\mu$s]") +ax.set_xlim(xmin=0.0, xmax=60.0) +ax.set_ylabel(r"$\left(R(t) - R_{0} \right) / R_{0}$ [-]") +ax.set_yscale("log") +ax.set_ylim(ymin=10**(-4), ymax=5.0e-2) + +### QA ### +ax.plot(np.array(dic_radii["QA"][1.0][400][0])*1.0e6, np.array(dic_radii["QA"][1.0][400][1301]), linewidth=2.0, color="black", linestyle="dashed", label="QA") +# ax.plot(np.array(dic_radii["QA"][1.0][400][0])*1.0e6, np.array(dic_radii["QA"][1.0][400][1]), linewidth=1.5, marker="s", markersize=5.0, markevery=1500, color="black", linestyle="dashed", label="QA, corner") + +### IC ### +ax.plot(np.array(dic_radii["IC"][1.0][400][0])*1.0e6, np.array(dic_radii["IC"][1.0][400][1301]), linewidth=2.0, color="red", linestyle="solid", label="IC") +# ax.plot(np.array(dic_radii["IC"][1.0][400][0])*1.0e6, np.array(dic_radii["IC"][1.0][400][1]), linewidth=1.5, marker="s", markersize=5.0, markevery=1500, color="red", linestyle="solid", label="IC, corner") + +ax.legend(bbox_to_anchor=(0.5, 1.05), loc="center", frameon=False, ncol=2) +fig.savefig("bubblyscreen_radiievolution.pdf", bbox_inches="tight",pad_inches=0.035) \ No newline at end of file From c14319268152e47ee8ced0cfeac8b6223d3faf51 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 5 Aug 2024 12:15:13 -0400 Subject: [PATCH 075/138] little few changes in test cases --- examples/bubblyscreen/run_bubblyscreen.sh | 6 +- examples/cavitationonset/IC/plot_temp.py | 71 +++++++++++++++++++ .../QA/execmpi.sh | 4 +- .../test_distribution.py | 44 ++++++++++++ .../src/sphericalclustertensionwave_apecss.c | 4 +- .../src/sphericalclustertensionwave_apecss.c | 4 +- .../src/sphericalclustertensionwave_apecss.c | 9 ++- .../run_sphericalclustertensionwave.sh | 15 ++-- 8 files changed, 140 insertions(+), 17 deletions(-) create mode 100644 examples/cavitationonset/IC/plot_temp.py create mode 100644 examples/sphericalclustercavitationonset/test_distribution.py diff --git a/examples/bubblyscreen/run_bubblyscreen.sh b/examples/bubblyscreen/run_bubblyscreen.sh index 3f90fe5..e1728ae 100755 --- a/examples/bubblyscreen/run_bubblyscreen.sh +++ b/examples/bubblyscreen/run_bubblyscreen.sh @@ -1,6 +1,6 @@ ######### Parameters ################################################################################################################################ -ncore=15 +ncore=20 nbubbles=2601 ######### Incompressible computations ############################################################################################################### @@ -12,7 +12,7 @@ cd .. f_list=(1.631e06 2.934e06 3.262e06 4.893e06) for f in "${f_list[@]}" do - ./build/bubblyscreen_apecss -options run.apecss -freq $f -amp 100.0 -tend 35.0e-6 + ./build/bubblyscreen_apecss -options run.apecss -freq $f -amp 100.0 -tend 60.0e-6 python3 gather_results.py done @@ -32,7 +32,7 @@ f_list=(1.631e06 2.934e06 3.262e06 4.893e06) c_list=(0.0005 0.005 0.05 0.001) for ((i=0; i<5; i++)) do - mpiexec -n $ncore ./build/bubblyscreen_apecss -options run.apecss -freq ${f_list[$i]} -amp 100.0 -tend 35.0e-6 -coeff ${c_list[$i]} + mpiexec -n $ncore ./build/bubblyscreen_apecss -options run.apecss -freq ${f_list[$i]} -amp 100.0 -tend 60.0e-6 -coeff ${c_list[$i]} python3 gather_results.py done cd .. diff --git a/examples/cavitationonset/IC/plot_temp.py b/examples/cavitationonset/IC/plot_temp.py new file mode 100644 index 0000000..0d8e866 --- /dev/null +++ b/examples/cavitationonset/IC/plot_temp.py @@ -0,0 +1,71 @@ +import os +import numpy as np +import matplotlib.pyplot as plt + +plt.rcParams['font.family']='serif' +plt.rcParams['font.serif']=['Times New Roman'] + plt.rcParams['font.serif'] +plt.rcParams['mathtext.fontset']='stix' +plt.rcParams['font.size']=10 + +cm = 1/2.54 + +count = 0 +for file in os.listdir() : + if "Bubble_" in file : + count += 1 + +Bubbles = [] +for i in range(count) : + Bubble_file = os.listdir(os.path.join(os.getcwd(), "Bubble_{}".format(i)))[0] + Bubble = np.genfromtxt("Bubble_{}/".format(i) + Bubble_file, delimiter=" ") + Bubbles.append(Bubble) + +Bubbles_A = [[]] +for i in range(count) : + Bubbles_A.append([]) + +file_results = open("Ida2009_results.txt", "r") +lines = file_results.readlines() +file_results.close() + +for line in lines[3:] : + data = line.split(" ") + t = float(data[0]) + Bubbles_A[0].append(t) + for i in range(count) : + Bubbles_A[1+i].append(float(data[1 + 2 * count + i])) + +fig1 = plt.figure(figsize=(21*cm,5*cm)) +ax1 = plt.subplot2grid((1,4),(0,0),colspan=1) +ax2 = plt.subplot2grid((1,4),(0,1),colspan=1) +ax3 = plt.subplot2grid((1,4),(0,2),colspan=1) +ax4 = plt.subplot2grid((1,4),(0,3),colspan=1) +plt.subplots_adjust(wspace=1.2*cm,hspace=1.2*cm) + +ax1.set_xlabel(r"t ($\mu$s)") +ax1.set_xlim(xmin=10.0, xmax=60.0) +ax2.set_xlabel(r"t ($\mu$s)") +ax2.set_xlim(xmin=10.0, xmax=60.0) +ax3.set_xlabel(r"t ($\mu$s)") +ax3.set_xlim(xmin=10.0, xmax=60.0) +ax4.set_xlabel(r"t ($\mu$s)") +ax4.set_xlim(xmin=10.0, xmax=60.0) + +ax1.set_ylabel(r"R ($\mu$m)") +ax2.set_ylabel(r"U (m.$s^{-1}$)") +ax3.set_ylabel(r"$p_{\infty}$ / $p_{0}$ (-)") +ax3.set_ylim(ymin=-0.25, ymax=0.0) +ax4.set_ylabel(r"A (m.$s^{-2}$)") + +ax1.grid() +ax2.grid() +ax3.grid() +ax4.grid() + +for i in range(count) : + ax1.plot(Bubbles[i][:, 1]*1e6, Bubbles[i][:, 3]*1e6) + ax2.plot(Bubbles[i][:, 1]*1e6, Bubbles[i][:, 4]) + ax3.plot(Bubbles[i][:, 1]*1e6, Bubbles[i][:, 7] * 1 / (101.3e03)) + ax4.plot(np.array(Bubbles_A[0])*1e6, np.array(Bubbles_A[1+i])) + +plt.show() \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/QA/execmpi.sh b/examples/sphericalclustercavitationonset/QA/execmpi.sh index c0d69a8..09cb14d 100755 --- a/examples/sphericalclustercavitationonset/QA/execmpi.sh +++ b/examples/sphericalclustercavitationonset/QA/execmpi.sh @@ -1,10 +1,10 @@ nbubbles=2500 -ncores=15 +ncores=20 cd build ./compile.sh cd .. -mpiexec -n $ncores ./build/sphericalclustercavitationonset_apecss -options run.apecss -amp -25325 -tend 5.0e-06 -cldistrib 0 +mpiexec -n $ncores ./build/sphericalclustercavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-06 -cldistrib 1 python3 gather_results.py # rm -rf bubble_loc.txt diff --git a/examples/sphericalclustercavitationonset/test_distribution.py b/examples/sphericalclustercavitationonset/test_distribution.py new file mode 100644 index 0000000..620d814 --- /dev/null +++ b/examples/sphericalclustercavitationonset/test_distribution.py @@ -0,0 +1,44 @@ +import random +import numpy as np +import matplotlib.pyplot as plt +from math import pi, sqrt, cos, log, exp + +# Small file to test if the distribution used for the polydispersed cluster follows a log-normal distribution + +def normal_distribution (mu, sigma) : + u1 = random.random() + while u1 == 0.0 : + u1 = random.random() + u2 = random.random() + + mag = sigma * sqrt(-2 * log(u1)) + z1 = mag * cos(2 * pi * u2) + mu + return z1 + +mu = 0.0 +sigma = 0.7 +nBubbles = 2500 +r_ref = 10.0e-6 + +distrib = [] +for i in range(nBubbles) : + r = r_ref * exp(normal_distribution(mu, sigma)) + while r > 20 * r_ref and r < 0.5 * r_ref : + r = r_ref * exp(normal_distribution(mu, sigma)) + distrib.append(r) +distrib = np.array(distrib) / r_ref + +fig, ax = plt.subplots(1, 1, figsize=((15, 12.5))) +ax.set_title("Test for the proposed radii distribution") + +ax.set_xlabel(r"$R/R_{ref}$") +ax.grid() + +count, bins, ignored = ax.hist(distrib, 100, density=True, align='mid') +x = np.linspace(min(bins), max(bins), 10000) + +pdf = (np.exp(-(np.log(x) - mu)**2 / (2 * sigma**2)) / (x * sigma * np.sqrt(2 * np.pi))) + +ax.plot(x, pdf, color="red", linewidth=2) + +plt.show() \ No newline at end of file diff --git a/examples/sphericalclustertensionwave/IC/src/sphericalclustertensionwave_apecss.c b/examples/sphericalclustertensionwave/IC/src/sphericalclustertensionwave_apecss.c index ffe6ef1..e2ed2f7 100644 --- a/examples/sphericalclustertensionwave/IC/src/sphericalclustertensionwave_apecss.c +++ b/examples/sphericalclustertensionwave/IC/src/sphericalclustertensionwave_apecss.c @@ -365,7 +365,7 @@ int main(int argc, char **args) APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { - APECSS_FLOAT tau = 1.75e-6; + APECSS_FLOAT tau = 1.41e-6; if (t < tau) { return (Bubble->p0 - (Bubble->p0 - Bubble->Excitation->dp) * APECSS_POW2(APECSS_SIN(APECSS_PI * t / tau)) + Bubble->Interaction->dp_neighbor); @@ -378,7 +378,7 @@ APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_ APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { - APECSS_FLOAT tau = 1.75e-6; + APECSS_FLOAT tau = 1.41e-6; if (t < tau) { APECSS_FLOAT inv_tau = 1 / tau; diff --git a/examples/sphericalclustertensionwave/NI/src/sphericalclustertensionwave_apecss.c b/examples/sphericalclustertensionwave/NI/src/sphericalclustertensionwave_apecss.c index 22dfb7d..7226437 100644 --- a/examples/sphericalclustertensionwave/NI/src/sphericalclustertensionwave_apecss.c +++ b/examples/sphericalclustertensionwave/NI/src/sphericalclustertensionwave_apecss.c @@ -360,7 +360,7 @@ int main(int argc, char **args) APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { - APECSS_FLOAT tau = 1.75e-6; + APECSS_FLOAT tau = 1.41e-6; if (t < tau) { return (Bubble->p0 - (Bubble->p0 - Bubble->Excitation->dp) * APECSS_POW2(APECSS_SIN(APECSS_PI * t / tau)) + Bubble->Interaction->dp_neighbor); @@ -373,7 +373,7 @@ APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_ APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { - APECSS_FLOAT tau = 1.75e-6; + APECSS_FLOAT tau = 1.41e-6; if (t < tau) { APECSS_FLOAT inv_tau = 1 / tau; diff --git a/examples/sphericalclustertensionwave/QA/src/sphericalclustertensionwave_apecss.c b/examples/sphericalclustertensionwave/QA/src/sphericalclustertensionwave_apecss.c index 1dbaa2f..2c21c0c 100644 --- a/examples/sphericalclustertensionwave/QA/src/sphericalclustertensionwave_apecss.c +++ b/examples/sphericalclustertensionwave/QA/src/sphericalclustertensionwave_apecss.c @@ -128,6 +128,11 @@ int main(int argc, char **args) ++j; } } + // /* Adapt dt_interbubble for polydispersed cluster */ + // if (cluster_distrib != 0) + // { + // dt_interbubble = 2.5e-10; + // } /* Allocate structure for parallel data */ struct APECSS_Parallel_Cluster *RankInfo = (struct APECSS_Parallel_Cluster *) malloc(sizeof(struct APECSS_Parallel_Cluster)); @@ -488,7 +493,7 @@ int main(int argc, char **args) APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { - APECSS_FLOAT tau = 1.75e-6; + APECSS_FLOAT tau = 1.41e-6; if (t < tau) { return (Bubble->p0 - (Bubble->p0 - Bubble->Excitation->dp) * APECSS_POW2(APECSS_SIN(APECSS_PI * t / tau)) + Bubble->Interaction->dp_neighbor); @@ -502,7 +507,7 @@ APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, stru APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { // Approximate numerical computation of p_infinity derivative - APECSS_FLOAT tau = 1.75e-6; + APECSS_FLOAT tau = 1.41e-6; APECSS_FLOAT derivative = 0.0; if (t < tau) { diff --git a/examples/sphericalclustertensionwave/run_sphericalclustertensionwave.sh b/examples/sphericalclustertensionwave/run_sphericalclustertensionwave.sh index 8a3996b..28be3ba 100755 --- a/examples/sphericalclustertensionwave/run_sphericalclustertensionwave.sh +++ b/examples/sphericalclustertensionwave/run_sphericalclustertensionwave.sh @@ -3,6 +3,9 @@ ncores=12 nbubbles=250 +pressure=-3.0e4 +pressure_bis=-1.0e5 + ######### No interaction computations ############################################################################################################### cd NI/build @@ -10,11 +13,11 @@ cd NI/build cd .. ######### Monodispersed system #################################################################### -./build/sphericalclustertensionwave_apecss -options run.apecss -amp -3.0e4 -tend 15.0e-6 -cldistrib 0 +./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure_bis -tend 15.0e-6 -cldistrib 0 python3 gather_results.py # ######### Polydispersed system #################################################################### -./build/sphericalclustertensionwave_apecss -options run.apecss -amp -3.0e4 -tend 50.0e-6 -cldistrib 1 +./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure_bis -tend 50.0e-6 -cldistrib 1 python3 gather_results.py cd .. @@ -30,11 +33,11 @@ cd IC/build cd .. ######### Monodispersed system #################################################################### -./build/sphericalclustertensionwave_apecss -options run.apecss -amp -3.0e4 -tend 15.0e-6 -cldistrib 0 +./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure_bis -tend 15.0e-6 -cldistrib 0 python3 gather_results.py ######### Polydispersed system #################################################################### -./build/sphericalclustertensionwave_apecss -options run.apecss -amp -3.0e4 -tend 150.0e-6 -cldistrib 1 +./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure_bis -tend 150.0e-6 -cldistrib 1 python3 gather_results.py cd .. @@ -50,11 +53,11 @@ cd QA/build cd .. ######### Monodispersed system #################################################################### -mpiexec -n $ncores ./build/sphericalclustertensionwave_apecss -options run.apecss -amp -3.0e4 -tend 25.0e-06 -cldistrib 0 +mpiexec -n $ncores ./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure_bis -tend 25.0e-06 -cldistrib 0 python3 gather_results.py ######### Polydispersed system #################################################################### -mpiexec -n $ncores ./build/sphericalclustertensionwave_apecss -options run.apecss -amp -3.0e4 -tend 200.0e-06 -cldistrib 1 +mpiexec -n $ncores ./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure_bis -tend 200.0e-06 -cldistrib 1 python3 gather_results.py cd .. From 9b4a491c30456458c2c1cf6af1ab69eabd6acce9 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Thu, 29 Aug 2024 13:25:36 -0400 Subject: [PATCH 076/138] bubblyscreen ; ploting dimensionless amplitude instead of radius evolution, faster way to retrieve the evolution for one bubble --- examples/bubblyscreen/plot_results.py | 85 +++++++++++++++++++++++---- 1 file changed, 73 insertions(+), 12 deletions(-) diff --git a/examples/bubblyscreen/plot_results.py b/examples/bubblyscreen/plot_results.py index ba591a3..685008d 100644 --- a/examples/bubblyscreen/plot_results.py +++ b/examples/bubblyscreen/plot_results.py @@ -24,15 +24,20 @@ dic_bubbly_screen = {} dic_radii = {} +dic_radii_index = {} +index = 1301 for intype in interaction_types : dic_bubbly_screen[intype] = {} dic_radii[intype] = {} + dic_radii_index[intype] = {} for w in excitation_w : dic_bubbly_screen[intype][w] = {} dic_radii[intype][w] = {} + dic_radii_index[intype][w] = {} for r in ratio_D_R0 : dic_bubbly_screen[intype][w][r] = np.zeros((51,51),dtype=float) dic_radii[intype][w][r] = [[] for i in range(51*51 + 1)] + dic_radii_index[intype][w][r] = [[], []] for intype in interaction_types : path = os.path.join(os.getcwd(), intype) @@ -83,14 +88,22 @@ w = float("{:.1f}".format(2 * pi * fa / w0)) if pa == 10**2 : - for i in range(2, len(lines), 25) : + # for i in range(2, len(lines), 25) : + # line = lines[i] + # t = float(line.split(" ")[0]) + # dic_radii[intype][w][ratio][0].append(t) + + # for i in range(51*51) : + # r = (float(line.split(" ")[i + 1]) - R0) / R0 + # dic_radii[intype][w][ratio][i + 1].append(r) + + for i in range(2, len(lines)) : line = lines[i] t = float(line.split(" ")[0]) - dic_radii[intype][w][ratio][0].append(t) - - for i in range(51*51) : - r = (float(line.split(" ")[i + 1]) - R0) / R0 - dic_radii[intype][w][ratio][i + 1].append(r) + dic_radii_index[intype][w][ratio][0].append(t) + # r = (float(line.split(" ")[index]) - R0) / R0 + r = float(line.split(" ")[index]) + dic_radii_index[intype][w][ratio][1].append(r) ######### Functions ################################################################################################################################# @@ -121,13 +134,55 @@ def plot_oscillation_distribution(fig, axs, row, col, nbubbles_x, inttype, rati colors = cset.cmap(cset.norm(cset.get_array())) for i in range(nbubbles_x) : for j in range(nbubbles_x) : - index = nbubbles_x * i + j - index_color = colors[index] + # index = nbubbles_x * i + j + index_color = colors[j][i] x = j - space y = i - space circle = Circle((x, y), 0.4, facecolor=(index_color[0], index_color[1], index_color[2])) axs[row, col].add_patch(circle) +def identify_oscillation_amplitude(t_list, r_list) : + # t_list and r_list must be 1D-arrays + # Determine the evolution of the oscillation amplitude by decomposing the entry signal + r_mean = np.mean(r_list) + r_mmean_list = r_list - r_mean + + index = 0 + index_positive_list = [] + while index < len(t_list) : + if r_mmean_list[index] > 0 : + index_positive_list.append(index) + index += 1 + + periods_index = [] + list_index = 1 + periods_index.append([index_positive_list[0]]) + while list_index < len(index_positive_list) : + if index_positive_list[list_index] - index_positive_list[list_index - 1] > 1 : + # A step larger than one in index means a new period has been reached + periods_index[-1].append(index_positive_list[list_index] - 1) + periods_index.append([index_positive_list[list_index]]) + list_index += 1 + + if len(periods_index[-1]) == 1 : + periods_index = periods_index[:len(periods_index)-1] + + t_amp_list = [] + r_amp_list = [] + for i in range(len(periods_index)) : + start_index = periods_index[i][0] + stop_index = periods_index[i][1] + + mean_index = int(0.5 * (start_index + stop_index)) + t_amp_list.append(t_list[mean_index]) + + r_slice_list = r_list[start_index : stop_index + 1] + r_max = np.max(r_slice_list) + r_min = np.min(r_slice_list) + r_amp_list.append(0.5 * (r_max - r_min)) + + return t_amp_list, r_amp_list + ######### Step 2 : Plot results ##################################################################################################################### ######### D/R0 = 400 : Comparison between QA and IC ############################################### @@ -163,18 +218,24 @@ def plot_oscillation_distribution(fig, axs, row, col, nbubbles_x, inttype, rati ######### D/R0 = 400 : Radius evolution ########################################################### fig, ax = plt.subplots(1, 1, figsize=(27.5*cm, 12.5*cm)) -ax.set_xlabel(r"t [$\mu$s]") +ax.set_xlabel(r"$t$ [$\mu$s]") ax.set_xlim(xmin=0.0, xmax=60.0) -ax.set_ylabel(r"$\left(R(t) - R_{0} \right) / R_{0}$ [-]") +ax.set_ylabel(r"$|r'|$ [-]") ax.set_yscale("log") ax.set_ylim(ymin=10**(-4), ymax=5.0e-2) ### QA ### -ax.plot(np.array(dic_radii["QA"][1.0][400][0])*1.0e6, np.array(dic_radii["QA"][1.0][400][1301]), linewidth=2.0, color="black", linestyle="dashed", label="QA") +t_list, r_list = identify_oscillation_amplitude(np.array(dic_radii_index["QA"][1.0][400][0]), np.array(dic_radii_index["QA"][1.0][400][1])) +ax.plot(np.array(t_list)*1.0e6, np.array(r_list)/R0, linewidth=2.0, color="black", linestyle="dashed", label="QA") +# ax.plot(np.array(dic_radii_index["QA"][1.0][400][0])*1.0e6, np.array(dic_radii_index["QA"][1.0][400][1]), linewidth=2.0, color="black", linestyle="dashed", label="QA") +# ax.plot(np.array(dic_radii["QA"][1.0][400][0])*1.0e6, np.array(dic_radii["QA"][1.0][400][1301]), linewidth=2.0, color="black", linestyle="dashed", label="QA") # ax.plot(np.array(dic_radii["QA"][1.0][400][0])*1.0e6, np.array(dic_radii["QA"][1.0][400][1]), linewidth=1.5, marker="s", markersize=5.0, markevery=1500, color="black", linestyle="dashed", label="QA, corner") ### IC ### -ax.plot(np.array(dic_radii["IC"][1.0][400][0])*1.0e6, np.array(dic_radii["IC"][1.0][400][1301]), linewidth=2.0, color="red", linestyle="solid", label="IC") +t_list, r_list = identify_oscillation_amplitude(np.array(dic_radii_index["IC"][1.0][400][0]), np.array(dic_radii_index["IC"][1.0][400][1])) +ax.plot(np.array(t_list)*1.0e6, np.array(r_list)/R0, linewidth=2.0, color="red", linestyle="solid", label="IC") +# ax.plot(np.array(dic_radii_index["IC"][1.0][400][0])*1.0e6, np.array(dic_radii_index["IC"][1.0][400][1]), linewidth=2.0, color="red", linestyle="solid", label="IC") +# ax.plot(np.array(dic_radii["IC"][1.0][400][0])*1.0e6, np.array(dic_radii["IC"][1.0][400][1301]), linewidth=2.0, color="red", linestyle="solid", label="IC") # ax.plot(np.array(dic_radii["IC"][1.0][400][0])*1.0e6, np.array(dic_radii["IC"][1.0][400][1]), linewidth=1.5, marker="s", markersize=5.0, markevery=1500, color="red", linestyle="solid", label="IC, corner") ax.legend(bbox_to_anchor=(0.5, 1.05), loc="center", frameon=False, ncol=2) From 626815462d8726a8095fd13ebd67864e8a13c02a Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 30 Aug 2024 12:00:50 -0400 Subject: [PATCH 077/138] cavitationonset ; new figure for pressure evolution in 2 bubbles test case + function to identify time when 2 bubbles are colliding + small figure improvements --- examples/cavitationonset/plot_results.py | 122 ++++++++++++++---- .../cavitationonset/run_cavitationonset.sh | 2 +- 2 files changed, 101 insertions(+), 23 deletions(-) diff --git a/examples/cavitationonset/plot_results.py b/examples/cavitationonset/plot_results.py index e9ea27b..733c29f 100644 --- a/examples/cavitationonset/plot_results.py +++ b/examples/cavitationonset/plot_results.py @@ -76,6 +76,18 @@ dic_data[i][2].append(r) dic_data[i][3].append(pt) +######### Functions ############################################################################### + +def identify_end_time_index(inttype, png, dist) : + # identify in the 2 bubbles case the time at which the bubbles are touching (the spherical assumption becomes unrelevant) + data = dic_2_bubbles[inttype][png][dist] + + index = 0 + while index < len(data[0][1]) and data[0][2][index] + data[1][2][index] < dist * (data[0][2][0] + data[1][2][0]) : + index += 1 + + return index + ######### Step 2 : Plotting results ################################################################################################################# ######### Initial parameters #################### @@ -92,9 +104,9 @@ plt.subplots_adjust(wspace=0.5*cm, hspace=0.5*cm) axs[0].set_title("Pressure time history (" + r"$T$ = " + "{:.1f} ".format(T*1.0e06) + r"$\mu$s)") -axs[0].set_xlabel(r"t [$\mu$s]", fontsize=27.5) +axs[0].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) axs[0].set_xlim(xmin=0.0, xmax=60.0) -axs[0].set_ylabel(r"$p_{\infty}$/$p_{0}$ [-]", fontsize=27.5) +axs[0].set_ylabel(r"$p_{\infty}$/$p_{0}$", fontsize=27.5) axs[0].grid() t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][1]) * 1.0e6 @@ -102,17 +114,19 @@ axs[0].plot(t_list, p_list, color="black", linewidth=2.5) axs[1].set_title("Evolution of radius without interaction") -axs[1].set_xlabel(r"t [$\mu$s]", fontsize=27.5) +axs[1].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) axs[1].set_xlim(xmin=0.0, xmax=60.0) axs[1].set_ylabel(r"$R$ [$\mu$m]", fontsize=27.5) axs[1].grid() -t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][1]) * 1.0e6 -r_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][2]) * 1.0e6 +index_t = identify_end_time_index("NI", -25325, 15.0) + +t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][1])[:index_t] * 1.0e6 +r_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][2])[:index_t] * 1.0e6 axs[1].plot(t_list, r_list, color="blue", label=r"$R_{1,0}$ = 2.0 $\mu$m", linewidth=2.5) -t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][1][1]) * 1.0e6 -r_list = np.array(dic_2_bubbles["NI"][-25325][15.0][1][2]) * 1.0e6 +t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][1][1])[:index_t] * 1.0e6 +r_list = np.array(dic_2_bubbles["NI"][-25325][15.0][1][2])[:index_t] * 1.0e6 axs[1].plot(t_list, r_list, color="magenta", linestyle="dashed", label=r"$R_{2,0}$ = 20.0 $\mu$m", linewidth=2.5) axs[1].legend(loc="upper left", frameon=False) @@ -130,7 +144,7 @@ png_list = [-17221, -17725.5, -18353.2, -18770.3] ax.set_title("Cavitation inception of a single bubble \n depending on " + r"$p_{ng}$/$p_{0}$ ($R_{0}$ = 2 $\mu$m)") -ax.set_xlabel(r"t [$\mu$s]", fontsize=27.5) +ax.set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) ax.set_xlim(xmin=10.0, xmax=60.0) ax.set_ylabel(r"$R$ [$\mu$m]", fontsize=27.5) ax.set_ylim(ymin=0.0, ymax=14.0) @@ -160,7 +174,7 @@ dist_list = [10, 12, 12.1, 12.5, 15, 20] axs[0].set_title(r"Incompressible interactions") -axs[0].set_xlabel(r"t [$\mu$s]", fontsize=27.5) +axs[0].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) axs[0].set_xlim(xmin=0.0, xmax=60.0) axs[0].set_ylabel(r"$R$ [$\mu$m]", fontsize=27.5) axs[0].set_ylim(ymin=-5.0, ymax=80.0) @@ -186,15 +200,15 @@ axs[0].text(36.5, 73.5, r"$\infty$", color="blue") axs[0].text(42.5, 73.5, r"20", color="blue") axs[0].text(54.0, 73.5, r"15", color="blue") -axs[0].text(50.0, 54.0, r"12.5", color="blue") -axs[0].text(45.0, 15.0, r"12.1", color="blue") -axs[0].text(37.0, 6.5, r"12", color="blue") +axs[0].text(47.0, 54.0, r"12.5", color="blue") +axs[0].text(45.0, 17.0, r"12.1", color="blue") +axs[0].text(41.0, 6.75, r"12", color="blue") axs[0].text(25.0, -2.5, r"10", color="blue") dist_list = [10, 11.9, 12, 15, 20] axs[1].set_title(r"Quasi-acoustic interactions") -axs[1].set_xlabel(r"t [$\mu$s]", fontsize=27.5) +axs[1].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) axs[1].set_xlim(xmin=0.0, xmax=60.0) # axs[1].set_ylabel(r"$R$ [$\mu$m]") axs[1].set_ylim(ymin=-5.0, ymax=80.0) @@ -234,10 +248,10 @@ fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm))) plt.subplots_adjust(wspace=0.35*cm, hspace=0.5*cm) -png_list = [-25325, -27351, -27958.8, -29377] +png_list = [-25325, -27351, -27654.9, -27958.8, -29377] axs[0].set_title(r"Incompressible interactions") -axs[0].set_xlabel(r"t [$\mu$s]", fontsize=27.5) +axs[0].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) axs[0].set_xlim(xmin=0.0, xmax=60.0) axs[0].set_ylabel(r"$R_{1}$ [$\mu$m]", fontsize=27.5) axs[0].set_ylim(ymin=0.0, ymax=40.0) @@ -249,17 +263,24 @@ axs[0].plot(t_list, r_list, color="blue", linewidth=2.5) +# index_t = identify_end_time_index("IC", -27958.8, 10.0) +# t_list = np.array(dic_2_bubbles["IC"][-27958.8][10.0][1][1])[:index_t] * 1.0e6 +# r_list = np.array(dic_2_bubbles["IC"][-27958.8][10.0][1][2])[:index_t] * 1.0e6 + +# axs[0].plot(t_list, r_list, color="magenta", linewidth=2.5, linestyle="dashed") + axs[0].text(0.5, 3.0, r"$R_{1,0}$", color="blue") axs[0].text(32.0, 37.5, r"-0.29", color="blue") -axs[0].text(45.0, 25.5, r"-0.276", color="blue") +axs[0].text(45.0, 28.5, r"-0.276", color="blue") +axs[0].text(43.0, 17.5, r"-0.273", color="blue") axs[0].text(30.0, 8.0, r"-0.27", color="blue") axs[0].text(23.0, 0.5, r"-0.25", color="blue") png_list = [-25325, -27351, -27958.8, -27654.9, -29377] axs[1].set_title(r"Quasi-acoustic interactions") -axs[1].set_xlabel(r"t [$\mu$s]", fontsize=27.5) +axs[1].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) axs[1].set_xlim(xmin=0.0, xmax=60.0) # axs[1].set_ylabel(r"$R$ [$\mu$m]") axs[1].set_ylim(ymin=0.0, ymax=40.0) @@ -281,6 +302,61 @@ fig.savefig("cavitationonset_varyingpressure.pdf", bbox_inches='tight',pad_inches=0.35) +##### Pressure evolution ###### + +nrow = 1 +ncol = 1 + +fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm))) +plt.subplots_adjust(wspace=0.35*cm, hspace=0.5*cm) + +png_list = [-27351] + +axs.set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) +axs.set_ylabel(r"$p_{\infty, 1} / p_{0}$", fontsize=27.5) +axs.set_xlim(xmin=0.0, xmax=60.0) +axs.grid() + +secyax = axs.twinx() +secyax.yaxis.label.set_color("blue") +secyax.spines["right"].set_color("blue") +secyax.tick_params("y", colors="blue") +secyax.spines["right"].set_edgecolor("blue") +secyax.set_ylabel(r"$(p_{\infty, 1, \mathrm{QA}} - p_{\infty, 1, \mathrm{IC}}) / p_{0}$", fontsize=27.5) + +for png in png_list : + t_list = np.array(dic_2_bubbles["IC"][png][10.0][0][1]) * 1.0e6 + p_list = np.array(dic_2_bubbles["IC"][png][10.0][0][3]) / P0 + + axs.plot(t_list, p_list, color="red", linewidth=2.5, label="IC") + + t_IC = t_list[dic_2_bubbles["IC"][png][10.0][0][2].index(np.max(dic_2_bubbles["IC"][png][10.0][0][2]))] + + t_list = np.array(dic_2_bubbles["QA"][png][10.0][0][1]) * 1.0e6 + p_list = np.array(dic_2_bubbles["QA"][png][10.0][0][3]) / P0 + + axs.plot(t_list, p_list, color="black", linewidth=2.5, linestyle="dashed", label="QA") + + t_QA = t_list[dic_2_bubbles["QA"][png][10.0][0][2].index(np.max(dic_2_bubbles["QA"][png][10.0][0][2]))] + + p_list_new = [] + for i in range(0, len(p_list), 10) : + p_list_new.append(p_list[i]) + + diff_p = np.array(p_list_new) - np.array(dic_2_bubbles["IC"][png][10.0][0][3]) / P0 + + secyax.plot(np.array(dic_2_bubbles["IC"][png][10.0][0][1]) * 1.0e6, diff_p, color="blue", linewidth=2.5, linestyle="dotted", label=r"$\Delta p_{\infty, 1}$ (QA - IC)") + +axs.set_xticks([20, t_IC, t_QA, 40]) +axs.set_xticklabels([20, r"$t_{\mathrm{IC}}$", r"$t_{\mathrm{QA}}$", 40]) +axs.set_xlim(xmin=10.0, xmax=35.0) +secyax.set_ylim(ymin=-0.002, ymax=0.002) + +axs.legend(bbox_to_anchor=(0.5, 1.15), loc="center", ncol=2, frameon=False) +secyax.legend(bbox_to_anchor=(0.5, 1.05), loc="center", ncol=1, frameon=False) + +fig.savefig("cavitationonset_varyingpressure_pressure.pdf", bbox_inches='tight',pad_inches=0.35) + ######### Cavitation inception with monodispersed simple distributions ############################ nrow = 2 @@ -291,7 +367,7 @@ dic_color = {1 : "black", 2 : "red", 3 : "magenta", 4 : "blue", 8 : "green"} nbubble_list = [1, 2, 3, 4, 8] -dic_shape = {1 : "single bubble", 2 : "Line of 2 bubbles", 3 : "3 bubbles-regular triangle", 4 : "4 bubbles-regular tetragon", 8 : "8 bubbles-regular hexaedron"} +dic_shape = {1 : "single bubble", 2 : "2 bubbles", 3 : "3 bubbles (regular triangle)", 4 : "4 bubbles (regular tetrahedron)", 8 : "8 bubbles (regular hexaedron)"} dic_linestyle = {1 : "solid", 2 : "dashed", 3 : "-.", 4 : "dotted", 8 : "dashdot"} dic_marker = {1 : "*", 2 : "s", 3 : "X", 4 : "^", 8 : "D"} @@ -303,11 +379,13 @@ axs[0, 0].set_title(r"Incompressible interactions") axs[0, 1].set_title(r"Quasi-acoustic interactions") -axs[1, 0].set_xlabel(r"t [$\mu$s]", fontsize=27.5) -axs[1, 1].set_xlabel(r"t [$\mu$s]", fontsize=27.5) +axs[1, 0].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) +axs[1, 1].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) +# axs[0, 0].set_ylim(ymin=10.0, ymax=40.0) +# axs[0, 1].set_ylim(ymin=10.0, ymax=40.0) -axs[0, 0].set_ylabel(r"$R_{1}$ [$\mu$m]", fontsize=27.5) -axs[1, 0].set_ylabel(r"$P_{1, \infty}$/$P_{0}$ [-]", fontsize=27.5) +axs[0, 0].set_ylabel(r"$R$ [$\mu$m]", fontsize=27.5) +axs[1, 0].set_ylabel(r"$p_{\infty}$/$p_{0}$", fontsize=27.5) axs[1, 0].set_ylim(ymin=-0.255, ymax=0.0) axs[1, 1].set_ylim(ymin=-0.255, ymax=0.0) diff --git a/examples/cavitationonset/run_cavitationonset.sh b/examples/cavitationonset/run_cavitationonset.sh index c688f6b..473c3d1 100755 --- a/examples/cavitationonset/run_cavitationonset.sh +++ b/examples/cavitationonset/run_cavitationonset.sh @@ -53,7 +53,7 @@ do done ######### Cavitation inception with interactions with varying pressure between 2 bubbles ########## -png_list=(-25325 -27351 -27958.8 -29377) +png_list=(-25325 -27351 -27654.9 -27958.8 -29377) for png in "${png_list[@]}" do ./build/cavitationonset_apecss -options run.apecss -amp $png -tend 60.0e-6 -nbb 2 -cldistrib 0 -clsize 10 -inttype 1 From 6ac0b241f53fa802d8e8775d9ffc7979c7b305da Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 30 Aug 2024 13:24:31 -0400 Subject: [PATCH 078/138] cavitationonset ; adding a new figure for the multibubble test case exhibiting the differences in radius and pressure evolution between the two interaction models --- examples/cavitationonset/plot_results.py | 38 ++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/examples/cavitationonset/plot_results.py b/examples/cavitationonset/plot_results.py index 733c29f..6c6da29 100644 --- a/examples/cavitationonset/plot_results.py +++ b/examples/cavitationonset/plot_results.py @@ -345,7 +345,7 @@ def identify_end_time_index(inttype, png, dist) : diff_p = np.array(p_list_new) - np.array(dic_2_bubbles["IC"][png][10.0][0][3]) / P0 - secyax.plot(np.array(dic_2_bubbles["IC"][png][10.0][0][1]) * 1.0e6, diff_p, color="blue", linewidth=2.5, linestyle="dotted", label=r"$\Delta p_{\infty, 1}$ (QA - IC)") + secyax.plot(np.array(dic_2_bubbles["IC"][png][10.0][0][1]) * 1.0e6, diff_p, color="blue", linewidth=2.5, linestyle="dotted", label=r"$\Delta p_{\infty, 1} / p_{0}$ (QA - IC)") axs.set_xticks([20, t_IC, t_QA, 40]) axs.set_xticklabels([20, r"$t_{\mathrm{IC}}$", r"$t_{\mathrm{QA}}$", 40]) @@ -406,4 +406,38 @@ def identify_end_time_index(inttype, png, dist) : axs[0, 0].legend(bbox_to_anchor=(1.1, 1.05), loc="lower center", ncol=2, frameon=False) -fig.savefig("cavitationonset_monodispersedclusters.pdf", bbox_inches='tight',pad_inches=0.35) \ No newline at end of file +fig.savefig("cavitationonset_monodispersedclusters.pdf", bbox_inches='tight',pad_inches=0.35) + +######### Exhibiting differences ################################################################## + +nrow = 1 +ncol = 2 + +fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm)), sharex=True) +plt.subplots_adjust(wspace=0.85*cm, hspace=0.25*cm) + +for i in range(2) : + axs[i].grid() + axs[i].set_xlim(xmin=10.0, xmax=60.0) + +axs[0].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) +axs[1].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) + +axs[0].set_ylabel(r"$R_{\mathrm{QA}} - R_{\mathrm{IC}}$ [$\mu$m]", fontsize=27.5) +axs[1].set_ylabel(r"$(p_{\infty, \mathrm{QA}} - p_{\infty, \mathrm{IC}})$/$p_{0}$", fontsize=27.5) + +for nbubble in nbubble_list : + t_list_IC = np.array(dic_n_bubbles["IC"][nbubble][0][1]) * 1.0e6 + r_list_IC = np.array(dic_n_bubbles["IC"][nbubble][0][2]) * 1.0e6 + p_list_IC = np.array(dic_n_bubbles["IC"][nbubble][0][3]) / P0 + + t_list_QA = np.array(dic_n_bubbles["QA"][nbubble][0][1]) * 1.0e6 + r_list_QA = np.array(dic_n_bubbles["QA"][nbubble][0][2]) * 1.0e6 + p_list_QA = np.array(dic_n_bubbles["QA"][nbubble][0][3]) / P0 + + axs[0].plot(t_list_IC, r_list_QA - r_list_IC, color=dic_color[nbubble], label=dic_shape[nbubble], marker=dic_marker[nbubble], markevery=600, markersize=10.0, linewidth=2.5) + axs[1].plot(t_list_IC, p_list_QA - p_list_IC, color=dic_color[nbubble], marker=dic_marker[nbubble], markevery=600, markersize=10.0, linewidth=2.5) + +axs[0].legend(bbox_to_anchor=(1.1, 0.95), loc="lower center", ncol=2, frameon=False) + +fig.savefig("cavitationonset_monodispersedclusters_differences.pdf", bbox_inches='tight',pad_inches=0.35) \ No newline at end of file From 31b1b2a0159b7e885260aa5fc8eeaaa84f74c2ca Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 30 Aug 2024 14:09:57 -0400 Subject: [PATCH 079/138] tensionwave ; figures correction --- .../plot_results.py | 230 +++++++++--------- 1 file changed, 117 insertions(+), 113 deletions(-) diff --git a/examples/sphericalclustertensionwave/plot_results.py b/examples/sphericalclustertensionwave/plot_results.py index ff0dcd7..a445aaa 100644 --- a/examples/sphericalclustertensionwave/plot_results.py +++ b/examples/sphericalclustertensionwave/plot_results.py @@ -217,7 +217,7 @@ print("{} cluster with N={} bubbles, minimum distance between bubbles equals {:.2f} microns".format(cluster, count, min_dist*1.0e6)) fig, ax = plt.subplots(1, 1, figsize=(17.5*cm, 12.5*cm)) -ax.set_xlabel(r"$ / R_{0,ref}$ [-]", fontsize=15) +ax.set_xlabel(r"$ / R_{0,ref}$", fontsize=15) ax.grid() for count in list(dic_bubbles["NI"]["poly"].keys()) : @@ -243,12 +243,12 @@ ncol = 3 fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) for i in range(ncol) : - axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=15) - axs[i].set_ylabel(r"$ / R_{0}$ [-]", fontsize=15) - axs[i].set_xlim(xmin=0.0, xmax=80.0) + axs[i].set_xlabel(r"$ t$ [$\mu$s]", fontsize=15) + axs[i].set_ylabel(r"$ / R_{0}$", fontsize=15) + axs[i].set_xlim(xmin=0.0, xmax=15.0) axs[i].grid() -axs[0].set_title(r"No interaction" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[0].set_title(r"No interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) @@ -258,8 +258,8 @@ for k in dic_loc_distrib_global[count][p1].keys() : index_list = dic_loc_distrib_global[count][p1][k] - # No interaction - t_list = (1/t_i) * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) + # No interactions + t_list = 1.0e06 * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) r_list_0 = np.array(dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][1]) init_r_0 = dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][0] @@ -277,7 +277,7 @@ axs[0].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) # Incompressible interactions - t_list = (1/t_i) * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) r_list_0 = np.array(dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][1]) init_r_0 = dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][0] @@ -295,7 +295,7 @@ axs[1].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) # Quasi-acoustic interactions - t_list = (1/t_i) * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) r_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][1]) init_r_0 = dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][0] @@ -325,15 +325,15 @@ ncol = 3 fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) for i in range(ncol) : - axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=27.5) - if i == 0 : axs[i].set_ylabel(r"$ / R_{0}$ [-]", fontsize=27.5) - axs[i].set_xlim(xmin=0.0, xmax=80.0) + axs[i].set_xlabel(r"$ t$ [$\mu$s]", fontsize=27.5) + if i == 0 : axs[i].set_ylabel(r"$ / R_{0}$", fontsize=27.5) + axs[i].set_xlim(xmin=0.0, xmax=15.0) axs[i].tick_params(axis="both", labelsize=25) axs[i].grid() plt.subplots_adjust(wspace=0.35*cm) -axs[0].set_title(r"No interaction", fontsize=27.5) +axs[0].set_title(r"No interactions", fontsize=27.5) axs[1].set_title(r"Incompressible interactions", fontsize=27.5) axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) @@ -343,8 +343,8 @@ for k in dic_loc_distrib_global[count][p1].keys() : index_list = dic_loc_distrib_global[count][p1][k] - # No interaction - t_list = (1/t_i) * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) + # No interactions + t_list = 1.0e06 * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) r_list_0 = np.array(dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][1]) init_r_0 = dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][0] @@ -362,7 +362,7 @@ axs[0].plot(t_list, avg_radius, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) # Incompressible interactions - t_list = (1/t_i) * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) r_list_0 = np.array(dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][1]) init_r_0 = dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][0] @@ -380,7 +380,7 @@ axs[1].plot(t_list, avg_radius, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) # Quasi-acoustic interactions - t_list = (1/t_i) * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) r_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][1]) init_r_0 = dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][0] @@ -411,12 +411,12 @@ ncol = 3 fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) for i in range(ncol) : - axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=15) - axs[i].set_ylabel(r"$$ [-]", fontsize=15) + axs[i].set_xlabel(r"$ t$ [$\mu$s]", fontsize=15) + axs[i].set_ylabel(r"$$", fontsize=15) # axs[i].set_xlim(xmin=10.0, xmax=60.0) axs[i].grid() -axs[0].set_title(r"No interaction" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[0].set_title(r"No interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) @@ -439,18 +439,18 @@ elif i == 2 : dic_label_q[quantile] = "3rd-{}".format(quantile_name) -# No interaction -axs[0].set_xlim(xmin=0.0,xmax=250.0) +# No interactions +axs[0].set_xlim(xmin=0.0,xmax=50.0) axs[0].set_ylim(ymin=0.95,ymax=1.6) zm = axs[0].inset_axes([0.25, 0.25, 0.7, 0.7]) zm.grid() -zm.set_xlim(xmax=50.0) +zm.set_xlim(xmax=10.0) for q in list(dic_polydisperse["NI"][count][p1].keys())[1:] : index_list = dic_polydisperse["NI"][count][p1][q] - t_list = (1/t_i) * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) r_list_0 = np.array(dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][1]) init_r_0 = dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][0] @@ -470,17 +470,17 @@ zm.plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) # Incompressible interactions -axs[1].set_xlim(xmin=-10.0,xmax=800.0) +axs[1].set_xlim(xmin=0.0,xmax=150.0) axs[1].set_ylim(ymin=0.925,ymax=1.25) zm = axs[1].inset_axes([0.25, 0.5, 0.7, 0.45]) zm.grid() -zm.set_xlim(xmax=200.0) +zm.set_xlim(xmax=37.5) for q in list(dic_polydisperse["IC"][count][p1].keys())[1:] : index_list = dic_polydisperse["IC"][count][p1][q] - t_list = (1/t_i) * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) r_list_0 = np.array(dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][1]) init_r_0 = dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][0] @@ -500,17 +500,17 @@ zm.plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) # Quasi-acoustic interactions -axs[2].set_xlim(xmin=-10.0,xmax=1000.0) +axs[2].set_xlim(xmin=0.0,xmax=150.0) axs[2].set_ylim(ymin=0.925,ymax=1.25) zm = axs[2].inset_axes([0.25, 0.5, 0.7, 0.45]) zm.grid() -zm.set_xlim(xmax=250.0) +zm.set_xlim(xmax=37.5) for q in list(dic_polydisperse["QA"][count][p1].keys())[1:] : index_list = dic_polydisperse["QA"][count][p1][q] - t_list = (1/t_i) * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) r_list_0 = np.array(dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][1]) init_r_0 = dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][0] @@ -542,14 +542,14 @@ ncol = 3 fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) for i in range(ncol) : - axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=27.5) - if i == 0 : axs[i].set_ylabel(r"$$ [-]", fontsize=27.5) + axs[i].set_xlabel(r"$ t$ [$\mu$s]", fontsize=27.5) + if i == 0 : axs[i].set_ylabel(r"$$", fontsize=27.5) # axs[i].set_xlim(xmin=10.0, xmax=60.0) axs[i].tick_params(axis="both", labelsize=25) axs[i].grid() plt.subplots_adjust(wspace=0.35*cm) -axs[0].set_title(r"No interaction", fontsize=27.5) +axs[0].set_title(r"No interactions", fontsize=27.5) axs[1].set_title(r"Incompressible interactions", fontsize=27.5) axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) @@ -572,19 +572,19 @@ elif i == 2 : dic_label_q[quantile] = "3rd-{}".format(quantile_name) -# No interaction -axs[0].set_xlim(xmin=0.0,xmax=250.0) +# No interactions +axs[0].set_xlim(xmin=0.0,xmax=50.0) axs[0].set_ylim(ymin=0.95,ymax=1.6) zm = axs[0].inset_axes([0.25, 0.25, 0.7, 0.7]) zm.grid() -zm.set_xlim(xmin=0.0, xmax=50.0) +zm.set_xlim(xmin=0.0, xmax=10.0) zm.tick_params(axis="both", labelsize=25) for q in list(dic_polydisperse["NI"][count][p1].keys())[1:] : index_list = dic_polydisperse["NI"][count][p1][q] - t_list = (1/t_i) * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) r_list_0 = np.array(dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][1]) init_r_0 = dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][0] @@ -604,18 +604,18 @@ zm.plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) # Incompressible interactions -axs[1].set_xlim(xmin=-10.0,xmax=800.0) +axs[1].set_xlim(xmin=0.0,xmax=150.0) axs[1].set_ylim(ymin=0.925,ymax=1.25) zm = axs[1].inset_axes([0.25, 0.5, 0.7, 0.45]) zm.grid() -zm.set_xlim(xmax=200.0) +zm.set_xlim(xmax=37.5) zm.tick_params(axis="both", labelsize=25) for q in list(dic_polydisperse["IC"][count][p1].keys())[1:] : index_list = dic_polydisperse["IC"][count][p1][q] - t_list = (1/t_i) * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) r_list_0 = np.array(dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][1]) init_r_0 = dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][0] @@ -635,18 +635,18 @@ zm.plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) # Quasi-acoustic interactions -axs[2].set_xlim(xmin=-10.0,xmax=800.0) +axs[2].set_xlim(xmin=0.0,xmax=150.0) axs[2].set_ylim(ymin=0.925,ymax=1.25) zm = axs[2].inset_axes([0.25, 0.5, 0.7, 0.45]) zm.grid() -zm.set_xlim(xmax=200.0) +zm.set_xlim(xmax=37.5) zm.tick_params(axis="both", labelsize=25) for q in list(dic_polydisperse["QA"][count][p1].keys())[1:] : index_list = dic_polydisperse["QA"][count][p1][q] - t_list = (1/t_i) * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) r_list_0 = np.array(dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][1]) init_r_0 = dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][0] @@ -677,12 +677,12 @@ ncol = 3 fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) for i in range(ncol) : - axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=15) - axs[i].set_ylabel(r"$ / R_{0}$ [-]", fontsize=15) + axs[i].set_xlabel(r"$ t$ [$\mu$s]", fontsize=15) + axs[i].set_ylabel(r"$ / R_{0}$", fontsize=15) # axs[i].set_xlim(xmin=10.0, xmax=60.0) axs[i].grid() -axs[0].set_title(r"No interaction" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[0].set_title(r"No interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) @@ -695,8 +695,8 @@ for k in dic_loc_distrib_global[count][p1].keys() : index_list = dic_loc_distrib_global[count][p1][k] - # No interaction - t_list = (1/t_i) * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) + # No interactions + t_list = 1.0e06 * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) r_list_0 = np.array(dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][1]) init_r_0 = dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][0] @@ -714,7 +714,7 @@ axs[0].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) # Incompressible interactions - t_list = (1/t_i) * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) r_list_0 = np.array(dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][1]) init_r_0 = dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][0] @@ -732,7 +732,7 @@ axs[1].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) # Quasi-acoustic interactions - t_list = (1/t_i) * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) r_list_0 = np.array(dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][1]) init_r_0 = dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][0] @@ -764,12 +764,12 @@ ncol = 3 fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) for i in range(ncol) : - axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=15) - axs[i].set_ylabel(r"$ / p_{0}$ [-]", fontsize=15) - axs[i].set_xlim(xmin=0.0, xmax=80.0) + axs[i].set_xlabel(r"$ t$ [$\mu$s]", fontsize=15) + axs[i].set_ylabel(r"$ / p_{0}$", fontsize=15) + axs[i].set_xlim(xmin=0.0, xmax=15.0) axs[i].grid() -axs[0].set_title(r"No interaction" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[0].set_title(r"No interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) @@ -779,8 +779,8 @@ for k in dic_loc_distrib_global[count][p1].keys() : index_list = dic_loc_distrib_global[count][p1][k] - # No interaction - t_list = (1/t_i) * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) + # No interactions + t_list = 1.0e06 * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) p_list_0 = np.array(dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][2]) avg_pressure = p_list_0 / p0 @@ -796,7 +796,7 @@ axs[0].plot(t_list, avg_pressure, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) # Incompressible interactions - t_list = (1/t_i) * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) p_list_0 = np.array(dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][2]) avg_pressure = p_list_0 / p0 @@ -812,7 +812,7 @@ axs[1].plot(t_list, avg_pressure, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) # Quasi-acoustic interactions - t_list = (1/t_i) * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) p_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][2]) avg_pressure = p_list_0 / p0 @@ -841,15 +841,15 @@ ncol = 3 fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) for i in range(ncol) : - axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=27.5) - if i == 0 : axs[i].set_ylabel(r"$ / p_{0}$ [-]", fontsize=27.5) - axs[i].set_xlim(xmin=0.0, xmax=80.0) + axs[i].set_xlabel(r"$ t$ [$\mu$s]", fontsize=27.5) + if i == 0 : axs[i].set_ylabel(r"$ / p_{0}$", fontsize=27.5) + axs[i].set_xlim(xmin=0.0, xmax=15.0) axs[i].tick_params(axis="both", labelsize=25) axs[i].grid() plt.subplots_adjust(wspace=0.35*cm) -axs[0].set_title(r"No interaction", fontsize=27.5) +axs[0].set_title(r"No interactions", fontsize=27.5) axs[1].set_title(r"Incompressible interactions", fontsize=27.5) axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) @@ -858,16 +858,18 @@ zm_IC = axs[1].inset_axes([0.35, 0.35, 0.60, 0.60]) zm_IC.grid() -zm_IC.set_xlim(xmin=0.0,xmax=20.0) +zm_IC.set_xlim(xmin=0.0,xmax=5.0) zm_IC.set_ylim(ymin=-0.5,ymax=2.0) +zm_IC.set_xticks([0, 2, 4]) zm_IC.set_yticks([-0.267, 0.0, 1.0, 2.0]) zm_IC.set_yticklabels([r"$p_{\mathrm{C}}$", 0, 1, 2]) zm_IC.tick_params(axis="both", labelsize=25) zm_QA = axs[2].inset_axes([0.30, 0.4, 0.65, 0.55]) zm_QA.grid() -zm_QA.set_xlim(xmin=0.0,xmax=20.0) +zm_QA.set_xlim(xmin=0.0,xmax=5.0) zm_QA.set_ylim(ymin=-0.5,ymax=2.0) +zm_QA.set_xticks([0, 2, 4]) zm_QA.set_yticks([-0.267, 0.0, 1.0, 2.0]) zm_QA.set_yticklabels([r"$p_{\mathrm{C}}$", 0, 1, 2]) zm_QA.tick_params(axis="both", labelsize=25) @@ -875,8 +877,8 @@ for k in dic_loc_distrib_global[count][p1].keys() : index_list = dic_loc_distrib_global[count][p1][k] - # No interaction - t_list = (1/t_i) * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) + # No interactions + t_list = 1.0e06 * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) p_list_0 = np.array(dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][2]) avg_pressure = p_list_0 / p0 @@ -892,7 +894,7 @@ axs[0].plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) # Incompressible interactions - t_list = (1/t_i) * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) p_list_0 = np.array(dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][2]) avg_pressure = p_list_0 / p0 @@ -910,7 +912,7 @@ zm_IC.plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) # Quasi-acoustic interactions - t_list = (1/t_i) * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) p_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][2]) avg_pressure = p_list_0 / p0 @@ -941,12 +943,12 @@ ncol = 3 fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) for i in range(ncol) : - axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=15) - axs[i].set_ylabel(r"$/p_{0}$ [-]", fontsize=15) + axs[i].set_xlabel(r"$ t$ [$\mu$s]", fontsize=15) + axs[i].set_ylabel(r"$/p_{0}$", fontsize=15) # axs[i].set_xlim(xmin=10.0, xmax=60.0) axs[i].grid() -axs[0].set_title(r"No interaction" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[0].set_title(r"No interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) @@ -965,11 +967,11 @@ elif i == 2 : dic_label_q[quantile] = "3rd-{}".format(quantile_name) -# No interaction +# No interactions for q in list(dic_polydisperse["NI"][count][p1].keys())[1:] : index_list = dic_polydisperse["NI"][count][p1][q] - t_list = (1/t_i) * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) p_list_0 = np.array(dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][2]) avg_pressure = p_list_0 / p0 @@ -988,7 +990,7 @@ for q in list(dic_polydisperse["IC"][count][p1].keys())[1:] : index_list = dic_polydisperse["IC"][count][p1][q] - t_list = (1/t_i) * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) p_list_0 = np.array(dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][2]) avg_pressure = p_list_0 / p0 @@ -1007,7 +1009,7 @@ for q in list(dic_polydisperse["QA"][count][p1].keys())[1:] : index_list = dic_polydisperse["QA"][count][p1][q] - t_list = (1/t_i) * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) p_list_0 = np.array(dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][2]) avg_pressure = p_list_0 / p0 @@ -1036,15 +1038,15 @@ ncol = 3 fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) for i in range(ncol) : - axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=27.5) - if i == 0 : axs[i].set_ylabel(r"$/p_{0}$ [-]", fontsize=27.5) + axs[i].set_xlabel(r"$ t$ [$\mu$s]", fontsize=27.5) + if i == 0 : axs[i].set_ylabel(r"$/p_{0}$", fontsize=27.5) # axs[i].set_xlim(xmin=10.0, xmax=60.0) axs[i].tick_params(axis="both", labelsize=25) axs[i].grid() plt.subplots_adjust(wspace=0.35*cm) -axs[0].set_title(r"No interaction", fontsize=27.5) +axs[0].set_title(r"No interactions", fontsize=27.5) axs[1].set_title(r"Incompressible interactions", fontsize=27.5) axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) @@ -1063,11 +1065,11 @@ elif i == 2 : dic_label_q[quantile] = "3rd-{}".format(quantile_name) -# No interaction +# No interactions for q in list(dic_polydisperse["NI"][count][p1].keys())[1:] : index_list = dic_polydisperse["NI"][count][p1][q] - t_list = (1/t_i) * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) p_list_0 = np.array(dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][2]) avg_pressure = p_list_0 / p0 @@ -1086,7 +1088,7 @@ for q in list(dic_polydisperse["IC"][count][p1].keys())[1:] : index_list = dic_polydisperse["IC"][count][p1][q] - t_list = (1/t_i) * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) p_list_0 = np.array(dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][2]) avg_pressure = p_list_0 / p0 @@ -1105,7 +1107,7 @@ for q in list(dic_polydisperse["QA"][count][p1].keys())[1:] : index_list = dic_polydisperse["QA"][count][p1][q] - t_list = (1/t_i) * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) p_list_0 = np.array(dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][2]) avg_pressure = p_list_0 / p0 @@ -1134,15 +1136,15 @@ ncol = 3 fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) for i in range(ncol) : - axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=27.5) - if i == 0 : axs[i].set_ylabel(r"$ / R_{0}$ [-]", fontsize=27.5) - axs[i].set_xlim(xmin=0.0, xmax=80.0) + axs[i].set_xlabel(r"$ t$ [$\mu$s]", fontsize=27.5) + if i == 0 : axs[i].set_ylabel(r"$ / R_{0}$", fontsize=27.5) + axs[i].set_xlim(xmin=0.0, xmax=15.0) axs[i].tick_params(axis="both", labelsize=25) axs[i].grid() plt.subplots_adjust(wspace=0.35*cm) -axs[0].set_title(r"No interaction", fontsize=27.5) +axs[0].set_title(r"No interactions", fontsize=27.5) axs[1].set_title(r"Incompressible interactions", fontsize=27.5) axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) @@ -1152,8 +1154,8 @@ for k in dic_loc_distrib_global[count][p1].keys() : index_list = dic_loc_distrib_global[count][p1][k] - # No interaction - t_list = (1/t_i) * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) + # No interactions + t_list = 1.0e06 * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) r_list_0 = np.array(dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][1]) init_r_0 = dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][0] @@ -1171,7 +1173,7 @@ axs[0].plot(t_list, avg_radius, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) # Incompressible interactions - t_list = (1/t_i) * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) r_list_0 = np.array(dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][1]) init_r_0 = dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][0] @@ -1189,7 +1191,7 @@ axs[1].plot(t_list, avg_radius, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) # Quasi-acoustic interactions - t_list = (1/t_i) * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) r_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][1]) init_r_0 = dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][0] @@ -1222,15 +1224,15 @@ ncol = 3 fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) for i in range(ncol) : - axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=27.5) - if i == 0 : axs[i].set_ylabel(r"$ / p_{0}$ [-]", fontsize=27.5) - axs[i].set_xlim(xmin=0.0, xmax=80.0) + axs[i].set_xlabel(r"$ t$ [$\mu$s]", fontsize=27.5) + if i == 0 : axs[i].set_ylabel(r"$ / p_{0}$", fontsize=27.5) + axs[i].set_xlim(xmin=0.0, xmax=15.0) axs[i].tick_params(axis="both", labelsize=25) axs[i].grid() plt.subplots_adjust(wspace=0.35*cm) -axs[0].set_title(r"No interaction", fontsize=27.5) +axs[0].set_title(r"No interactions", fontsize=27.5) axs[1].set_title(r"Incompressible interactions", fontsize=27.5) axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) @@ -1239,16 +1241,18 @@ zm_IC = axs[1].inset_axes([0.35, 0.35, 0.60, 0.60]) zm_IC.grid() -zm_IC.set_xlim(xmin=0.0,xmax=20.0) +zm_IC.set_xlim(xmin=0.0,xmax=5.0) zm_IC.set_ylim(ymin=-0.5,ymax=2.0) +zm_IC.set_xticks([0, 2, 4]) zm_IC.set_yticks([-0.267, 0.0, 1.0, 2.0]) zm_IC.set_yticklabels([r"$p_{\mathrm{C}}$", 0, 1, 2]) zm_IC.tick_params(axis="both", labelsize=25) zm_QA = axs[2].inset_axes([0.30, 0.4, 0.65, 0.55]) zm_QA.grid() -zm_QA.set_xlim(xmin=0.0,xmax=20.0) +zm_QA.set_xlim(xmin=0.0,xmax=5.0) zm_QA.set_ylim(ymin=-0.5,ymax=2.0) +zm_QA.set_xticks([0, 2, 4]) zm_QA.set_yticks([-0.267, 0.0, 1.0, 2.0]) zm_QA.set_yticklabels([r"$p_{\mathrm{C}}$", 0, 1, 2]) zm_QA.tick_params(axis="both", labelsize=25) @@ -1256,8 +1260,8 @@ for k in dic_loc_distrib_global[count][p1].keys() : index_list = dic_loc_distrib_global[count][p1][k] - # No interaction - t_list = (1/t_i) * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) + # No interactions + t_list = 1.0e06 * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) p_list_0 = np.array(dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][2]) avg_pressure = p_list_0 / p0 @@ -1273,7 +1277,7 @@ axs[0].plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) # Incompressible interactions - t_list = (1/t_i) * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) p_list_0 = np.array(dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][2]) avg_pressure = p_list_0 / p0 @@ -1291,7 +1295,7 @@ zm_IC.plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) # Quasi-acoustic interactions - t_list = (1/t_i) * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) p_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][2]) avg_pressure = p_list_0 / p0 @@ -1322,14 +1326,14 @@ ncol = 3 fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) for i in range(ncol) : - axs[i].set_xlabel(r"$ t / t_{i}$ [-]", fontsize=27.5) - if i == 0 : axs[i].set_ylabel(r"$$ [-]", fontsize=27.5) + axs[i].set_xlabel(r"$ t$ [$\mu$s]", fontsize=27.5) + if i == 0 : axs[i].set_ylabel(r"$$", fontsize=27.5) # axs[i].set_xlim(xmin=10.0, xmax=60.0) axs[i].tick_params(axis="both", labelsize=25) axs[i].grid() plt.subplots_adjust(wspace=0.35*cm) -axs[0].set_title(r"No interaction", fontsize=27.5) +axs[0].set_title(r"No interactions", fontsize=27.5) axs[1].set_title(r"Incompressible interactions", fontsize=27.5) axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) @@ -1352,19 +1356,19 @@ elif i == 2 : dic_label_q[quantile] = "3rd-{}".format(quantile_name) -# No interaction -axs[0].set_xlim(xmin=0.0,xmax=250.0) +# No interactions +axs[0].set_xlim(xmin=0.0,xmax=50.0) axs[0].set_ylim(ymin=0.95,ymax=3.0) zm = axs[0].inset_axes([0.25, 0.25, 0.7, 0.7]) zm.grid() -zm.set_xlim(xmin=0.0, xmax=50.0) +zm.set_xlim(xmin=0.0, xmax=10.0) zm.tick_params(axis="both", labelsize=25) for q in list(dic_polydisperse["NI"][count][p1].keys())[1:] : index_list = dic_polydisperse["NI"][count][p1][q] - t_list = (1/t_i) * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) r_list_0 = np.array(dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][1]) init_r_0 = dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][0] @@ -1384,18 +1388,18 @@ zm.plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) # Incompressible interactions -axs[1].set_xlim(xmin=-10.0,xmax=800.0) +axs[1].set_xlim(xmin=0.0,xmax=150.0) axs[1].set_ylim(ymin=0.925,ymax=1.50) zm = axs[1].inset_axes([0.25, 0.5, 0.7, 0.45]) zm.grid() -zm.set_xlim(xmax=200.0) +zm.set_xlim(xmax=37.5) zm.tick_params(axis="both", labelsize=25) for q in list(dic_polydisperse["IC"][count][p1].keys())[1:] : index_list = dic_polydisperse["IC"][count][p1][q] - t_list = (1/t_i) * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) r_list_0 = np.array(dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][1]) init_r_0 = dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][0] @@ -1415,18 +1419,18 @@ zm.plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) # Quasi-acoustic interactions -axs[2].set_xlim(xmin=-10.0,xmax=800.0) +axs[2].set_xlim(xmin=0.0,xmax=150.0) axs[2].set_ylim(ymin=0.925,ymax=1.50) zm = axs[2].inset_axes([0.25, 0.5, 0.7, 0.45]) zm.grid() -zm.set_xlim(xmax=200.0) +zm.set_xlim(xmax=37.5) zm.tick_params(axis="both", labelsize=25) for q in list(dic_polydisperse["QA"][count][p1].keys())[1:] : index_list = dic_polydisperse["QA"][count][p1][q] - t_list = (1/t_i) * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) + t_list = 1.0e06 * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) r_list_0 = np.array(dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][1]) init_r_0 = dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][0] From 8935ed0cd2ab52561be4c91ee9a4b2811dbbf7b1 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 30 Aug 2024 14:46:12 -0400 Subject: [PATCH 080/138] tensionwave ; properly redifining tau in the incident wave for the lesser incident pressure --- .../IC/src/sphericalclustertensionwave_apecss.c | 4 ++-- .../NI/src/sphericalclustertensionwave_apecss.c | 4 ++-- .../QA/src/sphericalclustertensionwave_apecss.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/sphericalclustertensionwave/IC/src/sphericalclustertensionwave_apecss.c b/examples/sphericalclustertensionwave/IC/src/sphericalclustertensionwave_apecss.c index e2ed2f7..ffe6ef1 100644 --- a/examples/sphericalclustertensionwave/IC/src/sphericalclustertensionwave_apecss.c +++ b/examples/sphericalclustertensionwave/IC/src/sphericalclustertensionwave_apecss.c @@ -365,7 +365,7 @@ int main(int argc, char **args) APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { - APECSS_FLOAT tau = 1.41e-6; + APECSS_FLOAT tau = 1.75e-6; if (t < tau) { return (Bubble->p0 - (Bubble->p0 - Bubble->Excitation->dp) * APECSS_POW2(APECSS_SIN(APECSS_PI * t / tau)) + Bubble->Interaction->dp_neighbor); @@ -378,7 +378,7 @@ APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_ APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { - APECSS_FLOAT tau = 1.41e-6; + APECSS_FLOAT tau = 1.75e-6; if (t < tau) { APECSS_FLOAT inv_tau = 1 / tau; diff --git a/examples/sphericalclustertensionwave/NI/src/sphericalclustertensionwave_apecss.c b/examples/sphericalclustertensionwave/NI/src/sphericalclustertensionwave_apecss.c index 7226437..22dfb7d 100644 --- a/examples/sphericalclustertensionwave/NI/src/sphericalclustertensionwave_apecss.c +++ b/examples/sphericalclustertensionwave/NI/src/sphericalclustertensionwave_apecss.c @@ -360,7 +360,7 @@ int main(int argc, char **args) APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { - APECSS_FLOAT tau = 1.41e-6; + APECSS_FLOAT tau = 1.75e-6; if (t < tau) { return (Bubble->p0 - (Bubble->p0 - Bubble->Excitation->dp) * APECSS_POW2(APECSS_SIN(APECSS_PI * t / tau)) + Bubble->Interaction->dp_neighbor); @@ -373,7 +373,7 @@ APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_ APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { - APECSS_FLOAT tau = 1.41e-6; + APECSS_FLOAT tau = 1.75e-6; if (t < tau) { APECSS_FLOAT inv_tau = 1 / tau; diff --git a/examples/sphericalclustertensionwave/QA/src/sphericalclustertensionwave_apecss.c b/examples/sphericalclustertensionwave/QA/src/sphericalclustertensionwave_apecss.c index 2c21c0c..4fb6d5a 100644 --- a/examples/sphericalclustertensionwave/QA/src/sphericalclustertensionwave_apecss.c +++ b/examples/sphericalclustertensionwave/QA/src/sphericalclustertensionwave_apecss.c @@ -493,7 +493,7 @@ int main(int argc, char **args) APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { - APECSS_FLOAT tau = 1.41e-6; + APECSS_FLOAT tau = 1.75e-6; if (t < tau) { return (Bubble->p0 - (Bubble->p0 - Bubble->Excitation->dp) * APECSS_POW2(APECSS_SIN(APECSS_PI * t / tau)) + Bubble->Interaction->dp_neighbor); @@ -507,7 +507,7 @@ APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, stru APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { // Approximate numerical computation of p_infinity derivative - APECSS_FLOAT tau = 1.41e-6; + APECSS_FLOAT tau = 1.75e-6; APECSS_FLOAT derivative = 0.0; if (t < tau) { From fd7a53dcba0d25e2fbd5e402cfe562b46c08e3c4 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 3 Sep 2024 13:40:51 -0400 Subject: [PATCH 081/138] cavitationonset ; studying pressure drop for IC interactions --- .../IC/src/cavitationonset_apecss.c | 8 ++ examples/cavitationonset/plot_results.py | 100 +++++++++++++++++- 2 files changed, 106 insertions(+), 2 deletions(-) diff --git a/examples/cavitationonset/IC/src/cavitationonset_apecss.c b/examples/cavitationonset/IC/src/cavitationonset_apecss.c index cc2bfef..3f68ce1 100644 --- a/examples/cavitationonset/IC/src/cavitationonset_apecss.c +++ b/examples/cavitationonset/IC/src/cavitationonset_apecss.c @@ -400,6 +400,14 @@ int main(int argc, char **args) { fprintf(file_ida2009, " %e", Bubbles[i]->ode[0](Bubbles[i]->ODEsSol, Bubbles[i]->t, Bubbles[i])); } + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_ida2009, " %e", Bubbles[i]->Interaction->dp_neighbor); + } + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_ida2009, " %e", Bubbles[i]->U); + } fprintf(file_ida2009, "\n"); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< diff --git a/examples/cavitationonset/plot_results.py b/examples/cavitationonset/plot_results.py index 6c6da29..50f70d3 100644 --- a/examples/cavitationonset/plot_results.py +++ b/examples/cavitationonset/plot_results.py @@ -65,6 +65,10 @@ init_radius = float(second_line[i+1]) # list format : for each bubble, [R0, t_list, R_list, Pt_list] dic_data.append([init_radius, [], [], []]) + if (inttype == "IC") : + dic_data[-1].append([]) + dic_data[-1].append([]) + dic_data[-1].append([]) for line in lines[3:] : data = line.split(" ") @@ -75,6 +79,13 @@ dic_data[i][1].append(t) dic_data[i][2].append(r) dic_data[i][3].append(pt) + if (inttype == "IC") : + a = float(data[1 + 2 * count + i]) + dp = float(data[1 + 3 * count + i]) + u = float(data[1 + 4 * count + i]) + dic_data[i][4].append(a) + dic_data[i][5].append(dp) + dic_data[i][6].append(u) ######### Functions ############################################################################### @@ -94,6 +105,7 @@ def identify_end_time_index(inttype, png, dist) : T = 10.0e-06 P0 = 0.1013e06 +rho = 1000.0 ######### Pressure time history & radius evolution without interaction ############################ @@ -310,7 +322,7 @@ def identify_end_time_index(inttype, png, dist) : fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm))) plt.subplots_adjust(wspace=0.35*cm, hspace=0.5*cm) -png_list = [-27351] +png_list = [-27654.9] axs.set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) axs.set_ylabel(r"$p_{\infty, 1} / p_{0}$", fontsize=27.5) @@ -349,7 +361,7 @@ def identify_end_time_index(inttype, png, dist) : axs.set_xticks([20, t_IC, t_QA, 40]) axs.set_xticklabels([20, r"$t_{\mathrm{IC}}$", r"$t_{\mathrm{QA}}$", 40]) -axs.set_xlim(xmin=10.0, xmax=35.0) +# axs.set_xlim(xmin=10.0, xmax=35.0) secyax.set_ylim(ymin=-0.002, ymax=0.002) axs.legend(bbox_to_anchor=(0.5, 1.15), loc="center", ncol=2, frameon=False) @@ -357,6 +369,90 @@ def identify_end_time_index(inttype, png, dist) : fig.savefig("cavitationonset_varyingpressure_pressure.pdf", bbox_inches='tight',pad_inches=0.35) +#### Test ##### + +nrow = 6 +ncol = 1 + +fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm)), sharex=True) +plt.subplots_adjust(wspace=0.35*cm, hspace=0.25*cm) + +png_list = [-27654.9] + +axs[0].set_ylabel(r"$R / R_{0}$") +axs[1].set_ylabel(r"$p_{\infty} / p_{0}$") +axs[2].set_ylabel(r"$\rho R^{2} \ddot{R} / \Delta x_{12} p_{0}$") +axs[3].set_ylabel(r"$2 \rho \dot{R}^{2} R / \Delta x_{12} p_{0}$") +axs[4].set_ylabel(r"$\rho R^{4} \dot{R}^{2} / 2 \Delta x_{12}^{4} p_{0}$") +axs[5].set_ylabel(r"$\Delta p / p_{0}$") +axs[5].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) + +# axs[2].set_yscale("log") + +for i in range(nrow) : + axs[i].grid() + axs[i].set_xlim(xmin=55.0, xmax=60.0) + +axs[1].set_ylim(ymin=-0.4, ymax=0.15) + +for png in png_list : + dist = 10.0 + delta_x = dist * (dic_2_bubbles["IC"][png][dist][0][0] + dic_2_bubbles["IC"][png][dist][1][0]) + # first bubble + r0 = dic_2_bubbles["IC"][png][dist][0][0] + + t_list = np.array(dic_2_bubbles["IC"][png][dist][0][1]) * 1.0e6 + r_list = np.array(dic_2_bubbles["IC"][png][dist][0][2]) / r0 + p_list = np.array(dic_2_bubbles["IC"][png][dist][0][3]) / P0 + a_list = np.array(dic_2_bubbles["IC"][png][dist][0][4]) + dp_list = np.array(dic_2_bubbles["IC"][png][dist][0][5]) / P0 + u_list = np.array(dic_2_bubbles["IC"][png][dist][0][6]) + + t_collapse = t_list[dic_2_bubbles["IC"][png][dist][0][2].index(np.min(dic_2_bubbles["IC"][png][dist][0][2]))] + + dp_bis_list = rho * np.multiply(np.multiply(r_list * r0, r_list * r0), a_list) / (delta_x * P0) + dp_bis_bis_list = 2 * rho * np.multiply(np.multiply(u_list, u_list), r_list * r0) / (delta_x * P0) + + r_4_list = np.multiply(np.multiply(r_list * r0, r_list * r0), np.multiply(r_list * r0, r_list * r0)) + dp_bis_bis_bis_list = rho * np.multiply(r_4_list, np.multiply(u_list, u_list)) / (2 * (delta_x**4) * P0) + + axs[0].plot(t_list, r_list, linewidth=2.5, linestyle="solid", color="blue", label=r"$R_{0} = 2.0 \ \mu\mathrm{m}$") + axs[1].plot(t_list, p_list, linewidth=2.5, linestyle="solid", color="blue") + axs[2].plot(t_list, dp_bis_list, linewidth=2.5, linestyle="solid", color="blue") + axs[3].plot(t_list, dp_bis_bis_list, linewidth=2.5, linestyle="solid", color="blue") + axs[4].plot(t_list, dp_bis_bis_bis_list, linewidth=2.5, linestyle="solid", color="blue") + axs[5].plot(t_list, dp_list, linewidth=2.5, linestyle="solid", color="blue") + + # second bubbles + r0 = dic_2_bubbles["IC"][png][dist][1][0] + t_list = np.array(dic_2_bubbles["IC"][png][dist][1][1]) * 1.0e6 + r_list = np.array(dic_2_bubbles["IC"][png][dist][1][2]) / r0 + p_list = np.array(dic_2_bubbles["IC"][png][dist][1][3]) / P0 + a_list = np.array(dic_2_bubbles["IC"][png][dist][1][4]) + dp_list = np.array(dic_2_bubbles["IC"][png][dist][1][5]) / P0 + u_list = np.array(dic_2_bubbles["IC"][png][dist][1][6]) + + dp_bis_list = rho * np.multiply(np.multiply(r_list * r0, r_list * r0), a_list) / (delta_x * P0) + dp_bis_bis_list = 2 * rho * np.multiply(np.multiply(u_list, u_list), r_list * r0) / (delta_x * P0) + + r_4_list = np.multiply(np.multiply(r_list * r0, r_list * r0), np.multiply(r_list * r0, r_list * r0)) + dp_bis_bis_bis_list = rho * np.multiply(r_4_list, np.multiply(u_list, u_list)) / (2 * (delta_x**4) * P0) + + axs[0].plot(t_list, r_list, linewidth=2.5, linestyle="dashed", color="magenta", label=r"$R_{0} = 20.0 \ \mu\mathrm{m}$") + axs[1].plot(t_list, p_list, linewidth=2.5, linestyle="dashed", color="magenta") + axs[2].plot(t_list, dp_bis_list, linewidth=2.5, linestyle="dashed", color="magenta") + axs[3].plot(t_list, dp_bis_bis_list, linewidth=2.5, linestyle="dashed", color="magenta") + axs[4].plot(t_list, dp_bis_bis_bis_list, linewidth=2.5, linestyle="dashed", color="magenta") + axs[5].plot(t_list, dp_list, linewidth=2.5, linestyle="dashed", color="magenta") + + axs[5].plot(t_list, dp_bis_list + dp_bis_bis_list - dp_bis_bis_bis_list, linewidth=2.0, linestyle="dotted", color="red") + + axs[0].legend(bbox_to_anchor=(0.5, 1.05), loc="center", ncol=2, frameon=False) + axs[5].set_xticks([55.0, t_collapse, 60.0]) + axs[5].set_xticklabels([55.0, r"$t_{\mathrm{collapse}}$", 60.0]) + +fig.savefig("cavitationonset_varyingpressure_pressure_understanding.pdf", bbox_inches='tight',pad_inches=0.35) + ######### Cavitation inception with monodispersed simple distributions ############################ nrow = 2 From 0d15ac485ea7c86096ec3c1c9511fcdfb3179a2c Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 3 Sep 2024 14:52:00 -0400 Subject: [PATCH 082/138] cavitationonset ; better displayed pressure plot for varyong pressure test case --- examples/cavitationonset/plot_results.py | 43 +++++++++++++----------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/examples/cavitationonset/plot_results.py b/examples/cavitationonset/plot_results.py index 50f70d3..ce56c0b 100644 --- a/examples/cavitationonset/plot_results.py +++ b/examples/cavitationonset/plot_results.py @@ -326,7 +326,7 @@ def identify_end_time_index(inttype, png, dist) : axs.set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) axs.set_ylabel(r"$p_{\infty, 1} / p_{0}$", fontsize=27.5) -axs.set_xlim(xmin=0.0, xmax=60.0) +axs.set_xlim(xmin=10.0, xmax=60.0) axs.grid() secyax = axs.twinx() @@ -335,36 +335,39 @@ def identify_end_time_index(inttype, png, dist) : secyax.tick_params("y", colors="blue") secyax.spines["right"].set_edgecolor("blue") secyax.set_ylabel(r"$(p_{\infty, 1, \mathrm{QA}} - p_{\infty, 1, \mathrm{IC}}) / p_{0}$", fontsize=27.5) +secyax.grid(linestyle="dashed") -for png in png_list : - t_list = np.array(dic_2_bubbles["IC"][png][10.0][0][1]) * 1.0e6 - p_list = np.array(dic_2_bubbles["IC"][png][10.0][0][3]) / P0 - - axs.plot(t_list, p_list, color="red", linewidth=2.5, label="IC") +sec_bis_yaxis = axs.twinx() +sec_bis_yaxis.set_yticks([]) - t_IC = t_list[dic_2_bubbles["IC"][png][10.0][0][2].index(np.max(dic_2_bubbles["IC"][png][10.0][0][2]))] +for png in png_list : + t_list_IC = np.array(dic_2_bubbles["IC"][png][10.0][0][1]) * 1.0e6 + p_list_IC = np.array(dic_2_bubbles["IC"][png][10.0][0][3]) / P0 - t_list = np.array(dic_2_bubbles["QA"][png][10.0][0][1]) * 1.0e6 - p_list = np.array(dic_2_bubbles["QA"][png][10.0][0][3]) / P0 + t_list_QA = np.array(dic_2_bubbles["QA"][png][10.0][0][1]) * 1.0e6 + p_list_QA = np.array(dic_2_bubbles["QA"][png][10.0][0][3]) / P0 - axs.plot(t_list, p_list, color="black", linewidth=2.5, linestyle="dashed", label="QA") + p_list_QA_new = [] + for i in range(0, len(p_list_QA), 10) : + p_list_QA_new.append(p_list_QA[i]) - t_QA = t_list[dic_2_bubbles["QA"][png][10.0][0][2].index(np.max(dic_2_bubbles["QA"][png][10.0][0][2]))] + diff_p = np.array(p_list_QA_new) - p_list_IC - p_list_new = [] - for i in range(0, len(p_list), 10) : - p_list_new.append(p_list[i]) - - diff_p = np.array(p_list_new) - np.array(dic_2_bubbles["IC"][png][10.0][0][3]) / P0 + axs.plot(t_list_IC, p_list_IC, color="red", linewidth=3.0, linestyle="solid", label="IC") + axs.plot(t_list_QA, p_list_QA, color="black", linewidth=3.0, linestyle="dashed", label="QA") + secyax.plot(t_list_IC, diff_p, color="blue", linewidth=3.0, linestyle="dotted", label=r"$\Delta p_{\infty, 1} / p_{0}$ (QA - IC)") + sec_bis_yaxis.plot(t_list_IC, p_list_IC, color="red", linewidth=3.0, linestyle="solid", label="IC") + sec_bis_yaxis.plot(t_list_QA, p_list_QA, color="black", linewidth=3.0, linestyle="dashed", label="QA") - secyax.plot(np.array(dic_2_bubbles["IC"][png][10.0][0][1]) * 1.0e6, diff_p, color="blue", linewidth=2.5, linestyle="dotted", label=r"$\Delta p_{\infty, 1} / p_{0}$ (QA - IC)") + t_IC = t_list_IC[dic_2_bubbles["IC"][png][10.0][0][2].index(np.max(dic_2_bubbles["IC"][png][10.0][0][2]))] + t_QA = t_list_QA[dic_2_bubbles["QA"][png][10.0][0][2].index(np.max(dic_2_bubbles["QA"][png][10.0][0][2]))] axs.set_xticks([20, t_IC, t_QA, 40]) axs.set_xticklabels([20, r"$t_{\mathrm{IC}}$", r"$t_{\mathrm{QA}}$", 40]) -# axs.set_xlim(xmin=10.0, xmax=35.0) -secyax.set_ylim(ymin=-0.002, ymax=0.002) +secyax.set_ylim(ymin=-0.005, ymax=0.005) +secyax.set_yticks([-0.005, 0.0, 0.005]) -axs.legend(bbox_to_anchor=(0.5, 1.15), loc="center", ncol=2, frameon=False) +sec_bis_yaxis.legend(bbox_to_anchor=(0.5, 1.15), loc="center", ncol=2, frameon=False) secyax.legend(bbox_to_anchor=(0.5, 1.05), loc="center", ncol=1, frameon=False) fig.savefig("cavitationonset_varyingpressure_pressure.pdf", bbox_inches='tight',pad_inches=0.35) From 139fcaa01ede1ecc50281d881f86071aadcbb9f8 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 6 Sep 2024 10:18:31 -0400 Subject: [PATCH 083/138] frequencyresponse ; new folder for test case, only no interactions (NI) computation for now --- .../frequencyresponse/NI/build/CMakeLists.txt | 41 +++ .../frequencyresponse/NI/build/compile.sh | 5 + examples/frequencyresponse/NI/run.apecss | 36 +++ .../NI/src/frequencyresponse_apecss.c | 299 ++++++++++++++++++ 4 files changed, 381 insertions(+) create mode 100644 examples/frequencyresponse/NI/build/CMakeLists.txt create mode 100755 examples/frequencyresponse/NI/build/compile.sh create mode 100644 examples/frequencyresponse/NI/run.apecss create mode 100644 examples/frequencyresponse/NI/src/frequencyresponse_apecss.c diff --git a/examples/frequencyresponse/NI/build/CMakeLists.txt b/examples/frequencyresponse/NI/build/CMakeLists.txt new file mode 100644 index 0000000..7e6cde8 --- /dev/null +++ b/examples/frequencyresponse/NI/build/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.12) + +project (frequencyresponse_apecss) +set(CMAKE_C_COMPILER /usr/bin/gcc) + +include_directories($ENV{APECSS_DIR}/include) +FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) + +set (mylibs m apecss) +link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) + +foreach(arg ${myincludes}) + IF (arg MATCHES "-I") + STRING(REGEX REPLACE "-I" "" myinc ${arg}) + message("Additional include: ${myinc}") + include_directories(${myinc}) + ENDIF(arg MATCHES "-I") +endforeach(arg ${myincludes}) + +foreach(arg ${mylibs}) + STRING(REGEX REPLACE "lib" "" myl1 ${arg}) + STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) + set(mylibs ${myl2} ${mylibs} ${myl2}) +endforeach(arg ${mylibs}) + +if(NOT CMAKE_BUILD_TYPE) + message(STATUS "Optimization: No optimization specified.") + set(CMAKE_BUILD_TYPE Release) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + message(STATUS "Optimization: Debug") + set(CMAKE_C_FLAGS_DEBUG "-Wall -g") +elseif(CMAKE_BUILD_TYPE STREQUAL "Release") + message(STATUS "Optimization: Release") + add_definitions(-DNDEBUG) + set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") +endif() + +add_executable(frequencyresponse_apecss ${myfiles}) +target_link_libraries(frequencyresponse_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/frequencyresponse/NI/build/compile.sh b/examples/frequencyresponse/NI/build/compile.sh new file mode 100755 index 0000000..55dab1c --- /dev/null +++ b/examples/frequencyresponse/NI/build/compile.sh @@ -0,0 +1,5 @@ +#!/bin/bash +rm frequencyresponse_apecss +cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release +make +rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/frequencyresponse/NI/run.apecss b/examples/frequencyresponse/NI/run.apecss new file mode 100644 index 0000000..4f5add7 --- /dev/null +++ b/examples/frequencyresponse/NI/run.apecss @@ -0,0 +1,36 @@ +######################################################### +# # +# APECSS Options File # +# # +######################################################### + +BUBBLE +RPModel KM +Emissions IC 300.0e-6 +PressureAmbient 1.0e5 +END + +GAS +EoS HC +ReferenceDensity 1.2 +PolytropicExponent 1.4 +END + +LIQUID +ReferencePressure 1.0e5 +ReferenceDensity 1000.0 +ReferenceSoundSpeed 1500.0 +Viscosity 1.002e-3 +END + +INTERFACE +SurfaceTensionCoeff 0.0728 +END + +RESULTS +Bubble +END + +ODESOLVER +tolerance 1.0e-10 +END diff --git a/examples/frequencyresponse/NI/src/frequencyresponse_apecss.c b/examples/frequencyresponse/NI/src/frequencyresponse_apecss.c new file mode 100644 index 0000000..074c9b0 --- /dev/null +++ b/examples/frequencyresponse/NI/src/frequencyresponse_apecss.c @@ -0,0 +1,299 @@ +// This source file is part of APECSS, an open-source software toolbox +// for the computation of pressure-driven bubble dynamics and acoustic +// emissions in spherical symmetry. +// +// Copyright (C) 2022-2024 The APECSS Developers +// +// The APECSS Developers are listed in the README.md file available in +// the GitHub repository at https://github.com/polycfd/apecss. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// ------------------------------------------------------------------- +// APECSS standalone example of acoustically-interacting microbubbles, +// based on Jiang et al., Ultrasonics Sonochemistry 34 (2017), 90-97. +// ------------------------------------------------------------------- + +#include +#include "apecss.h" + +// Declaration of additional case-dependent functions +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); + +// Declaration of the structure holding the interaction variables of each bubble +struct Interaction +{ + APECSS_FLOAT dp_neighbor; +}; + +int main(int argc, char **args) +{ + char OptionsDir[APECSS_STRINGLENGTH]; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Set the case-dependent simulation parameters + const int nBubbles = 2; // Number of bubbles + APECSS_FLOAT bubble_bubble_dist = 200.0e-6; // Bubble-bubble distance + + // Interbubble time-step, defining the frequency with which the neighbor influence is updated + APECSS_FLOAT dt_interbubble = 1.0e-8; + + // Initialize the simulation parameters given by the execution command + double tEnd = 0.0; + double fa = 0.0; + double pa = 0.0; + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + apecss_infoscreen(); + + /* Read commandline options */ + sprintf(OptionsDir, "./run.apecss"); // This is the default + int j = 1; // First argument is the call to the executable + while (j < argc) + { + if (strcmp("-options", args[j]) == 0) + { + sprintf(OptionsDir, "%s", args[j + 1]); + j += 2; + } + else if (strcmp("-tend", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &tEnd); + j += 2; + } + else if (strcmp("-freq", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &fa); + j += 2; + } + else if (strcmp("-amp", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &pa); + j += 2; + } + else if (strcmp("-h", args[j]) == 0) + { + apecss_helpscreen(); + } + else + { + char str[APECSS_STRINGLENGTH_SPRINTF]; + sprintf(str, "Unknown command line options: %s", args[j]); + apecss_erroronscreen(1, str); + ++j; + } + } + + /* Allocate and initialize Bubble structure */ + struct APECSS_Bubble *Bubbles[nBubbles]; + for (register int i = 0; i < nBubbles; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(nBubbles * sizeof(struct APECSS_Bubble)); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initializestruct(Bubbles[i]); + + /* Set default options and read the options for the bubble */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); + + // // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // // Allocate and set bubble-associated variables for the interaction + // for (register int i = 0; i < nBubbles; i++) + // { + // struct Interaction *interaction_data = (struct Interaction *) malloc(sizeof(struct Interaction)); + // interaction_data->dp_neighbor = 0.0; // Pressure excerted by the neighbor bubbles + + // // Hook interaction-structure to the void data pointer + // Bubbles[i]->user_data = interaction_data; + // } + // // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Allocate the structures for the fluid properties and ODE solver parameters */ + struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); + struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); + struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); + struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); + + /* Set the default options for the fluid properties and solver parameters */ + apecss_gas_setdefaultoptions(Gas); + apecss_liquid_setdefaultoptions(Liquid); + apecss_interface_setdefaultoptions(Interface); + apecss_odesolver_setdefaultoptions(NumericsODE); + + /* Read the options file for the fluid properties and solver parameters */ + apecss_gas_readoptions(Gas, OptionsDir); + apecss_liquid_readoptions(Liquid, OptionsDir); + apecss_interface_readoptions(Interface, OptionsDir); + apecss_odesolver_readoptions(NumericsODE, OptionsDir); + + /* Associate the bubble with the relevant fluid properties and solver parameters */ + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Gas = Gas; + Bubbles[i]->Liquid = Liquid; + Bubbles[i]->Interface = Interface; + Bubbles[i]->NumericsODE = NumericsODE; + } + + /* Allocate and set the excitation parameters */ + struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); + Excitation->type = APECSS_EXCITATION_SIN; + Excitation->f = (APECSS_FLOAT) fa; + Excitation->dp = (APECSS_FLOAT) pa; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Excitation = Excitation; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Create individual folders for the results of each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (Bubbles[i]->Results != NULL) + { + sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", i); + struct stat st = {0}; + if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Process all options */ + apecss_gas_processoptions(Gas); + apecss_liquid_processoptions(Liquid); + apecss_interface_processoptions(Interface); + apecss_odesolver_processoptions(NumericsODE); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_processoptions(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Use the revised pressure at infinity, including neighbor contributions + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressure_infinity = interaction_bubble_pressure_infinity; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressurederivative_infinity = interaction_bubble_pressurederivative_infinity; + + // Initialize interaction structure + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); + + // Update interaction structure + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Interaction->nBubbles = nBubbles; + Bubbles[i]->Interaction->dp_neighbor = 0.0; + Bubbles[i]->Interaction->last_t_1 = 0.0; + Bubbles[i]->Interaction->last_t_2 = 0.0; + Bubbles[i]->Interaction->last_p_1 = 0.0; + Bubbles[i]->Interaction->last_p_2 = 0.0; + } + + // Define the size of each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (0 == i) + Bubbles[i]->R0 = 5.0e-6; + else if (1 == i) + Bubbles[i]->R0 = 10.0e-6; + + Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; + } + + // Define center location for each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (0 == i) + { + Bubbles[i]->Interaction->location[0] = 0.0; + Bubbles[i]->Interaction->location[1] = 0.0; + Bubbles[i]->Interaction->location[2] = 0.0; + } + else if (1 == i) + { + Bubbles[i]->Interaction->location[0] = bubble_bubble_dist; + Bubbles[i]->Interaction->location[1] = 0.0; + Bubbles[i]->Interaction->location[2] = 0.0; + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + clock_t starttimebubble = clock(); + APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system + + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->tStart = tSim; + Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; + Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step + } + + /* Initialize the bubble based on the selected options */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initialize(Bubbles[i]); + + /* Initialize */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_initialize(Bubbles[i]); + + /* Solve the bubble dynamics */ + while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered + { + APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); + tSim += dtSim; + + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); + + // for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Update the contribution of the neighbor bubble + apecss_interactions_instantaneous(Bubbles); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; + Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; + + Bubbles[i]->Interaction->last_t_1 = tSim; + Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; + } + } + + /* Finalize the simulation*/ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_finalize(Bubbles[i]); + + char str[APECSS_STRINGLENGTH_SPRINTF]; + for (register int i = 0; i < nBubbles; i++) + { + sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", i, Bubbles[i]->dtNumber, Bubbles[i]->nSubIter, + (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); + apecss_writeonscreen(str); + } + + for (register int i = 0; i < nBubbles; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); + for (register int i = 0; i < nBubbles; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); + + /* Make sure all allocated memory is freed */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_freestruct(Bubbles[i]); + + for (register int i = 0; i < nBubbles; i++) free(Bubbles[i]); + free(Gas); + free(Liquid); + free(Interface); + free(NumericsODE); + free(Excitation); + + return (0); +} + +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * t) + Bubble->Interaction->dp_neighbor); +} + +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + // Approximate numerical computation of p_infinity derivative + APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; + APECSS_FLOAT derivative = -Bubble->Excitation->dp * 2.0 * APECSS_PI * Bubble->Excitation->f * APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * t); + if (delta_t > Bubble->dt) + { + return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) / (Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2))); + } + else + { + return (derivative); + } +} \ No newline at end of file From ef60489c5b9cc1cc59cca1fb7896d331dff52aac Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 6 Sep 2024 14:13:52 -0400 Subject: [PATCH 084/138] frequencyresponse ; NI computation, c source file with 2 ODEs --- examples/frequencyresponse/NI/run.apecss | 2 +- .../NI/src/frequencyresponse_apecss.c | 216 ++++++++++++++---- 2 files changed, 170 insertions(+), 48 deletions(-) diff --git a/examples/frequencyresponse/NI/run.apecss b/examples/frequencyresponse/NI/run.apecss index 4f5add7..67300c7 100644 --- a/examples/frequencyresponse/NI/run.apecss +++ b/examples/frequencyresponse/NI/run.apecss @@ -11,7 +11,7 @@ PressureAmbient 1.0e5 END GAS -EoS HC +EoS IG ReferenceDensity 1.2 PolytropicExponent 1.4 END diff --git a/examples/frequencyresponse/NI/src/frequencyresponse_apecss.c b/examples/frequencyresponse/NI/src/frequencyresponse_apecss.c index 074c9b0..ecbaf3d 100644 --- a/examples/frequencyresponse/NI/src/frequencyresponse_apecss.c +++ b/examples/frequencyresponse/NI/src/frequencyresponse_apecss.c @@ -22,12 +22,10 @@ // Declaration of additional case-dependent functions APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +APECSS_FLOAT apecss_rp_kellermiksisvelocity_ode_simplified(APECSS_FLOAT *Sol, APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +int apecss_new_bubble_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble); -// Declaration of the structure holding the interaction variables of each bubble -struct Interaction -{ - APECSS_FLOAT dp_neighbor; -}; +APECSS_FLOAT maxR; int main(int argc, char **args) { @@ -35,8 +33,8 @@ int main(int argc, char **args) // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // Set the case-dependent simulation parameters - const int nBubbles = 2; // Number of bubbles - APECSS_FLOAT bubble_bubble_dist = 200.0e-6; // Bubble-bubble distance + int nBubbles = 3; // Number of bubbles + APECSS_FLOAT bubble_bubble_dist = 5.0e-6; // Bubble-bubble distance // Interbubble time-step, defining the frequency with which the neighbor influence is updated APECSS_FLOAT dt_interbubble = 1.0e-8; @@ -45,6 +43,9 @@ int main(int argc, char **args) double tEnd = 0.0; double fa = 0.0; double pa = 0.0; + double dist = 5.0e-6; + double dt_inter = 1.0e-8; + int ode = 0; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< apecss_infoscreen(); @@ -59,6 +60,11 @@ int main(int argc, char **args) sprintf(OptionsDir, "%s", args[j + 1]); j += 2; } + else if (strcmp("-nb", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &nBubbles); + j += 2; + } else if (strcmp("-tend", args[j]) == 0) { sscanf(args[j + 1], "%le", &tEnd); @@ -74,6 +80,21 @@ int main(int argc, char **args) sscanf(args[j + 1], "%le", &pa); j += 2; } + else if (strcmp("-dist", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &dist); + j += 2; + } + else if (strcmp("-dt_inter", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &dt_inter); + j += 2; + } + else if (strcmp("-ode", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &ode); + j += 2; + } else if (strcmp("-h", args[j]) == 0) { apecss_helpscreen(); @@ -87,6 +108,17 @@ int main(int argc, char **args) } } + /* Properly update parameters with commandline options */ + bubble_bubble_dist = (APECSS_FLOAT) dist; + dt_interbubble = (APECSS_FLOAT) dt_inter; + tEnd = 30 / fa; + + /* Check if the number of bubbles is right */ + if ((nBubbles != 3) && (nBubbles != 4)) + { + nBubbles = 3; + } + /* Allocate and initialize Bubble structure */ struct APECSS_Bubble *Bubbles[nBubbles]; for (register int i = 0; i < nBubbles; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(nBubbles * sizeof(struct APECSS_Bubble)); @@ -96,18 +128,6 @@ int main(int argc, char **args) for (register int i = 0; i < nBubbles; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); for (register int i = 0; i < nBubbles; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); - // // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // // Allocate and set bubble-associated variables for the interaction - // for (register int i = 0; i < nBubbles; i++) - // { - // struct Interaction *interaction_data = (struct Interaction *) malloc(sizeof(struct Interaction)); - // interaction_data->dp_neighbor = 0.0; // Pressure excerted by the neighbor bubbles - - // // Hook interaction-structure to the void data pointer - // Bubbles[i]->user_data = interaction_data; - // } - // // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - /* Allocate the structures for the fluid properties and ODE solver parameters */ struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); @@ -167,6 +187,12 @@ int main(int argc, char **args) for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressure_infinity = interaction_bubble_pressure_infinity; for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressurederivative_infinity = interaction_bubble_pressurederivative_infinity; + // Update the Keller-Miksis ODE + if (ode == 1) + { + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->ode[0] = apecss_rp_kellermiksisvelocity_ode_simplified; + } + // Initialize interaction structure for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); @@ -185,14 +211,16 @@ int main(int argc, char **args) for (register int i = 0; i < nBubbles; i++) { if (0 == i) - Bubbles[i]->R0 = 5.0e-6; + Bubbles[i]->R0 = 1.0e-6; else if (1 == i) - Bubbles[i]->R0 = 10.0e-6; - - Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; + Bubbles[i]->R0 = 0.8e-6; + else if (2 == i) + Bubbles[i]->R0 = 0.5e-6; + else if (3 == i) + Bubbles[i]->R0 = 1.5e-6; } - // Define center location for each bubble + // Define center location for each bubble (only x is important for this test case) for (register int i = 0; i < nBubbles; i++) { if (0 == i) @@ -207,7 +235,27 @@ int main(int argc, char **args) Bubbles[i]->Interaction->location[1] = 0.0; Bubbles[i]->Interaction->location[2] = 0.0; } + else if (2 == i) + { + Bubbles[i]->Interaction->location[0] = 0.5 * bubble_bubble_dist; + Bubbles[i]->Interaction->location[1] = 0.0; + Bubbles[i]->Interaction->location[2] = 0.0; + } + else if (3 == i) + { + Bubbles[i]->Interaction->location[0] = 0.5 * bubble_bubble_dist; + Bubbles[i]->Interaction->location[1] = 0.0; + Bubbles[i]->Interaction->location[2] = 0.0; + } + } + + // Create array to gather maximum radius value for each bubble + APECSS_FLOAT max_bubble[nBubbles]; + for (register int i = 0; i < nBubbles; i++) + { + max_bubble[i] = Bubbles[i]->R0; } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< clock_t starttimebubble = clock(); @@ -232,25 +280,28 @@ int main(int argc, char **args) APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); tSim += dtSim; - for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); - - // for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Update the contribution of the neighbor bubble - apecss_interactions_instantaneous(Bubbles); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - for (register int i = 0; i < nBubbles; i++) { - Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; - Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; - - Bubbles[i]->Interaction->last_t_1 = tSim; - Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; + maxR = Bubbles[i]->R0; + apecss_new_bubble_solver_run(tSim, (APECSS_FLOAT) tEnd, Bubbles[i]); + if (maxR > max_bubble[i]) + { + max_bubble[i] = maxR; + } } } + /* Retrieve results */ + FILE *file_max_radius; + file_max_radius = fopen("max_radius.txt", "a"); + fprintf(file_max_radius, "nb %d f(Hz) %e p(Pa) %e dist %e ODE %d R0(m);Rmax(m)", nBubbles, fa, pa, dist, ode); + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_max_radius, " %e;%e", Bubbles[i]->R0, max_bubble[i]); + } + fprintf(file_max_radius, "\n"); + fclose(file_max_radius); + /* Finalize the simulation*/ for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_finalize(Bubbles[i]); @@ -280,20 +331,91 @@ int main(int argc, char **args) APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { - return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * t) + Bubble->Interaction->dp_neighbor); + APECSS_FLOAT x = Bubble->Interaction->location[0]; + return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * (t - x / Bubble->Liquid->cref))); } APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { // Approximate numerical computation of p_infinity derivative - APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; - APECSS_FLOAT derivative = -Bubble->Excitation->dp * 2.0 * APECSS_PI * Bubble->Excitation->f * APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * t); - if (delta_t > Bubble->dt) - { - return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) / (Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2))); - } - else + APECSS_FLOAT x = Bubble->Interaction->location[0]; + APECSS_FLOAT derivative = + -Bubble->Excitation->dp * 2.0 * APECSS_PI * Bubble->Excitation->f * APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * (t - x / Bubble->Liquid->cref)); + return (derivative); +} + +APECSS_FLOAT apecss_rp_kellermiksisvelocity_ode_simplified(APECSS_FLOAT *Sol, APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + /** Simplified model for comparison with Haghi **/ + APECSS_FLOAT inv_c = 1.0 / Bubble->Liquid->cref; + APECSS_FLOAT inv_rho = 1.0 / Bubble->Liquid->rhoref; + + APECSS_FLOAT rhs = ((Bubble->Liquid->get_pressure_bubblewall(Sol, t, Bubble) - Bubble->get_pressure_infinity(t, Bubble)) * inv_rho - + 1.5 * (1.0 - (Sol[0] * APECSS_ONETHIRD * inv_c)) * APECSS_POW2(Sol[0])) / + Sol[1]; + + return (rhs / (1.0 - Sol[0] * inv_c)); +} + +int apecss_new_bubble_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble) +{ + while (Bubble->t < tend - 0.01 * Bubble->NumericsODE->dtMin) { - return (derivative); + // Store the previous solution for sub-iterations + for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSolOld[i] = Bubble->ODEsSol[i]; + + // Check what comes next: the end of the solver run or, if applicable, a time instance to output the emissions + APECSS_FLOAT next_event_time = Bubble->results_emissionstime_check(tend, Bubble); + + // Set the time-step for the ODEs + apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); + + // Solve the ODEs + Bubble->err = apecss_odesolver(Bubble); + + // Perform sub-iterations on the control of the time-step when err > tol + register int subiter = 0; + while ((Bubble->err > Bubble->NumericsODE->tol) && (subiter < Bubble->NumericsODE->maxSubIter)) + { + ++subiter; + // Rewind the solution + for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSol[i] = Bubble->ODEsSolOld[i]; + // Set the time-step for the ODEs + apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); + // Solve the ODEs again + Bubble->err = apecss_odesolver(Bubble); + } + Bubble->nSubIter += subiter; + + // Set new values + ++(Bubble->dtNumber); + Bubble->t += Bubble->dt; + Bubble->U = Bubble->ODEsSol[0]; + Bubble->R = Bubble->ODEsSol[1]; + + // Detect max value of radius + if (Bubble->t > tEnd - 10 / Bubble->Excitation->f) maxR = APECSS_MAX(maxR, Bubble->R); + + // Update allocation of the results (if necessary) + Bubble->results_emissionsnodeminmax_identify(Bubble); + Bubble->results_emissionsnode_alloc(Bubble); + + // Acoustic emissions (if applicable) + Bubble->emissions_update(Bubble); + + // Store results (if applicable) + Bubble->results_rayleighplesset_store(Bubble); + Bubble->results_emissionsspace_store(Bubble); + + // Write one-off results (if applicable) + Bubble->results_emissionstime_write(Bubble); + + // Update the last-step solution of the RK54 scheme + for (register int i = 0; i < Bubble->nODEs; i++) Bubble->kLast[i] = Bubble->k7[i]; + + // Update progress screen in the terminal (if applicable) + Bubble->progress_update(&(*Bubble).progress, Bubble->t - Bubble->tStart, Bubble->tEnd - Bubble->tStart); } + + return (0); } \ No newline at end of file From a57abed66c154cd38216c335dbd676c95d20742f Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 6 Sep 2024 14:14:31 -0400 Subject: [PATCH 085/138] frequencyresponse ; python file for gathering results --- .../frequencyresponse/NI/gather_results.py | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 examples/frequencyresponse/NI/gather_results.py diff --git a/examples/frequencyresponse/NI/gather_results.py b/examples/frequencyresponse/NI/gather_results.py new file mode 100644 index 0000000..7362d5a --- /dev/null +++ b/examples/frequencyresponse/NI/gather_results.py @@ -0,0 +1,35 @@ +import os + +######### File designed to retrieve and gather in the "results" folder the data obtained with frequency response computations + +working_path = os.getcwd() + +results_file = open(os.path.join(working_path, "max_radius.txt"), "r") +lines = results_file.readlines() +results_file.close() + +firstline = lines[0].split(" ") +nBubbles = int(firstline[1]) +pa = float(firstline[5]) +dist = float(firstline[7]) +ode = int(firstline[9]) + +gather_path = os.path.join(working_path, "results") + +file_name = "{}_p{:.5E}_d{:.2E}_{}.txt".format(nBubbles, pa, dist, ode) + +data_file = open(os.path.join(gather_path, file_name), "w") +data_file.write("nb {} p(Pa) {:.5E} dist {:.2E} ODE {}\n".format(nBubbles, pa, dist, ode)) +data_file.write("#f(Hz) R0(m);R(m)\n") + +for line in lines : + if line != "" : + data = line.split(" ") + f = float(data[3]) + data_file.write("{:.5E}".format(f)) + + r_list = data[11:] + for r in r_list : + data_file.write(" {}".format(r)) + +data_file.close() \ No newline at end of file From 00e35738ca9475598196a67f5fad21ed2c58ffb5 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 6 Sep 2024 14:15:10 -0400 Subject: [PATCH 086/138] frequencyresponse ; sh file to tun computations and python file to plot results --- examples/frequencyresponse/plot_results.py | 131 ++++++++++++++++++ .../run_frequencyresponse.sh | 32 +++++ 2 files changed, 163 insertions(+) create mode 100644 examples/frequencyresponse/plot_results.py create mode 100755 examples/frequencyresponse/run_frequencyresponse.sh diff --git a/examples/frequencyresponse/plot_results.py b/examples/frequencyresponse/plot_results.py new file mode 100644 index 0000000..af60235 --- /dev/null +++ b/examples/frequencyresponse/plot_results.py @@ -0,0 +1,131 @@ +import os +import numpy as np +import matplotlib.pyplot as plt + +######### Graphical parameters #################################################################### +fontsize = 25 + +plt.rcParams['font.family']='serif' +plt.rcParams['font.serif']=['Times New Roman'] + plt.rcParams['font.serif'] +plt.rcParams['mathtext.fontset']='stix' +plt.rcParams['font.size']=fontsize + +cm = 1/2.54 + +######### Step 1 : Retrieving data ################################################################ + +#### Original paper results ##################### +paper_results_NI = {} + +working_path = os.getcwd() +paper_path = os.path.join(working_path, "articleresults") +paper_path = os.path.join(paper_path, "NI") + +for file in os.listdir(paper_path) : + file_path = os.path.join(paper_path, file) + + text = open(file_path, "r") + lines = text.readlines() + text.close() + + r_init = float(lines[1].split(" : ")[-1]) + f_list = [] + r_list = [] + for i in range(3, len(lines)) : + line = lines[i].split(" ") + f_list.append(float(line[0].replace(",", "."))) + r_list.append(float(line[1].replace(",", "."))) + + paper_results_NI[r_init] = [f_list, r_list] + +#### Computation results ######################## +# Key distribution : Inttype->ODE->nBubbles->pressure->distance +dic_results = {} + +inttype_list = ["NI", "IC", "QA"] +for inttype in inttype_list : + dic_results[inttype] = {} + inttype_path = os.path.join(working_path, inttype) + inttype_path = os.path.join(inttype_path, "results") + + for file in os.listdir(inttype_path) : + # Finding computation results + file_path = os.path.join(inttype_path, file) + file = open(file_path, "r") + lines = file.readlines() + file.close() + + # Updating the keys in the dictionnary + firstline = lines[0].split(" ") + nBubbles = int(firstline[1]) + pa = float(firstline[3]) + dist = float(firstline[5]) + ode = int(firstline[7]) + + # Small correction for ode number (only 0 and 1 are accepted values) + if (ode != 0 and ode != 1) : ode = 0 + + if ode not in list(dic_results[inttype].keys()) : + dic_results[inttype][ode] = {} + if nBubbles not in list(dic_results[inttype][ode].keys()) : + dic_results[inttype][ode][nBubbles] = {} + if pa not in list(dic_results[inttype][ode][nBubbles].keys()) : + dic_results[inttype][ode][nBubbles][pa] = {} + if dist not in list(dic_results[inttype][ode][nBubbles][pa].keys()) : + dic_results[inttype][ode][nBubbles][pa][dist] = [] + + # Adding computation results to the dictionnary + for i in range(nBubbles) : + # Format of the results in the dictionnary : for each bubble, [r_init, [f_list], [r_list]] + r_init = float(lines[2].split(" ")[1+i].split(";")[0]) + dic_results[inttype][ode][nBubbles][pa][dist].append([r_init, [], []]) + + for i in range(2, len(lines)) : + data = lines[i].split(" ") + f = float(data[0]) + for j in range(nBubbles) : + r = float(lines[i].split(" ")[1+j].split(";")[1]) + dic_results[inttype][ode][nBubbles][pa][dist][j][1].append(f) + dic_results[inttype][ode][nBubbles][pa][dist][j][2].append(r) + +######### Step 2 : Validation plots ############################################################### + +#### No interactions #### +n_row = 1 +n_col = 2 + +fig, axs = plt.subplots(n_row, n_col, figsize=(n_col*25.0*cm, n_row*12.5*cm), sharey=True) +for i in range(n_col) : + axs[i].set_xlabel(r"$f$ [MHz]") + axs[i].set_xlim(xmin=0.5, xmax=10.0) + axs[i].grid() +axs[0].set_ylabel(r"$R_{\mathrm{max}}/R_{0}$") +fig.subplots_adjust(hspace=0.0, wspace=0.1*cm) + +axs[0].set_title(r"full Keller-Miksis ODE") +axs[1].set_title(r"partial Keller-Miksis ODE") + +data_list = dic_results["NI"][0][4][1.2e5][5e-6] +axs[0].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.0$ $\mu$m") +axs[0].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.8$ $\mu$m") +axs[0].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.5$ $\mu$m") +axs[0].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.5$ $\mu$m") + +data_list = dic_results["NI"][1][4][1.2e5][5e-6] +axs[1].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid") +axs[1].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid") +axs[1].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid") +axs[1].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid") + +for i in range(n_col) : + axs[i].plot(paper_results_NI[1.0][0], paper_results_NI[1.0][1], color="blue", linewidth=2.5, linestyle="dashed") + axs[i].plot(paper_results_NI[0.8][0], paper_results_NI[0.8][1], color="magenta", linewidth=2.5, linestyle="dashed") + axs[i].plot(paper_results_NI[0.5][0], paper_results_NI[0.5][1], color="red", linewidth=2.5, linestyle="dashed") + axs[i].plot(paper_results_NI[1.5][0], paper_results_NI[1.5][1], color="black", linewidth=2.5, linestyle="dashed") + +axs[0].legend(loc="upper right", frameon=False) +fig.savefig("frequencyresponse_comparison_NI.pdf", bbox_inches='tight',pad_inches=0.35) + +#### Incompressible interactions #### + +######### Step 3 : Article plots ################################################################## \ No newline at end of file diff --git a/examples/frequencyresponse/run_frequencyresponse.sh b/examples/frequencyresponse/run_frequencyresponse.sh new file mode 100755 index 0000000..994eab6 --- /dev/null +++ b/examples/frequencyresponse/run_frequencyresponse.sh @@ -0,0 +1,32 @@ +set -e + +######################## No interactions (NI) ##################################################### + +cd NI/build +./compile.sh +cd .. + +for ((f=500000;f<=10000000;f+=3000)) +do + ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 +done +python3 gather_results.py +rm -rf max_radius.txt + +for ((f=500000;f<=10000000;f+=3000)) +do + ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -ode 1 +done +python3 gather_results.py +rm -rf max_radius.txt + +cd .. + +######################## Cleaning ################################################################# + +cd NI +for ((c=0;c<=4;c++)) +do + rm -rf Bubble_$c +done +cd .. \ No newline at end of file From 6a0cb415ea3713bd0561ba7496ba21abe30eda77 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 6 Sep 2024 14:39:10 -0400 Subject: [PATCH 087/138] frequencyresponse ; original IC computation files (copied from NI folder, need changes) --- .../frequencyresponse/IC/build/CMakeLists.txt | 41 ++ .../frequencyresponse/IC/build/compile.sh | 5 + .../frequencyresponse/IC/gather_results.py | 35 ++ examples/frequencyresponse/IC/run.apecss | 36 ++ .../IC/src/frequencyresponse_apecss.c | 421 ++++++++++++++++++ 5 files changed, 538 insertions(+) create mode 100644 examples/frequencyresponse/IC/build/CMakeLists.txt create mode 100755 examples/frequencyresponse/IC/build/compile.sh create mode 100644 examples/frequencyresponse/IC/gather_results.py create mode 100644 examples/frequencyresponse/IC/run.apecss create mode 100644 examples/frequencyresponse/IC/src/frequencyresponse_apecss.c diff --git a/examples/frequencyresponse/IC/build/CMakeLists.txt b/examples/frequencyresponse/IC/build/CMakeLists.txt new file mode 100644 index 0000000..7e6cde8 --- /dev/null +++ b/examples/frequencyresponse/IC/build/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.12) + +project (frequencyresponse_apecss) +set(CMAKE_C_COMPILER /usr/bin/gcc) + +include_directories($ENV{APECSS_DIR}/include) +FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) + +set (mylibs m apecss) +link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) + +foreach(arg ${myincludes}) + IF (arg MATCHES "-I") + STRING(REGEX REPLACE "-I" "" myinc ${arg}) + message("Additional include: ${myinc}") + include_directories(${myinc}) + ENDIF(arg MATCHES "-I") +endforeach(arg ${myincludes}) + +foreach(arg ${mylibs}) + STRING(REGEX REPLACE "lib" "" myl1 ${arg}) + STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) + set(mylibs ${myl2} ${mylibs} ${myl2}) +endforeach(arg ${mylibs}) + +if(NOT CMAKE_BUILD_TYPE) + message(STATUS "Optimization: No optimization specified.") + set(CMAKE_BUILD_TYPE Release) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + message(STATUS "Optimization: Debug") + set(CMAKE_C_FLAGS_DEBUG "-Wall -g") +elseif(CMAKE_BUILD_TYPE STREQUAL "Release") + message(STATUS "Optimization: Release") + add_definitions(-DNDEBUG) + set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") +endif() + +add_executable(frequencyresponse_apecss ${myfiles}) +target_link_libraries(frequencyresponse_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/frequencyresponse/IC/build/compile.sh b/examples/frequencyresponse/IC/build/compile.sh new file mode 100755 index 0000000..55dab1c --- /dev/null +++ b/examples/frequencyresponse/IC/build/compile.sh @@ -0,0 +1,5 @@ +#!/bin/bash +rm frequencyresponse_apecss +cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release +make +rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/frequencyresponse/IC/gather_results.py b/examples/frequencyresponse/IC/gather_results.py new file mode 100644 index 0000000..7362d5a --- /dev/null +++ b/examples/frequencyresponse/IC/gather_results.py @@ -0,0 +1,35 @@ +import os + +######### File designed to retrieve and gather in the "results" folder the data obtained with frequency response computations + +working_path = os.getcwd() + +results_file = open(os.path.join(working_path, "max_radius.txt"), "r") +lines = results_file.readlines() +results_file.close() + +firstline = lines[0].split(" ") +nBubbles = int(firstline[1]) +pa = float(firstline[5]) +dist = float(firstline[7]) +ode = int(firstline[9]) + +gather_path = os.path.join(working_path, "results") + +file_name = "{}_p{:.5E}_d{:.2E}_{}.txt".format(nBubbles, pa, dist, ode) + +data_file = open(os.path.join(gather_path, file_name), "w") +data_file.write("nb {} p(Pa) {:.5E} dist {:.2E} ODE {}\n".format(nBubbles, pa, dist, ode)) +data_file.write("#f(Hz) R0(m);R(m)\n") + +for line in lines : + if line != "" : + data = line.split(" ") + f = float(data[3]) + data_file.write("{:.5E}".format(f)) + + r_list = data[11:] + for r in r_list : + data_file.write(" {}".format(r)) + +data_file.close() \ No newline at end of file diff --git a/examples/frequencyresponse/IC/run.apecss b/examples/frequencyresponse/IC/run.apecss new file mode 100644 index 0000000..67300c7 --- /dev/null +++ b/examples/frequencyresponse/IC/run.apecss @@ -0,0 +1,36 @@ +######################################################### +# # +# APECSS Options File # +# # +######################################################### + +BUBBLE +RPModel KM +Emissions IC 300.0e-6 +PressureAmbient 1.0e5 +END + +GAS +EoS IG +ReferenceDensity 1.2 +PolytropicExponent 1.4 +END + +LIQUID +ReferencePressure 1.0e5 +ReferenceDensity 1000.0 +ReferenceSoundSpeed 1500.0 +Viscosity 1.002e-3 +END + +INTERFACE +SurfaceTensionCoeff 0.0728 +END + +RESULTS +Bubble +END + +ODESOLVER +tolerance 1.0e-10 +END diff --git a/examples/frequencyresponse/IC/src/frequencyresponse_apecss.c b/examples/frequencyresponse/IC/src/frequencyresponse_apecss.c new file mode 100644 index 0000000..ecbaf3d --- /dev/null +++ b/examples/frequencyresponse/IC/src/frequencyresponse_apecss.c @@ -0,0 +1,421 @@ +// This source file is part of APECSS, an open-source software toolbox +// for the computation of pressure-driven bubble dynamics and acoustic +// emissions in spherical symmetry. +// +// Copyright (C) 2022-2024 The APECSS Developers +// +// The APECSS Developers are listed in the README.md file available in +// the GitHub repository at https://github.com/polycfd/apecss. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// ------------------------------------------------------------------- +// APECSS standalone example of acoustically-interacting microbubbles, +// based on Jiang et al., Ultrasonics Sonochemistry 34 (2017), 90-97. +// ------------------------------------------------------------------- + +#include +#include "apecss.h" + +// Declaration of additional case-dependent functions +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +APECSS_FLOAT apecss_rp_kellermiksisvelocity_ode_simplified(APECSS_FLOAT *Sol, APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +int apecss_new_bubble_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble); + +APECSS_FLOAT maxR; + +int main(int argc, char **args) +{ + char OptionsDir[APECSS_STRINGLENGTH]; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Set the case-dependent simulation parameters + int nBubbles = 3; // Number of bubbles + APECSS_FLOAT bubble_bubble_dist = 5.0e-6; // Bubble-bubble distance + + // Interbubble time-step, defining the frequency with which the neighbor influence is updated + APECSS_FLOAT dt_interbubble = 1.0e-8; + + // Initialize the simulation parameters given by the execution command + double tEnd = 0.0; + double fa = 0.0; + double pa = 0.0; + double dist = 5.0e-6; + double dt_inter = 1.0e-8; + int ode = 0; + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + apecss_infoscreen(); + + /* Read commandline options */ + sprintf(OptionsDir, "./run.apecss"); // This is the default + int j = 1; // First argument is the call to the executable + while (j < argc) + { + if (strcmp("-options", args[j]) == 0) + { + sprintf(OptionsDir, "%s", args[j + 1]); + j += 2; + } + else if (strcmp("-nb", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &nBubbles); + j += 2; + } + else if (strcmp("-tend", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &tEnd); + j += 2; + } + else if (strcmp("-freq", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &fa); + j += 2; + } + else if (strcmp("-amp", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &pa); + j += 2; + } + else if (strcmp("-dist", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &dist); + j += 2; + } + else if (strcmp("-dt_inter", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &dt_inter); + j += 2; + } + else if (strcmp("-ode", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &ode); + j += 2; + } + else if (strcmp("-h", args[j]) == 0) + { + apecss_helpscreen(); + } + else + { + char str[APECSS_STRINGLENGTH_SPRINTF]; + sprintf(str, "Unknown command line options: %s", args[j]); + apecss_erroronscreen(1, str); + ++j; + } + } + + /* Properly update parameters with commandline options */ + bubble_bubble_dist = (APECSS_FLOAT) dist; + dt_interbubble = (APECSS_FLOAT) dt_inter; + tEnd = 30 / fa; + + /* Check if the number of bubbles is right */ + if ((nBubbles != 3) && (nBubbles != 4)) + { + nBubbles = 3; + } + + /* Allocate and initialize Bubble structure */ + struct APECSS_Bubble *Bubbles[nBubbles]; + for (register int i = 0; i < nBubbles; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(nBubbles * sizeof(struct APECSS_Bubble)); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initializestruct(Bubbles[i]); + + /* Set default options and read the options for the bubble */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); + + /* Allocate the structures for the fluid properties and ODE solver parameters */ + struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); + struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); + struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); + struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); + + /* Set the default options for the fluid properties and solver parameters */ + apecss_gas_setdefaultoptions(Gas); + apecss_liquid_setdefaultoptions(Liquid); + apecss_interface_setdefaultoptions(Interface); + apecss_odesolver_setdefaultoptions(NumericsODE); + + /* Read the options file for the fluid properties and solver parameters */ + apecss_gas_readoptions(Gas, OptionsDir); + apecss_liquid_readoptions(Liquid, OptionsDir); + apecss_interface_readoptions(Interface, OptionsDir); + apecss_odesolver_readoptions(NumericsODE, OptionsDir); + + /* Associate the bubble with the relevant fluid properties and solver parameters */ + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Gas = Gas; + Bubbles[i]->Liquid = Liquid; + Bubbles[i]->Interface = Interface; + Bubbles[i]->NumericsODE = NumericsODE; + } + + /* Allocate and set the excitation parameters */ + struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); + Excitation->type = APECSS_EXCITATION_SIN; + Excitation->f = (APECSS_FLOAT) fa; + Excitation->dp = (APECSS_FLOAT) pa; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Excitation = Excitation; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Create individual folders for the results of each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (Bubbles[i]->Results != NULL) + { + sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", i); + struct stat st = {0}; + if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Process all options */ + apecss_gas_processoptions(Gas); + apecss_liquid_processoptions(Liquid); + apecss_interface_processoptions(Interface); + apecss_odesolver_processoptions(NumericsODE); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_processoptions(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Use the revised pressure at infinity, including neighbor contributions + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressure_infinity = interaction_bubble_pressure_infinity; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressurederivative_infinity = interaction_bubble_pressurederivative_infinity; + + // Update the Keller-Miksis ODE + if (ode == 1) + { + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->ode[0] = apecss_rp_kellermiksisvelocity_ode_simplified; + } + + // Initialize interaction structure + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); + + // Update interaction structure + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Interaction->nBubbles = nBubbles; + Bubbles[i]->Interaction->dp_neighbor = 0.0; + Bubbles[i]->Interaction->last_t_1 = 0.0; + Bubbles[i]->Interaction->last_t_2 = 0.0; + Bubbles[i]->Interaction->last_p_1 = 0.0; + Bubbles[i]->Interaction->last_p_2 = 0.0; + } + + // Define the size of each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (0 == i) + Bubbles[i]->R0 = 1.0e-6; + else if (1 == i) + Bubbles[i]->R0 = 0.8e-6; + else if (2 == i) + Bubbles[i]->R0 = 0.5e-6; + else if (3 == i) + Bubbles[i]->R0 = 1.5e-6; + } + + // Define center location for each bubble (only x is important for this test case) + for (register int i = 0; i < nBubbles; i++) + { + if (0 == i) + { + Bubbles[i]->Interaction->location[0] = 0.0; + Bubbles[i]->Interaction->location[1] = 0.0; + Bubbles[i]->Interaction->location[2] = 0.0; + } + else if (1 == i) + { + Bubbles[i]->Interaction->location[0] = bubble_bubble_dist; + Bubbles[i]->Interaction->location[1] = 0.0; + Bubbles[i]->Interaction->location[2] = 0.0; + } + else if (2 == i) + { + Bubbles[i]->Interaction->location[0] = 0.5 * bubble_bubble_dist; + Bubbles[i]->Interaction->location[1] = 0.0; + Bubbles[i]->Interaction->location[2] = 0.0; + } + else if (3 == i) + { + Bubbles[i]->Interaction->location[0] = 0.5 * bubble_bubble_dist; + Bubbles[i]->Interaction->location[1] = 0.0; + Bubbles[i]->Interaction->location[2] = 0.0; + } + } + + // Create array to gather maximum radius value for each bubble + APECSS_FLOAT max_bubble[nBubbles]; + for (register int i = 0; i < nBubbles; i++) + { + max_bubble[i] = Bubbles[i]->R0; + } + + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + clock_t starttimebubble = clock(); + APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system + + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->tStart = tSim; + Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; + Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step + } + + /* Initialize the bubble based on the selected options */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initialize(Bubbles[i]); + + /* Initialize */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_initialize(Bubbles[i]); + + /* Solve the bubble dynamics */ + while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered + { + APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); + tSim += dtSim; + + for (register int i = 0; i < nBubbles; i++) + { + maxR = Bubbles[i]->R0; + apecss_new_bubble_solver_run(tSim, (APECSS_FLOAT) tEnd, Bubbles[i]); + if (maxR > max_bubble[i]) + { + max_bubble[i] = maxR; + } + } + } + + /* Retrieve results */ + FILE *file_max_radius; + file_max_radius = fopen("max_radius.txt", "a"); + fprintf(file_max_radius, "nb %d f(Hz) %e p(Pa) %e dist %e ODE %d R0(m);Rmax(m)", nBubbles, fa, pa, dist, ode); + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_max_radius, " %e;%e", Bubbles[i]->R0, max_bubble[i]); + } + fprintf(file_max_radius, "\n"); + fclose(file_max_radius); + + /* Finalize the simulation*/ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_finalize(Bubbles[i]); + + char str[APECSS_STRINGLENGTH_SPRINTF]; + for (register int i = 0; i < nBubbles; i++) + { + sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", i, Bubbles[i]->dtNumber, Bubbles[i]->nSubIter, + (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); + apecss_writeonscreen(str); + } + + for (register int i = 0; i < nBubbles; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); + for (register int i = 0; i < nBubbles; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); + + /* Make sure all allocated memory is freed */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_freestruct(Bubbles[i]); + + for (register int i = 0; i < nBubbles; i++) free(Bubbles[i]); + free(Gas); + free(Liquid); + free(Interface); + free(NumericsODE); + free(Excitation); + + return (0); +} + +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + APECSS_FLOAT x = Bubble->Interaction->location[0]; + return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * (t - x / Bubble->Liquid->cref))); +} + +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + // Approximate numerical computation of p_infinity derivative + APECSS_FLOAT x = Bubble->Interaction->location[0]; + APECSS_FLOAT derivative = + -Bubble->Excitation->dp * 2.0 * APECSS_PI * Bubble->Excitation->f * APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * (t - x / Bubble->Liquid->cref)); + return (derivative); +} + +APECSS_FLOAT apecss_rp_kellermiksisvelocity_ode_simplified(APECSS_FLOAT *Sol, APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + /** Simplified model for comparison with Haghi **/ + APECSS_FLOAT inv_c = 1.0 / Bubble->Liquid->cref; + APECSS_FLOAT inv_rho = 1.0 / Bubble->Liquid->rhoref; + + APECSS_FLOAT rhs = ((Bubble->Liquid->get_pressure_bubblewall(Sol, t, Bubble) - Bubble->get_pressure_infinity(t, Bubble)) * inv_rho - + 1.5 * (1.0 - (Sol[0] * APECSS_ONETHIRD * inv_c)) * APECSS_POW2(Sol[0])) / + Sol[1]; + + return (rhs / (1.0 - Sol[0] * inv_c)); +} + +int apecss_new_bubble_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble) +{ + while (Bubble->t < tend - 0.01 * Bubble->NumericsODE->dtMin) + { + // Store the previous solution for sub-iterations + for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSolOld[i] = Bubble->ODEsSol[i]; + + // Check what comes next: the end of the solver run or, if applicable, a time instance to output the emissions + APECSS_FLOAT next_event_time = Bubble->results_emissionstime_check(tend, Bubble); + + // Set the time-step for the ODEs + apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); + + // Solve the ODEs + Bubble->err = apecss_odesolver(Bubble); + + // Perform sub-iterations on the control of the time-step when err > tol + register int subiter = 0; + while ((Bubble->err > Bubble->NumericsODE->tol) && (subiter < Bubble->NumericsODE->maxSubIter)) + { + ++subiter; + // Rewind the solution + for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSol[i] = Bubble->ODEsSolOld[i]; + // Set the time-step for the ODEs + apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); + // Solve the ODEs again + Bubble->err = apecss_odesolver(Bubble); + } + Bubble->nSubIter += subiter; + + // Set new values + ++(Bubble->dtNumber); + Bubble->t += Bubble->dt; + Bubble->U = Bubble->ODEsSol[0]; + Bubble->R = Bubble->ODEsSol[1]; + + // Detect max value of radius + if (Bubble->t > tEnd - 10 / Bubble->Excitation->f) maxR = APECSS_MAX(maxR, Bubble->R); + + // Update allocation of the results (if necessary) + Bubble->results_emissionsnodeminmax_identify(Bubble); + Bubble->results_emissionsnode_alloc(Bubble); + + // Acoustic emissions (if applicable) + Bubble->emissions_update(Bubble); + + // Store results (if applicable) + Bubble->results_rayleighplesset_store(Bubble); + Bubble->results_emissionsspace_store(Bubble); + + // Write one-off results (if applicable) + Bubble->results_emissionstime_write(Bubble); + + // Update the last-step solution of the RK54 scheme + for (register int i = 0; i < Bubble->nODEs; i++) Bubble->kLast[i] = Bubble->k7[i]; + + // Update progress screen in the terminal (if applicable) + Bubble->progress_update(&(*Bubble).progress, Bubble->t - Bubble->tStart, Bubble->tEnd - Bubble->tStart); + } + + return (0); +} \ No newline at end of file From 978e5283ed4c7269687a54003061f531a0baa132 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 6 Sep 2024 16:40:37 -0400 Subject: [PATCH 088/138] frequencyresponse ; c source file for IC computations (modified and working) --- .../IC/src/frequencyresponse_apecss.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/examples/frequencyresponse/IC/src/frequencyresponse_apecss.c b/examples/frequencyresponse/IC/src/frequencyresponse_apecss.c index ecbaf3d..9cf0f16 100644 --- a/examples/frequencyresponse/IC/src/frequencyresponse_apecss.c +++ b/examples/frequencyresponse/IC/src/frequencyresponse_apecss.c @@ -25,6 +25,8 @@ APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, stru APECSS_FLOAT apecss_rp_kellermiksisvelocity_ode_simplified(APECSS_FLOAT *Sol, APECSS_FLOAT t, struct APECSS_Bubble *Bubble); int apecss_new_bubble_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble); +APECSS_FLOAT APECSS_TAN(APECSS_FLOAT x) { return APECSS_SIN(x) / APECSS_COS(x); } + APECSS_FLOAT maxR; int main(int argc, char **args) @@ -220,7 +222,7 @@ int main(int argc, char **args) Bubbles[i]->R0 = 1.5e-6; } - // Define center location for each bubble (only x is important for this test case) + // Define center location for each bubble for (register int i = 0; i < nBubbles; i++) { if (0 == i) @@ -238,14 +240,15 @@ int main(int argc, char **args) else if (2 == i) { Bubbles[i]->Interaction->location[0] = 0.5 * bubble_bubble_dist; - Bubbles[i]->Interaction->location[1] = 0.0; + Bubbles[i]->Interaction->location[1] = -APECSS_SIN(APECSS_PI / 3) * bubble_bubble_dist; Bubbles[i]->Interaction->location[2] = 0.0; } else if (3 == i) { Bubbles[i]->Interaction->location[0] = 0.5 * bubble_bubble_dist; - Bubbles[i]->Interaction->location[1] = 0.0; - Bubbles[i]->Interaction->location[2] = 0.0; + Bubbles[i]->Interaction->location[1] = -APECSS_TAN(APECSS_PI / 6) * 0.5 * bubble_bubble_dist; + Bubbles[i]->Interaction->location[2] = APECSS_SQRT(APECSS_POW2(bubble_bubble_dist) - APECSS_POW2(0.5 * bubble_bubble_dist) - + APECSS_POW2(APECSS_TAN(APECSS_PI / 6) * 0.5 * bubble_bubble_dist)); } } @@ -289,6 +292,11 @@ int main(int argc, char **args) max_bubble[i] = maxR; } } + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Update the contribution of the neighbor bubbles + apecss_interactions_instantaneous(Bubbles); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< } /* Retrieve results */ @@ -332,7 +340,8 @@ int main(int argc, char **args) APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { APECSS_FLOAT x = Bubble->Interaction->location[0]; - return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * (t - x / Bubble->Liquid->cref))); + return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * (t - x / Bubble->Liquid->cref)) + + Bubble->Interaction->dp_neighbor); } APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) From 616450c76d0b26b16ab9be6365d74d35c4fb84b9 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 6 Sep 2024 16:41:21 -0400 Subject: [PATCH 089/138] frequencyresponse ; original QA folder copied from IC folder, need changes --- .../frequencyresponse/QA/build/CMakeLists.txt | 41 ++ .../frequencyresponse/QA/build/compile.sh | 5 + .../frequencyresponse/QA/gather_results.py | 35 ++ examples/frequencyresponse/QA/run.apecss | 36 ++ .../QA/src/frequencyresponse_apecss.c | 444 ++++++++++++++++++ 5 files changed, 561 insertions(+) create mode 100644 examples/frequencyresponse/QA/build/CMakeLists.txt create mode 100755 examples/frequencyresponse/QA/build/compile.sh create mode 100644 examples/frequencyresponse/QA/gather_results.py create mode 100644 examples/frequencyresponse/QA/run.apecss create mode 100644 examples/frequencyresponse/QA/src/frequencyresponse_apecss.c diff --git a/examples/frequencyresponse/QA/build/CMakeLists.txt b/examples/frequencyresponse/QA/build/CMakeLists.txt new file mode 100644 index 0000000..7e6cde8 --- /dev/null +++ b/examples/frequencyresponse/QA/build/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.12) + +project (frequencyresponse_apecss) +set(CMAKE_C_COMPILER /usr/bin/gcc) + +include_directories($ENV{APECSS_DIR}/include) +FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) + +set (mylibs m apecss) +link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) + +foreach(arg ${myincludes}) + IF (arg MATCHES "-I") + STRING(REGEX REPLACE "-I" "" myinc ${arg}) + message("Additional include: ${myinc}") + include_directories(${myinc}) + ENDIF(arg MATCHES "-I") +endforeach(arg ${myincludes}) + +foreach(arg ${mylibs}) + STRING(REGEX REPLACE "lib" "" myl1 ${arg}) + STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) + set(mylibs ${myl2} ${mylibs} ${myl2}) +endforeach(arg ${mylibs}) + +if(NOT CMAKE_BUILD_TYPE) + message(STATUS "Optimization: No optimization specified.") + set(CMAKE_BUILD_TYPE Release) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + message(STATUS "Optimization: Debug") + set(CMAKE_C_FLAGS_DEBUG "-Wall -g") +elseif(CMAKE_BUILD_TYPE STREQUAL "Release") + message(STATUS "Optimization: Release") + add_definitions(-DNDEBUG) + set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") +endif() + +add_executable(frequencyresponse_apecss ${myfiles}) +target_link_libraries(frequencyresponse_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/frequencyresponse/QA/build/compile.sh b/examples/frequencyresponse/QA/build/compile.sh new file mode 100755 index 0000000..55dab1c --- /dev/null +++ b/examples/frequencyresponse/QA/build/compile.sh @@ -0,0 +1,5 @@ +#!/bin/bash +rm frequencyresponse_apecss +cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release +make +rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/frequencyresponse/QA/gather_results.py b/examples/frequencyresponse/QA/gather_results.py new file mode 100644 index 0000000..7362d5a --- /dev/null +++ b/examples/frequencyresponse/QA/gather_results.py @@ -0,0 +1,35 @@ +import os + +######### File designed to retrieve and gather in the "results" folder the data obtained with frequency response computations + +working_path = os.getcwd() + +results_file = open(os.path.join(working_path, "max_radius.txt"), "r") +lines = results_file.readlines() +results_file.close() + +firstline = lines[0].split(" ") +nBubbles = int(firstline[1]) +pa = float(firstline[5]) +dist = float(firstline[7]) +ode = int(firstline[9]) + +gather_path = os.path.join(working_path, "results") + +file_name = "{}_p{:.5E}_d{:.2E}_{}.txt".format(nBubbles, pa, dist, ode) + +data_file = open(os.path.join(gather_path, file_name), "w") +data_file.write("nb {} p(Pa) {:.5E} dist {:.2E} ODE {}\n".format(nBubbles, pa, dist, ode)) +data_file.write("#f(Hz) R0(m);R(m)\n") + +for line in lines : + if line != "" : + data = line.split(" ") + f = float(data[3]) + data_file.write("{:.5E}".format(f)) + + r_list = data[11:] + for r in r_list : + data_file.write(" {}".format(r)) + +data_file.close() \ No newline at end of file diff --git a/examples/frequencyresponse/QA/run.apecss b/examples/frequencyresponse/QA/run.apecss new file mode 100644 index 0000000..67300c7 --- /dev/null +++ b/examples/frequencyresponse/QA/run.apecss @@ -0,0 +1,36 @@ +######################################################### +# # +# APECSS Options File # +# # +######################################################### + +BUBBLE +RPModel KM +Emissions IC 300.0e-6 +PressureAmbient 1.0e5 +END + +GAS +EoS IG +ReferenceDensity 1.2 +PolytropicExponent 1.4 +END + +LIQUID +ReferencePressure 1.0e5 +ReferenceDensity 1000.0 +ReferenceSoundSpeed 1500.0 +Viscosity 1.002e-3 +END + +INTERFACE +SurfaceTensionCoeff 0.0728 +END + +RESULTS +Bubble +END + +ODESOLVER +tolerance 1.0e-10 +END diff --git a/examples/frequencyresponse/QA/src/frequencyresponse_apecss.c b/examples/frequencyresponse/QA/src/frequencyresponse_apecss.c new file mode 100644 index 0000000..9592c5b --- /dev/null +++ b/examples/frequencyresponse/QA/src/frequencyresponse_apecss.c @@ -0,0 +1,444 @@ +// This source file is part of APECSS, an open-source software toolbox +// for the computation of pressure-driven bubble dynamics and acoustic +// emissions in spherical symmetry. +// +// Copyright (C) 2022-2024 The APECSS Developers +// +// The APECSS Developers are listed in the README.md file available in +// the GitHub repository at https://github.com/polycfd/apecss. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// ------------------------------------------------------------------- +// APECSS standalone example of acoustically-interacting microbubbles, +// based on Jiang et al., Ultrasonics Sonochemistry 34 (2017), 90-97. +// ------------------------------------------------------------------- + +#include +#include "apecss.h" + +// Declaration of additional case-dependent functions +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +APECSS_FLOAT apecss_rp_kellermiksisvelocity_ode_simplified(APECSS_FLOAT *Sol, APECSS_FLOAT t, struct APECSS_Bubble *Bubble); +int apecss_new_bubble_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble); + +APECSS_FLOAT APECSS_TAN(APECSS_FLOAT x) { return APECSS_SIN(x) / APECSS_COS(x); } + +APECSS_FLOAT maxR; + +int main(int argc, char **args) +{ + char OptionsDir[APECSS_STRINGLENGTH]; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Set the case-dependent simulation parameters + int nBubbles = 3; // Number of bubbles + APECSS_FLOAT bubble_bubble_dist = 5.0e-6; // Bubble-bubble distance + + // Interbubble time-step, defining the frequency with which the neighbor influence is updated + APECSS_FLOAT dt_interbubble = 1.0e-8; + + // Initialize the simulation parameters given by the execution command + double tEnd = 0.0; + double fa = 0.0; + double pa = 0.0; + double dist = 5.0e-6; + double dt_inter = 1.0e-8; + int ode = 0; + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + apecss_infoscreen(); + + /* Read commandline options */ + sprintf(OptionsDir, "./run.apecss"); // This is the default + int j = 1; // First argument is the call to the executable + while (j < argc) + { + if (strcmp("-options", args[j]) == 0) + { + sprintf(OptionsDir, "%s", args[j + 1]); + j += 2; + } + else if (strcmp("-nb", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &nBubbles); + j += 2; + } + else if (strcmp("-tend", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &tEnd); + j += 2; + } + else if (strcmp("-freq", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &fa); + j += 2; + } + else if (strcmp("-amp", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &pa); + j += 2; + } + else if (strcmp("-dist", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &dist); + j += 2; + } + else if (strcmp("-dt_inter", args[j]) == 0) + { + sscanf(args[j + 1], "%le", &dt_inter); + j += 2; + } + else if (strcmp("-ode", args[j]) == 0) + { + sscanf(args[j + 1], "%d", &ode); + j += 2; + } + else if (strcmp("-h", args[j]) == 0) + { + apecss_helpscreen(); + } + else + { + char str[APECSS_STRINGLENGTH_SPRINTF]; + sprintf(str, "Unknown command line options: %s", args[j]); + apecss_erroronscreen(1, str); + ++j; + } + } + + /* Properly update parameters with commandline options */ + bubble_bubble_dist = (APECSS_FLOAT) dist; + dt_interbubble = (APECSS_FLOAT) dt_inter; + tEnd = 30 / fa; + + /* Check if the number of bubbles is right */ + if ((nBubbles != 3) && (nBubbles != 4)) + { + nBubbles = 3; + } + + /* Allocate and initialize Bubble structure */ + struct APECSS_Bubble *Bubbles[nBubbles]; + for (register int i = 0; i < nBubbles; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(nBubbles * sizeof(struct APECSS_Bubble)); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initializestruct(Bubbles[i]); + + /* Set default options and read the options for the bubble */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); + + /* Allocate the structures for the fluid properties and ODE solver parameters */ + struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); + struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); + struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); + struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); + + /* Set the default options for the fluid properties and solver parameters */ + apecss_gas_setdefaultoptions(Gas); + apecss_liquid_setdefaultoptions(Liquid); + apecss_interface_setdefaultoptions(Interface); + apecss_odesolver_setdefaultoptions(NumericsODE); + + /* Read the options file for the fluid properties and solver parameters */ + apecss_gas_readoptions(Gas, OptionsDir); + apecss_liquid_readoptions(Liquid, OptionsDir); + apecss_interface_readoptions(Interface, OptionsDir); + apecss_odesolver_readoptions(NumericsODE, OptionsDir); + + /* Associate the bubble with the relevant fluid properties and solver parameters */ + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Gas = Gas; + Bubbles[i]->Liquid = Liquid; + Bubbles[i]->Interface = Interface; + Bubbles[i]->NumericsODE = NumericsODE; + } + + /* Allocate and set the excitation parameters */ + struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); + Excitation->type = APECSS_EXCITATION_SIN; + Excitation->f = (APECSS_FLOAT) fa; + Excitation->dp = (APECSS_FLOAT) pa; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Excitation = Excitation; + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Create individual folders for the results of each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (Bubbles[i]->Results != NULL) + { + sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", i); + struct stat st = {0}; + if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); + } + } + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /* Process all options */ + apecss_gas_processoptions(Gas); + apecss_liquid_processoptions(Liquid); + apecss_interface_processoptions(Interface); + apecss_odesolver_processoptions(NumericsODE); + for (register int i = 0; i < nBubbles; i++) apecss_bubble_processoptions(Bubbles[i]); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Use the revised pressure at infinity, including neighbor contributions + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressure_infinity = interaction_bubble_pressure_infinity; + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressurederivative_infinity = interaction_bubble_pressurederivative_infinity; + + // Update the Keller-Miksis ODE + if (ode == 1) + { + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->ode[0] = apecss_rp_kellermiksisvelocity_ode_simplified; + } + + // Initialize interaction structure + for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); + + // Update interaction structure + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Interaction->nBubbles = nBubbles; + Bubbles[i]->Interaction->dp_neighbor = 0.0; + Bubbles[i]->Interaction->last_t_1 = 0.0; + Bubbles[i]->Interaction->last_t_2 = 0.0; + Bubbles[i]->Interaction->last_p_1 = 0.0; + Bubbles[i]->Interaction->last_p_2 = 0.0; + } + + // Define the size of each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (0 == i) + Bubbles[i]->R0 = 1.0e-6; + else if (1 == i) + Bubbles[i]->R0 = 0.8e-6; + else if (2 == i) + Bubbles[i]->R0 = 0.5e-6; + else if (3 == i) + Bubbles[i]->R0 = 1.5e-6; + } + + // Define center location for each bubble + for (register int i = 0; i < nBubbles; i++) + { + if (0 == i) + { + Bubbles[i]->Interaction->location[0] = 0.0; + Bubbles[i]->Interaction->location[1] = 0.0; + Bubbles[i]->Interaction->location[2] = 0.0; + } + else if (1 == i) + { + Bubbles[i]->Interaction->location[0] = bubble_bubble_dist; + Bubbles[i]->Interaction->location[1] = 0.0; + Bubbles[i]->Interaction->location[2] = 0.0; + } + else if (2 == i) + { + Bubbles[i]->Interaction->location[0] = 0.5 * bubble_bubble_dist; + Bubbles[i]->Interaction->location[1] = -APECSS_SIN(APECSS_PI / 3) * bubble_bubble_dist; + Bubbles[i]->Interaction->location[2] = 0.0; + } + else if (3 == i) + { + Bubbles[i]->Interaction->location[0] = 0.5 * bubble_bubble_dist; + Bubbles[i]->Interaction->location[1] = -APECSS_TAN(APECSS_PI / 6) * 0.5 * bubble_bubble_dist; + Bubbles[i]->Interaction->location[2] = APECSS_SQRT(APECSS_POW2(bubble_bubble_dist) - APECSS_POW2(0.5 * bubble_bubble_dist) - + APECSS_POW2(APECSS_TAN(APECSS_PI / 6) * 0.5 * bubble_bubble_dist)); + } + } + + // Create array to gather maximum radius value for each bubble + APECSS_FLOAT max_bubble[nBubbles]; + for (register int i = 0; i < nBubbles; i++) + { + max_bubble[i] = Bubbles[i]->R0; + } + + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + clock_t starttimebubble = clock(); + APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system + + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->tStart = tSim; + Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; + Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step + } + + /* Initialize the bubble based on the selected options */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_initialize(Bubbles[i]); + + /* Initialize */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_initialize(Bubbles[i]); + + /* Solve the bubble dynamics */ + while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered + { + APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); + tSim += dtSim; + + for (register int i = 0; i < nBubbles; i++) + { + maxR = Bubbles[i]->R0; + apecss_new_bubble_solver_run(tSim, (APECSS_FLOAT) tEnd, Bubbles[i]); + if (maxR > max_bubble[i]) + { + max_bubble[i] = maxR; + } + } + + // printf("%e", tSim); + // for (register int i = 0; i < nBubbles; i++) + // { + // printf(" %e %e", Bubbles[0]->Interaction->dp_neighbor, Bubbles[0]->ode[0](Bubbles[0]->ODEsSol, Bubbles[0]->t, Bubbles[0])); + // } + // printf("\n"); + + // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Update the contribution of the neighbor bubbles + apecss_interactions_instantaneous(Bubbles); + // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + // printf("%e", tSim); + // for (register int i = 0; i < nBubbles; i++) + // { + // printf(" %e %e", Bubbles[0]->Interaction->dp_neighbor, Bubbles[0]->ode[0](Bubbles[0]->ODEsSol, Bubbles[0]->t, Bubbles[0])); + // } + // printf("\n"); + } + + /* Retrieve results */ + FILE *file_max_radius; + file_max_radius = fopen("max_radius.txt", "a"); + fprintf(file_max_radius, "nb %d f(Hz) %e p(Pa) %e dist %e ODE %d R0(m);Rmax(m)", nBubbles, fa, pa, dist, ode); + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_max_radius, " %e;%e", Bubbles[i]->R0, max_bubble[i]); + } + fprintf(file_max_radius, "\n"); + fclose(file_max_radius); + + /* Finalize the simulation*/ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_finalize(Bubbles[i]); + + char str[APECSS_STRINGLENGTH_SPRINTF]; + for (register int i = 0; i < nBubbles; i++) + { + sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", i, Bubbles[i]->dtNumber, Bubbles[i]->nSubIter, + (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); + apecss_writeonscreen(str); + } + + for (register int i = 0; i < nBubbles; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); + for (register int i = 0; i < nBubbles; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); + + /* Make sure all allocated memory is freed */ + for (register int i = 0; i < nBubbles; i++) apecss_bubble_freestruct(Bubbles[i]); + + for (register int i = 0; i < nBubbles; i++) free(Bubbles[i]); + free(Gas); + free(Liquid); + free(Interface); + free(NumericsODE); + free(Excitation); + + return (0); +} + +APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + APECSS_FLOAT x = Bubble->Interaction->location[0]; + return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * (t - x / Bubble->Liquid->cref)) + + Bubble->Interaction->dp_neighbor); +} + +APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + // Approximate numerical computation of p_infinity derivative + APECSS_FLOAT x = Bubble->Interaction->location[0]; + APECSS_FLOAT derivative = + -Bubble->Excitation->dp * 2.0 * APECSS_PI * Bubble->Excitation->f * APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * (t - x / Bubble->Liquid->cref)); + return (derivative); +} + +APECSS_FLOAT apecss_rp_kellermiksisvelocity_ode_simplified(APECSS_FLOAT *Sol, APECSS_FLOAT t, struct APECSS_Bubble *Bubble) +{ + /** Simplified model for comparison with Haghi **/ + APECSS_FLOAT inv_c = 1.0 / Bubble->Liquid->cref; + APECSS_FLOAT inv_rho = 1.0 / Bubble->Liquid->rhoref; + + APECSS_FLOAT rhs = ((Bubble->Liquid->get_pressure_bubblewall(Sol, t, Bubble) - Bubble->get_pressure_infinity(t, Bubble)) * inv_rho - + 1.5 * (1.0 - (Sol[0] * APECSS_ONETHIRD * inv_c)) * APECSS_POW2(Sol[0])) / + Sol[1]; + + return (rhs / (1.0 - Sol[0] * inv_c)); +} + +int apecss_new_bubble_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble) +{ + while (Bubble->t < tend - 0.01 * Bubble->NumericsODE->dtMin) + { + // Store the previous solution for sub-iterations + for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSolOld[i] = Bubble->ODEsSol[i]; + + // Check what comes next: the end of the solver run or, if applicable, a time instance to output the emissions + APECSS_FLOAT next_event_time = Bubble->results_emissionstime_check(tend, Bubble); + + // Set the time-step for the ODEs + apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); + + // Solve the ODEs + Bubble->err = apecss_odesolver(Bubble); + + // Perform sub-iterations on the control of the time-step when err > tol + register int subiter = 0; + while ((Bubble->err > Bubble->NumericsODE->tol) && (subiter < Bubble->NumericsODE->maxSubIter)) + { + ++subiter; + // Rewind the solution + for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSol[i] = Bubble->ODEsSolOld[i]; + // Set the time-step for the ODEs + apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); + // Solve the ODEs again + Bubble->err = apecss_odesolver(Bubble); + } + Bubble->nSubIter += subiter; + + // Set new values + ++(Bubble->dtNumber); + Bubble->t += Bubble->dt; + Bubble->U = Bubble->ODEsSol[0]; + Bubble->R = Bubble->ODEsSol[1]; + + // Detect max value of radius + if (Bubble->t > tEnd - 10 / Bubble->Excitation->f) maxR = APECSS_MAX(maxR, Bubble->R); + + // Update allocation of the results (if necessary) + Bubble->results_emissionsnodeminmax_identify(Bubble); + Bubble->results_emissionsnode_alloc(Bubble); + + // Acoustic emissions (if applicable) + Bubble->emissions_update(Bubble); + + // Store results (if applicable) + Bubble->results_rayleighplesset_store(Bubble); + Bubble->results_emissionsspace_store(Bubble); + + // Write one-off results (if applicable) + Bubble->results_emissionstime_write(Bubble); + + // Update the last-step solution of the RK54 scheme + for (register int i = 0; i < Bubble->nODEs; i++) Bubble->kLast[i] = Bubble->k7[i]; + + // Update progress screen in the terminal (if applicable) + Bubble->progress_update(&(*Bubble).progress, Bubble->t - Bubble->tStart, Bubble->tEnd - Bubble->tStart); + } + + return (0); +} \ No newline at end of file From 0de5b80e954e82c703ea381e53407db5acd08178 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 6 Sep 2024 16:42:43 -0400 Subject: [PATCH 090/138] frequencyresponse ; updated sh run file and python plot results file for IC computations --- examples/frequencyresponse/plot_results.py | 104 +++++++++++++++++- .../run_frequencyresponse.sh | 43 ++++++++ 2 files changed, 146 insertions(+), 1 deletion(-) diff --git a/examples/frequencyresponse/plot_results.py b/examples/frequencyresponse/plot_results.py index af60235..0bbdde7 100644 --- a/examples/frequencyresponse/plot_results.py +++ b/examples/frequencyresponse/plot_results.py @@ -16,8 +16,12 @@ #### Original paper results ##################### paper_results_NI = {} +paper_results_IC_3 = {} +paper_results_IC_4 = {} working_path = os.getcwd() + +# No interactions (NI) paper_path = os.path.join(working_path, "articleresults") paper_path = os.path.join(paper_path, "NI") @@ -38,6 +42,50 @@ paper_results_NI[r_init] = [f_list, r_list] +# Incompressible interactions (IC) with 3 bubbles +paper_path = os.path.join(working_path, "articleresults") +paper_path = os.path.join(paper_path, "IC") +paper_path = os.path.join(paper_path, "3MBs") + +for file in os.listdir(paper_path) : + file_path = os.path.join(paper_path, file) + + text = open(file_path, "r") + lines = text.readlines() + text.close() + + r_init = float(lines[1].split(" : ")[-1]) + f_list = [] + r_list = [] + for i in range(3, len(lines)) : + line = lines[i].split(" ") + f_list.append(float(line[0].replace(",", "."))) + r_list.append(float(line[1].replace(",", "."))) + + paper_results_IC_3[r_init] = [f_list, r_list] + +# Incompressible interactions (IC) with 4 bubbles +paper_path = os.path.join(working_path, "articleresults") +paper_path = os.path.join(paper_path, "IC") +paper_path = os.path.join(paper_path, "4MBs") + +for file in os.listdir(paper_path) : + file_path = os.path.join(paper_path, file) + + text = open(file_path, "r") + lines = text.readlines() + text.close() + + r_init = float(lines[1].split(" : ")[-1]) + f_list = [] + r_list = [] + for i in range(3, len(lines)) : + line = lines[i].split(" ") + f_list.append(float(line[0].replace(",", "."))) + r_list.append(float(line[1].replace(",", "."))) + + paper_results_IC_4[r_init] = [f_list, r_list] + #### Computation results ######################## # Key distribution : Inttype->ODE->nBubbles->pressure->distance dic_results = {} @@ -100,7 +148,7 @@ axs[i].set_xlim(xmin=0.5, xmax=10.0) axs[i].grid() axs[0].set_ylabel(r"$R_{\mathrm{max}}/R_{0}$") -fig.subplots_adjust(hspace=0.0, wspace=0.1*cm) +fig.subplots_adjust(hspace=0.0, wspace=0.05*cm) axs[0].set_title(r"full Keller-Miksis ODE") axs[1].set_title(r"partial Keller-Miksis ODE") @@ -127,5 +175,59 @@ fig.savefig("frequencyresponse_comparison_NI.pdf", bbox_inches='tight',pad_inches=0.35) #### Incompressible interactions #### +n_row = 2 +n_col = 2 + +fig, axs = plt.subplots(n_row, n_col, figsize=(n_col*25.0*cm, n_row*12.5*cm), sharey=True, sharex=True) +for i in range(n_row) : + for j in range(n_col) : + axs[i, j].grid() + if i == 1 : + axs[i, j].set_xlabel(r"$f$ [MHz]") + axs[i, j].set_xlim(xmin=0.5, xmax=10.0) + if j == 0 : + axs[i, j].set_ylabel(r"$R_{\mathrm{max}}/R_{0}$") +fig.subplots_adjust(hspace=0.1*cm, wspace=0.05*cm) + +axs[0, 0].set_title(r"full Keller-Miksis ODE") +axs[0, 1].set_title(r"partial Keller-Miksis ODE") + +# 3 MBs +data_list = dic_results["IC"][0][3][1.2e5][5e-6] +axs[0, 0].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.0$ $\mu$m") +axs[0, 0].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.8$ $\mu$m") +axs[0, 0].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.5$ $\mu$m") + +data_list = dic_results["IC"][1][3][1.2e5][5e-6] +axs[0, 1].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid") +axs[0, 1].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid") +axs[0, 1].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid") + +# 4 MBs +data_list = dic_results["IC"][0][4][1.2e5][5e-6] +axs[1, 0].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.0$ $\mu$m") +axs[1, 0].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.8$ $\mu$m") +axs[1, 0].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.5$ $\mu$m") +axs[1, 0].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.5$ $\mu$m") + +data_list = dic_results["IC"][1][4][1.2e5][5e-6] +axs[1, 1].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.0$ $\mu$m") +axs[1, 1].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.8$ $\mu$m") +axs[1, 1].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.5$ $\mu$m") +axs[1, 1].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.5$ $\mu$m") + +for j in range(n_col) : + axs[0, j].plot(paper_results_IC_3[1.0][0], paper_results_IC_3[1.0][1], color="blue", linewidth=2.5, linestyle="dashed") + axs[0, j].plot(paper_results_IC_3[0.8][0], paper_results_IC_3[0.8][1], color="magenta", linewidth=2.5, linestyle="dashed") + axs[0, j].plot(paper_results_IC_3[0.5][0], paper_results_IC_3[0.5][1], color="red", linewidth=2.5, linestyle="dashed") + + axs[1, j].plot(paper_results_IC_4[1.0][0], paper_results_IC_4[1.0][1], color="blue", linewidth=2.5, linestyle="dashed") + axs[1, j].plot(paper_results_IC_4[0.8][0], paper_results_IC_4[0.8][1], color="magenta", linewidth=2.5, linestyle="dashed") + axs[1, j].plot(paper_results_IC_4[0.5][0], paper_results_IC_4[0.5][1], color="red", linewidth=2.5, linestyle="dashed") + axs[1, j].plot(paper_results_IC_4[1.5][0], paper_results_IC_4[1.5][1], color="black", linewidth=2.5, linestyle="dashed") + +axs[0, 0].legend(loc="upper right", frameon=False) +axs[1, 0].legend(loc="upper right", frameon=False) +fig.savefig("frequencyresponse_comparison_IC.pdf", bbox_inches='tight',pad_inches=0.35) ######### Step 3 : Article plots ################################################################## \ No newline at end of file diff --git a/examples/frequencyresponse/run_frequencyresponse.sh b/examples/frequencyresponse/run_frequencyresponse.sh index 994eab6..b58f2f1 100755 --- a/examples/frequencyresponse/run_frequencyresponse.sh +++ b/examples/frequencyresponse/run_frequencyresponse.sh @@ -22,6 +22,42 @@ rm -rf max_radius.txt cd .. +######################## Incompressible interactions (IC) ######################################### + +cd IC/build +./compile.sh +cd .. + +for ((f=500000;f<=10000000;f+=3000)) +do + ./build/frequencyresponse_apecss -options run.apecss -nb 3 -freq $f -amp 120e3 -dt_inter 1e-9 +done +python3 gather_results.py +rm -rf max_radius.txt + +for ((f=500000;f<=10000000;f+=3000)) +do + ./build/frequencyresponse_apecss -options run.apecss -nb 3 -freq $f -amp 120e3 -ode 1 -dt_inter 1e-9 +done +python3 gather_results.py +rm -rf max_radius.txt + +for ((f=500000;f<=10000000;f+=3000)) +do + ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -dt_inter 1e-9 +done +python3 gather_results.py +rm -rf max_radius.txt + +for ((f=500000;f<=10000000;f+=3000)) +do + ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -ode 1 -dt_inter 1e-9 +done +python3 gather_results.py +rm -rf max_radius.txt + +cd .. + ######################## Cleaning ################################################################# cd NI @@ -29,4 +65,11 @@ for ((c=0;c<=4;c++)) do rm -rf Bubble_$c done +cd .. + +cd IC +for ((c=0;c<=4;c++)) +do + rm -rf Bubble_$c +done cd .. \ No newline at end of file From 9599ce677dbda11a8781eabb88ed792838a352d1 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 6 Sep 2024 17:36:47 -0400 Subject: [PATCH 091/138] frequencyresponse ; c source file for QA computations completed --- examples/frequencyresponse/QA/run.apecss | 2 +- .../QA/src/frequencyresponse_apecss.c | 33 ++++++++++--------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/examples/frequencyresponse/QA/run.apecss b/examples/frequencyresponse/QA/run.apecss index 67300c7..73dab5c 100644 --- a/examples/frequencyresponse/QA/run.apecss +++ b/examples/frequencyresponse/QA/run.apecss @@ -6,7 +6,7 @@ BUBBLE RPModel KM -Emissions IC 300.0e-6 +Emissions QA 60.0e-6 PressureAmbient 1.0e5 END diff --git a/examples/frequencyresponse/QA/src/frequencyresponse_apecss.c b/examples/frequencyresponse/QA/src/frequencyresponse_apecss.c index 9592c5b..632f9d8 100644 --- a/examples/frequencyresponse/QA/src/frequencyresponse_apecss.c +++ b/examples/frequencyresponse/QA/src/frequencyresponse_apecss.c @@ -293,24 +293,19 @@ int main(int argc, char **args) } } - // printf("%e", tSim); - // for (register int i = 0; i < nBubbles; i++) - // { - // printf(" %e %e", Bubbles[0]->Interaction->dp_neighbor, Bubbles[0]->ode[0](Bubbles[0]->ODEsSol, Bubbles[0]->t, Bubbles[0])); - // } - // printf("\n"); - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // Update the contribution of the neighbor bubbles - apecss_interactions_instantaneous(Bubbles); + apecss_interactions_quasi_acoustic(Bubbles); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - // printf("%e", tSim); - // for (register int i = 0; i < nBubbles; i++) - // { - // printf(" %e %e", Bubbles[0]->Interaction->dp_neighbor, Bubbles[0]->ode[0](Bubbles[0]->ODEsSol, Bubbles[0]->t, Bubbles[0])); - // } - // printf("\n"); + for (register int i = 0; i < nBubbles; i++) + { + Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; + Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; + + Bubbles[i]->Interaction->last_t_1 = tSim; + Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; + } } /* Retrieve results */ @@ -361,10 +356,18 @@ APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_ APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { // Approximate numerical computation of p_infinity derivative + APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; APECSS_FLOAT x = Bubble->Interaction->location[0]; APECSS_FLOAT derivative = -Bubble->Excitation->dp * 2.0 * APECSS_PI * Bubble->Excitation->f * APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * (t - x / Bubble->Liquid->cref)); - return (derivative); + if (delta_t > Bubble->dt) + { + return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) / (Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2))); + } + else + { + return (derivative); + } } APECSS_FLOAT apecss_rp_kellermiksisvelocity_ode_simplified(APECSS_FLOAT *Sol, APECSS_FLOAT t, struct APECSS_Bubble *Bubble) From 9669a5a288f5517090a3cfa675f2900105ca1c5c Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 6 Sep 2024 17:37:31 -0400 Subject: [PATCH 092/138] frequencyresponse ; updated sh run file and python plot results for QA computations --- examples/frequencyresponse/plot_results.py | 84 ++++++++++++++++++- .../run_frequencyresponse.sh | 37 ++++++++ 2 files changed, 120 insertions(+), 1 deletion(-) diff --git a/examples/frequencyresponse/plot_results.py b/examples/frequencyresponse/plot_results.py index 0bbdde7..a9df2fb 100644 --- a/examples/frequencyresponse/plot_results.py +++ b/examples/frequencyresponse/plot_results.py @@ -230,4 +230,86 @@ axs[1, 0].legend(loc="upper right", frameon=False) fig.savefig("frequencyresponse_comparison_IC.pdf", bbox_inches='tight',pad_inches=0.35) -######### Step 3 : Article plots ################################################################## \ No newline at end of file +######### Step 3 : Article plots ################################################################## + +######## Reproduction of Haghi's results ################################# +n_row = 3 +n_col = 2 + +fig, axs = plt.subplots(n_row, n_col, figsize=(n_col*25.0*cm, n_row*12.5*cm), sharey=True, sharex=True) +for i in range(n_row) : + for j in range(n_col) : + axs[i, j].grid() + if i == 2 : + axs[i, j].set_xlabel(r"$f$ [MHz]") + axs[i, j].set_xlim(xmin=0.5, xmax=10.0) + if j == 0 : + axs[i, j].set_ylabel(r"$R_{\mathrm{max}}/R_{0}$") +fig.subplots_adjust(hspace=0.1*cm, wspace=0.05*cm) + +axs[0, 0].set_title(r"(a) 3MBs") +axs[0, 1].set_title(r"(b) 4MBs") + +# 3 MBs +data_list = dic_results["NI"][0][4][1.2e5][5e-6] +axs[0, 0].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.0$ $\mu$m") +axs[0, 0].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.8$ $\mu$m") +axs[0, 0].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.5$ $\mu$m") +axs[0, 0].text(3.0, 2.25,r"No interactions") + +data_list = dic_results["IC"][0][3][1.2e5][5e-6] +axs[1, 0].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid") +axs[1, 0].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid") +axs[1, 0].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid") +axs[1, 0].text(3.0, 2.25,r"Incompressible interactions") + +data_list = dic_results["QA"][0][3][1.2e5][5e-6] +axs[2, 0].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid") +axs[2, 0].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid") +axs[2, 0].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid") +axs[2, 0].text(3.0, 2.25,r"Quasi-acoustic interactions") + +# 4 MBs +data_list = dic_results["NI"][0][4][1.2e5][5e-6] +axs[0, 1].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.0$ $\mu$m") +axs[0, 1].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.8$ $\mu$m") +axs[0, 1].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.5$ $\mu$m") +axs[0, 1].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.5$ $\mu$m") +axs[0, 1].text(3.0, 2.25,r"No interactions") + +data_list = dic_results["IC"][0][4][1.2e5][5e-6] +axs[1, 1].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid") +axs[1, 1].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid") +axs[1, 1].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid") +axs[1, 1].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid") +axs[1, 1].text(3.0, 2.25,r"Incompressible interactions") + +data_list = dic_results["QA"][0][4][1.2e5][5e-6] +axs[2, 1].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid") +axs[2, 1].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid") +axs[2, 1].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid") +axs[2, 1].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid") +axs[2, 1].text(3.0, 2.25,r"Quasi-acoustic interactions") + +# Reference values +axs[0, 0].plot(paper_results_NI[1.0][0], paper_results_NI[1.0][1], color="blue", linewidth=2.5, linestyle="dashed") +axs[0, 0].plot(paper_results_NI[0.8][0], paper_results_NI[0.8][1], color="magenta", linewidth=2.5, linestyle="dashed") +axs[0, 0].plot(paper_results_NI[0.5][0], paper_results_NI[0.5][1], color="red", linewidth=2.5, linestyle="dashed") + +axs[0, 1].plot(paper_results_NI[1.0][0], paper_results_NI[1.0][1], color="blue", linewidth=2.5, linestyle="dashed") +axs[0, 1].plot(paper_results_NI[0.8][0], paper_results_NI[0.8][1], color="magenta", linewidth=2.5, linestyle="dashed") +axs[0, 1].plot(paper_results_NI[0.5][0], paper_results_NI[0.5][1], color="red", linewidth=2.5, linestyle="dashed") +axs[0, 1].plot(paper_results_NI[1.5][0], paper_results_NI[1.5][1], color="black", linewidth=2.5, linestyle="dashed") + +axs[1, 0].plot(paper_results_IC_3[1.0][0], paper_results_IC_3[1.0][1], color="blue", linewidth=2.5, linestyle="dashed") +axs[1, 0].plot(paper_results_IC_3[0.8][0], paper_results_IC_3[0.8][1], color="magenta", linewidth=2.5, linestyle="dashed") +axs[1, 0].plot(paper_results_IC_3[0.5][0], paper_results_IC_3[0.5][1], color="red", linewidth=2.5, linestyle="dashed") + +axs[1, 1].plot(paper_results_IC_4[1.0][0], paper_results_IC_4[1.0][1], color="blue", linewidth=2.5, linestyle="dashed") +axs[1, 1].plot(paper_results_IC_4[0.8][0], paper_results_IC_4[0.8][1], color="magenta", linewidth=2.5, linestyle="dashed") +axs[1, 1].plot(paper_results_IC_4[0.5][0], paper_results_IC_4[0.5][1], color="red", linewidth=2.5, linestyle="dashed") +axs[1, 1].plot(paper_results_IC_4[1.5][0], paper_results_IC_4[1.5][1], color="black", linewidth=2.5, linestyle="dashed") + +axs[0, 0].legend(loc="upper right", frameon=False) +axs[0, 1].legend(loc="upper right", frameon=False) +fig.savefig("frequencyresponse.pdf", bbox_inches='tight',pad_inches=0.35) \ No newline at end of file diff --git a/examples/frequencyresponse/run_frequencyresponse.sh b/examples/frequencyresponse/run_frequencyresponse.sh index b58f2f1..19c2e4e 100755 --- a/examples/frequencyresponse/run_frequencyresponse.sh +++ b/examples/frequencyresponse/run_frequencyresponse.sh @@ -58,6 +58,36 @@ rm -rf max_radius.txt cd .. +######################## Quasi-acoustic interactions (QA) ######################################### + +cd QA/build +./compile.sh +cd .. + +for ((f=500000;f<=10000000;f+=3000)) +do + ./build/frequencyresponse_apecss -options run.apecss -nb 3 -freq $f -amp 120e3 -dt_inter 1e-9 +done +python3 gather_results.py +rm -rf max_radius.txt + +for ((f=500000;f<1900000;f+=3000)) +do + ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -dt_inter 1e-9 +done +for ((f=1900000;f<2900000;f+=3000)) +do + ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -dt_inter 5.0e-10 +done +for ((f=2900000;f<=10000000;f+=3000)) +do + ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -dt_inter 1e-9 +done +python3 gather_results.py +rm -rf max_radius.txt + +cd .. + ######################## Cleaning ################################################################# cd NI @@ -72,4 +102,11 @@ for ((c=0;c<=4;c++)) do rm -rf Bubble_$c done +cd .. + +cd QA +for ((c=0;c<=4;c++)) +do + rm -rf Bubble_$c +done cd .. \ No newline at end of file From 3c67de9e95c010667a2ae91237caca9063520018 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 9 Sep 2024 09:10:07 -0400 Subject: [PATCH 093/138] frequencyresponse ; updated dt_interbubble depending on the computation --- examples/frequencyresponse/run_frequencyresponse.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/frequencyresponse/run_frequencyresponse.sh b/examples/frequencyresponse/run_frequencyresponse.sh index 19c2e4e..7ca8ec6 100755 --- a/examples/frequencyresponse/run_frequencyresponse.sh +++ b/examples/frequencyresponse/run_frequencyresponse.sh @@ -15,7 +15,7 @@ rm -rf max_radius.txt for ((f=500000;f<=10000000;f+=3000)) do - ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -ode 1 + ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -ode 1 -dt_inter 5.0e-10 done python3 gather_results.py rm -rf max_radius.txt @@ -37,7 +37,7 @@ rm -rf max_radius.txt for ((f=500000;f<=10000000;f+=3000)) do - ./build/frequencyresponse_apecss -options run.apecss -nb 3 -freq $f -amp 120e3 -ode 1 -dt_inter 1e-9 + ./build/frequencyresponse_apecss -options run.apecss -nb 3 -freq $f -amp 120e3 -ode 1 -dt_inter 5.0e-10 done python3 gather_results.py rm -rf max_radius.txt @@ -51,7 +51,7 @@ rm -rf max_radius.txt for ((f=500000;f<=10000000;f+=3000)) do - ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -ode 1 -dt_inter 1e-9 + ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -ode 1 -dt_inter 5.0e-10 done python3 gather_results.py rm -rf max_radius.txt From ab24dbf830df688c2d208d77aa516a86c3d5404d Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 9 Sep 2024 09:22:43 -0400 Subject: [PATCH 094/138] frequencyresponse ; plot results, changing fontsize and texts location --- examples/frequencyresponse/plot_results.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/frequencyresponse/plot_results.py b/examples/frequencyresponse/plot_results.py index a9df2fb..de991eb 100644 --- a/examples/frequencyresponse/plot_results.py +++ b/examples/frequencyresponse/plot_results.py @@ -3,7 +3,7 @@ import matplotlib.pyplot as plt ######### Graphical parameters #################################################################### -fontsize = 25 +fontsize = 27.5 plt.rcParams['font.family']='serif' plt.rcParams['font.serif']=['Times New Roman'] + plt.rcParams['font.serif'] @@ -255,19 +255,19 @@ axs[0, 0].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.0$ $\mu$m") axs[0, 0].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.8$ $\mu$m") axs[0, 0].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.5$ $\mu$m") -axs[0, 0].text(3.0, 2.25,r"No interactions") +axs[0, 0].text(2.75, 2.25,r"No interactions") data_list = dic_results["IC"][0][3][1.2e5][5e-6] axs[1, 0].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid") axs[1, 0].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid") axs[1, 0].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid") -axs[1, 0].text(3.0, 2.25,r"Incompressible interactions") +axs[1, 0].text(2.75, 2.25,r"Incompressible interactions") data_list = dic_results["QA"][0][3][1.2e5][5e-6] axs[2, 0].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid") axs[2, 0].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid") axs[2, 0].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid") -axs[2, 0].text(3.0, 2.25,r"Quasi-acoustic interactions") +axs[2, 0].text(2.75, 2.25,r"Quasi-acoustic interactions") # 4 MBs data_list = dic_results["NI"][0][4][1.2e5][5e-6] @@ -275,21 +275,21 @@ axs[0, 1].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.8$ $\mu$m") axs[0, 1].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.5$ $\mu$m") axs[0, 1].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.5$ $\mu$m") -axs[0, 1].text(3.0, 2.25,r"No interactions") +axs[0, 1].text(2.75, 2.25,r"No interactions") data_list = dic_results["IC"][0][4][1.2e5][5e-6] axs[1, 1].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid") axs[1, 1].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid") axs[1, 1].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid") axs[1, 1].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid") -axs[1, 1].text(3.0, 2.25,r"Incompressible interactions") +axs[1, 1].text(2.75, 2.25,r"Incompressible interactions") data_list = dic_results["QA"][0][4][1.2e5][5e-6] axs[2, 1].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid") axs[2, 1].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid") axs[2, 1].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid") axs[2, 1].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid") -axs[2, 1].text(3.0, 2.25,r"Quasi-acoustic interactions") +axs[2, 1].text(2.75, 2.25,r"Quasi-acoustic interactions") # Reference values axs[0, 0].plot(paper_results_NI[1.0][0], paper_results_NI[1.0][1], color="blue", linewidth=2.5, linestyle="dashed") From 873e904bddb1b24f898fe3f014070dff64ac98bc Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 10 Sep 2024 09:40:43 -0400 Subject: [PATCH 095/138] cavitationonset ; defining the right begin index to compute the difference of pressure infinity between QA and IC in pressure evolution plot --- examples/cavitationonset/plot_results.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/cavitationonset/plot_results.py b/examples/cavitationonset/plot_results.py index ce56c0b..df3c431 100644 --- a/examples/cavitationonset/plot_results.py +++ b/examples/cavitationonset/plot_results.py @@ -348,7 +348,7 @@ def identify_end_time_index(inttype, png, dist) : p_list_QA = np.array(dic_2_bubbles["QA"][png][10.0][0][3]) / P0 p_list_QA_new = [] - for i in range(0, len(p_list_QA), 10) : + for i in range(9, len(p_list_QA), 10) : p_list_QA_new.append(p_list_QA[i]) diff_p = np.array(p_list_QA_new) - p_list_IC From 0ff08d0975614120e80091cc8cc84db7d39e0610 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 10 Sep 2024 09:41:57 -0400 Subject: [PATCH 096/138] frequencyresponse ; adding the command lines to conduct the study about the influence of interbubble distance in .sh file + the corresponding plot in python file --- examples/frequencyresponse/plot_results.py | 77 ++++++++++++++++++- .../run_frequencyresponse.sh | 32 ++++++++ 2 files changed, 108 insertions(+), 1 deletion(-) diff --git a/examples/frequencyresponse/plot_results.py b/examples/frequencyresponse/plot_results.py index de991eb..c38cdf8 100644 --- a/examples/frequencyresponse/plot_results.py +++ b/examples/frequencyresponse/plot_results.py @@ -312,4 +312,79 @@ axs[0, 0].legend(loc="upper right", frameon=False) axs[0, 1].legend(loc="upper right", frameon=False) -fig.savefig("frequencyresponse.pdf", bbox_inches='tight',pad_inches=0.35) \ No newline at end of file +fig.savefig("frequencyresponse.pdf", bbox_inches='tight',pad_inches=0.35) + +######## Interaction distance study ###################################### +n_row = 2 +n_col = 2 + +fig, axs = plt.subplots(n_row, n_col, figsize=(n_col*25.0*cm, n_row*12.5*cm), sharey=True, sharex=True) +for i in range(n_row) : + for j in range(n_col) : + axs[i, j].grid() + if i == 1 : + axs[i, j].set_xlabel(r"$f$ [MHz]") + axs[i, j].set_xlim(xmin=0.5, xmax=8.0) + if j == 0 : + axs[i, j].set_ylabel(r"$R_{\mathrm{max}}/R_{0}$") +fig.subplots_adjust(hspace=0.35*cm, wspace=0.05*cm) + +axs[0, 0].set_title(r"4MBs interacting at $d = 5$ $\mu$m") +axs[0, 1].set_title(r"4MBs interacting at $d = 10$ $\mu$m") +axs[1, 0].set_title(r"4MBs interacting at $d = 25$ $\mu$m") +axs[1, 1].set_title(r"4MBs interacting at $d = 50$ $\mu$m") + +# 5 microns +data_list = dic_results["QA"][0][4][1.2e5][5e-6] +axs[0, 0].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.0$ $\mu$m") +axs[0, 0].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.8$ $\mu$m") +axs[0, 0].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.5$ $\mu$m") +axs[0, 0].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.5$ $\mu$m") + +data_list = dic_results["IC"][0][4][1.2e5][5e-6] +axs[0, 0].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="dashed") +axs[0, 0].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="dashed") +axs[0, 0].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="dashed") +axs[0, 0].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="dashed") + +# 10 microns +data_list = dic_results["QA"][0][4][1.2e5][10e-6] +axs[0, 1].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid") +axs[0, 1].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid") +axs[0, 1].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid") +axs[0, 1].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid") + +data_list = dic_results["IC"][0][4][1.2e5][10e-6] +axs[0, 1].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="dashed") +axs[0, 1].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="dashed") +axs[0, 1].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="dashed") +axs[0, 1].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="dashed") + +# 25 microns +data_list = dic_results["QA"][0][4][1.2e5][25e-6] +axs[1, 0].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid") +axs[1, 0].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid") +axs[1, 0].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid") +axs[1, 0].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid") + +data_list = dic_results["IC"][0][4][1.2e5][25e-6] +axs[1, 0].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="dashed") +axs[1, 0].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="dashed") +axs[1, 0].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="dashed") +axs[1, 0].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="dashed") + +# 50 microns +data_list = dic_results["QA"][0][4][1.2e5][50e-6] +axs[1, 1].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid") +axs[1, 1].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid") +axs[1, 1].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid") +axs[1, 1].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid") + +data_list = dic_results["IC"][0][4][1.2e5][50e-6] +axs[1, 1].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="dashed") +axs[1, 1].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="dashed") +axs[1, 1].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="dashed") +axs[1, 1].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="dashed") + +axs[0, 0].legend(loc="upper right", frameon=False) +fig.savefig("frequencyresponse_distancestudy.pdf", bbox_inches='tight',pad_inches=0.35) \ No newline at end of file diff --git a/examples/frequencyresponse/run_frequencyresponse.sh b/examples/frequencyresponse/run_frequencyresponse.sh index 7ca8ec6..9661a59 100755 --- a/examples/frequencyresponse/run_frequencyresponse.sh +++ b/examples/frequencyresponse/run_frequencyresponse.sh @@ -56,6 +56,18 @@ done python3 gather_results.py rm -rf max_radius.txt +# Distance study +dist_list=(10e-6 25e-6 50e-6) +for dist in "${dist_list[@]}" +do + for ((f=500000;f<=10000000;f+=3000)) + do + ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -dt_inter 1e-9 -dist $dist + done + python3 gather_results.py + rm -rf max_radius.txt +done + cd .. ######################## Quasi-acoustic interactions (QA) ######################################### @@ -86,6 +98,26 @@ done python3 gather_results.py rm -rf max_radius.txt +# Distance study +dist_list=(10e-6 25e-6 50e-6) +for dist in "${dist_list[@]}" +do + for ((f=500000;f<1900000;f+=3000)) + do + ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -dt_inter 1e-9 -dist $dist + done + for ((f=1900000;f<2900000;f+=3000)) + do + ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -dt_inter 5.0e-10 -dist $dist + done + for ((f=2900000;f<=10000000;f+=3000)) + do + ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -dt_inter 1e-9 -dist $dist + done + python3 gather_results.py + rm -rf max_radius.txt +done + cd .. ######################## Cleaning ################################################################# From 1e1e665a0527053ca1991742772fa1cdbe5cfa41 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 10 Sep 2024 15:20:33 -0400 Subject: [PATCH 097/138] cavitationonset ; attempt to compute unstable radius like in Ida's article --- examples/cavitationonset/plot_results.py | 56 ++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/examples/cavitationonset/plot_results.py b/examples/cavitationonset/plot_results.py index df3c431..6a3b584 100644 --- a/examples/cavitationonset/plot_results.py +++ b/examples/cavitationonset/plot_results.py @@ -106,6 +106,8 @@ def identify_end_time_index(inttype, png, dist) : T = 10.0e-06 P0 = 0.1013e06 rho = 1000.0 +sigma = 0.0728 +mu = 1.002e-3 ######### Pressure time history & radius evolution without interaction ############################ @@ -456,6 +458,60 @@ def identify_end_time_index(inttype, png, dist) : fig.savefig("cavitationonset_varyingpressure_pressure_understanding.pdf", bbox_inches='tight',pad_inches=0.35) +#### Unstable radius #### + +png = -25325 +dist = 12.0 + +nrow = 1 +ncol = 2 + +fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm))) +plt.subplots_adjust(wspace=0.35*cm, hspace=0.5*cm) + +axs[0].set_title(r"Incompressible interactions") +axs[0].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) +axs[0].set_xlim(xmin=0.0, xmax=60.0) +axs[0].set_ylabel(r"$R_{1}$ [$\mu$m]", fontsize=27.5) +axs[0].set_ylim(ymin=0.0, ymax=40.0) +axs[0].grid() + +# IC +t_list = np.array(dic_2_bubbles["IC"][png][dist][0][1]) +r_list = np.array(dic_2_bubbles["IC"][png][dist][0][2]) +p_list = np.array(dic_2_bubbles["IC"][png][dist][0][3]) +u_list = np.array(dic_2_bubbles["IC"][png][dist][1][6]) + +R0 = r_list[0] +pG0 = P0 + (2 * sigma / R0) +pL = pG0 * ((R0 / r_list)**3) - (2 * sigma / r_list) - 4 * mu * (u_list / r_list) +p_pL = p_list - pL + +index_t = [] +for i in range(len(t_list)-1) : + if p_pL[i] > 0 and p_pL[i+1] < 0 : + index_t.append(i) + elif p_pL[i] < 0 and p_pL[i+1] > 0 : + index_t.append(i) +index_t0 = index_t[0] + +r_unstable_list = [r_list[index_t0]] +for i in range(index_t0, len(t_list)-1) : + approx = r_unstable_list[-1] * (pG0 * ((R0 / r_unstable_list[-1])**3) - (2 * sigma / r_unstable_list[-1]) - p_list[i]) / (4 * mu) + r_unstable_list.append(r_unstable_list[-1] + (t_list[i+1] - t_list[i]) * approx) + +r_unstable_list_bis = [] +for i in range(len(t_list)) : + p = np.polynomial.Polynomial([-pG0 * (R0**3), 0, 2 * sigma, p_list[i]]) + roots = p.roots() + r_unstable_list_bis.append(float(np.real(roots[-1]))) + +axs[0].plot(t_list*1e6, r_list*1e6, color="blue", linewidth=2.5) +axs[0].plot(t_list[index_t0:]*1e6, np.array(r_unstable_list)*1e6, linestyle="dashed", color="red", linewidth=2.5) +axs[0].plot(t_list*1e6, np.array(r_unstable_list_bis)*1e6, linestyle="dotted", color="magenta", linewidth=2.5) + +fig.savefig("cavitationonset_varyingpressure_unstableradius.pdf", bbox_inches='tight',pad_inches=0.35) + ######### Cavitation inception with monodispersed simple distributions ############################ nrow = 2 From 646186647d95905f217da7d278d4b6af0e76acda Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 10 Sep 2024 17:08:10 -0400 Subject: [PATCH 098/138] cavitationonset ; retrieving more date for post-processing with QA computations --- .../cavitationonset/QA/src/cavitationonset_apecss.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/examples/cavitationonset/QA/src/cavitationonset_apecss.c b/examples/cavitationonset/QA/src/cavitationonset_apecss.c index 93d0788..2d2bc77 100644 --- a/examples/cavitationonset/QA/src/cavitationonset_apecss.c +++ b/examples/cavitationonset/QA/src/cavitationonset_apecss.c @@ -383,6 +383,18 @@ int main(int argc, char **args) { fprintf(file_ida2009, " %e", Bubbles[i]->get_pressure_infinity(tSim, Bubbles[i])); } + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_ida2009, " %e", Bubbles[i]->ode[0](Bubbles[i]->ODEsSol, Bubbles[i]->t, Bubbles[i])); + } + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_ida2009, " %e", Bubbles[i]->Interaction->dp_neighbor); + } + for (register int i = 0; i < nBubbles; i++) + { + fprintf(file_ida2009, " %e", Bubbles[i]->U); + } fprintf(file_ida2009, "\n"); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< From 3c55b001d4923619b02dd5515a4d046e6d82c390 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 10 Sep 2024 17:08:47 -0400 Subject: [PATCH 099/138] cavitationonset ; new plot for understanding the pressure peaks during collapse with two bubbles --- examples/cavitationonset/plot_results.py | 87 +++++++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-) diff --git a/examples/cavitationonset/plot_results.py b/examples/cavitationonset/plot_results.py index 6a3b584..a91ceda 100644 --- a/examples/cavitationonset/plot_results.py +++ b/examples/cavitationonset/plot_results.py @@ -65,7 +65,7 @@ init_radius = float(second_line[i+1]) # list format : for each bubble, [R0, t_list, R_list, Pt_list] dic_data.append([init_radius, [], [], []]) - if (inttype == "IC") : + if (inttype == "IC" or inttype == "QA") : dic_data[-1].append([]) dic_data[-1].append([]) dic_data[-1].append([]) @@ -79,7 +79,7 @@ dic_data[i][1].append(t) dic_data[i][2].append(r) dic_data[i][3].append(pt) - if (inttype == "IC") : + if (inttype == "IC" or inttype == "QA") : a = float(data[1 + 2 * count + i]) dp = float(data[1 + 3 * count + i]) u = float(data[1 + 4 * count + i]) @@ -458,6 +458,89 @@ def identify_end_time_index(inttype, png, dist) : fig.savefig("cavitationonset_varyingpressure_pressure_understanding.pdf", bbox_inches='tight',pad_inches=0.35) +#### Test bis #### + +png = -27351 +dist = 10.0 + +nrow = 2 +ncol = 2 + +fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*25*cm, nrow*12.5*cm)), sharex=True) +plt.subplots_adjust(wspace=0.35*cm, hspace=0.25*cm) + +fig.suptitle(r"$p_{ng}/p_{0}=$" + "{:.3f}, ".format(png/P0) + r"$\Delta x_{12}=$" + "{:.1f}".format(dist) + r"($R_{1,0} + R_{2,0}$)") +axs[0, 0].set_title("Incompressible interactions") +axs[0, 1].set_title("Quasi-acoustic interactions") + +for i in range(nrow) : + for j in range(ncol) : + axs[i, j].grid() + +axs[1, 0].set_xlabel(r"$t$ [$\mu$s]") +axs[1, 1].set_xlabel(r"$t$ [$\mu$s]") + +axs[0, 0].set_ylabel(r"$R/R_{0}$") +axs[1, 0].set_ylabel(r"$p_{\infty} / p_{0}$") + +axs[1, 0].set_xlim(xmin=30.0, xmax=50.0) +axs[0, 0].set_ylim(ymin=0.0, ymax=10.0) +axs[0, 1].set_ylim(ymin=0.0, ymax=10.0) +axs[1, 0].set_ylim(ymin=-0.3, ymax=0.0) +axs[1, 1].set_ylim(ymin=-0.3, ymax=0.0) + +# IC +r0 = dic_2_bubbles["IC"][png][dist][0][0] +t_list = np.array(dic_2_bubbles["IC"][png][dist][0][1]) * 1.0e6 +r_list = np.array(dic_2_bubbles["IC"][png][dist][0][2]) / r0 +p_list = np.array(dic_2_bubbles["IC"][png][dist][0][3]) / P0 +dp_list = dic_2_bubbles["IC"][png][dist][0][5] + +t_deltap_min_IC = t_list[dp_list.index(np.min(dp_list[int(33.5e2):int(35e2)]))] + +axs[0, 0].plot(t_list, r_list, color="blue", linewidth=2.5, label=r"$R_{0}=2.0$ $\mu$m") +axs[1, 0].plot(t_list, p_list, color="blue", linewidth=2.5) + +r0 = dic_2_bubbles["IC"][png][dist][1][0] +t_list = np.array(dic_2_bubbles["IC"][png][dist][1][1]) * 1.0e6 +r_list = np.array(dic_2_bubbles["IC"][png][dist][1][2]) / r0 +p_list = np.array(dic_2_bubbles["IC"][png][dist][1][3]) / P0 +dp_list = dic_2_bubbles["IC"][png][dist][1][5] + +t_delta_max_IC = t_list[dp_list.index(np.max(dp_list[int(33.5e2):int(35e2)]))] + +axs[0, 0].plot(t_list, r_list, color="magenta", linestyle="dashed", linewidth=2.5, label=r"$R_{0}=20.0$ $\mu$m") +axs[1, 0].plot(t_list, p_list, color="magenta", linestyle="dashed", linewidth=2.5) + +# QA +r0 = dic_2_bubbles["QA"][png][dist][0][0] +t_list = np.array(dic_2_bubbles["QA"][png][dist][0][1]) * 1.0e6 +r_list = np.array(dic_2_bubbles["QA"][png][dist][0][2]) / r0 +p_list = np.array(dic_2_bubbles["QA"][png][dist][0][3]) / P0 +dp_list = dic_2_bubbles["QA"][png][dist][0][5] + +t_deltap_min_QA = t_list[dp_list.index(np.min(dp_list[int(35e3):int(40e3)]))] + +axs[0, 1].plot(t_list, r_list, color="blue", linewidth=2.5) +axs[1, 1].plot(t_list, p_list, color="blue", linewidth=2.5) + +r0 = dic_2_bubbles["QA"][png][dist][1][0] +t_list = np.array(dic_2_bubbles["QA"][png][dist][1][1]) * 1.0e6 +r_list = np.array(dic_2_bubbles["QA"][png][dist][1][2]) / r0 +p_list = np.array(dic_2_bubbles["QA"][png][dist][1][3]) / P0 +dp_list = dic_2_bubbles["QA"][png][dist][1][5] + +t_delta_max_QA = t_list[dp_list.index(np.max(dp_list[int(35e3):int(40e3)]))] + +axs[0, 1].plot(t_list, r_list, color="magenta", linestyle="dashed", linewidth=2.5) +axs[1, 1].plot(t_list, p_list, color="magenta", linestyle="dashed", linewidth=2.5) + +axs[0, 0].legend(loc="upper left", frameon=False) +fig.savefig("cavitationonset_varyingpressure_pressure_understanding_bis.pdf", bbox_inches='tight',pad_inches=0.35) + +print("For IC computations, respectively time for max dp for bubble 2 and min dp for bubble 1 : {:.5E}, {:.5E}".format(t_delta_max_IC, t_deltap_min_IC)) +print("For QA computations, respectively time for max dp for bubble 2 and min dp for bubble 1 : {:.5E}, {:.5E}".format(t_delta_max_QA, t_deltap_min_QA)) + #### Unstable radius #### png = -25325 From 9e7e7a62838a37c89ba61083a85f48622a056cab Mon Sep 17 00:00:00 2001 From: Pierre C Date: Wed, 11 Sep 2024 11:34:14 -0400 Subject: [PATCH 100/138] bubblyscreen ; small corrections in plot for the paper --- examples/bubblyscreen/plot_results.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/bubblyscreen/plot_results.py b/examples/bubblyscreen/plot_results.py index 685008d..3af6452 100644 --- a/examples/bubblyscreen/plot_results.py +++ b/examples/bubblyscreen/plot_results.py @@ -199,14 +199,14 @@ def identify_oscillation_amplitude(t_list, r_list) : axs[i,j].set_aspect("equal") ### First row : QA ### -plt.figtext(0.5, 0.875, r"QA, $D/R_{0}$ = 400", fontsize=25.0, horizontalalignment="center") +plt.figtext(0.5, 0.875, r"(a) QA", fontsize=25.0, horizontalalignment="center") plot_oscillation_distribution(fig, axs, 0, 0, 51, "QA", 0.5, 400, order=4) plot_oscillation_distribution(fig, axs, 0, 1, 51, "QA", 0.9, 400, order=3) plot_oscillation_distribution(fig, axs, 0, 2, 51, "QA", 1.0, 400, order=2) plot_oscillation_distribution(fig, axs, 0, 3, 51, "QA", 1.5, 400, order=4) ### Second row : IC ### -plt.figtext(0.5, 0.475, r"IC, $D/R_{0}$ = 400", fontsize=25.0, horizontalalignment="center") +plt.figtext(0.5, 0.475, r"(b) IC", fontsize=25.0, horizontalalignment="center") plot_oscillation_distribution(fig, axs, 1, 0, 51, "IC", 0.5, 400, order=4) plot_oscillation_distribution(fig, axs, 1, 1, 51, "IC", 0.9, 400, order=3) plot_oscillation_distribution(fig, axs, 1, 2, 51, "IC", 1.0, 400, order=3) @@ -220,9 +220,10 @@ def identify_oscillation_amplitude(t_list, r_list) : fig, ax = plt.subplots(1, 1, figsize=(27.5*cm, 12.5*cm)) ax.set_xlabel(r"$t$ [$\mu$s]") ax.set_xlim(xmin=0.0, xmax=60.0) -ax.set_ylabel(r"$|r'|$ [-]") +ax.set_ylabel(r"$|r'|$") ax.set_yscale("log") ax.set_ylim(ymin=10**(-4), ymax=5.0e-2) +ax.grid() ### QA ### t_list, r_list = identify_oscillation_amplitude(np.array(dic_radii_index["QA"][1.0][400][0]), np.array(dic_radii_index["QA"][1.0][400][1])) From 2c198b5f807f2d0612dc9f41026a5727d1fab1e9 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Wed, 11 Sep 2024 11:55:10 -0400 Subject: [PATCH 101/138] cavitationonset ; updated unstable radius plot (correct formula and QA computations added) --- examples/cavitationonset/plot_results.py | 54 +++++++++++++----------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/examples/cavitationonset/plot_results.py b/examples/cavitationonset/plot_results.py index a91ceda..bf7c491 100644 --- a/examples/cavitationonset/plot_results.py +++ b/examples/cavitationonset/plot_results.py @@ -549,49 +549,53 @@ def identify_end_time_index(inttype, png, dist) : nrow = 1 ncol = 2 -fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm))) -plt.subplots_adjust(wspace=0.35*cm, hspace=0.5*cm) +fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm)), sharey=True, sharex=True) +plt.subplots_adjust(wspace=0.15*cm, hspace=0.5*cm) axs[0].set_title(r"Incompressible interactions") axs[0].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) axs[0].set_xlim(xmin=0.0, xmax=60.0) -axs[0].set_ylabel(r"$R_{1}$ [$\mu$m]", fontsize=27.5) +axs[0].set_ylabel(r"$R$ [$\mu$m]", fontsize=27.5) axs[0].set_ylim(ymin=0.0, ymax=40.0) axs[0].grid() +axs[1].set_title(r"Quasi-acoustic interactions") +axs[1].grid() + # IC t_list = np.array(dic_2_bubbles["IC"][png][dist][0][1]) r_list = np.array(dic_2_bubbles["IC"][png][dist][0][2]) p_list = np.array(dic_2_bubbles["IC"][png][dist][0][3]) -u_list = np.array(dic_2_bubbles["IC"][png][dist][1][6]) R0 = r_list[0] pG0 = P0 + (2 * sigma / R0) -pL = pG0 * ((R0 / r_list)**3) - (2 * sigma / r_list) - 4 * mu * (u_list / r_list) -p_pL = p_list - pL - -index_t = [] -for i in range(len(t_list)-1) : - if p_pL[i] > 0 and p_pL[i+1] < 0 : - index_t.append(i) - elif p_pL[i] < 0 and p_pL[i+1] > 0 : - index_t.append(i) -index_t0 = index_t[0] - -r_unstable_list = [r_list[index_t0]] -for i in range(index_t0, len(t_list)-1) : - approx = r_unstable_list[-1] * (pG0 * ((R0 / r_unstable_list[-1])**3) - (2 * sigma / r_unstable_list[-1]) - p_list[i]) / (4 * mu) - r_unstable_list.append(r_unstable_list[-1] + (t_list[i+1] - t_list[i]) * approx) - -r_unstable_list_bis = [] + +r_unstable_list = [] +for i in range(len(t_list)) : + p = np.polynomial.Polynomial([-pG0 * (R0**3), 0, 2 * sigma, p_list[i]]) + roots = p.roots() + r_unstable_list.append(float(np.real(roots[-1]))) + +axs[0].plot(t_list*1e6, r_list*1e6, color="blue", linewidth=2.5, label=r"$R_{1}$") +axs[0].plot(t_list*1e6, np.array(r_unstable_list)*1e6, linestyle="solid", color="red", marker="o", markevery=500, linewidth=2, label=r"$R_{Ue}$") +axs[0].legend(loc="upper left", frameon=False) + +# QA +t_list = np.array(dic_2_bubbles["QA"][png][dist][0][1]) +r_list = np.array(dic_2_bubbles["QA"][png][dist][0][2]) +p_list = np.array(dic_2_bubbles["QA"][png][dist][0][3]) + +R0 = r_list[0] +pG0 = P0 + (2 * sigma / R0) + +r_unstable_list = [] for i in range(len(t_list)) : p = np.polynomial.Polynomial([-pG0 * (R0**3), 0, 2 * sigma, p_list[i]]) roots = p.roots() - r_unstable_list_bis.append(float(np.real(roots[-1]))) + r_unstable_list.append(float(np.real(roots[-1]))) -axs[0].plot(t_list*1e6, r_list*1e6, color="blue", linewidth=2.5) -axs[0].plot(t_list[index_t0:]*1e6, np.array(r_unstable_list)*1e6, linestyle="dashed", color="red", linewidth=2.5) -axs[0].plot(t_list*1e6, np.array(r_unstable_list_bis)*1e6, linestyle="dotted", color="magenta", linewidth=2.5) +axs[1].plot(t_list*1e6, r_list*1e6, color="blue", linewidth=2.5) +axs[1].plot(t_list*1e6, np.array(r_unstable_list)*1e6, linestyle="solid", color="red", marker="o", markevery=5000, linewidth=2) fig.savefig("cavitationonset_varyingpressure_unstableradius.pdf", bbox_inches='tight',pad_inches=0.35) From d2c2df5956bb4d5c60f64ea9179e337a1764c2d0 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Wed, 11 Sep 2024 13:56:02 -0400 Subject: [PATCH 102/138] cavitationonset ; adding a more complete unstable radius plot for comparison between IC and QA --- examples/cavitationonset/plot_results.py | 74 ++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/examples/cavitationonset/plot_results.py b/examples/cavitationonset/plot_results.py index bf7c491..9e1c8c6 100644 --- a/examples/cavitationonset/plot_results.py +++ b/examples/cavitationonset/plot_results.py @@ -599,6 +599,80 @@ def identify_end_time_index(inttype, png, dist) : fig.savefig("cavitationonset_varyingpressure_unstableradius.pdf", bbox_inches='tight',pad_inches=0.35) +nrow = 3 +ncol = 2 + +fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*15*cm, nrow*9.375*cm)), sharey=True, sharex=True) +plt.subplots_adjust(wspace=0.14*cm, hspace=0.25*cm) + +for i in range(nrow) : + for j in range(ncol) : + axs[i, j].grid() + if j == 0 : + axs[i, j].set_ylabel(r"$R$ [$\mu$m]", fontsize=27.5) + axs[i, j].set_ylim(ymin=0.0, ymax=40.0) + if i == nrow - 1 : + axs[i, j].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) + axs[i, j].set_xlim(xmin=0.0, xmax=60.0) + axs[i, j].set_xticks([10, 30, 50], [10, 30, 50]) + +axs[0, 0].set_title(r"Incompressible interactions") +axs[0, 1].set_title(r"Quasi-acoustic interactions") + +png_list = [-25325, -25325, -27654.9] +dist_list = [12.0, 10.0, 10.0] + +for l in range(nrow) : + png = png_list[l] + dist = dist_list[l] + + # IC + t_list = np.array(dic_2_bubbles["IC"][png][dist][0][1]) + r_list = np.array(dic_2_bubbles["IC"][png][dist][0][2]) + p_list = np.array(dic_2_bubbles["IC"][png][dist][0][3]) + + axs[l, 0].text(31.0, 30.0, r"$p_{ng}^{*}=$" + " {:.3f}".format(png/P0), horizontalalignment="center", fontsize=26) + axs[l, 0].text(31.0, 35.0, r"$\Delta x_{12}^{*}=$" + " {:.1f}".format(dist), horizontalalignment="center", fontsize=26) + + R0 = r_list[0] + pG0 = P0 + (2 * sigma / R0) + + r_unstable_list = [] + for i in range(len(t_list)) : + p = np.polynomial.Polynomial([-pG0 * (R0**3), 0, 2 * sigma, p_list[i]]) + roots = p.roots() + r_unstable_list.append(float(np.real(roots[-1]))) + + if (l == 0) : + axs[l, 0].plot(t_list*1e6, r_list*1e6, color="blue", linewidth=3.0, label=r"$R_{1}$") + axs[l, 0].plot(t_list*1e6, np.array(r_unstable_list)*1e6, linestyle="solid", color="red", marker="o", markevery=500, linewidth=2.5, label=r"$R_{Ue}$") + else : + axs[l, 0].plot(t_list*1e6, r_list*1e6, color="blue", linewidth=3.0) + axs[l, 0].plot(t_list*1e6, np.array(r_unstable_list)*1e6, linestyle="solid", color="red", marker="o", markevery=500, linewidth=2.5) + + # QA + t_list = np.array(dic_2_bubbles["QA"][png][dist][0][1]) + r_list = np.array(dic_2_bubbles["QA"][png][dist][0][2]) + p_list = np.array(dic_2_bubbles["QA"][png][dist][0][3]) + + axs[l, 1].text(31.0, 30.0, r"$p_{ng}^{*}=$" + " {:.3f}".format(png/P0), horizontalalignment="center", fontsize=26) + axs[l, 1].text(31.0, 35.0, r"$\Delta x_{12}^{*}=$" + " {:.1f}".format(dist), horizontalalignment="center", fontsize=26) + + R0 = r_list[0] + pG0 = P0 + (2 * sigma / R0) + + r_unstable_list = [] + for i in range(len(t_list)) : + p = np.polynomial.Polynomial([-pG0 * (R0**3), 0, 2 * sigma, p_list[i]]) + roots = p.roots() + r_unstable_list.append(float(np.real(roots[-1]))) + + axs[l, 1].plot(t_list*1e6, r_list*1e6, color="blue", linewidth=3.0) + axs[l, 1].plot(t_list*1e6, np.array(r_unstable_list)*1e6, linestyle="solid", color="red", marker="o", markevery=5000, linewidth=2.5) + +axs[0, 0].legend(bbox_to_anchor=(1.05, 1.05), loc="lower center", ncol=2, frameon=False, fontsize=27.5) +fig.savefig("cavitationonset_unstableradius.pdf", bbox_inches='tight',pad_inches=0.35) + ######### Cavitation inception with monodispersed simple distributions ############################ nrow = 2 From 9467b26501f9c0e87afffb68c49ad3616a98ae93 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Thu, 12 Sep 2024 11:36:54 -0400 Subject: [PATCH 103/138] cavitationonset; small changes in plot results for the understanding bis plot --- examples/cavitationonset/plot_results.py | 26 ++++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/examples/cavitationonset/plot_results.py b/examples/cavitationonset/plot_results.py index 9e1c8c6..8c56244 100644 --- a/examples/cavitationonset/plot_results.py +++ b/examples/cavitationonset/plot_results.py @@ -466,10 +466,10 @@ def identify_end_time_index(inttype, png, dist) : nrow = 2 ncol = 2 -fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*25*cm, nrow*12.5*cm)), sharex=True) -plt.subplots_adjust(wspace=0.35*cm, hspace=0.25*cm) +fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*18.75*cm, nrow*9.375*cm)), sharex=True) +plt.subplots_adjust(wspace=0.45*cm, hspace=0.25*cm) -fig.suptitle(r"$p_{ng}/p_{0}=$" + "{:.3f}, ".format(png/P0) + r"$\Delta x_{12}=$" + "{:.1f}".format(dist) + r"($R_{1,0} + R_{2,0}$)") +# fig.suptitle(r"$p_{ng}/p_{0}=$" + "{:.3f}, ".format(png/P0) + r"$\Delta x_{12}=$" + "{:.1f}".format(dist) + r"($R_{1,0} + R_{2,0}$)") axs[0, 0].set_title("Incompressible interactions") axs[0, 1].set_title("Quasi-acoustic interactions") @@ -477,17 +477,17 @@ def identify_end_time_index(inttype, png, dist) : for j in range(ncol) : axs[i, j].grid() -axs[1, 0].set_xlabel(r"$t$ [$\mu$s]") -axs[1, 1].set_xlabel(r"$t$ [$\mu$s]") +axs[nrow - 1, 0].set_xlabel(r"$t$ [$\mu$s]") +axs[nrow - 1, 1].set_xlabel(r"$t$ [$\mu$s]") axs[0, 0].set_ylabel(r"$R/R_{0}$") -axs[1, 0].set_ylabel(r"$p_{\infty} / p_{0}$") +axs[nrow - 1, 0].set_ylabel(r"$p_{\infty} / p_{0}$") axs[1, 0].set_xlim(xmin=30.0, xmax=50.0) axs[0, 0].set_ylim(ymin=0.0, ymax=10.0) axs[0, 1].set_ylim(ymin=0.0, ymax=10.0) -axs[1, 0].set_ylim(ymin=-0.3, ymax=0.0) -axs[1, 1].set_ylim(ymin=-0.3, ymax=0.0) +axs[nrow - 1, 0].set_ylim(ymin=-0.3, ymax=0.0) +axs[nrow - 1, 1].set_ylim(ymin=-0.3, ymax=0.0) # IC r0 = dic_2_bubbles["IC"][png][dist][0][0] @@ -499,7 +499,7 @@ def identify_end_time_index(inttype, png, dist) : t_deltap_min_IC = t_list[dp_list.index(np.min(dp_list[int(33.5e2):int(35e2)]))] axs[0, 0].plot(t_list, r_list, color="blue", linewidth=2.5, label=r"$R_{0}=2.0$ $\mu$m") -axs[1, 0].plot(t_list, p_list, color="blue", linewidth=2.5) +axs[nrow - 1, 0].plot(t_list, p_list, color="blue", linewidth=2.5) r0 = dic_2_bubbles["IC"][png][dist][1][0] t_list = np.array(dic_2_bubbles["IC"][png][dist][1][1]) * 1.0e6 @@ -510,7 +510,7 @@ def identify_end_time_index(inttype, png, dist) : t_delta_max_IC = t_list[dp_list.index(np.max(dp_list[int(33.5e2):int(35e2)]))] axs[0, 0].plot(t_list, r_list, color="magenta", linestyle="dashed", linewidth=2.5, label=r"$R_{0}=20.0$ $\mu$m") -axs[1, 0].plot(t_list, p_list, color="magenta", linestyle="dashed", linewidth=2.5) +axs[nrow - 1, 0].plot(t_list, p_list, color="magenta", linestyle="dashed", linewidth=2.5) # QA r0 = dic_2_bubbles["QA"][png][dist][0][0] @@ -522,7 +522,7 @@ def identify_end_time_index(inttype, png, dist) : t_deltap_min_QA = t_list[dp_list.index(np.min(dp_list[int(35e3):int(40e3)]))] axs[0, 1].plot(t_list, r_list, color="blue", linewidth=2.5) -axs[1, 1].plot(t_list, p_list, color="blue", linewidth=2.5) +axs[nrow - 1, 1].plot(t_list, p_list, color="blue", linewidth=2.5) r0 = dic_2_bubbles["QA"][png][dist][1][0] t_list = np.array(dic_2_bubbles["QA"][png][dist][1][1]) * 1.0e6 @@ -533,9 +533,9 @@ def identify_end_time_index(inttype, png, dist) : t_delta_max_QA = t_list[dp_list.index(np.max(dp_list[int(35e3):int(40e3)]))] axs[0, 1].plot(t_list, r_list, color="magenta", linestyle="dashed", linewidth=2.5) -axs[1, 1].plot(t_list, p_list, color="magenta", linestyle="dashed", linewidth=2.5) +axs[nrow - 1, 1].plot(t_list, p_list, color="magenta", linestyle="dashed", linewidth=2.5) -axs[0, 0].legend(loc="upper left", frameon=False) +axs[0, 0].legend(bbox_to_anchor=(1.05, 1.05), loc="lower center", ncol=2, frameon=False, fontsize=27.5) fig.savefig("cavitationonset_varyingpressure_pressure_understanding_bis.pdf", bbox_inches='tight',pad_inches=0.35) print("For IC computations, respectively time for max dp for bubble 2 and min dp for bubble 1 : {:.5E}, {:.5E}".format(t_delta_max_IC, t_deltap_min_IC)) From f7c07fb8fd9b483e56e1f5eaf350affdc9c1edea Mon Sep 17 00:00:00 2001 From: Pierre C Date: Thu, 12 Sep 2024 17:24:05 -0400 Subject: [PATCH 104/138] cavitationonset; rework of the pressure differences plot and small typo corrections for the unstable radius plot --- examples/cavitationonset/plot_results.py | 91 +++++++++++++----------- 1 file changed, 49 insertions(+), 42 deletions(-) diff --git a/examples/cavitationonset/plot_results.py b/examples/cavitationonset/plot_results.py index 8c56244..0fe3e3a 100644 --- a/examples/cavitationonset/plot_results.py +++ b/examples/cavitationonset/plot_results.py @@ -157,7 +157,7 @@ def identify_end_time_index(inttype, png, dist) : png_list = [-17221, -17725.5, -18353.2, -18770.3] -ax.set_title("Cavitation inception of a single bubble \n depending on " + r"$p_{ng}$/$p_{0}$ ($R_{0}$ = 2 $\mu$m)") +ax.set_title("Cavitation inception of a single bubble \n depending on " + r"$p_{\mathrm{ng}}$/$p_{0}$ ($R_{0}$ = 2 $\mu$m)") ax.set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) ax.set_xlim(xmin=10.0, xmax=60.0) ax.set_ylabel(r"$R$ [$\mu$m]", fontsize=27.5) @@ -318,45 +318,50 @@ def identify_end_time_index(inttype, png, dist) : ##### Pressure evolution ###### -nrow = 1 +nrow = 2 ncol = 1 -fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm))) -plt.subplots_adjust(wspace=0.35*cm, hspace=0.5*cm) +fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm)), sharex=True) +plt.subplots_adjust(wspace=1.5*cm, hspace=0.25*cm) -png_list = [-27654.9] +png_list = [-25325, -27654.9] +dist_list = [12.0, 10.0] -axs.set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) -axs.set_ylabel(r"$p_{\infty, 1} / p_{0}$", fontsize=27.5) -axs.set_xlim(xmin=10.0, xmax=60.0) -axs.grid() +for i in range(nrow) : + png = png_list[i] + dist = dist_list[i] -secyax = axs.twinx() -secyax.yaxis.label.set_color("blue") -secyax.spines["right"].set_color("blue") -secyax.tick_params("y", colors="blue") -secyax.spines["right"].set_edgecolor("blue") -secyax.set_ylabel(r"$(p_{\infty, 1, \mathrm{QA}} - p_{\infty, 1, \mathrm{IC}}) / p_{0}$", fontsize=27.5) -secyax.grid(linestyle="dashed") + if (i == 1) : + axs[i].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) + axs[i].set_ylabel(r"$p_{\infty, 1} / p_{0}$", fontsize=27.5) + axs[i].set_xlim(xmin=10.0, xmax=60.0) + axs[i].grid() -sec_bis_yaxis = axs.twinx() -sec_bis_yaxis.set_yticks([]) + secyax = axs[i].twinx() + secyax.yaxis.label.set_color("blue") + secyax.spines["right"].set_color("blue") + secyax.tick_params("y", colors="blue") + secyax.spines["right"].set_edgecolor("blue") + secyax.set_ylabel(r"$(p_{\infty, 1, \mathrm{QA}} - p_{\infty, 1, \mathrm{IC}}) / p_{0}$", fontsize=27.5) + secyax.grid(linestyle="dashed") -for png in png_list : - t_list_IC = np.array(dic_2_bubbles["IC"][png][10.0][0][1]) * 1.0e6 - p_list_IC = np.array(dic_2_bubbles["IC"][png][10.0][0][3]) / P0 + sec_bis_yaxis = axs[i].twinx() + sec_bis_yaxis.set_yticks([]) - t_list_QA = np.array(dic_2_bubbles["QA"][png][10.0][0][1]) * 1.0e6 - p_list_QA = np.array(dic_2_bubbles["QA"][png][10.0][0][3]) / P0 + t_list_IC = np.array(dic_2_bubbles["IC"][png][dist][0][1]) * 1.0e6 + p_list_IC = np.array(dic_2_bubbles["IC"][png][dist][0][3]) / P0 + + t_list_QA = np.array(dic_2_bubbles["QA"][png][dist][0][1]) * 1.0e6 + p_list_QA = np.array(dic_2_bubbles["QA"][png][dist][0][3]) / P0 p_list_QA_new = [] - for i in range(9, len(p_list_QA), 10) : - p_list_QA_new.append(p_list_QA[i]) + for j in range(9, len(p_list_QA), 10) : + p_list_QA_new.append(p_list_QA[j]) diff_p = np.array(p_list_QA_new) - p_list_IC - axs.plot(t_list_IC, p_list_IC, color="red", linewidth=3.0, linestyle="solid", label="IC") - axs.plot(t_list_QA, p_list_QA, color="black", linewidth=3.0, linestyle="dashed", label="QA") + axs[i].plot(t_list_IC, p_list_IC, color="red", linewidth=3.0, linestyle="solid", label="IC") + axs[i].plot(t_list_QA, p_list_QA, color="black", linewidth=3.0, linestyle="dashed", label="QA") secyax.plot(t_list_IC, diff_p, color="blue", linewidth=3.0, linestyle="dotted", label=r"$\Delta p_{\infty, 1} / p_{0}$ (QA - IC)") sec_bis_yaxis.plot(t_list_IC, p_list_IC, color="red", linewidth=3.0, linestyle="solid", label="IC") sec_bis_yaxis.plot(t_list_QA, p_list_QA, color="black", linewidth=3.0, linestyle="dashed", label="QA") @@ -364,15 +369,17 @@ def identify_end_time_index(inttype, png, dist) : t_IC = t_list_IC[dic_2_bubbles["IC"][png][10.0][0][2].index(np.max(dic_2_bubbles["IC"][png][10.0][0][2]))] t_QA = t_list_QA[dic_2_bubbles["QA"][png][10.0][0][2].index(np.max(dic_2_bubbles["QA"][png][10.0][0][2]))] -axs.set_xticks([20, t_IC, t_QA, 40]) -axs.set_xticklabels([20, r"$t_{\mathrm{IC}}$", r"$t_{\mathrm{QA}}$", 40]) -secyax.set_ylim(ymin=-0.005, ymax=0.005) -secyax.set_yticks([-0.005, 0.0, 0.005]) + secyax.set_ylim(ymin=-0.005, ymax=0.005) + secyax.set_yticks([-0.005, 0.0, 0.005]) -sec_bis_yaxis.legend(bbox_to_anchor=(0.5, 1.15), loc="center", ncol=2, frameon=False) -secyax.legend(bbox_to_anchor=(0.5, 1.05), loc="center", ncol=1, frameon=False) + if (i == 0) : + sec_bis_yaxis.legend(bbox_to_anchor=(0.5, 1.15), loc="center", ncol=2, frameon=False) + secyax.legend(bbox_to_anchor=(0.5, 1.05), loc="center", ncol=1, frameon=False) + + axs[i].text(25.0, 0.85, r"$\Delta x_{12}^{*}=$" + " {:.1f}".format(dist), horizontalalignment="center", fontsize=27.5) + axs[i].text(25.0, 0.65, r"$p_{\mathrm{ng}}^{*}=$" + " {:.3f}".format(png/P0), horizontalalignment="center", fontsize=27.5) -fig.savefig("cavitationonset_varyingpressure_pressure.pdf", bbox_inches='tight',pad_inches=0.35) +fig.savefig("cavitationonset_pressuredifferences.pdf", bbox_inches='tight',pad_inches=0.35) #### Test ##### @@ -469,7 +476,7 @@ def identify_end_time_index(inttype, png, dist) : fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*18.75*cm, nrow*9.375*cm)), sharex=True) plt.subplots_adjust(wspace=0.45*cm, hspace=0.25*cm) -# fig.suptitle(r"$p_{ng}/p_{0}=$" + "{:.3f}, ".format(png/P0) + r"$\Delta x_{12}=$" + "{:.1f}".format(dist) + r"($R_{1,0} + R_{2,0}$)") +# fig.suptitle(r"$p_{\mathrm{ng}}/p_{0}=$" + "{:.3f}, ".format(png/P0) + r"$\Delta x_{12}=$" + "{:.1f}".format(dist) + r"($R_{1,0} + R_{2,0}$)") axs[0, 0].set_title("Incompressible interactions") axs[0, 1].set_title("Quasi-acoustic interactions") @@ -577,7 +584,7 @@ def identify_end_time_index(inttype, png, dist) : r_unstable_list.append(float(np.real(roots[-1]))) axs[0].plot(t_list*1e6, r_list*1e6, color="blue", linewidth=2.5, label=r"$R_{1}$") -axs[0].plot(t_list*1e6, np.array(r_unstable_list)*1e6, linestyle="solid", color="red", marker="o", markevery=500, linewidth=2, label=r"$R_{Ue}$") +axs[0].plot(t_list*1e6, np.array(r_unstable_list)*1e6, linestyle="solid", color="red", marker="o", markevery=500, linewidth=2, label=r"$R_{\mathrm{Ue}}$") axs[0].legend(loc="upper left", frameon=False) # QA @@ -599,7 +606,7 @@ def identify_end_time_index(inttype, png, dist) : fig.savefig("cavitationonset_varyingpressure_unstableradius.pdf", bbox_inches='tight',pad_inches=0.35) -nrow = 3 +nrow = 2 ncol = 2 fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*15*cm, nrow*9.375*cm)), sharey=True, sharex=True) @@ -619,8 +626,8 @@ def identify_end_time_index(inttype, png, dist) : axs[0, 0].set_title(r"Incompressible interactions") axs[0, 1].set_title(r"Quasi-acoustic interactions") -png_list = [-25325, -25325, -27654.9] -dist_list = [12.0, 10.0, 10.0] +png_list = [-25325, -27654.9] +dist_list = [12.0, 10.0] for l in range(nrow) : png = png_list[l] @@ -631,7 +638,7 @@ def identify_end_time_index(inttype, png, dist) : r_list = np.array(dic_2_bubbles["IC"][png][dist][0][2]) p_list = np.array(dic_2_bubbles["IC"][png][dist][0][3]) - axs[l, 0].text(31.0, 30.0, r"$p_{ng}^{*}=$" + " {:.3f}".format(png/P0), horizontalalignment="center", fontsize=26) + axs[l, 0].text(31.0, 30.0, r"$p_{\mathrm{ng}}^{*}=$" + " {:.3f}".format(png/P0), horizontalalignment="center", fontsize=26) axs[l, 0].text(31.0, 35.0, r"$\Delta x_{12}^{*}=$" + " {:.1f}".format(dist), horizontalalignment="center", fontsize=26) R0 = r_list[0] @@ -645,7 +652,7 @@ def identify_end_time_index(inttype, png, dist) : if (l == 0) : axs[l, 0].plot(t_list*1e6, r_list*1e6, color="blue", linewidth=3.0, label=r"$R_{1}$") - axs[l, 0].plot(t_list*1e6, np.array(r_unstable_list)*1e6, linestyle="solid", color="red", marker="o", markevery=500, linewidth=2.5, label=r"$R_{Ue}$") + axs[l, 0].plot(t_list*1e6, np.array(r_unstable_list)*1e6, linestyle="solid", color="red", marker="o", markevery=500, linewidth=2.5, label=r"$R_{\mathrm{Ue}}$") else : axs[l, 0].plot(t_list*1e6, r_list*1e6, color="blue", linewidth=3.0) axs[l, 0].plot(t_list*1e6, np.array(r_unstable_list)*1e6, linestyle="solid", color="red", marker="o", markevery=500, linewidth=2.5) @@ -655,7 +662,7 @@ def identify_end_time_index(inttype, png, dist) : r_list = np.array(dic_2_bubbles["QA"][png][dist][0][2]) p_list = np.array(dic_2_bubbles["QA"][png][dist][0][3]) - axs[l, 1].text(31.0, 30.0, r"$p_{ng}^{*}=$" + " {:.3f}".format(png/P0), horizontalalignment="center", fontsize=26) + axs[l, 1].text(31.0, 30.0, r"$p_{\mathrm{ng}}^{*}=$" + " {:.3f}".format(png/P0), horizontalalignment="center", fontsize=26) axs[l, 1].text(31.0, 35.0, r"$\Delta x_{12}^{*}=$" + " {:.1f}".format(dist), horizontalalignment="center", fontsize=26) R0 = r_list[0] From 07464d7f5f89770a0267cd241fe8c2d8e15a0294 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 13 Sep 2024 14:36:40 -0400 Subject: [PATCH 105/138] sphericaltensionwave ; mentioning the right pressure for all computations --- .../run_sphericalclustertensionwave.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/sphericalclustertensionwave/run_sphericalclustertensionwave.sh b/examples/sphericalclustertensionwave/run_sphericalclustertensionwave.sh index 28be3ba..686bbe2 100755 --- a/examples/sphericalclustertensionwave/run_sphericalclustertensionwave.sh +++ b/examples/sphericalclustertensionwave/run_sphericalclustertensionwave.sh @@ -13,11 +13,11 @@ cd NI/build cd .. ######### Monodispersed system #################################################################### -./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure_bis -tend 15.0e-6 -cldistrib 0 +./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure -tend 15.0e-6 -cldistrib 0 python3 gather_results.py # ######### Polydispersed system #################################################################### -./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure_bis -tend 50.0e-6 -cldistrib 1 +./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure -tend 50.0e-6 -cldistrib 1 python3 gather_results.py cd .. @@ -33,11 +33,11 @@ cd IC/build cd .. ######### Monodispersed system #################################################################### -./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure_bis -tend 15.0e-6 -cldistrib 0 +./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure -tend 15.0e-6 -cldistrib 0 python3 gather_results.py ######### Polydispersed system #################################################################### -./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure_bis -tend 150.0e-6 -cldistrib 1 +./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure -tend 150.0e-6 -cldistrib 1 python3 gather_results.py cd .. @@ -53,11 +53,11 @@ cd QA/build cd .. ######### Monodispersed system #################################################################### -mpiexec -n $ncores ./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure_bis -tend 25.0e-06 -cldistrib 0 +mpiexec -n $ncores ./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure -tend 25.0e-06 -cldistrib 0 python3 gather_results.py ######### Polydispersed system #################################################################### -mpiexec -n $ncores ./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure_bis -tend 200.0e-06 -cldistrib 1 +mpiexec -n $ncores ./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure -tend 200.0e-06 -cldistrib 1 python3 gather_results.py cd .. From 2568cfdea75b79b21db2f3ac86a8930dc090ef2d Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 16 Sep 2024 13:20:00 -0400 Subject: [PATCH 106/138] sphericalclustertensionwave ; adding two new groups for bubble locations if needed for the plots (but the plots still contain only the three old groups for now) --- .../plot_results.py | 50 +++++++++++-------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/examples/sphericalclustertensionwave/plot_results.py b/examples/sphericalclustertensionwave/plot_results.py index a445aaa..e250f75 100644 --- a/examples/sphericalclustertensionwave/plot_results.py +++ b/examples/sphericalclustertensionwave/plot_results.py @@ -97,7 +97,7 @@ interval_size = cluster_radius / 10 dic_loc_distrib_global = {} -dic_loc_distrib = {0.0 : [], 0.5 : [], 1.0 : []} +dic_loc_distrib = {0.0 : [], 0.25 : [], 0.5 : [], 0.75 : [], 1.0 : []} for count in list(dic_bubbles_loc["mono"].keys()) : if count not in list(dic_loc_distrib_global.keys()) : @@ -111,13 +111,19 @@ radius_to_center = sqrt(dic_bubbles_loc["mono"][count][p1][i][0]**2 + dic_bubbles_loc["mono"][count][p1][i][1]**2 + dic_bubbles_loc["mono"][count][p1][i][2]**2) if radius_to_center < 0.0 * cluster_radius + interval_size : dic_loc_distrib_global[count][p1][0.0].append(i) + elif 0.25 * cluster_radius - 0.5 * interval_size < radius_to_center < 0.25 * cluster_radius + 0.5 * interval_size : + dic_loc_distrib_global[count][p1][0.25].append(i) elif 0.5 * (cluster_radius - interval_size) < radius_to_center < 0.5 * (cluster_radius + interval_size) : dic_loc_distrib_global[count][p1][0.5].append(i) + elif 0.75 * cluster_radius - 0.5 * interval_size < radius_to_center < 0.75 * cluster_radius + 0.5 * interval_size : + dic_loc_distrib_global[count][p1][0.75].append(i) elif 1.0 * cluster_radius - interval_size < radius_to_center : dic_loc_distrib_global[count][p1][1.0].append(i) dic_loc_label = {1.0 : "{:.1f}".format(1.0 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f}".format(1.0), + 0.75 : "{:.1f}".format(0.75 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f}".format(0.75 + interval_size/cluster_radius), 0.5 : "{:.1f}".format(0.5 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f}".format(0.5 + interval_size/cluster_radius), + 0.25 : "{:.1f}".format(0.25 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f}".format(0.25 + interval_size/cluster_radius), 0.0 : "{:.1f}".format(0.0) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f}".format(interval_size/cluster_radius)} # For polydispersed cluster, results are plotted based on bubbles initial radii @@ -252,10 +258,10 @@ axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) -dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} -dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} +dic_color_loc = {0.0 : "blue", 0.25 : "magenta", 0.5 : "red", 0.75 : "green", 1.0 : "black"} +dic_lines_loc = {0.0 : "dotted", 0.25 : "dashed", 0.5 : "dashed", 0.75 : "dashed", 1.0 : "solid"} -for k in dic_loc_distrib_global[count][p1].keys() : +for k in [0.0, 0.5, 1.0] : index_list = dic_loc_distrib_global[count][p1][k] # No interactions @@ -337,10 +343,10 @@ axs[1].set_title(r"Incompressible interactions", fontsize=27.5) axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) -dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} -dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} +dic_color_loc = {0.0 : "blue", 0.25 : "magenta", 0.5 : "red", 0.75 : "green", 1.0 : "black"} +dic_lines_loc = {0.0 : "dotted", 0.25 : "dashed", 0.5 : "dashed", 0.75 : "dashed", 1.0 : "solid"} -for k in dic_loc_distrib_global[count][p1].keys() : +for k in [0.0, 0.5, 1.0] : index_list = dic_loc_distrib_global[count][p1][k] # No interactions @@ -686,13 +692,13 @@ axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) -dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} -dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} +dic_color_loc = {0.0 : "blue", 0.25 : "magenta", 0.5 : "red", 0.75 : "green", 1.0 : "black"} +dic_lines_loc = {0.0 : "dotted", 0.25 : "dashed", 0.5 : "dashed", 0.75 : "dashed", 1.0 : "solid"} axs[0].set_xlim(xmin=0.0, xmax=250.0) axs[1].set_xlim(xmin=-10.0, xmax=800.0) -for k in dic_loc_distrib_global[count][p1].keys() : +for k in [0.0, 0.5, 1.0] : index_list = dic_loc_distrib_global[count][p1][k] # No interactions @@ -773,10 +779,10 @@ axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) -dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} -dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} +dic_color_loc = {0.0 : "blue", 0.25 : "magenta", 0.5 : "red", 0.75 : "green", 1.0 : "black"} +dic_lines_loc = {0.0 : "dotted", 0.25 : "dashed", 0.5 : "dashed", 0.75 : "dashed", 1.0 : "solid"} -for k in dic_loc_distrib_global[count][p1].keys() : +for k in [0.0, 0.5, 1.0] : index_list = dic_loc_distrib_global[count][p1][k] # No interactions @@ -853,8 +859,8 @@ axs[1].set_title(r"Incompressible interactions", fontsize=27.5) axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) -dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} -dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} +dic_color_loc = {0.0 : "blue", 0.25 : "magenta", 0.5 : "red", 0.75 : "green", 1.0 : "black"} +dic_lines_loc = {0.0 : "dotted", 0.25 : "dashed", 0.5 : "dashed", 0.75 : "dashed", 1.0 : "solid"} zm_IC = axs[1].inset_axes([0.35, 0.35, 0.60, 0.60]) zm_IC.grid() @@ -874,7 +880,7 @@ zm_QA.set_yticklabels([r"$p_{\mathrm{C}}$", 0, 1, 2]) zm_QA.tick_params(axis="both", labelsize=25) -for k in dic_loc_distrib_global[count][p1].keys() : +for k in [0.0, 0.5, 1.0] : index_list = dic_loc_distrib_global[count][p1][k] # No interactions @@ -1148,10 +1154,10 @@ axs[1].set_title(r"Incompressible interactions", fontsize=27.5) axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) -dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} -dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} +dic_color_loc = {0.0 : "blue", 0.25 : "magenta", 0.5 : "red", 0.75 : "green", 1.0 : "black"} +dic_lines_loc = {0.0 : "dotted", 0.25 : "dashed", 0.5 : "dashed", 0.75 : "dashed", 1.0 : "solid"} -for k in dic_loc_distrib_global[count][p1].keys() : +for k in [0.0, 0.5, 1.0] : index_list = dic_loc_distrib_global[count][p1][k] # No interactions @@ -1236,8 +1242,8 @@ axs[1].set_title(r"Incompressible interactions", fontsize=27.5) axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) -dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} -dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} +dic_color_loc = {0.0 : "blue", 0.25 : "magenta", 0.5 : "red", 0.75 : "green", 1.0 : "black"} +dic_lines_loc = {0.0 : "dotted",0.25 : "dashed", 0.5 : "dashed", 0.75 : "dashed", 1.0 : "solid"} zm_IC = axs[1].inset_axes([0.35, 0.35, 0.60, 0.60]) zm_IC.grid() @@ -1257,7 +1263,7 @@ zm_QA.set_yticklabels([r"$p_{\mathrm{C}}$", 0, 1, 2]) zm_QA.tick_params(axis="both", labelsize=25) -for k in dic_loc_distrib_global[count][p1].keys() : +for k in [0.0, 0.5, 1.0] : index_list = dic_loc_distrib_global[count][p1][k] # No interactions From 8baf53e6630dd6a2ad59a54b088fc9e995fac9ff Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 17 Sep 2024 15:44:02 -0400 Subject: [PATCH 107/138] frequencyresponse ; small rework of the axis titles for distance study plot --- examples/frequencyresponse/plot_results.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/frequencyresponse/plot_results.py b/examples/frequencyresponse/plot_results.py index c38cdf8..64f7605 100644 --- a/examples/frequencyresponse/plot_results.py +++ b/examples/frequencyresponse/plot_results.py @@ -327,12 +327,12 @@ axs[i, j].set_xlim(xmin=0.5, xmax=8.0) if j == 0 : axs[i, j].set_ylabel(r"$R_{\mathrm{max}}/R_{0}$") -fig.subplots_adjust(hspace=0.35*cm, wspace=0.05*cm) +fig.subplots_adjust(hspace=0.55*cm, wspace=0.05*cm) -axs[0, 0].set_title(r"4MBs interacting at $d = 5$ $\mu$m") -axs[0, 1].set_title(r"4MBs interacting at $d = 10$ $\mu$m") -axs[1, 0].set_title(r"4MBs interacting at $d = 25$ $\mu$m") -axs[1, 1].set_title(r"4MBs interacting at $d = 50$ $\mu$m") +axs[0, 0].set_title(r"$d = 5$ $\mu$m") +axs[0, 1].set_title(r"$d = 10$ $\mu$m") +axs[1, 0].set_title(r"$d = 25$ $\mu$m") +axs[1, 1].set_title(r"$d = 50$ $\mu$m") # 5 microns data_list = dic_results["QA"][0][4][1.2e5][5e-6] From cd6142d96cd7dc5a8005eb6f5c3afc1d094b2b8c Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 17 Sep 2024 15:58:06 -0400 Subject: [PATCH 108/138] bubblyscreen ; changing the time limit in the radius oscillation amplitude evolution plot --- examples/bubblyscreen/plot_results.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/bubblyscreen/plot_results.py b/examples/bubblyscreen/plot_results.py index 3af6452..578528e 100644 --- a/examples/bubblyscreen/plot_results.py +++ b/examples/bubblyscreen/plot_results.py @@ -219,7 +219,7 @@ def identify_oscillation_amplitude(t_list, r_list) : fig, ax = plt.subplots(1, 1, figsize=(27.5*cm, 12.5*cm)) ax.set_xlabel(r"$t$ [$\mu$s]") -ax.set_xlim(xmin=0.0, xmax=60.0) +ax.set_xlim(xmin=0.0, xmax=35.0) ax.set_ylabel(r"$|r'|$") ax.set_yscale("log") ax.set_ylim(ymin=10**(-4), ymax=5.0e-2) From a0e05bb96c096893b49b606a384398c6cb2c6063 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Tue, 17 Sep 2024 16:30:01 -0400 Subject: [PATCH 109/138] cavitationonset ; small correction of the vertical location of axis titles for unstable radius plot --- examples/cavitationonset/plot_results.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/cavitationonset/plot_results.py b/examples/cavitationonset/plot_results.py index 0fe3e3a..c819949 100644 --- a/examples/cavitationonset/plot_results.py +++ b/examples/cavitationonset/plot_results.py @@ -623,8 +623,8 @@ def identify_end_time_index(inttype, png, dist) : axs[i, j].set_xlim(xmin=0.0, xmax=60.0) axs[i, j].set_xticks([10, 30, 50], [10, 30, 50]) -axs[0, 0].set_title(r"Incompressible interactions") -axs[0, 1].set_title(r"Quasi-acoustic interactions") +axs[0, 0].set_title(r"Incompressible interactions", y=1.025) +axs[0, 1].set_title(r"Quasi-acoustic interactions", y=1.025) png_list = [-25325, -27654.9] dist_list = [12.0, 10.0] From 25c2a131be479362faa23c74a76e834f3b9ca92c Mon Sep 17 00:00:00 2001 From: Pierre C Date: Wed, 18 Sep 2024 10:51:40 -0400 Subject: [PATCH 110/138] cavitationonset ; small adjustment of the axis titles vertical positions --- examples/cavitationonset/plot_results.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/cavitationonset/plot_results.py b/examples/cavitationonset/plot_results.py index c819949..58d1fb8 100644 --- a/examples/cavitationonset/plot_results.py +++ b/examples/cavitationonset/plot_results.py @@ -477,8 +477,8 @@ def identify_end_time_index(inttype, png, dist) : plt.subplots_adjust(wspace=0.45*cm, hspace=0.25*cm) # fig.suptitle(r"$p_{\mathrm{ng}}/p_{0}=$" + "{:.3f}, ".format(png/P0) + r"$\Delta x_{12}=$" + "{:.1f}".format(dist) + r"($R_{1,0} + R_{2,0}$)") -axs[0, 0].set_title("Incompressible interactions") -axs[0, 1].set_title("Quasi-acoustic interactions") +axs[0, 0].set_title("Incompressible interactions", y=1.025) +axs[0, 1].set_title("Quasi-acoustic interactions", y=1.025) for i in range(nrow) : for j in range(ncol) : From 42bfda3b91042bca6a3c25ac9e2b50b0e87234dc Mon Sep 17 00:00:00 2001 From: Pierre C Date: Wed, 18 Sep 2024 11:08:21 -0400 Subject: [PATCH 111/138] cavitationonset ; vertical adjustments for every axis titles in the figures --- examples/cavitationonset/plot_results.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/cavitationonset/plot_results.py b/examples/cavitationonset/plot_results.py index 58d1fb8..452634c 100644 --- a/examples/cavitationonset/plot_results.py +++ b/examples/cavitationonset/plot_results.py @@ -187,7 +187,7 @@ def identify_end_time_index(inttype, png, dist) : dist_list = [10, 12, 12.1, 12.5, 15, 20] -axs[0].set_title(r"Incompressible interactions") +axs[0].set_title(r"Incompressible interactions", y=1.025) axs[0].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) axs[0].set_xlim(xmin=0.0, xmax=60.0) axs[0].set_ylabel(r"$R$ [$\mu$m]", fontsize=27.5) @@ -221,7 +221,7 @@ def identify_end_time_index(inttype, png, dist) : dist_list = [10, 11.9, 12, 15, 20] -axs[1].set_title(r"Quasi-acoustic interactions") +axs[1].set_title(r"Quasi-acoustic interactions", y=1.025) axs[1].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) axs[1].set_xlim(xmin=0.0, xmax=60.0) # axs[1].set_ylabel(r"$R$ [$\mu$m]") @@ -264,7 +264,7 @@ def identify_end_time_index(inttype, png, dist) : png_list = [-25325, -27351, -27654.9, -27958.8, -29377] -axs[0].set_title(r"Incompressible interactions") +axs[0].set_title(r"Incompressible interactions", y=1.025) axs[0].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) axs[0].set_xlim(xmin=0.0, xmax=60.0) axs[0].set_ylabel(r"$R_{1}$ [$\mu$m]", fontsize=27.5) @@ -293,7 +293,7 @@ def identify_end_time_index(inttype, png, dist) : png_list = [-25325, -27351, -27958.8, -27654.9, -29377] -axs[1].set_title(r"Quasi-acoustic interactions") +axs[1].set_title(r"Quasi-acoustic interactions", y=1.025) axs[1].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) axs[1].set_xlim(xmin=0.0, xmax=60.0) # axs[1].set_ylabel(r"$R$ [$\mu$m]") @@ -559,14 +559,14 @@ def identify_end_time_index(inttype, png, dist) : fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm)), sharey=True, sharex=True) plt.subplots_adjust(wspace=0.15*cm, hspace=0.5*cm) -axs[0].set_title(r"Incompressible interactions") +axs[0].set_title(r"Incompressible interactions", y=1.025) axs[0].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) axs[0].set_xlim(xmin=0.0, xmax=60.0) axs[0].set_ylabel(r"$R$ [$\mu$m]", fontsize=27.5) axs[0].set_ylim(ymin=0.0, ymax=40.0) axs[0].grid() -axs[1].set_title(r"Quasi-acoustic interactions") +axs[1].set_title(r"Quasi-acoustic interactions", y=1.025) axs[1].grid() # IC @@ -699,8 +699,8 @@ def identify_end_time_index(inttype, png, dist) : axs[i, j].grid() axs[i, j].set_xlim(xmin=10.0, xmax=60.0) -axs[0, 0].set_title(r"Incompressible interactions") -axs[0, 1].set_title(r"Quasi-acoustic interactions") +axs[0, 0].set_title(r"Incompressible interactions", y=1.025) +axs[0, 1].set_title(r"Quasi-acoustic interactions", y=1.025) axs[1, 0].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) axs[1, 1].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) From d43451db69c2f9a2af87e31483889cca6ad8c529 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Wed, 18 Sep 2024 11:20:44 -0400 Subject: [PATCH 112/138] sphericalclustertensionwave ; adjustments for vertical locations of axis titles --- .../plot_results.py | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/examples/sphericalclustertensionwave/plot_results.py b/examples/sphericalclustertensionwave/plot_results.py index e250f75..f258800 100644 --- a/examples/sphericalclustertensionwave/plot_results.py +++ b/examples/sphericalclustertensionwave/plot_results.py @@ -254,9 +254,9 @@ axs[i].set_xlim(xmin=0.0, xmax=15.0) axs[i].grid() -axs[0].set_title(r"No interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) -axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) -axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[0].set_title(r"No interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) +axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) +axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) dic_color_loc = {0.0 : "blue", 0.25 : "magenta", 0.5 : "red", 0.75 : "green", 1.0 : "black"} dic_lines_loc = {0.0 : "dotted", 0.25 : "dashed", 0.5 : "dashed", 0.75 : "dashed", 1.0 : "solid"} @@ -339,9 +339,9 @@ plt.subplots_adjust(wspace=0.35*cm) -axs[0].set_title(r"No interactions", fontsize=27.5) -axs[1].set_title(r"Incompressible interactions", fontsize=27.5) -axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) +axs[0].set_title(r"No interactions", fontsize=27.5, y=1.025) +axs[1].set_title(r"Incompressible interactions", fontsize=27.5, y=1.025) +axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5, y=1.025) dic_color_loc = {0.0 : "blue", 0.25 : "magenta", 0.5 : "red", 0.75 : "green", 1.0 : "black"} dic_lines_loc = {0.0 : "dotted", 0.25 : "dashed", 0.5 : "dashed", 0.75 : "dashed", 1.0 : "solid"} @@ -422,9 +422,9 @@ # axs[i].set_xlim(xmin=10.0, xmax=60.0) axs[i].grid() -axs[0].set_title(r"No interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) -axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) -axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[0].set_title(r"No interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) +axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) +axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) color_list = ["black", "magenta", "blue", "green", "red"] # linestyle_list = [(0, (1, 1)), (5, (10, 3)), (0, (5, 5)), (0, (3, 5, 1, 5)), (0, (3, 1, 1, 1, 1, 1))] @@ -555,9 +555,9 @@ axs[i].grid() plt.subplots_adjust(wspace=0.35*cm) -axs[0].set_title(r"No interactions", fontsize=27.5) -axs[1].set_title(r"Incompressible interactions", fontsize=27.5) -axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) +axs[0].set_title(r"No interactions", fontsize=27.5, y=1.025) +axs[1].set_title(r"Incompressible interactions", fontsize=27.5, y=1.025) +axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5, y=1.025) color_list = ["black", "magenta", "blue", "green", "red"] # linestyle_list = [(0, (1, 1)), (5, (10, 3)), (0, (5, 5)), (0, (3, 5, 1, 5)), (0, (3, 1, 1, 1, 1, 1))] @@ -688,9 +688,9 @@ # axs[i].set_xlim(xmin=10.0, xmax=60.0) axs[i].grid() -axs[0].set_title(r"No interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) -axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) -axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[0].set_title(r"No interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) +axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) +axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) dic_color_loc = {0.0 : "blue", 0.25 : "magenta", 0.5 : "red", 0.75 : "green", 1.0 : "black"} dic_lines_loc = {0.0 : "dotted", 0.25 : "dashed", 0.5 : "dashed", 0.75 : "dashed", 1.0 : "solid"} @@ -775,9 +775,9 @@ axs[i].set_xlim(xmin=0.0, xmax=15.0) axs[i].grid() -axs[0].set_title(r"No interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) -axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) -axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[0].set_title(r"No interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) +axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) +axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) dic_color_loc = {0.0 : "blue", 0.25 : "magenta", 0.5 : "red", 0.75 : "green", 1.0 : "black"} dic_lines_loc = {0.0 : "dotted", 0.25 : "dashed", 0.5 : "dashed", 0.75 : "dashed", 1.0 : "solid"} @@ -855,9 +855,9 @@ plt.subplots_adjust(wspace=0.35*cm) -axs[0].set_title(r"No interactions", fontsize=27.5) -axs[1].set_title(r"Incompressible interactions", fontsize=27.5) -axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) +axs[0].set_title(r"No interactions", fontsize=27.5, y=1.025) +axs[1].set_title(r"Incompressible interactions", fontsize=27.5, y=1.025) +axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5, y=1.025) dic_color_loc = {0.0 : "blue", 0.25 : "magenta", 0.5 : "red", 0.75 : "green", 1.0 : "black"} dic_lines_loc = {0.0 : "dotted", 0.25 : "dashed", 0.5 : "dashed", 0.75 : "dashed", 1.0 : "solid"} @@ -954,9 +954,9 @@ # axs[i].set_xlim(xmin=10.0, xmax=60.0) axs[i].grid() -axs[0].set_title(r"No interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) -axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) -axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15) +axs[0].set_title(r"No interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) +axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) +axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) color_list = ["black", "magenta", "blue", "green", "red"] dic_color_q = {} @@ -1052,9 +1052,9 @@ plt.subplots_adjust(wspace=0.35*cm) -axs[0].set_title(r"No interactions", fontsize=27.5) -axs[1].set_title(r"Incompressible interactions", fontsize=27.5) -axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) +axs[0].set_title(r"No interactions", fontsize=27.5, y=1.025) +axs[1].set_title(r"Incompressible interactions", fontsize=27.5, y=1.025) +axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5, y=1.025) color_list = ["black", "magenta", "blue", "green", "red"] dic_color_q = {} @@ -1150,9 +1150,9 @@ plt.subplots_adjust(wspace=0.35*cm) -axs[0].set_title(r"No interactions", fontsize=27.5) -axs[1].set_title(r"Incompressible interactions", fontsize=27.5) -axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) +axs[0].set_title(r"No interactions", fontsize=27.5, y=1.025) +axs[1].set_title(r"Incompressible interactions", fontsize=27.5, y=1.025) +axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5, y=1.025) dic_color_loc = {0.0 : "blue", 0.25 : "magenta", 0.5 : "red", 0.75 : "green", 1.0 : "black"} dic_lines_loc = {0.0 : "dotted", 0.25 : "dashed", 0.5 : "dashed", 0.75 : "dashed", 1.0 : "solid"} @@ -1238,9 +1238,9 @@ plt.subplots_adjust(wspace=0.35*cm) -axs[0].set_title(r"No interactions", fontsize=27.5) -axs[1].set_title(r"Incompressible interactions", fontsize=27.5) -axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) +axs[0].set_title(r"No interactions", fontsize=27.5, y=1.025) +axs[1].set_title(r"Incompressible interactions", fontsize=27.5, y=1.025) +axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5, y=1.025) dic_color_loc = {0.0 : "blue", 0.25 : "magenta", 0.5 : "red", 0.75 : "green", 1.0 : "black"} dic_lines_loc = {0.0 : "dotted",0.25 : "dashed", 0.5 : "dashed", 0.75 : "dashed", 1.0 : "solid"} @@ -1339,9 +1339,9 @@ axs[i].grid() plt.subplots_adjust(wspace=0.35*cm) -axs[0].set_title(r"No interactions", fontsize=27.5) -axs[1].set_title(r"Incompressible interactions", fontsize=27.5) -axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5) +axs[0].set_title(r"No interactions", fontsize=27.5, y=1.025) +axs[1].set_title(r"Incompressible interactions", fontsize=27.5, y=1.025) +axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5, y=1.025) color_list = ["black", "magenta", "blue", "green", "red"] # linestyle_list = [(0, (1, 1)), (5, (10, 3)), (0, (5, 5)), (0, (3, 5, 1, 5)), (0, (3, 1, 1, 1, 1, 1))] From baf0c204dc5c51b4ebc9bcc859d6311a2240f488 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Wed, 18 Sep 2024 14:47:04 -0400 Subject: [PATCH 113/138] interactions ; removing unnecessary comments to have a clean file --- src/interactions.c | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/src/interactions.c b/src/interactions.c index 50830dc..0bf92bf 100644 --- a/src/interactions.c +++ b/src/interactions.c @@ -28,20 +28,6 @@ int apecss_interactions_instantaneous(struct APECSS_Bubble *Bubbles[]) // All bubbles are supposed to be in the same liquid struct APECSS_Liquid *Liquid = Bubbles[0]->Liquid; - // Preliminary step to gather bubble wall acceleration values - // APECSS_FLOAT Bubbles_A[nBubbles]; - // for (register int i = 0; i < nBubbles; i++) - // { - // APECSS_FLOAT acceleration = Bubbles[i]->ode[0](Bubbles[i]->ODEsSol, Bubbles[i]->t, Bubbles[i]); - // Bubbles_A[i] = acceleration; - // } - - // // Reset pressure contributions of the neighbours - // for (register int i = 0; i < nBubbles; i++) - // { - // Bubbles[i]->Interaction->dp_neighbor = 0.0; - // } - for (register int i = 0; i < nBubbles; i++) { APECSS_FLOAT x_i = Bubbles[i]->Interaction->location[0]; @@ -59,32 +45,12 @@ int apecss_interactions_instantaneous(struct APECSS_Bubble *Bubbles[]) APECSS_FLOAT z_j = Bubbles[j]->Interaction->location[2]; APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); - // printf("Bubble %d vs Bubble %d, %e %e %e", i, j, interbubble_dist, Bubbles[i]->ode[0](Bubbles[i]->ODEsSol, Bubbles[i]->t, Bubbles[i]), - // Bubbles[j]->ode[0](Bubbles[j]->ODEsSol, Bubbles[j]->t, Bubbles[j])); - // printf("Bubble %d vs Bubble %d, %e %e %e", i, j, interbubble_dist, Bubbles_A[i], Bubbles_A[j]); - - // APECSS_FLOAT dp = Liquid->rhoref * ((2.0 * Bubbles[j]->R * APECSS_POW2(Bubbles[j]->U) + - // APECSS_POW2(Bubbles[j]->R) * Bubbles[j]->ode[0](Bubbles[j]->ODEsSol, Bubbles[j]->t, Bubbles[j])) * - // (1 / interbubble_dist) - - // (APECSS_POW4(Bubbles[j]->R) * APECSS_POW2(Bubbles[j]->U)) * (1 / (2 * APECSS_POW4(interbubble_dist)))); - - // APECSS_FLOAT dp = - // Liquid->rhoref * (((2.0 * Bubbles[j]->R * APECSS_POW2(Bubbles[j]->U) + APECSS_POW2(Bubbles[j]->R) * Bubbles_A[j]) * (1 / interbubble_dist)) - - // ((APECSS_POW4(Bubbles[j]->R) * APECSS_POW2(Bubbles[j]->U)) * (1 / (2 * APECSS_POW4(interbubble_dist))))); APECSS_FLOAT dp = Liquid->rhoref * 2.0 * Bubbles[j]->R * APECSS_POW2(Bubbles[j]->U) * (1 / interbubble_dist); dp += Liquid->rhoref * APECSS_POW2(Bubbles[j]->R) * Bubbles[j]->ode[0](Bubbles[j]->ODEsSol, Bubbles[j]->t, Bubbles[j]) * (1 / interbubble_dist); dp += -Liquid->rhoref * APECSS_POW4(Bubbles[j]->R) * APECSS_POW2(Bubbles[j]->U) * (1 / (2 * APECSS_POW4(interbubble_dist))); - // if ((i == 0) && (j == 1)) - // printf(" %e %e %e", 2.0 * Bubbles[j]->R * APECSS_POW2(Bubbles[j]->U) * (1 / interbubble_dist), - // APECSS_POW2(Bubbles[j]->R) * Bubbles_A[j] * (1 / interbubble_dist), - // (APECSS_POW4(Bubbles[j]->R) * APECSS_POW2(Bubbles[j]->U)) * (1 / (2 * APECSS_POW4(interbubble_dist)))); - Bubbles[i]->Interaction->dp_neighbor += dp; - // printf(" %e %e\n", Bubbles[i]->ode[0](Bubbles[i]->ODEsSol, Bubbles[i]->t, Bubbles[i]), - // Bubbles[j]->ode[0](Bubbles[j]->ODEsSol, Bubbles[j]->t, Bubbles[j])); - // printf(" %e\n", Bubbles[i]->Interaction->dp_neighbor); } } } @@ -164,7 +130,6 @@ int apecss_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[]) } } Bubbles[i]->Interaction->dp_neighbor += Liquid->rhoref * (sumG - 0.5 * APECSS_POW2(sumU)); - // printf(" %e\n", Bubbles[i]->Interaction->dp_neighbor); } return (0); From f52fe5bd208ef0fe764925bc8b255a1621f0847e Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 20 Sep 2024 10:31:03 -0400 Subject: [PATCH 114/138] README ; small changes in the "key features" bullet points --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f729ffa..7bb5a8b 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ APECSS is a software toolbox to compute pressure-driven bubble dynamics and the Key features of APECSS are: - Bubble dynamics using widely-used models (Rayleigh-Plesset, Keller-Miksis, Gilmore), solved using an in-built 5th-order Runge-Kutta scheme with adaptive time stepping. - Acoustic emissions of the bubble under different assumptions (incompressible, quasi-acoustic, fully compressible). -- *(Work in progress)* Interbubble interactions within a cavitation cluster +- Interbubble interactions through their acoustic emissions - Prediction of the formation and attenuation of shock fronts emitted by the bubble. - Viscoelastic media (Kelvin-Voigt, Zener, Oldroyd-B). - Lipid monolayer coating of the bubble as used for ultrasound contrast agents. From 63e3a3272d0be2faa2d8a763d8396c209b9df3b8 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 20 Sep 2024 11:11:09 -0400 Subject: [PATCH 115/138] cavitationonset ; update of README --- examples/cavitationonset/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/cavitationonset/README.md b/examples/cavitationonset/README.md index 2b982c1..7c1ed31 100644 --- a/examples/cavitationonset/README.md +++ b/examples/cavitationonset/README.md @@ -1 +1 @@ -This example builds a standalone APECSS code for two (or more) interacting microbubbles, following the work of [Ida, M. (2009). Multibubble cavitation inception. Physics of Fluids, 21(11), 113302.](https://doi.org/10.1063/1.3265547), using the _standard incompressible model_ and the newly developped _quasi acoustic model_ to compute the acoustic emissions. There is three folders, representing each a specific interaction model ("NI" for "no interaction, "IC" for the _standard incompressible model_ and "QA" for the _quasi acoustic model_). Each folder is containing a provided [run.apecss](./IC/run.apecss) file to reproduce the bubble dynamics shown in Figs. 2, 3, 4, 5, 6 and 16 of the paper of Ida such as a [gather_results.py](./IC/gather_results.py) to properly keep the results. The [run_cavitationonset.sh](./run_cavitationonset.sh) file provides the whole execution commands needed to gather data in order to reproduce results from the source article. \ No newline at end of file +This example builds a standalone APECSS code for two interacting microbubbles, following the work of [Ida, M. (2009). Multibubble cavitation inception. Physics of Fluids, 21(11), 113302.](https://doi.org/10.1063/1.3265547), using the _standard incompressible model_ and the newly developped _quasi acoustic model_ to compute the acoustic emissions. There is three folders, representing each a specific interaction model ("NI" for "no interaction, "IC" for the _standard incompressible model_ and "QA" for the _quasi acoustic model_). Each folder is containing a provided [run.apecss](./IC/run.apecss) file to reproduce the bubble dynamics shown in Figs. 5, 6, 9, 11, 12 and 13 of the paper of Ida such as a [gather_results.py](./IC/gather_results.py) to properly keep the results. The [run_cavitationonset.sh](./run_cavitationonset.sh) file provides the whole execution commands needed to gather data in order to reproduce results from the source article. The plots are designed to exhibit the differences between the two interaction models when studying cavitation onset and collapse of the bubbles. \ No newline at end of file From 09e1d8f4e20d1c1efba0e072ea0a52a031b30eb1 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 20 Sep 2024 11:49:12 -0400 Subject: [PATCH 116/138] cavitationonset ; cleaning files to run computations for each interaction model --- examples/cavitationonset/IC/gather_results.py | 9 +- .../IC/src/cavitationonset_apecss.c | 214 ++---------------- examples/cavitationonset/NI/gather_results.py | 9 +- .../NI/src/cavitationonset_apecss.c | 194 ++-------------- examples/cavitationonset/QA/gather_results.py | 9 +- .../QA/src/cavitationonset_apecss.c | 172 ++------------ 6 files changed, 44 insertions(+), 563 deletions(-) diff --git a/examples/cavitationonset/IC/gather_results.py b/examples/cavitationonset/IC/gather_results.py index 2fad87b..9eaed77 100644 --- a/examples/cavitationonset/IC/gather_results.py +++ b/examples/cavitationonset/IC/gather_results.py @@ -9,15 +9,8 @@ count = int(lines[0].split(" ")[0]) png = float(lines[0].split(" ")[5]) cl_size = float(lines[0].split(" ")[7]) -cl_distrib = int(lines[0].split(" ")[9]) -if cl_distrib == 0 : - # Two bubbles of different size - file_name = "{}_{:.4E}_{:.2f}.txt".format(count, png, cl_size) - -else : - # Monodispersed system - file_name = "{}_{:.4E}.txt".format(count, png) +file_name = "{}_{:.4E}_{:.2f}.txt".format(count, png, cl_size) working_path = os.getcwd() results_path = os.path.join(working_path, "results") diff --git a/examples/cavitationonset/IC/src/cavitationonset_apecss.c b/examples/cavitationonset/IC/src/cavitationonset_apecss.c index 3f68ce1..1dd191a 100644 --- a/examples/cavitationonset/IC/src/cavitationonset_apecss.c +++ b/examples/cavitationonset/IC/src/cavitationonset_apecss.c @@ -24,12 +24,6 @@ APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -// Declaration of the structure holding the interaction variables of each bubble -struct Interaction -{ - APECSS_FLOAT dp_neighbor; -}; - int main(int argc, char **args) { char OptionsDir[APECSS_STRINGLENGTH]; @@ -38,14 +32,14 @@ int main(int argc, char **args) // Interbubble time-step, defining the frequency with which the neighbor influence is updated APECSS_FLOAT dt_interbubble = 1.0e-8; + // Number of bubbles + const int nBubbles = 2; + // Initialize the simulation parameters given by the execution command - int nBubbles = 2; double tEnd = 0.0; double fa = 0.0; double pa = 0.0; - int cluster_distrib = 0; double cluster_size = 0; - int inttype = 0; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< apecss_infoscreen(); @@ -75,26 +69,11 @@ int main(int argc, char **args) sscanf(args[j + 1], "%le", &pa); j += 2; } - else if (strcmp("-nbb", args[j]) == 0) - { - sscanf(args[j + 1], "%d", &nBubbles); - j += 2; - } - else if (strcmp("-cldistrib", args[j]) == 0) - { - sscanf(args[j + 1], "%d", &cluster_distrib); - j += 2; - } else if (strcmp("-clsize", args[j]) == 0) { sscanf(args[j + 1], "%le", &cluster_size); j += 2; } - else if (strcmp("-inttype", args[j]) == 0) - { - sscanf(args[j + 1], "%d", &inttype); - j += 2; - } else if (strcmp("-dt_inter", args[j]) == 0) { sscanf(args[j + 1], "%le", &dt_interbubble); @@ -197,131 +176,17 @@ int main(int argc, char **args) } // Define the size of each bubble - if (cluster_distrib == 0) - { - // Two bubbles of different initial size interacting - Bubbles[0]->R0 = 2.0e-06; - Bubbles[1]->R0 = 20.0e-06; - } - else - { - // Monodispersed multibubble distributions - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->R0 = 20.0e-06; - } - } + Bubbles[0]->R0 = 2.0e-06; + Bubbles[1]->R0 = 20.0e-06; // Define center location for each bubble - if (cluster_distrib == 0) - { - // Two bubbles of different initial size interacting - Bubbles[0]->Interaction->location[0] = 0.0; - Bubbles[0]->Interaction->location[1] = 0.0; - Bubbles[0]->Interaction->location[2] = 0.0; - - Bubbles[1]->Interaction->location[0] = (APECSS_FLOAT) cluster_size * (Bubbles[0]->R0 + Bubbles[1]->R0); - Bubbles[1]->Interaction->location[1] = 0.0; - Bubbles[1]->Interaction->location[2] = 0.0; - } - else - { - // Monodispersed multibubble distributions - APECSS_FLOAT D = 400.0e-06; - if (nBubbles == 1) - { - // Single bubble - Bubbles[0]->Interaction->location[0] = 0.0; - Bubbles[0]->Interaction->location[1] = 0.0; - Bubbles[0]->Interaction->location[2] = 0.0; - } - else if (nBubbles == 2) - { - // Two bubbles - Bubbles[0]->Interaction->location[0] = 0.0; - Bubbles[0]->Interaction->location[1] = 0.0; - Bubbles[0]->Interaction->location[2] = 0.0; - - Bubbles[1]->Interaction->location[0] = D; - Bubbles[1]->Interaction->location[1] = 0.0; - Bubbles[1]->Interaction->location[2] = 0.0; - } - else if (nBubbles == 3) - { - // Regular triangle - Bubbles[0]->Interaction->location[0] = 0.0; - Bubbles[0]->Interaction->location[1] = 0.0; - Bubbles[0]->Interaction->location[2] = 0.0; - - Bubbles[1]->Interaction->location[0] = D; - Bubbles[1]->Interaction->location[1] = 0.0; - Bubbles[1]->Interaction->location[2] = 0.0; - - Bubbles[2]->Interaction->location[0] = 0.5 * D; - Bubbles[2]->Interaction->location[1] = D * APECSS_SIN(APECSS_ONETHIRD * APECSS_PI); - Bubbles[2]->Interaction->location[2] = 0.0; - } - else if (nBubbles == 4) - { - // Regular tetragon - Bubbles[0]->Interaction->location[0] = 0.0; - Bubbles[0]->Interaction->location[1] = 0.0; - Bubbles[0]->Interaction->location[2] = 0.0; - - Bubbles[1]->Interaction->location[0] = D; - Bubbles[1]->Interaction->location[1] = 0.0; - Bubbles[1]->Interaction->location[2] = 0.0; - - Bubbles[2]->Interaction->location[0] = 0.0; - Bubbles[2]->Interaction->location[1] = D; - Bubbles[2]->Interaction->location[2] = 0.0; - - Bubbles[3]->Interaction->location[0] = D; - Bubbles[3]->Interaction->location[1] = D; - Bubbles[3]->Interaction->location[2] = 0.0; - } - else if (nBubbles == 8) - { - // Regular hexaedron - Bubbles[0]->Interaction->location[0] = 0.0; - Bubbles[0]->Interaction->location[1] = 0.0; - Bubbles[0]->Interaction->location[2] = 0.0; - - Bubbles[1]->Interaction->location[0] = D; - Bubbles[1]->Interaction->location[1] = 0.0; - Bubbles[1]->Interaction->location[2] = 0.0; - - Bubbles[2]->Interaction->location[0] = 0.0; - Bubbles[2]->Interaction->location[1] = D; - Bubbles[2]->Interaction->location[2] = 0.0; - - Bubbles[3]->Interaction->location[0] = D; - Bubbles[3]->Interaction->location[1] = D; - Bubbles[3]->Interaction->location[2] = 0.0; - - Bubbles[4]->Interaction->location[0] = 0.0; - Bubbles[4]->Interaction->location[1] = 0.0; - Bubbles[4]->Interaction->location[2] = D; - - Bubbles[5]->Interaction->location[0] = D; - Bubbles[5]->Interaction->location[1] = 0.0; - Bubbles[5]->Interaction->location[2] = D; - - Bubbles[6]->Interaction->location[0] = 0.0; - Bubbles[6]->Interaction->location[1] = D; - Bubbles[6]->Interaction->location[2] = D; - - Bubbles[7]->Interaction->location[0] = D; - Bubbles[7]->Interaction->location[1] = D; - Bubbles[7]->Interaction->location[2] = D; - } - else - { - char str[APECSS_STRINGLENGTH_SPRINTF]; - sprintf(str, "Wrong number of bubbles as input for this specific cluster distribution (1, 2, 3, 4 or 8)"); - apecss_erroronscreen(1, str); - } - } + Bubbles[0]->Interaction->location[0] = 0.0; + Bubbles[0]->Interaction->location[1] = 0.0; + Bubbles[0]->Interaction->location[2] = 0.0; + + Bubbles[1]->Interaction->location[0] = (APECSS_FLOAT) cluster_size * (Bubbles[0]->R0 + Bubbles[1]->R0); + Bubbles[1]->Interaction->location[1] = 0.0; + Bubbles[1]->Interaction->location[2] = 0.0; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< clock_t starttimebubble = clock(); @@ -344,8 +209,7 @@ int main(int argc, char **args) // File to retrieve all valuable information for cavitation onset test case FILE *file_ida2009; file_ida2009 = fopen("Ida2009_results.txt", "w"); - fprintf(file_ida2009, "%d Bubbles p0(pa) %e png(Pa) %e D_multiplier(-) %e cl_distrib %d Interaction-type %d\n", nBubbles, Liquid->pref, pa, cluster_size, - cluster_distrib, inttype); + fprintf(file_ida2009, "%d Bubbles p0(pa) %e png(Pa) %e D_multiplier(-) %e Interaction-type %d\n", nBubbles, Liquid->pref, pa, cluster_size, 1); fprintf(file_ida2009, "Initial_radii(m)"); for (register int i = 0; i < nBubbles; i++) fprintf(file_ida2009, " %e", Bubbles[i]->R0); fprintf(file_ida2009, "\n"); @@ -358,32 +222,12 @@ int main(int argc, char **args) APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); tSim += dtSim; - // printf("%e", tSim); - // printf(" %e", Bubbles[0]->ode[0](Bubbles[0]->ODEsSol, Bubbles[0]->t, Bubbles[0])); for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); - // for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; - - // printf(" %e", Bubbles[0]->R); - // printf(" %e", Bubbles[0]->ode[0](Bubbles[0]->ODEsSol, Bubbles[0]->t, Bubbles[0])); // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // Update the contribution of the neighbor bubbles - if (inttype == 1) - { - apecss_interactions_instantaneous(Bubbles); - } - else if (inttype == 2) - { - apecss_interactions_quasi_acoustic(Bubbles); - } + apecss_interactions_instantaneous(Bubbles); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - // for (register int i = 0; i < nBubbles; i++) - // { - // printf(" %e", Bubbles[i]->get_pressure_infinity(tSim, Bubbles[i])); - // } - // printf(" %e", Bubbles[0]->get_pressure_infinity(Bubbles[0]->t, Bubbles[0])); - // printf(" %e", Bubbles[0]->ode[0](Bubbles[0]->ODEsSol, Bubbles[0]->t, Bubbles[0])); - // printf("\n"); // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // Retrieve data @@ -410,25 +254,6 @@ int main(int argc, char **args) } fprintf(file_ida2009, "\n"); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - // int index = 0; - // // APECSS_FLOAT derivative = (Bubbles[index]->Interaction->last_p_1 - Bubbles[index]->Interaction->last_p_2) / - // // (Bubbles[index]->Interaction->last_t_1 - Bubbles[index]->Interaction->last_t_2); - // printf("%e Bubble %d R %e U %e A %e t_1 %e t_2 %e inv_t %e p_1 %e p_2 %e diff_p %e derivative %e pinfty %e\n", tSim, index, Bubbles[index]->R, - // Bubbles[index]->U, Bubbles[index]->ode[0](Bubbles[index]->ODEsSol, Bubbles[index]->t, Bubbles[index]), Bubbles[index]->Interaction->last_t_1, - // Bubbles[index]->Interaction->last_t_2, 1 / (Bubbles[index]->Interaction->last_t_1 - Bubbles[index]->Interaction->last_t_2), - // Bubbles[index]->Interaction->last_p_1, Bubbles[index]->Interaction->last_p_2, - // (Bubbles[index]->Interaction->last_p_1 - Bubbles[index]->Interaction->last_p_2), - // Bubbles[index]->get_pressurederivative_infinity(tSim, Bubbles[index]), Bubbles[index]->get_pressure_infinity(tSim, Bubbles[index])); - - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; - Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; - - Bubbles[i]->Interaction->last_t_1 = tSim; - Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; - } } fclose(file_ida2009); @@ -489,15 +314,4 @@ APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, stru derivative = 0.5 * APECSS_PI * inv_T * APECSS_SIN(APECSS_PI * (t + T) * inv_T) * (Bubble->Excitation->dp - Bubble->p0); } return (derivative); - - APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; - if (delta_t > Bubble->dt) - { - APECSS_FLOAT inv_delta_t = 1 / delta_t; - return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) * inv_delta_t)); - } - else - { - return (derivative); - } } \ No newline at end of file diff --git a/examples/cavitationonset/NI/gather_results.py b/examples/cavitationonset/NI/gather_results.py index 2fad87b..9eaed77 100644 --- a/examples/cavitationonset/NI/gather_results.py +++ b/examples/cavitationonset/NI/gather_results.py @@ -9,15 +9,8 @@ count = int(lines[0].split(" ")[0]) png = float(lines[0].split(" ")[5]) cl_size = float(lines[0].split(" ")[7]) -cl_distrib = int(lines[0].split(" ")[9]) -if cl_distrib == 0 : - # Two bubbles of different size - file_name = "{}_{:.4E}_{:.2f}.txt".format(count, png, cl_size) - -else : - # Monodispersed system - file_name = "{}_{:.4E}.txt".format(count, png) +file_name = "{}_{:.4E}_{:.2f}.txt".format(count, png, cl_size) working_path = os.getcwd() results_path = os.path.join(working_path, "results") diff --git a/examples/cavitationonset/NI/src/cavitationonset_apecss.c b/examples/cavitationonset/NI/src/cavitationonset_apecss.c index 1f2b1e9..c9971b4 100644 --- a/examples/cavitationonset/NI/src/cavitationonset_apecss.c +++ b/examples/cavitationonset/NI/src/cavitationonset_apecss.c @@ -24,12 +24,6 @@ APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -// Declaration of the structure holding the interaction variables of each bubble -struct Interaction -{ - APECSS_FLOAT dp_neighbor; -}; - int main(int argc, char **args) { char OptionsDir[APECSS_STRINGLENGTH]; @@ -38,14 +32,14 @@ int main(int argc, char **args) // Interbubble time-step, defining the frequency with which the neighbor influence is updated APECSS_FLOAT dt_interbubble = 1.0e-8; + // Number of bubbles + const int nBubbles = 2; + // Initialize the simulation parameters given by the execution command - int nBubbles = 2; double tEnd = 0.0; double fa = 0.0; double pa = 0.0; - int cluster_distrib = 0; double cluster_size = 0; - int inttype = 0; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< apecss_infoscreen(); @@ -75,26 +69,11 @@ int main(int argc, char **args) sscanf(args[j + 1], "%le", &pa); j += 2; } - else if (strcmp("-nbb", args[j]) == 0) - { - sscanf(args[j + 1], "%d", &nBubbles); - j += 2; - } - else if (strcmp("-cldistrib", args[j]) == 0) - { - sscanf(args[j + 1], "%d", &cluster_distrib); - j += 2; - } else if (strcmp("-clsize", args[j]) == 0) { sscanf(args[j + 1], "%le", &cluster_size); j += 2; } - else if (strcmp("-inttype", args[j]) == 0) - { - sscanf(args[j + 1], "%d", &inttype); - j += 2; - } else if (strcmp("-dt_inter", args[j]) == 0) { sscanf(args[j + 1], "%le", &dt_interbubble); @@ -197,131 +176,17 @@ int main(int argc, char **args) } // Define the size of each bubble - if (cluster_distrib == 0) - { - // Two bubbles of different initial size interacting - Bubbles[0]->R0 = 2.0e-06; - Bubbles[1]->R0 = 20.0e-06; - } - else - { - // Monodispersed multibubble distributions - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->R0 = 20.0e-06; - } - } + Bubbles[0]->R0 = 2.0e-06; + Bubbles[1]->R0 = 20.0e-06; // Define center location for each bubble - if (cluster_distrib == 0) - { - // Two bubbles of different initial size interacting - Bubbles[0]->Interaction->location[0] = 0.0; - Bubbles[0]->Interaction->location[1] = 0.0; - Bubbles[0]->Interaction->location[2] = 0.0; - - Bubbles[1]->Interaction->location[0] = (APECSS_FLOAT) cluster_size * (Bubbles[0]->R0 + Bubbles[1]->R0); - Bubbles[1]->Interaction->location[1] = 0.0; - Bubbles[1]->Interaction->location[2] = 0.0; - } - else - { - // Monodispersed multibubble distributions - APECSS_FLOAT D = 400.0e-06; - if (nBubbles == 1) - { - // Single bubble - Bubbles[0]->Interaction->location[0] = 0.0; - Bubbles[0]->Interaction->location[1] = 0.0; - Bubbles[0]->Interaction->location[2] = 0.0; - } - else if (nBubbles == 2) - { - // Two bubbles - Bubbles[0]->Interaction->location[0] = 0.0; - Bubbles[0]->Interaction->location[1] = 0.0; - Bubbles[0]->Interaction->location[2] = 0.0; - - Bubbles[1]->Interaction->location[0] = D; - Bubbles[1]->Interaction->location[1] = 0.0; - Bubbles[1]->Interaction->location[2] = 0.0; - } - else if (nBubbles == 3) - { - // Regular triangle - Bubbles[0]->Interaction->location[0] = 0.0; - Bubbles[0]->Interaction->location[1] = 0.0; - Bubbles[0]->Interaction->location[2] = 0.0; - - Bubbles[1]->Interaction->location[0] = D; - Bubbles[1]->Interaction->location[1] = 0.0; - Bubbles[1]->Interaction->location[2] = 0.0; - - Bubbles[2]->Interaction->location[0] = 0.5 * D; - Bubbles[2]->Interaction->location[1] = D * APECSS_SIN(APECSS_ONETHIRD * APECSS_PI); - Bubbles[2]->Interaction->location[2] = 0.0; - } - else if (nBubbles == 4) - { - // Regular tetragon - Bubbles[0]->Interaction->location[0] = 0.0; - Bubbles[0]->Interaction->location[1] = 0.0; - Bubbles[0]->Interaction->location[2] = 0.0; - - Bubbles[1]->Interaction->location[0] = D; - Bubbles[1]->Interaction->location[1] = 0.0; - Bubbles[1]->Interaction->location[2] = 0.0; - - Bubbles[2]->Interaction->location[0] = 0.0; - Bubbles[2]->Interaction->location[1] = D; - Bubbles[2]->Interaction->location[2] = 0.0; - - Bubbles[3]->Interaction->location[0] = D; - Bubbles[3]->Interaction->location[1] = D; - Bubbles[3]->Interaction->location[2] = 0.0; - } - else if (nBubbles == 8) - { - // Regular hexaedron - Bubbles[0]->Interaction->location[0] = 0.0; - Bubbles[0]->Interaction->location[1] = 0.0; - Bubbles[0]->Interaction->location[2] = 0.0; - - Bubbles[1]->Interaction->location[0] = D; - Bubbles[1]->Interaction->location[1] = 0.0; - Bubbles[1]->Interaction->location[2] = 0.0; - - Bubbles[2]->Interaction->location[0] = 0.0; - Bubbles[2]->Interaction->location[1] = D; - Bubbles[2]->Interaction->location[2] = 0.0; - - Bubbles[3]->Interaction->location[0] = D; - Bubbles[3]->Interaction->location[1] = D; - Bubbles[3]->Interaction->location[2] = 0.0; - - Bubbles[4]->Interaction->location[0] = 0.0; - Bubbles[4]->Interaction->location[1] = 0.0; - Bubbles[4]->Interaction->location[2] = D; - - Bubbles[5]->Interaction->location[0] = D; - Bubbles[5]->Interaction->location[1] = 0.0; - Bubbles[5]->Interaction->location[2] = D; - - Bubbles[6]->Interaction->location[0] = 0.0; - Bubbles[6]->Interaction->location[1] = D; - Bubbles[6]->Interaction->location[2] = D; - - Bubbles[7]->Interaction->location[0] = D; - Bubbles[7]->Interaction->location[1] = D; - Bubbles[7]->Interaction->location[2] = D; - } - else - { - char str[APECSS_STRINGLENGTH_SPRINTF]; - sprintf(str, "Wrong number of bubbles as input for this specific cluster distribution (1, 2, 3, 4 or 8)"); - apecss_erroronscreen(1, str); - } - } + Bubbles[0]->Interaction->location[0] = 0.0; + Bubbles[0]->Interaction->location[1] = 0.0; + Bubbles[0]->Interaction->location[2] = 0.0; + + Bubbles[1]->Interaction->location[0] = (APECSS_FLOAT) cluster_size * (Bubbles[0]->R0 + Bubbles[1]->R0); + Bubbles[1]->Interaction->location[1] = 0.0; + Bubbles[1]->Interaction->location[2] = 0.0; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< clock_t starttimebubble = clock(); @@ -344,8 +209,7 @@ int main(int argc, char **args) // File to retrieve all valuable information for cavitation onset test case FILE *file_ida2009; file_ida2009 = fopen("Ida2009_results.txt", "w"); - fprintf(file_ida2009, "%d Bubbles p0(pa) %e png(Pa) %e D_multiplier(-) %e cl_distrib %d Interaction-type %d\n", nBubbles, Liquid->pref, pa, cluster_size, - cluster_distrib, inttype); + fprintf(file_ida2009, "%d Bubbles p0(pa) %e png(Pa) %e D_multiplier(-) %e Interaction-type %d\n", nBubbles, Liquid->pref, pa, cluster_size, 0); fprintf(file_ida2009, "Initial_radii(m)"); for (register int i = 0; i < nBubbles; i++) fprintf(file_ida2009, " %e", Bubbles[i]->R0); fprintf(file_ida2009, "\n"); @@ -360,18 +224,6 @@ int main(int argc, char **args) for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Update the contribution of the neighbor bubbles - if (inttype == 1) - { - apecss_interactions_instantaneous(Bubbles); - } - else if (inttype == 2) - { - apecss_interactions_quasi_acoustic(Bubbles); - } - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // Retrieve data fprintf(file_ida2009, "%e", tSim); @@ -385,15 +237,6 @@ int main(int argc, char **args) } fprintf(file_ida2009, "\n"); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; - Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; - - Bubbles[i]->Interaction->last_t_1 = tSim; - Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; - } } fclose(file_ida2009); @@ -454,15 +297,4 @@ APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, stru derivative = 0.5 * APECSS_PI * inv_T * APECSS_SIN(APECSS_PI * (t + T) * inv_T) * (Bubble->Excitation->dp - Bubble->p0); } return (derivative); - - // APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; - // if (delta_t > Bubble->dt) - // { - // APECSS_FLOAT inv_delta_t = 1 / delta_t; - // return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) * inv_delta_t)); - // } - // else - // { - // return (derivative); - // } } \ No newline at end of file diff --git a/examples/cavitationonset/QA/gather_results.py b/examples/cavitationonset/QA/gather_results.py index 2fad87b..9eaed77 100644 --- a/examples/cavitationonset/QA/gather_results.py +++ b/examples/cavitationonset/QA/gather_results.py @@ -9,15 +9,8 @@ count = int(lines[0].split(" ")[0]) png = float(lines[0].split(" ")[5]) cl_size = float(lines[0].split(" ")[7]) -cl_distrib = int(lines[0].split(" ")[9]) -if cl_distrib == 0 : - # Two bubbles of different size - file_name = "{}_{:.4E}_{:.2f}.txt".format(count, png, cl_size) - -else : - # Monodispersed system - file_name = "{}_{:.4E}.txt".format(count, png) +file_name = "{}_{:.4E}_{:.2f}.txt".format(count, png, cl_size) working_path = os.getcwd() results_path = os.path.join(working_path, "results") diff --git a/examples/cavitationonset/QA/src/cavitationonset_apecss.c b/examples/cavitationonset/QA/src/cavitationonset_apecss.c index 2d2bc77..a2bf36e 100644 --- a/examples/cavitationonset/QA/src/cavitationonset_apecss.c +++ b/examples/cavitationonset/QA/src/cavitationonset_apecss.c @@ -24,12 +24,6 @@ APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -// Declaration of the structure holding the interaction variables of each bubble -struct Interaction -{ - APECSS_FLOAT dp_neighbor; -}; - int main(int argc, char **args) { char OptionsDir[APECSS_STRINGLENGTH]; @@ -38,14 +32,14 @@ int main(int argc, char **args) // Interbubble time-step, defining the frequency with which the neighbor influence is updated APECSS_FLOAT dt_interbubble = 1.0e-8; + // Number of bubbles + const int nBubbles = 2; + // Initialize the simulation parameters given by the execution command - int nBubbles = 2; double tEnd = 0.0; double fa = 0.0; double pa = 0.0; - int cluster_distrib = 0; double cluster_size = 0; - int inttype = 0; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< apecss_infoscreen(); @@ -75,26 +69,11 @@ int main(int argc, char **args) sscanf(args[j + 1], "%le", &pa); j += 2; } - else if (strcmp("-nbb", args[j]) == 0) - { - sscanf(args[j + 1], "%d", &nBubbles); - j += 2; - } - else if (strcmp("-cldistrib", args[j]) == 0) - { - sscanf(args[j + 1], "%d", &cluster_distrib); - j += 2; - } else if (strcmp("-clsize", args[j]) == 0) { sscanf(args[j + 1], "%le", &cluster_size); j += 2; } - else if (strcmp("-inttype", args[j]) == 0) - { - sscanf(args[j + 1], "%d", &inttype); - j += 2; - } else if (strcmp("-dt_inter", args[j]) == 0) { sscanf(args[j + 1], "%le", &dt_interbubble); @@ -197,131 +176,17 @@ int main(int argc, char **args) } // Define the size of each bubble - if (cluster_distrib == 0) - { - // Two bubbles of different initial size interacting - Bubbles[0]->R0 = 2.0e-06; - Bubbles[1]->R0 = 20.0e-06; - } - else - { - // Monodispersed multibubble distributions - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->R0 = 20.0e-06; - } - } + Bubbles[0]->R0 = 2.0e-06; + Bubbles[1]->R0 = 20.0e-06; // Define center location for each bubble - if (cluster_distrib == 0) - { - // Two bubbles of different initial size interacting - Bubbles[0]->Interaction->location[0] = 0.0; - Bubbles[0]->Interaction->location[1] = 0.0; - Bubbles[0]->Interaction->location[2] = 0.0; - - Bubbles[1]->Interaction->location[0] = (APECSS_FLOAT) cluster_size * (Bubbles[0]->R0 + Bubbles[1]->R0); - Bubbles[1]->Interaction->location[1] = 0.0; - Bubbles[1]->Interaction->location[2] = 0.0; - } - else - { - // Monodispersed multibubble distributions - APECSS_FLOAT D = 400.0e-06; - if (nBubbles == 1) - { - // Single bubble - Bubbles[0]->Interaction->location[0] = 0.0; - Bubbles[0]->Interaction->location[1] = 0.0; - Bubbles[0]->Interaction->location[2] = 0.0; - } - else if (nBubbles == 2) - { - // Two bubbles - Bubbles[0]->Interaction->location[0] = 0.0; - Bubbles[0]->Interaction->location[1] = 0.0; - Bubbles[0]->Interaction->location[2] = 0.0; - - Bubbles[1]->Interaction->location[0] = D; - Bubbles[1]->Interaction->location[1] = 0.0; - Bubbles[1]->Interaction->location[2] = 0.0; - } - else if (nBubbles == 3) - { - // Regular triangle - Bubbles[0]->Interaction->location[0] = 0.0; - Bubbles[0]->Interaction->location[1] = 0.0; - Bubbles[0]->Interaction->location[2] = 0.0; - - Bubbles[1]->Interaction->location[0] = D; - Bubbles[1]->Interaction->location[1] = 0.0; - Bubbles[1]->Interaction->location[2] = 0.0; - - Bubbles[2]->Interaction->location[0] = 0.5 * D; - Bubbles[2]->Interaction->location[1] = D * APECSS_SIN(APECSS_ONETHIRD * APECSS_PI); - Bubbles[2]->Interaction->location[2] = 0.0; - } - else if (nBubbles == 4) - { - // Regular tetragon - Bubbles[0]->Interaction->location[0] = 0.0; - Bubbles[0]->Interaction->location[1] = 0.0; - Bubbles[0]->Interaction->location[2] = 0.0; - - Bubbles[1]->Interaction->location[0] = D; - Bubbles[1]->Interaction->location[1] = 0.0; - Bubbles[1]->Interaction->location[2] = 0.0; - - Bubbles[2]->Interaction->location[0] = 0.0; - Bubbles[2]->Interaction->location[1] = D; - Bubbles[2]->Interaction->location[2] = 0.0; - - Bubbles[3]->Interaction->location[0] = D; - Bubbles[3]->Interaction->location[1] = D; - Bubbles[3]->Interaction->location[2] = 0.0; - } - else if (nBubbles == 8) - { - // Regular hexaedron - Bubbles[0]->Interaction->location[0] = 0.0; - Bubbles[0]->Interaction->location[1] = 0.0; - Bubbles[0]->Interaction->location[2] = 0.0; - - Bubbles[1]->Interaction->location[0] = D; - Bubbles[1]->Interaction->location[1] = 0.0; - Bubbles[1]->Interaction->location[2] = 0.0; - - Bubbles[2]->Interaction->location[0] = 0.0; - Bubbles[2]->Interaction->location[1] = D; - Bubbles[2]->Interaction->location[2] = 0.0; - - Bubbles[3]->Interaction->location[0] = D; - Bubbles[3]->Interaction->location[1] = D; - Bubbles[3]->Interaction->location[2] = 0.0; - - Bubbles[4]->Interaction->location[0] = 0.0; - Bubbles[4]->Interaction->location[1] = 0.0; - Bubbles[4]->Interaction->location[2] = D; - - Bubbles[5]->Interaction->location[0] = D; - Bubbles[5]->Interaction->location[1] = 0.0; - Bubbles[5]->Interaction->location[2] = D; - - Bubbles[6]->Interaction->location[0] = 0.0; - Bubbles[6]->Interaction->location[1] = D; - Bubbles[6]->Interaction->location[2] = D; - - Bubbles[7]->Interaction->location[0] = D; - Bubbles[7]->Interaction->location[1] = D; - Bubbles[7]->Interaction->location[2] = D; - } - else - { - char str[APECSS_STRINGLENGTH_SPRINTF]; - sprintf(str, "Wrong number of bubbles as input for this specific cluster distribution (1, 2, 3, 4 or 8)"); - apecss_erroronscreen(1, str); - } - } + Bubbles[0]->Interaction->location[0] = 0.0; + Bubbles[0]->Interaction->location[1] = 0.0; + Bubbles[0]->Interaction->location[2] = 0.0; + + Bubbles[1]->Interaction->location[0] = (APECSS_FLOAT) cluster_size * (Bubbles[0]->R0 + Bubbles[1]->R0); + Bubbles[1]->Interaction->location[1] = 0.0; + Bubbles[1]->Interaction->location[2] = 0.0; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< clock_t starttimebubble = clock(); @@ -344,8 +209,7 @@ int main(int argc, char **args) // File to retrieve all valuable information for cavitation onset test case FILE *file_ida2009; file_ida2009 = fopen("Ida2009_results.txt", "w"); - fprintf(file_ida2009, "%d Bubbles p0(pa) %e png(Pa) %e D_multiplier(-) %e cl_distrib %d Interaction-type %d\n", nBubbles, Liquid->pref, pa, cluster_size, - cluster_distrib, inttype); + fprintf(file_ida2009, "%d Bubbles p0(pa) %e png(Pa) %e D_multiplier(-) %e Interaction-type %d\n", nBubbles, Liquid->pref, pa, cluster_size, 2); fprintf(file_ida2009, "Initial_radii(m)"); for (register int i = 0; i < nBubbles; i++) fprintf(file_ida2009, " %e", Bubbles[i]->R0); fprintf(file_ida2009, "\n"); @@ -362,14 +226,7 @@ int main(int argc, char **args) // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // Update the contribution of the neighbor bubbles - if (inttype == 1) - { - apecss_interactions_instantaneous(Bubbles); - } - else if (inttype == 2) - { - apecss_interactions_quasi_acoustic(Bubbles); - } + apecss_interactions_quasi_acoustic(Bubbles); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -465,7 +322,6 @@ APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, stru APECSS_FLOAT inv_T = 1 / T; derivative = 0.5 * APECSS_PI * inv_T * APECSS_SIN(APECSS_PI * (t + T) * inv_T) * (Bubble->Excitation->dp - Bubble->p0); } - // return (derivative); APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; if (delta_t > Bubble->dt) From 4dc2a03a468196d4329f70e13fcaad8094add1b4 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 20 Sep 2024 11:49:44 -0400 Subject: [PATCH 117/138] cavitationonset ; update of the plot python file to only keep the plots presented in the paper --- examples/cavitationonset/plot_results.py | 363 +---------------------- 1 file changed, 12 insertions(+), 351 deletions(-) diff --git a/examples/cavitationonset/plot_results.py b/examples/cavitationonset/plot_results.py index 452634c..0e9fc78 100644 --- a/examples/cavitationonset/plot_results.py +++ b/examples/cavitationonset/plot_results.py @@ -12,24 +12,20 @@ cm = 1/2.54 -# File designed to recover and copy/paste results to reproduce Ida's cavitation onset test case -# DOI : https://doi.org/10.1063/1.3265547 +# File designed to recover and plot results in order to study cavitation onset and collapse with the two interaction models +# This test case is inspired by https://doi.org/10.1063/1.3265547 ######### Step 1 : Recovering data ################################################################################################################## inttype_list = ["NI", "IC", "QA"] dic_2_bubbles = {} -dic_n_bubbles = {} working_path = os.getcwd() for inttype in inttype_list : if inttype not in list(dic_2_bubbles.keys()) : dic_2_bubbles[inttype] = {} - - if inttype not in list(dic_n_bubbles.keys()) : - dic_n_bubbles[inttype] = {} inttype_path = os.path.join(working_path, inttype) inttype_path = os.path.join(inttype_path, "results") @@ -44,21 +40,13 @@ count = int(first_line[0]) png = float(first_line[5]) size = float(first_line[7]) - cluster = float(first_line[9]) - - if cluster == 0 : - if png not in list(dic_2_bubbles[inttype].keys()) : - dic_2_bubbles[inttype][png] = {} - if size not in list(dic_2_bubbles[inttype][png].keys()) : - dic_2_bubbles[inttype][png][size] = [] - - dic_data = dic_2_bubbles[inttype][png][size] + + if png not in list(dic_2_bubbles[inttype].keys()) : + dic_2_bubbles[inttype][png] = {} + if size not in list(dic_2_bubbles[inttype][png].keys()) : + dic_2_bubbles[inttype][png][size] = [] - else : - if count not in list(dic_n_bubbles[inttype].keys()) : - dic_n_bubbles[inttype][count] = [] - - dic_data = dic_n_bubbles[inttype][count] + dic_data = dic_2_bubbles[inttype][png][size] second_line = lines[1].split(" ") for i in range(count) : @@ -87,95 +75,13 @@ dic_data[i][5].append(dp) dic_data[i][6].append(u) -######### Functions ############################################################################### - -def identify_end_time_index(inttype, png, dist) : - # identify in the 2 bubbles case the time at which the bubbles are touching (the spherical assumption becomes unrelevant) - data = dic_2_bubbles[inttype][png][dist] - - index = 0 - while index < len(data[0][1]) and data[0][2][index] + data[1][2][index] < dist * (data[0][2][0] + data[1][2][0]) : - index += 1 - - return index - ######### Step 2 : Plotting results ################################################################################################################# ######### Initial parameters #################### T = 10.0e-06 P0 = 0.1013e06 -rho = 1000.0 sigma = 0.0728 -mu = 1.002e-3 - -######### Pressure time history & radius evolution without interaction ############################ - -nrow = 1 -ncol = 2 - -fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm))) -plt.subplots_adjust(wspace=0.5*cm, hspace=0.5*cm) - -axs[0].set_title("Pressure time history (" + r"$T$ = " + "{:.1f} ".format(T*1.0e06) + r"$\mu$s)") -axs[0].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) -axs[0].set_xlim(xmin=0.0, xmax=60.0) -axs[0].set_ylabel(r"$p_{\infty}$/$p_{0}$", fontsize=27.5) -axs[0].grid() - -t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][1]) * 1.0e6 -p_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][3]) / P0 -axs[0].plot(t_list, p_list, color="black", linewidth=2.5) - -axs[1].set_title("Evolution of radius without interaction") -axs[1].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) -axs[1].set_xlim(xmin=0.0, xmax=60.0) -axs[1].set_ylabel(r"$R$ [$\mu$m]", fontsize=27.5) -axs[1].grid() - -index_t = identify_end_time_index("NI", -25325, 15.0) - -t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][1])[:index_t] * 1.0e6 -r_list = np.array(dic_2_bubbles["NI"][-25325][15.0][0][2])[:index_t] * 1.0e6 -axs[1].plot(t_list, r_list, color="blue", label=r"$R_{1,0}$ = 2.0 $\mu$m", linewidth=2.5) - -t_list = np.array(dic_2_bubbles["NI"][-25325][15.0][1][1])[:index_t] * 1.0e6 -r_list = np.array(dic_2_bubbles["NI"][-25325][15.0][1][2])[:index_t] * 1.0e6 -axs[1].plot(t_list, r_list, color="magenta", linestyle="dashed", label=r"$R_{2,0}$ = 20.0 $\mu$m", linewidth=2.5) - -axs[1].legend(loc="upper left", frameon=False) - -fig.savefig("cavitationonset_pressurehistory_radiusevolutionNI.pdf", bbox_inches='tight',pad_inches=0.35) - -######### Cavitation inception for one single bubble ############################################## - -nrow = 1 -ncol = 1 - -fig, ax = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm))) -plt.subplots_adjust(wspace=0.5*cm, hspace=0.5*cm) - -png_list = [-17221, -17725.5, -18353.2, -18770.3] - -ax.set_title("Cavitation inception of a single bubble \n depending on " + r"$p_{\mathrm{ng}}$/$p_{0}$ ($R_{0}$ = 2 $\mu$m)") -ax.set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) -ax.set_xlim(xmin=10.0, xmax=60.0) -ax.set_ylabel(r"$R$ [$\mu$m]", fontsize=27.5) -ax.set_ylim(ymin=0.0, ymax=14.0) -ax.grid() - -for png in png_list : - t_list = np.array(dic_2_bubbles["NI"][png][15.0][0][1]) * 1.0e6 - r_list = np.array(dic_2_bubbles["NI"][png][15.0][0][2]) * 1.0e6 - - ax.plot(t_list, r_list, color="blue", linewidth=2.5) - -ax.text(25.0, 3.00, r"$-0.17$") -ax.text(31.0, 6.25, r"$-0.175$") -ax.text(28.0, 9.00, r"$-0.176$") -ax.text(21.0, 13.0, r"$-0.18$") - -fig.savefig("cavitationonset_singlebubble.pdf", bbox_inches='tight',pad_inches=0.35) ######### Cavitation inception with interactions with varying distance between 2 bubbles ########## @@ -224,7 +130,6 @@ def identify_end_time_index(inttype, png, dist) : axs[1].set_title(r"Quasi-acoustic interactions", y=1.025) axs[1].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) axs[1].set_xlim(xmin=0.0, xmax=60.0) -# axs[1].set_ylabel(r"$R$ [$\mu$m]") axs[1].set_ylim(ymin=-5.0, ymax=80.0) axs[1].grid() @@ -277,12 +182,6 @@ def identify_end_time_index(inttype, png, dist) : axs[0].plot(t_list, r_list, color="blue", linewidth=2.5) -# index_t = identify_end_time_index("IC", -27958.8, 10.0) -# t_list = np.array(dic_2_bubbles["IC"][-27958.8][10.0][1][1])[:index_t] * 1.0e6 -# r_list = np.array(dic_2_bubbles["IC"][-27958.8][10.0][1][2])[:index_t] * 1.0e6 - -# axs[0].plot(t_list, r_list, color="magenta", linewidth=2.5, linestyle="dashed") - axs[0].text(0.5, 3.0, r"$R_{1,0}$", color="blue") axs[0].text(32.0, 37.5, r"-0.29", color="blue") @@ -296,7 +195,6 @@ def identify_end_time_index(inttype, png, dist) : axs[1].set_title(r"Quasi-acoustic interactions", y=1.025) axs[1].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) axs[1].set_xlim(xmin=0.0, xmax=60.0) -# axs[1].set_ylabel(r"$R$ [$\mu$m]") axs[1].set_ylim(ymin=0.0, ymax=40.0) axs[1].grid() @@ -316,7 +214,7 @@ def identify_end_time_index(inttype, png, dist) : fig.savefig("cavitationonset_varyingpressure.pdf", bbox_inches='tight',pad_inches=0.35) -##### Pressure evolution ###### +##### Pressure differences between the two interactions models evolution ###### nrow = 2 ncol = 1 @@ -381,91 +279,7 @@ def identify_end_time_index(inttype, png, dist) : fig.savefig("cavitationonset_pressuredifferences.pdf", bbox_inches='tight',pad_inches=0.35) -#### Test ##### - -nrow = 6 -ncol = 1 - -fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm)), sharex=True) -plt.subplots_adjust(wspace=0.35*cm, hspace=0.25*cm) - -png_list = [-27654.9] - -axs[0].set_ylabel(r"$R / R_{0}$") -axs[1].set_ylabel(r"$p_{\infty} / p_{0}$") -axs[2].set_ylabel(r"$\rho R^{2} \ddot{R} / \Delta x_{12} p_{0}$") -axs[3].set_ylabel(r"$2 \rho \dot{R}^{2} R / \Delta x_{12} p_{0}$") -axs[4].set_ylabel(r"$\rho R^{4} \dot{R}^{2} / 2 \Delta x_{12}^{4} p_{0}$") -axs[5].set_ylabel(r"$\Delta p / p_{0}$") -axs[5].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) - -# axs[2].set_yscale("log") - -for i in range(nrow) : - axs[i].grid() - axs[i].set_xlim(xmin=55.0, xmax=60.0) - -axs[1].set_ylim(ymin=-0.4, ymax=0.15) - -for png in png_list : - dist = 10.0 - delta_x = dist * (dic_2_bubbles["IC"][png][dist][0][0] + dic_2_bubbles["IC"][png][dist][1][0]) - # first bubble - r0 = dic_2_bubbles["IC"][png][dist][0][0] - - t_list = np.array(dic_2_bubbles["IC"][png][dist][0][1]) * 1.0e6 - r_list = np.array(dic_2_bubbles["IC"][png][dist][0][2]) / r0 - p_list = np.array(dic_2_bubbles["IC"][png][dist][0][3]) / P0 - a_list = np.array(dic_2_bubbles["IC"][png][dist][0][4]) - dp_list = np.array(dic_2_bubbles["IC"][png][dist][0][5]) / P0 - u_list = np.array(dic_2_bubbles["IC"][png][dist][0][6]) - - t_collapse = t_list[dic_2_bubbles["IC"][png][dist][0][2].index(np.min(dic_2_bubbles["IC"][png][dist][0][2]))] - - dp_bis_list = rho * np.multiply(np.multiply(r_list * r0, r_list * r0), a_list) / (delta_x * P0) - dp_bis_bis_list = 2 * rho * np.multiply(np.multiply(u_list, u_list), r_list * r0) / (delta_x * P0) - - r_4_list = np.multiply(np.multiply(r_list * r0, r_list * r0), np.multiply(r_list * r0, r_list * r0)) - dp_bis_bis_bis_list = rho * np.multiply(r_4_list, np.multiply(u_list, u_list)) / (2 * (delta_x**4) * P0) - - axs[0].plot(t_list, r_list, linewidth=2.5, linestyle="solid", color="blue", label=r"$R_{0} = 2.0 \ \mu\mathrm{m}$") - axs[1].plot(t_list, p_list, linewidth=2.5, linestyle="solid", color="blue") - axs[2].plot(t_list, dp_bis_list, linewidth=2.5, linestyle="solid", color="blue") - axs[3].plot(t_list, dp_bis_bis_list, linewidth=2.5, linestyle="solid", color="blue") - axs[4].plot(t_list, dp_bis_bis_bis_list, linewidth=2.5, linestyle="solid", color="blue") - axs[5].plot(t_list, dp_list, linewidth=2.5, linestyle="solid", color="blue") - - # second bubbles - r0 = dic_2_bubbles["IC"][png][dist][1][0] - t_list = np.array(dic_2_bubbles["IC"][png][dist][1][1]) * 1.0e6 - r_list = np.array(dic_2_bubbles["IC"][png][dist][1][2]) / r0 - p_list = np.array(dic_2_bubbles["IC"][png][dist][1][3]) / P0 - a_list = np.array(dic_2_bubbles["IC"][png][dist][1][4]) - dp_list = np.array(dic_2_bubbles["IC"][png][dist][1][5]) / P0 - u_list = np.array(dic_2_bubbles["IC"][png][dist][1][6]) - - dp_bis_list = rho * np.multiply(np.multiply(r_list * r0, r_list * r0), a_list) / (delta_x * P0) - dp_bis_bis_list = 2 * rho * np.multiply(np.multiply(u_list, u_list), r_list * r0) / (delta_x * P0) - - r_4_list = np.multiply(np.multiply(r_list * r0, r_list * r0), np.multiply(r_list * r0, r_list * r0)) - dp_bis_bis_bis_list = rho * np.multiply(r_4_list, np.multiply(u_list, u_list)) / (2 * (delta_x**4) * P0) - - axs[0].plot(t_list, r_list, linewidth=2.5, linestyle="dashed", color="magenta", label=r"$R_{0} = 20.0 \ \mu\mathrm{m}$") - axs[1].plot(t_list, p_list, linewidth=2.5, linestyle="dashed", color="magenta") - axs[2].plot(t_list, dp_bis_list, linewidth=2.5, linestyle="dashed", color="magenta") - axs[3].plot(t_list, dp_bis_bis_list, linewidth=2.5, linestyle="dashed", color="magenta") - axs[4].plot(t_list, dp_bis_bis_bis_list, linewidth=2.5, linestyle="dashed", color="magenta") - axs[5].plot(t_list, dp_list, linewidth=2.5, linestyle="dashed", color="magenta") - - axs[5].plot(t_list, dp_bis_list + dp_bis_bis_list - dp_bis_bis_bis_list, linewidth=2.0, linestyle="dotted", color="red") - - axs[0].legend(bbox_to_anchor=(0.5, 1.05), loc="center", ncol=2, frameon=False) - axs[5].set_xticks([55.0, t_collapse, 60.0]) - axs[5].set_xticklabels([55.0, r"$t_{\mathrm{collapse}}$", 60.0]) - -fig.savefig("cavitationonset_varyingpressure_pressure_understanding.pdf", bbox_inches='tight',pad_inches=0.35) - -#### Test bis #### +#### Ambient pressure during collapse evolution #### png = -27351 dist = 10.0 @@ -476,7 +290,6 @@ def identify_end_time_index(inttype, png, dist) : fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*18.75*cm, nrow*9.375*cm)), sharex=True) plt.subplots_adjust(wspace=0.45*cm, hspace=0.25*cm) -# fig.suptitle(r"$p_{\mathrm{ng}}/p_{0}=$" + "{:.3f}, ".format(png/P0) + r"$\Delta x_{12}=$" + "{:.1f}".format(dist) + r"($R_{1,0} + R_{2,0}$)") axs[0, 0].set_title("Incompressible interactions", y=1.025) axs[0, 1].set_title("Quasi-acoustic interactions", y=1.025) @@ -503,8 +316,6 @@ def identify_end_time_index(inttype, png, dist) : p_list = np.array(dic_2_bubbles["IC"][png][dist][0][3]) / P0 dp_list = dic_2_bubbles["IC"][png][dist][0][5] -t_deltap_min_IC = t_list[dp_list.index(np.min(dp_list[int(33.5e2):int(35e2)]))] - axs[0, 0].plot(t_list, r_list, color="blue", linewidth=2.5, label=r"$R_{0}=2.0$ $\mu$m") axs[nrow - 1, 0].plot(t_list, p_list, color="blue", linewidth=2.5) @@ -514,8 +325,6 @@ def identify_end_time_index(inttype, png, dist) : p_list = np.array(dic_2_bubbles["IC"][png][dist][1][3]) / P0 dp_list = dic_2_bubbles["IC"][png][dist][1][5] -t_delta_max_IC = t_list[dp_list.index(np.max(dp_list[int(33.5e2):int(35e2)]))] - axs[0, 0].plot(t_list, r_list, color="magenta", linestyle="dashed", linewidth=2.5, label=r"$R_{0}=20.0$ $\mu$m") axs[nrow - 1, 0].plot(t_list, p_list, color="magenta", linestyle="dashed", linewidth=2.5) @@ -526,8 +335,6 @@ def identify_end_time_index(inttype, png, dist) : p_list = np.array(dic_2_bubbles["QA"][png][dist][0][3]) / P0 dp_list = dic_2_bubbles["QA"][png][dist][0][5] -t_deltap_min_QA = t_list[dp_list.index(np.min(dp_list[int(35e3):int(40e3)]))] - axs[0, 1].plot(t_list, r_list, color="blue", linewidth=2.5) axs[nrow - 1, 1].plot(t_list, p_list, color="blue", linewidth=2.5) @@ -537,75 +344,14 @@ def identify_end_time_index(inttype, png, dist) : p_list = np.array(dic_2_bubbles["QA"][png][dist][1][3]) / P0 dp_list = dic_2_bubbles["QA"][png][dist][1][5] -t_delta_max_QA = t_list[dp_list.index(np.max(dp_list[int(35e3):int(40e3)]))] - axs[0, 1].plot(t_list, r_list, color="magenta", linestyle="dashed", linewidth=2.5) axs[nrow - 1, 1].plot(t_list, p_list, color="magenta", linestyle="dashed", linewidth=2.5) axs[0, 0].legend(bbox_to_anchor=(1.05, 1.05), loc="lower center", ncol=2, frameon=False, fontsize=27.5) -fig.savefig("cavitationonset_varyingpressure_pressure_understanding_bis.pdf", bbox_inches='tight',pad_inches=0.35) - -print("For IC computations, respectively time for max dp for bubble 2 and min dp for bubble 1 : {:.5E}, {:.5E}".format(t_delta_max_IC, t_deltap_min_IC)) -print("For QA computations, respectively time for max dp for bubble 2 and min dp for bubble 1 : {:.5E}, {:.5E}".format(t_delta_max_QA, t_deltap_min_QA)) +fig.savefig("cavitationonset_collapse.pdf", bbox_inches='tight',pad_inches=0.35) #### Unstable radius #### -png = -25325 -dist = 12.0 - -nrow = 1 -ncol = 2 - -fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm)), sharey=True, sharex=True) -plt.subplots_adjust(wspace=0.15*cm, hspace=0.5*cm) - -axs[0].set_title(r"Incompressible interactions", y=1.025) -axs[0].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) -axs[0].set_xlim(xmin=0.0, xmax=60.0) -axs[0].set_ylabel(r"$R$ [$\mu$m]", fontsize=27.5) -axs[0].set_ylim(ymin=0.0, ymax=40.0) -axs[0].grid() - -axs[1].set_title(r"Quasi-acoustic interactions", y=1.025) -axs[1].grid() - -# IC -t_list = np.array(dic_2_bubbles["IC"][png][dist][0][1]) -r_list = np.array(dic_2_bubbles["IC"][png][dist][0][2]) -p_list = np.array(dic_2_bubbles["IC"][png][dist][0][3]) - -R0 = r_list[0] -pG0 = P0 + (2 * sigma / R0) - -r_unstable_list = [] -for i in range(len(t_list)) : - p = np.polynomial.Polynomial([-pG0 * (R0**3), 0, 2 * sigma, p_list[i]]) - roots = p.roots() - r_unstable_list.append(float(np.real(roots[-1]))) - -axs[0].plot(t_list*1e6, r_list*1e6, color="blue", linewidth=2.5, label=r"$R_{1}$") -axs[0].plot(t_list*1e6, np.array(r_unstable_list)*1e6, linestyle="solid", color="red", marker="o", markevery=500, linewidth=2, label=r"$R_{\mathrm{Ue}}$") -axs[0].legend(loc="upper left", frameon=False) - -# QA -t_list = np.array(dic_2_bubbles["QA"][png][dist][0][1]) -r_list = np.array(dic_2_bubbles["QA"][png][dist][0][2]) -p_list = np.array(dic_2_bubbles["QA"][png][dist][0][3]) - -R0 = r_list[0] -pG0 = P0 + (2 * sigma / R0) - -r_unstable_list = [] -for i in range(len(t_list)) : - p = np.polynomial.Polynomial([-pG0 * (R0**3), 0, 2 * sigma, p_list[i]]) - roots = p.roots() - r_unstable_list.append(float(np.real(roots[-1]))) - -axs[1].plot(t_list*1e6, r_list*1e6, color="blue", linewidth=2.5) -axs[1].plot(t_list*1e6, np.array(r_unstable_list)*1e6, linestyle="solid", color="red", marker="o", markevery=5000, linewidth=2) - -fig.savefig("cavitationonset_varyingpressure_unstableradius.pdf", bbox_inches='tight',pad_inches=0.35) - nrow = 2 ncol = 2 @@ -678,89 +424,4 @@ def identify_end_time_index(inttype, png, dist) : axs[l, 1].plot(t_list*1e6, np.array(r_unstable_list)*1e6, linestyle="solid", color="red", marker="o", markevery=5000, linewidth=2.5) axs[0, 0].legend(bbox_to_anchor=(1.05, 1.05), loc="lower center", ncol=2, frameon=False, fontsize=27.5) -fig.savefig("cavitationonset_unstableradius.pdf", bbox_inches='tight',pad_inches=0.35) - -######### Cavitation inception with monodispersed simple distributions ############################ - -nrow = 2 -ncol = 2 - -fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm)), sharex=True) -plt.subplots_adjust(wspace=0.35*cm, hspace=0.25*cm) - -dic_color = {1 : "black", 2 : "red", 3 : "magenta", 4 : "blue", 8 : "green"} -nbubble_list = [1, 2, 3, 4, 8] -dic_shape = {1 : "single bubble", 2 : "2 bubbles", 3 : "3 bubbles (regular triangle)", 4 : "4 bubbles (regular tetrahedron)", 8 : "8 bubbles (regular hexaedron)"} -dic_linestyle = {1 : "solid", 2 : "dashed", 3 : "-.", 4 : "dotted", 8 : "dashdot"} -dic_marker = {1 : "*", 2 : "s", 3 : "X", 4 : "^", 8 : "D"} - -for i in range(2) : - for j in range(2) : - axs[i, j].grid() - axs[i, j].set_xlim(xmin=10.0, xmax=60.0) - -axs[0, 0].set_title(r"Incompressible interactions", y=1.025) -axs[0, 1].set_title(r"Quasi-acoustic interactions", y=1.025) - -axs[1, 0].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) -axs[1, 1].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) -# axs[0, 0].set_ylim(ymin=10.0, ymax=40.0) -# axs[0, 1].set_ylim(ymin=10.0, ymax=40.0) - -axs[0, 0].set_ylabel(r"$R$ [$\mu$m]", fontsize=27.5) -axs[1, 0].set_ylabel(r"$p_{\infty}$/$p_{0}$", fontsize=27.5) -axs[1, 0].set_ylim(ymin=-0.255, ymax=0.0) -axs[1, 1].set_ylim(ymin=-0.255, ymax=0.0) - -for nbubble in nbubble_list : - t_list = np.array(dic_n_bubbles["IC"][nbubble][0][1]) * 1.0e6 - r_list = np.array(dic_n_bubbles["IC"][nbubble][0][2]) * 1.0e6 - p_list = np.array(dic_n_bubbles["IC"][nbubble][0][3]) / P0 - - axs[0, 0].plot(t_list, r_list, color=dic_color[nbubble], label=dic_shape[nbubble], marker=dic_marker[nbubble], markevery=600, markersize=10.0, linewidth=2.5) - axs[1, 0].plot(t_list, p_list, color=dic_color[nbubble], marker=dic_marker[nbubble], markevery=600, markersize=10.0, linewidth=2.5) - - t_list = np.array(dic_n_bubbles["QA"][nbubble][0][1]) * 1.0e6 - r_list = np.array(dic_n_bubbles["QA"][nbubble][0][2]) * 1.0e6 - p_list = np.array(dic_n_bubbles["QA"][nbubble][0][3]) / P0 - - axs[0, 1].plot(t_list, r_list, color=dic_color[nbubble], marker=dic_marker[nbubble], markevery=600, markersize=10.0, linewidth=2.5) - axs[1, 1].plot(t_list, p_list, color=dic_color[nbubble], marker=dic_marker[nbubble], markevery=600, markersize=12.5, linewidth=2.5) - -axs[0, 0].legend(bbox_to_anchor=(1.1, 1.05), loc="lower center", ncol=2, frameon=False) - -fig.savefig("cavitationonset_monodispersedclusters.pdf", bbox_inches='tight',pad_inches=0.35) - -######### Exhibiting differences ################################################################## - -nrow = 1 -ncol = 2 - -fig, axs = plt.subplots(nrow, ncol, figsize=((ncol*20*cm, nrow*12.5*cm)), sharex=True) -plt.subplots_adjust(wspace=0.85*cm, hspace=0.25*cm) - -for i in range(2) : - axs[i].grid() - axs[i].set_xlim(xmin=10.0, xmax=60.0) - -axs[0].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) -axs[1].set_xlabel(r"$t$ [$\mu$s]", fontsize=27.5) - -axs[0].set_ylabel(r"$R_{\mathrm{QA}} - R_{\mathrm{IC}}$ [$\mu$m]", fontsize=27.5) -axs[1].set_ylabel(r"$(p_{\infty, \mathrm{QA}} - p_{\infty, \mathrm{IC}})$/$p_{0}$", fontsize=27.5) - -for nbubble in nbubble_list : - t_list_IC = np.array(dic_n_bubbles["IC"][nbubble][0][1]) * 1.0e6 - r_list_IC = np.array(dic_n_bubbles["IC"][nbubble][0][2]) * 1.0e6 - p_list_IC = np.array(dic_n_bubbles["IC"][nbubble][0][3]) / P0 - - t_list_QA = np.array(dic_n_bubbles["QA"][nbubble][0][1]) * 1.0e6 - r_list_QA = np.array(dic_n_bubbles["QA"][nbubble][0][2]) * 1.0e6 - p_list_QA = np.array(dic_n_bubbles["QA"][nbubble][0][3]) / P0 - - axs[0].plot(t_list_IC, r_list_QA - r_list_IC, color=dic_color[nbubble], label=dic_shape[nbubble], marker=dic_marker[nbubble], markevery=600, markersize=10.0, linewidth=2.5) - axs[1].plot(t_list_IC, p_list_QA - p_list_IC, color=dic_color[nbubble], marker=dic_marker[nbubble], markevery=600, markersize=10.0, linewidth=2.5) - -axs[0].legend(bbox_to_anchor=(1.1, 0.95), loc="lower center", ncol=2, frameon=False) - -fig.savefig("cavitationonset_monodispersedclusters_differences.pdf", bbox_inches='tight',pad_inches=0.35) \ No newline at end of file +fig.savefig("cavitationonset_unstableradius.pdf", bbox_inches='tight',pad_inches=0.35) \ No newline at end of file From 79e81a22c1aa181cb71ee741395f03abf2e84a91 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 20 Sep 2024 11:50:59 -0400 Subject: [PATCH 118/138] cavitationonset ; update of run .sh file to only keep the computations whose results are presented in the paper --- .../cavitationonset/run_cavitationonset.sh | 52 +++---------------- 1 file changed, 6 insertions(+), 46 deletions(-) diff --git a/examples/cavitationonset/run_cavitationonset.sh b/examples/cavitationonset/run_cavitationonset.sh index 473c3d1..64cab53 100755 --- a/examples/cavitationonset/run_cavitationonset.sh +++ b/examples/cavitationonset/run_cavitationonset.sh @@ -1,19 +1,3 @@ -######### Test case ################################################################################################################################# - -# cd IC/build -# ./compile.sh -# cd .. -# nbubble=8 -# png=-25325 -# ./build/cavitationonset_apecss -options run.apecss -amp $png -tend 60.0e-6 -nbb $nbubble -cldistrib 1 -clsize 10 -inttype 1 -# python3 plot_temp.py -# for ((c=0; c<$nbubble; c++)) -# do -# rm -rf Bubble_$c -# done - -# cd .. - ######### No Interaction computations ############################################################################################################### cd NI/build @@ -21,17 +5,9 @@ cd NI/build cd .. ######### Pressure time history & Radius evolution without interaction ############################ -./build/cavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-6 -nbb 2 -cldistrib 0 -clsize 15 -inttype 0 +./build/cavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-6 -clsize 15 python3 gather_results.py -######### Cavitation inception pressure treshold for one single bubble ############################ -png_list=(-17221 -17725.5 -18353.2 -18770.3) -for png in "${png_list[@]}" -do - ./build/cavitationonset_apecss -options run.apecss -amp $png -tend 60.0e-6 -nbb 2 -cldistrib 0 -clsize 15 -inttype 0 - python3 gather_results.py -done - cd .. echo "" @@ -48,7 +24,7 @@ cd .. dist_list=(10 11 12 12.05 12.1 12.5 15 20) for d in "${dist_list[@]}" do - ./build/cavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-6 -nbb 2 -cldistrib 0 -clsize $d -inttype 1 + ./build/cavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-6 -clsize $d python3 gather_results.py done @@ -56,15 +32,7 @@ done png_list=(-25325 -27351 -27654.9 -27958.8 -29377) for png in "${png_list[@]}" do - ./build/cavitationonset_apecss -options run.apecss -amp $png -tend 60.0e-6 -nbb 2 -cldistrib 0 -clsize 10 -inttype 1 - python3 gather_results.py -done - -######### Cavitation inception with monodispersed simple distributions ############################ -nbubble_list=(1 2 3 4 8) -for nbubble in "${nbubble_list[@]}" -do - ./build/cavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-6 -nbb $nbubble -cldistrib 1 -clsize 10 -inttype 1 + ./build/cavitationonset_apecss -options run.apecss -amp $png -tend 60.0e-6 -clsize 10 python3 gather_results.py done @@ -84,23 +52,15 @@ cd .. dist_list=(10 11.9 12 15 20) for d in "${dist_list[@]}" do - ./build/cavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-6 -nbb 2 -cldistrib 0 -clsize $d -inttype 2 -dt_inter 1.0e-09 + ./build/cavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-6 -clsize $d -dt_inter 1.0e-09 python3 gather_results.py done ######### Cavitation inception with interactions with varying pressure between 2 bubbles ########## -png_list=(-25325 -27351 -27958.8 -27654.9 -29377) +png_list=(-25325 -27351 -27654.9 -27958.8 -29377) for png in "${png_list[@]}" do - ./build/cavitationonset_apecss -options run.apecss -amp $png -tend 60.0e-6 -nbb 2 -cldistrib 0 -clsize 10 -inttype 2 -dt_inter 1.0e-09 - python3 gather_results.py -done - -######### Cavitation inception with monodispersed simple distributions ############################ -nbubble_list=(1 2 3 4 8) -for nbubble in "${nbubble_list[@]}" -do - ./build/cavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-6 -nbb $nbubble -cldistrib 1 -clsize 10 -inttype 2 + ./build/cavitationonset_apecss -options run.apecss -amp $png -tend 60.0e-6 -clsize 10 -dt_inter 1.0e-09 python3 gather_results.py done From 69c6329b7795be4e6566c0df6563781697809cc5 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 20 Sep 2024 15:10:38 -0400 Subject: [PATCH 119/138] sphericalclusertensionwave ; cleaninf the computation files for each interaction type --- .../IC/gather_results.py | 23 ++----- .../src/sphericalclustertensionwave_apecss.c | 52 +--------------- .../NI/gather_results.py | 23 ++----- .../src/sphericalclustertensionwave_apecss.c | 52 +--------------- .../QA/gather_results.py | 19 ++---- .../src/sphericalclustertensionwave_apecss.c | 61 ++----------------- 6 files changed, 23 insertions(+), 207 deletions(-) diff --git a/examples/sphericalclustertensionwave/IC/gather_results.py b/examples/sphericalclustertensionwave/IC/gather_results.py index 92ecd08..61f7914 100644 --- a/examples/sphericalclustertensionwave/IC/gather_results.py +++ b/examples/sphericalclustertensionwave/IC/gather_results.py @@ -8,24 +8,15 @@ count = int(lines[0].split(" ")[0]) p1 = float(lines[0].split(" ")[5]) -cl_distrib = int(lines[0].split(" ")[7]) -if cl_distrib == 0 : - # monodispersed spherical cluster - file_name = "mono_{}_{:.4E}.txt".format(count, p1) - -else : - # polydispersed spherical cluster - file_name = "poly_{}_{:.4E}.txt".format(count, p1) +file_name = "mono_{}_{:.4E}.txt".format(count, p1) working_path = os.getcwd() results_path = os.path.join(working_path, "results") +if not os.path.exists(results_path) : + os.makedirs(results_path) file_results = open(os.path.join(results_path, file_name), "w") -# for line in lines : -# if "nan" not in line : -# file_results.write(line) - index = 0 while index < len(lines) and "nan" not in lines[index] : file_results.write(lines[index]) @@ -37,13 +28,7 @@ lines_loc = file_loc.readlines() file_loc.close() -if cl_distrib == 0 : - # monodispersed spherical cluster - file_name_loc = "mono_{}_{:.4E}_loc.txt".format(count, p1) - -else : - # polydispersed spherical cluster - file_name_loc = "poly_{}_{:.4E}_loc.txt".format(count, p1) +file_name_loc = "mono_{}_{:.4E}_loc.txt".format(count, p1) file_loc_results = open(os.path.join(results_path, file_name_loc), "w") diff --git a/examples/sphericalclustertensionwave/IC/src/sphericalclustertensionwave_apecss.c b/examples/sphericalclustertensionwave/IC/src/sphericalclustertensionwave_apecss.c index ffe6ef1..fbe0daf 100644 --- a/examples/sphericalclustertensionwave/IC/src/sphericalclustertensionwave_apecss.c +++ b/examples/sphericalclustertensionwave/IC/src/sphericalclustertensionwave_apecss.c @@ -28,28 +28,10 @@ APECSS_FLOAT rand_range(double min, double max) return (APECSS_FLOAT) number; } -APECSS_FLOAT normal_distribution(double mu, double sigma) -{ - // Generating a normal distribution using Box-Muller transform, with mu as mean and sigma**2 as variance - double u1 = (drand48()); - while (u1 == 0.0) u1 = (drand48()); - double u2 = (drand48()); - - double mag = sigma * APECSS_SQRT(-2.0 * APECSS_LOG(u1)); - double z1 = mag * APECSS_COS(2 * APECSS_PI * u2) + mu; - return (APECSS_FLOAT) z1; -} - // Declaration of additional case-dependent functions APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -// Declaration of the structure holding the interaction variables of each bubble -struct Interaction -{ - APECSS_FLOAT dp_neighbor; -}; - int main(int argc, char **args) { char OptionsDir[APECSS_STRINGLENGTH]; @@ -67,7 +49,6 @@ int main(int argc, char **args) double tEnd = 0.0; double fa = 0.0; double pa = 0.0; - int cluster_distrib = 0; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< apecss_infoscreen(); @@ -97,11 +78,6 @@ int main(int argc, char **args) sscanf(args[j + 1], "%le", &pa); j += 2; } - else if (strcmp("-cldistrib", args[j]) == 0) - { - sscanf(args[j + 1], "%d", &cluster_distrib); - j += 2; - } else if (strcmp("-h", args[j]) == 0) { apecss_helpscreen(); @@ -198,31 +174,9 @@ int main(int argc, char **args) } // Define the size of each bubble - if (cluster_distrib == 0) - { - // Monodispersed cluster - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->R0 = 2.0e-6; - } - } - else + for (register int i = 0; i < nBubbles; i++) { - // Polydispersed cluster (radii distribution is following a log normal law) - double mu = 0.0; - double sigma = 0.7; - APECSS_FLOAT radius_ref = 2.0e-6; - for (register int i = 0; i < nBubbles; i++) - { - APECSS_FLOAT radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); - // while ((radius > 20 * radius_ref) || (radius < 0.5 * radius_ref)) - while (radius > 20 * radius_ref) - { - // Small step to ensure no too big nor too small bubbles are generated (the distribution is conserved still) - radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); - } - Bubbles[i]->R0 = radius; - } + Bubbles[i]->R0 = 2.0e-6; } // Define center location for each bubble @@ -299,7 +253,7 @@ int main(int argc, char **args) FILE *file_tension; file_tension = fopen("tension_results.txt", "w"); - fprintf(file_tension, "%d Bubbles p0(pa) %e p1(Pa) %e cl_distrib %d\n", nBubbles, Liquid->pref, pa, cluster_distrib); + fprintf(file_tension, "%d Bubbles p0(pa) %e p1(Pa) %e\n", nBubbles, Liquid->pref, pa); fprintf(file_tension, "Initial_radii(m)"); for (register int i = 0; i < nBubbles; i++) fprintf(file_tension, " %e", Bubbles[i]->R0); fprintf(file_tension, "\n"); diff --git a/examples/sphericalclustertensionwave/NI/gather_results.py b/examples/sphericalclustertensionwave/NI/gather_results.py index 92ecd08..61f7914 100644 --- a/examples/sphericalclustertensionwave/NI/gather_results.py +++ b/examples/sphericalclustertensionwave/NI/gather_results.py @@ -8,24 +8,15 @@ count = int(lines[0].split(" ")[0]) p1 = float(lines[0].split(" ")[5]) -cl_distrib = int(lines[0].split(" ")[7]) -if cl_distrib == 0 : - # monodispersed spherical cluster - file_name = "mono_{}_{:.4E}.txt".format(count, p1) - -else : - # polydispersed spherical cluster - file_name = "poly_{}_{:.4E}.txt".format(count, p1) +file_name = "mono_{}_{:.4E}.txt".format(count, p1) working_path = os.getcwd() results_path = os.path.join(working_path, "results") +if not os.path.exists(results_path) : + os.makedirs(results_path) file_results = open(os.path.join(results_path, file_name), "w") -# for line in lines : -# if "nan" not in line : -# file_results.write(line) - index = 0 while index < len(lines) and "nan" not in lines[index] : file_results.write(lines[index]) @@ -37,13 +28,7 @@ lines_loc = file_loc.readlines() file_loc.close() -if cl_distrib == 0 : - # monodispersed spherical cluster - file_name_loc = "mono_{}_{:.4E}_loc.txt".format(count, p1) - -else : - # polydispersed spherical cluster - file_name_loc = "poly_{}_{:.4E}_loc.txt".format(count, p1) +file_name_loc = "mono_{}_{:.4E}_loc.txt".format(count, p1) file_loc_results = open(os.path.join(results_path, file_name_loc), "w") diff --git a/examples/sphericalclustertensionwave/NI/src/sphericalclustertensionwave_apecss.c b/examples/sphericalclustertensionwave/NI/src/sphericalclustertensionwave_apecss.c index 22dfb7d..0f1cde0 100644 --- a/examples/sphericalclustertensionwave/NI/src/sphericalclustertensionwave_apecss.c +++ b/examples/sphericalclustertensionwave/NI/src/sphericalclustertensionwave_apecss.c @@ -28,28 +28,10 @@ APECSS_FLOAT rand_range(double min, double max) return (APECSS_FLOAT) number; } -APECSS_FLOAT normal_distribution(double mu, double sigma) -{ - // Generating a normal distribution using Box-Muller transform, with mu as mean and sigma**2 as variance - double u1 = (drand48()); - while (u1 == 0.0) u1 = (drand48()); - double u2 = (drand48()); - - double mag = sigma * APECSS_SQRT(-2.0 * APECSS_LOG(u1)); - double z1 = mag * APECSS_COS(2 * APECSS_PI * u2) + mu; - return (APECSS_FLOAT) z1; -} - // Declaration of additional case-dependent functions APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -// Declaration of the structure holding the interaction variables of each bubble -struct Interaction -{ - APECSS_FLOAT dp_neighbor; -}; - int main(int argc, char **args) { char OptionsDir[APECSS_STRINGLENGTH]; @@ -67,7 +49,6 @@ int main(int argc, char **args) double tEnd = 0.0; double fa = 0.0; double pa = 0.0; - int cluster_distrib = 0; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< apecss_infoscreen(); @@ -97,11 +78,6 @@ int main(int argc, char **args) sscanf(args[j + 1], "%le", &pa); j += 2; } - else if (strcmp("-cldistrib", args[j]) == 0) - { - sscanf(args[j + 1], "%d", &cluster_distrib); - j += 2; - } else if (strcmp("-h", args[j]) == 0) { apecss_helpscreen(); @@ -198,31 +174,9 @@ int main(int argc, char **args) } // Define the size of each bubble - if (cluster_distrib == 0) - { - // Monodispersed cluster - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->R0 = 2.0e-6; - } - } - else + for (register int i = 0; i < nBubbles; i++) { - // Polydispersed cluster (radii distribution is following a log normal law) - double mu = 0.0; - double sigma = 0.7; - APECSS_FLOAT radius_ref = 2.0e-6; - for (register int i = 0; i < nBubbles; i++) - { - APECSS_FLOAT radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); - // while ((radius > 20 * radius_ref) || (radius < 0.5 * radius_ref)) - while (radius > 20 * radius_ref) - { - // Small step to ensure no too big nor too small bubbles are generated (the distribution is conserved still) - radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); - } - Bubbles[i]->R0 = radius; - } + Bubbles[i]->R0 = 2.0e-6; } // Define center location for each bubble @@ -299,7 +253,7 @@ int main(int argc, char **args) FILE *file_tension; file_tension = fopen("tension_results.txt", "w"); - fprintf(file_tension, "%d Bubbles p0(pa) %e p1(Pa) %e cl_distrib %d\n", nBubbles, Liquid->pref, pa, cluster_distrib); + fprintf(file_tension, "%d Bubbles p0(pa) %e p1(Pa) %e\n", nBubbles, Liquid->pref, pa); fprintf(file_tension, "Initial_radii(m)"); for (register int i = 0; i < nBubbles; i++) fprintf(file_tension, " %e", Bubbles[i]->R0); fprintf(file_tension, "\n"); diff --git a/examples/sphericalclustertensionwave/QA/gather_results.py b/examples/sphericalclustertensionwave/QA/gather_results.py index 7567636..280efa3 100644 --- a/examples/sphericalclustertensionwave/QA/gather_results.py +++ b/examples/sphericalclustertensionwave/QA/gather_results.py @@ -17,18 +17,13 @@ firstline = lines_tension[0][0].split(" ") count = int(firstline[0]) p1 = float(firstline[5]) -cl_distrib = int(firstline[7]) -if cl_distrib == 0 : - # monodispersed spherical cluster - file_name = "mono_{}_{:.4E}.txt".format(count, p1) - -else : - # polydispersed spherical cluster - file_name = "poly_{}_{:.4E}.txt".format(count, p1) +file_name = "mono_{}_{:.4E}.txt".format(count, p1) working_path = os.getcwd() results_path = os.path.join(working_path, "results") +if not os.path.exists(results_path) : + os.makedirs(results_path) file_results = open(os.path.join(results_path, file_name), "w") results_tension = open(os.path.join(results_path, file_name), "w") @@ -69,13 +64,7 @@ lines_loc = file_loc.readlines() file_loc.close() -if cl_distrib == 0 : - # monodispersed spherical cluster - file_name_loc = "mono_{}_{:.4E}_loc.txt".format(count, p1) - -else : - # polydispersed spherical cluster - file_name_loc = "poly_{}_{:.4E}_loc.txt".format(count, p1) +file_name_loc = "mono_{}_{:.4E}_loc.txt".format(count, p1) file_loc_results = open(os.path.join(results_path, file_name_loc), "w") diff --git a/examples/sphericalclustertensionwave/QA/src/sphericalclustertensionwave_apecss.c b/examples/sphericalclustertensionwave/QA/src/sphericalclustertensionwave_apecss.c index 4fb6d5a..bf1d0df 100644 --- a/examples/sphericalclustertensionwave/QA/src/sphericalclustertensionwave_apecss.c +++ b/examples/sphericalclustertensionwave/QA/src/sphericalclustertensionwave_apecss.c @@ -29,18 +29,6 @@ APECSS_FLOAT rand_range(double min, double max) return (APECSS_FLOAT) number; } -APECSS_FLOAT normal_distribution(double mu, double sigma) -{ - // Generating a normal distribution using Box-Muller transform, with mu as mean and sigma**2 as variance - double u1 = (drand48()); - while (u1 == 0.0) u1 = (drand48()); - double u2 = (drand48()); - - double mag = sigma * APECSS_SQRT(-2.0 * APECSS_LOG(u1)); - double z1 = mag * APECSS_COS(2 * APECSS_PI * u2) + mu; - return (APECSS_FLOAT) z1; -} - struct APECSS_Parallel_Cluster { int rank, size; @@ -81,7 +69,6 @@ int main(int argc, char **args) double tEnd = 0.0; double fa = 0.0; double pa = 0.0; - int cluster_distrib = 0; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< apecss_infoscreen(); @@ -111,11 +98,6 @@ int main(int argc, char **args) sscanf(args[j + 1], "%le", &pa); j += 2; } - else if (strcmp("-cldistrib", args[j]) == 0) - { - sscanf(args[j + 1], "%d", &cluster_distrib); - j += 2; - } else if (strcmp("-h", args[j]) == 0) { apecss_helpscreen(); @@ -128,11 +110,6 @@ int main(int argc, char **args) ++j; } } - // /* Adapt dt_interbubble for polydispersed cluster */ - // if (cluster_distrib != 0) - // { - // dt_interbubble = 2.5e-10; - // } /* Allocate structure for parallel data */ struct APECSS_Parallel_Cluster *RankInfo = (struct APECSS_Parallel_Cluster *) malloc(sizeof(struct APECSS_Parallel_Cluster)); @@ -237,41 +214,13 @@ int main(int argc, char **args) } // Update interaction structure - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->nBubbles = nBubbles; // Not used? + for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->nBubbles = nBubbles; // Define the size of each bubble - if (cluster_distrib == 0) - { - // Monodispersed cluster - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->R0 = 2.0e-6; - Bubbles[i]->R = Bubbles[i]->R0; - } - } - else + for (register int i = 0; i < RankInfo->nBubbles_local; i++) { - // Polydispersed cluster (radii distribution is following a log normal law) - double mu = 0.0; - double sigma = 0.7; - APECSS_FLOAT radius_ref = 2.0e-6; - APECSS_FLOAT Bubble_Radius[nBubbles]; - for (register int i = 0; i < nBubbles; i++) - { - APECSS_FLOAT radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); - while (radius > 20 * radius_ref) - { - // Small step to ensure no too big bubbles nor too small are generated (the distribution is conserved still) - radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); - } - Bubble_Radius[i] = radius; - } - - for (register int n = 0; n < RankInfo->nBubbles_local; n++) - { - Bubbles[n]->R0 = Bubble_Radius[RankInfo->bubblerank[RankInfo->rank] + n]; - Bubbles[n]->R = Bubble_Radius[RankInfo->bubblerank[RankInfo->rank] + n]; - } + Bubbles[i]->R0 = 2.0e-6; + Bubbles[i]->R = Bubbles[i]->R0; } // Define center location for each bubble @@ -399,7 +348,7 @@ int main(int argc, char **args) sprintf(file_name, "tension_results_%d.txt", RankInfo->rank); file_tension = fopen(file_name, "w"); - fprintf(file_tension, "%d Bubbles p0(pa) %e p1(Pa) %e cl_distrib %d\n", nBubbles, Liquid->pref, pa, cluster_distrib); + fprintf(file_tension, "%d Bubbles p0(pa) %e p1(Pa) %e\n", nBubbles, Liquid->pref, pa); fprintf(file_tension, "Initial_radii(m)"); for (register int i = 0; i < RankInfo->nBubbles_global; i++) { From 873ec711c7f6443bf00f9f44fc1a9634894311c9 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 20 Sep 2024 15:11:52 -0400 Subject: [PATCH 120/138] sphericalclustertensionwave ; cleaning the .sh file to run only computations involving monodisperse cluster --- .../run_sphericalclustertensionwave.sh | 22 +++---------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/examples/sphericalclustertensionwave/run_sphericalclustertensionwave.sh b/examples/sphericalclustertensionwave/run_sphericalclustertensionwave.sh index 686bbe2..6a017dd 100755 --- a/examples/sphericalclustertensionwave/run_sphericalclustertensionwave.sh +++ b/examples/sphericalclustertensionwave/run_sphericalclustertensionwave.sh @@ -4,7 +4,6 @@ ncores=12 nbubbles=250 pressure=-3.0e4 -pressure_bis=-1.0e5 ######### No interaction computations ############################################################################################################### @@ -12,12 +11,7 @@ cd NI/build ./compile.sh cd .. -######### Monodispersed system #################################################################### -./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure -tend 15.0e-6 -cldistrib 0 -python3 gather_results.py - -# ######### Polydispersed system #################################################################### -./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure -tend 50.0e-6 -cldistrib 1 +./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure -tend 15.0e-6 python3 gather_results.py cd .. @@ -32,12 +26,7 @@ cd IC/build ./compile.sh cd .. -######### Monodispersed system #################################################################### -./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure -tend 15.0e-6 -cldistrib 0 -python3 gather_results.py - -######### Polydispersed system #################################################################### -./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure -tend 150.0e-6 -cldistrib 1 +./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure -tend 15.0e-6 python3 gather_results.py cd .. @@ -52,12 +41,7 @@ cd QA/build ./compile.sh cd .. -######### Monodispersed system #################################################################### -mpiexec -n $ncores ./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure -tend 25.0e-06 -cldistrib 0 -python3 gather_results.py - -######### Polydispersed system #################################################################### -mpiexec -n $ncores ./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure -tend 200.0e-06 -cldistrib 1 +mpiexec -n $ncores ./build/sphericalclustertensionwave_apecss -options run.apecss -amp $pressure -tend 25.0e-06 python3 gather_results.py cd .. From 755153d9f6d26d372d4bda137bb5aa570f1dce03 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 20 Sep 2024 15:13:53 -0400 Subject: [PATCH 121/138] sphericalclustertensionwave ; python plot results file with only monodisperse cluster --- .../plot_results.py | 1189 +---------------- 1 file changed, 38 insertions(+), 1151 deletions(-) diff --git a/examples/sphericalclustertensionwave/plot_results.py b/examples/sphericalclustertensionwave/plot_results.py index f258800..a87daf3 100644 --- a/examples/sphericalclustertensionwave/plot_results.py +++ b/examples/sphericalclustertensionwave/plot_results.py @@ -16,7 +16,7 @@ ######### Step 1 : Retrieving data ################################################################################################################## interaction_types = ["NI", "IC", "QA"] -cluster_types = ["mono", "poly"] +cluster_types = ["mono"] dic_bubbles = {} dic_bubbles_loc = {} @@ -52,12 +52,8 @@ count = int(firstline[0]) p1 = float(firstline[5]) - if "mono" in file_name : - dic_res = dic_bubbles[inttype]["mono"] - dic_loc = dic_bubbles_loc["mono"] - else : - dic_res = dic_bubbles[inttype]["poly"] - dic_loc = dic_bubbles_loc["poly"] + dic_res = dic_bubbles[inttype]["mono"] + dic_loc = dic_bubbles_loc["mono"] if count not in list(dic_res.keys()) : dic_res[count] = {} @@ -126,1016 +122,45 @@ 0.25 : "{:.1f}".format(0.25 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f}".format(0.25 + interval_size/cluster_radius), 0.0 : "{:.1f}".format(0.0) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f}".format(interval_size/cluster_radius)} -# For polydispersed cluster, results are plotted based on bubbles initial radii -n_quantiles = 5 -quantile_name_dic = {4 : "quartile", 5 : "quintile"} -quantile_name = quantile_name_dic[n_quantiles] -quantiles_list = [] -for i in range(1, n_quantiles + 1) : - quantiles_list.append(i / n_quantiles) -quantiles_list = np.array(quantiles_list) - -dic_polydisperse = {} - -for inttype in interaction_types : - dic_polydisperse[inttype] = {} - for count in list(dic_bubbles[inttype]["poly"].keys()) : - if count not in list(dic_polydisperse[inttype].keys()) : - dic_polydisperse[inttype][count] = {} - for p1 in list(dic_bubbles[inttype]["poly"][count].keys()) : - if p1 not in list(dic_polydisperse[inttype][count].keys()) : - dic_polydisperse[inttype][count][p1] = {"quantiles" : []} - for q in quantiles_list : - dic_polydisperse[inttype][count][p1][q] = [] - - initial_radius_list = [] - for i in range(count) : - initial_radius_list.append(dic_bubbles[inttype]["poly"][count][p1][i][0]) - - quantiles = np.quantile(np.array(initial_radius_list), quantiles_list) - print(count, quantiles) - for q in quantiles : dic_polydisperse[inttype][count][p1]["quantiles"].append(q) - - for i in range(count) : - initial_radius = dic_bubbles[inttype]["poly"][count][p1][i][0] - - index = 0 - while initial_radius > dic_polydisperse[inttype][count][p1]["quantiles"][index] : - index += 1 - dic_polydisperse[inttype][count][p1][quantiles_list[index]].append(i) - -# It's possible also for polydispersed cluster to plot results based on bubbles locations -dic_loc_distrib_global_poly = {} - -for count in list(dic_bubbles_loc["poly"].keys()) : - if count not in list(dic_loc_distrib_global.keys()) : - dic_loc_distrib_global[count] = {} - - for p1 in list(dic_bubbles_loc["poly"][count].keys()) : - if p1 not in list(dic_loc_distrib_global[count].keys()) : - dic_loc_distrib_global[count][p1] = dic_loc_distrib - - for i in range(count) : - radius_to_center = sqrt(dic_bubbles_loc["poly"][count][p1][i][0]**2 + dic_bubbles_loc["poly"][count][p1][i][1]**2 + dic_bubbles_loc["poly"][count][p1][i][2]**2) - if radius_to_center < 0.0 * cluster_radius + interval_size : - dic_loc_distrib_global[count][p1][0.0].append(i) - elif 0.5 * (cluster_radius - interval_size) < radius_to_center < 0.5 * (cluster_radius + interval_size) : - dic_loc_distrib_global[count][p1][0.5].append(i) - elif 1.0 * cluster_radius - interval_size < radius_to_center : - dic_loc_distrib_global[count][p1][1.0].append(i) - -######### Step 3 : Plot results ##################################################################################################################### - -#### General parameters ##### -rho_l = 1000.0 -r_ref = 2.0e-6 -p0 = 1.0e5 -mu = 0.0 -sigma = 0.7 - -######### Radius and minimum distance between bubbles in both configurations ###################### -p1 = -3.0e4 - -for cluster in cluster_types : - dic_loc = dic_bubbles_loc[cluster] - - for count in list(dic_loc.keys()) : - min_dist = cluster_radius - loc_list = dic_loc[count][p1] - for i in range(count) : - x_i = loc_list[i][0] - y_i = loc_list[i][1] - z_i = loc_list[i][2] - min_dist_bubble = cluster_radius - - for j in range(count) : - if (i != j) : - x_j = loc_list[j][0] - y_j = loc_list[j][1] - z_j = loc_list[j][2] - dist = sqrt((x_i - x_j)**2 + (y_i - y_j)**2 + (z_i - z_j)**2) - if dist < min_dist_bubble : - min_dist_bubble = dist - - if min_dist_bubble < min_dist : - min_dist = min_dist_bubble - - print("{} cluster with N={} bubbles, minimum distance between bubbles equals {:.2f} microns".format(cluster, count, min_dist*1.0e6)) - -fig, ax = plt.subplots(1, 1, figsize=(17.5*cm, 12.5*cm)) -ax.set_xlabel(r"$ / R_{0,ref}$", fontsize=15) -ax.grid() - -for count in list(dic_bubbles["NI"]["poly"].keys()) : - init_r_list = [] - for i in range(count) : - init_r_list.append(dic_bubbles["NI"]["poly"][count][p1][i][0] / r_ref) - print("poly cluster with N={} bubbles, minimum initial radius equals {:.2E} m".format(count, np.min(init_r_list) * r_ref)) - count, bins, ignored = ax.hist(init_r_list, 100, density=True, align='mid', label="{} bubbles".format(count)) - -x = np.linspace(min(bins), max(bins), 10000) -pdf = (np.exp(-(np.log(x) - mu)**2 / (2 * sigma**2)) / (x * sigma * np.sqrt(2 * np.pi))) -ax.plot(x, pdf, color="red", linewidth=1.5, linestyle="solid") - -ax.legend(loc="upper right") -fig.savefig("sphericalclustertensionwave_poly_radiidistribution.pdf", bbox_inches='tight',pad_inches=0.35) - -######### Averaged radius versus time evolution for monodispersed cluster ######################### -count = 250 -p1 = -3.0e4 -t_i = r_ref * sqrt(rho_l / (p0 - p1)) - -nrow = 1 -ncol = 3 -fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) -for i in range(ncol) : - axs[i].set_xlabel(r"$ t$ [$\mu$s]", fontsize=15) - axs[i].set_ylabel(r"$ / R_{0}$", fontsize=15) - axs[i].set_xlim(xmin=0.0, xmax=15.0) - axs[i].grid() - -axs[0].set_title(r"No interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) -axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) -axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) - -dic_color_loc = {0.0 : "blue", 0.25 : "magenta", 0.5 : "red", 0.75 : "green", 1.0 : "black"} -dic_lines_loc = {0.0 : "dotted", 0.25 : "dashed", 0.5 : "dashed", 0.75 : "dashed", 1.0 : "solid"} - -for k in [0.0, 0.5, 1.0] : - index_list = dic_loc_distrib_global[count][p1][k] - - # No interactions - t_list = 1.0e06 * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) - - r_list_0 = np.array(dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][1]) - init_r_0 = dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][0] - avg_radius = r_list_0 / init_r_0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - r_list = np.array(dic_bubbles["NI"]["mono"][count][p1][index + 1][1]) - init_r = dic_bubbles["NI"]["mono"][count][p1][index + 1][0] - avg_radius = avg_radius + np.array(r_list) / init_r - - avg_radius = (1 / len(index_list)) * avg_radius - - axs[0].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) - - # Incompressible interactions - t_list = 1.0e06 * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) - - r_list_0 = np.array(dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][1]) - init_r_0 = dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][0] - avg_radius = r_list_0 / init_r_0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - r_list = np.array(dic_bubbles["IC"]["mono"][count][p1][index + 1][1]) - init_r = dic_bubbles["IC"]["mono"][count][p1][index + 1][0] - avg_radius = avg_radius + np.array(r_list) / init_r - - avg_radius = (1 / len(index_list)) * avg_radius - - axs[1].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) - - # Quasi-acoustic interactions - t_list = 1.0e06 * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) - - r_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][1]) - init_r_0 = dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][0] - avg_radius = r_list_0 / init_r_0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - r_list = np.array(dic_bubbles["QA"]["mono"][count][p1][index + 1][1]) - init_r = dic_bubbles["QA"]["mono"][count][p1][index + 1][0] - avg_radius = avg_radius + np.array(r_list) / init_r - - avg_radius = (1 / len(index_list)) * avg_radius - - axs[2].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) - - -axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=3, frameon=False) -fig.savefig("sphericalclustertensionwave_mono_radiusevolution.pdf", bbox_inches='tight',pad_inches=0.35) - -######### Averaged radius versus time evolution for monodispersed cluster (article) ############### -count = 250 -p1 = -3.0e4 -t_i = r_ref * sqrt(rho_l / (p0 - p1)) - -nrow = 1 -ncol = 3 -fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) -for i in range(ncol) : - axs[i].set_xlabel(r"$ t$ [$\mu$s]", fontsize=27.5) - if i == 0 : axs[i].set_ylabel(r"$ / R_{0}$", fontsize=27.5) - axs[i].set_xlim(xmin=0.0, xmax=15.0) - axs[i].tick_params(axis="both", labelsize=25) - axs[i].grid() - -plt.subplots_adjust(wspace=0.35*cm) - -axs[0].set_title(r"No interactions", fontsize=27.5, y=1.025) -axs[1].set_title(r"Incompressible interactions", fontsize=27.5, y=1.025) -axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5, y=1.025) - -dic_color_loc = {0.0 : "blue", 0.25 : "magenta", 0.5 : "red", 0.75 : "green", 1.0 : "black"} -dic_lines_loc = {0.0 : "dotted", 0.25 : "dashed", 0.5 : "dashed", 0.75 : "dashed", 1.0 : "solid"} - -for k in [0.0, 0.5, 1.0] : - index_list = dic_loc_distrib_global[count][p1][k] - - # No interactions - t_list = 1.0e06 * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) - - r_list_0 = np.array(dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][1]) - init_r_0 = dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][0] - avg_radius = r_list_0 / init_r_0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - r_list = np.array(dic_bubbles["NI"]["mono"][count][p1][index + 1][1]) - init_r = dic_bubbles["NI"]["mono"][count][p1][index + 1][0] - avg_radius = avg_radius + np.array(r_list) / init_r - - avg_radius = (1 / len(index_list)) * avg_radius - - axs[0].plot(t_list, avg_radius, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) - - # Incompressible interactions - t_list = 1.0e06 * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) - - r_list_0 = np.array(dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][1]) - init_r_0 = dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][0] - avg_radius = r_list_0 / init_r_0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - r_list = np.array(dic_bubbles["IC"]["mono"][count][p1][index + 1][1]) - init_r = dic_bubbles["IC"]["mono"][count][p1][index + 1][0] - avg_radius = avg_radius + np.array(r_list) / init_r - - avg_radius = (1 / len(index_list)) * avg_radius - - axs[1].plot(t_list, avg_radius, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) - - # Quasi-acoustic interactions - t_list = 1.0e06 * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) - - r_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][1]) - init_r_0 = dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][0] - avg_radius = r_list_0 / init_r_0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - r_list = np.array(dic_bubbles["QA"]["mono"][count][p1][index + 1][1]) - init_r = dic_bubbles["QA"]["mono"][count][p1][index + 1][0] - avg_radius = avg_radius + np.array(r_list) / init_r - - avg_radius = (1 / len(index_list)) * avg_radius - - axs[2].plot(t_list, avg_radius, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) - - -axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=26.5, ncol=3, frameon=False) -fig.savefig("sphericalclustertensionwave_mono_radiusevolution_article.pdf", bbox_inches='tight',pad_inches=0.35) - -######### Averaged radius versus time evolution for polydispersed cluster ######################### - -count = 250 -p1 = -3.0e4 -t_i = r_ref * sqrt(rho_l / (p0 - p1)) - -nrow = 1 -ncol = 3 -fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) -for i in range(ncol) : - axs[i].set_xlabel(r"$ t$ [$\mu$s]", fontsize=15) - axs[i].set_ylabel(r"$$", fontsize=15) - # axs[i].set_xlim(xmin=10.0, xmax=60.0) - axs[i].grid() - -axs[0].set_title(r"No interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) -axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) -axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) - -color_list = ["black", "magenta", "blue", "green", "red"] -# linestyle_list = [(0, (1, 1)), (5, (10, 3)), (0, (5, 5)), (0, (3, 5, 1, 5)), (0, (3, 1, 1, 1, 1, 1))] -linestyle_list = ["solid" for i in range(5)] -dic_color_q = {} -dic_linestyle_q = {} -dic_label_q = {} -for i in range(n_quantiles) : - quantile = quantiles_list[i] - dic_color_q[quantile] = color_list[i] - dic_linestyle_q[quantile] = linestyle_list[i] - - dic_label_q[quantile] = "{}th-{}".format(i+1, quantile_name) - if i == 0 : - dic_label_q[quantile] = "1st-{}".format(quantile_name) - elif i == 1 : - dic_label_q[quantile] = "2nd-{}".format(quantile_name) - elif i == 2 : - dic_label_q[quantile] = "3rd-{}".format(quantile_name) - -# No interactions -axs[0].set_xlim(xmin=0.0,xmax=50.0) -axs[0].set_ylim(ymin=0.95,ymax=1.6) - -zm = axs[0].inset_axes([0.25, 0.25, 0.7, 0.7]) -zm.grid() -zm.set_xlim(xmax=10.0) - -for q in list(dic_polydisperse["NI"][count][p1].keys())[1:] : - index_list = dic_polydisperse["NI"][count][p1][q] - - t_list = 1.0e06 * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) - - r_list_0 = np.array(dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][1]) - init_r_0 = dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][0] - avg_radius = r_list_0 / init_r_0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - r_list = np.array(dic_bubbles["NI"]["poly"][count][p1][index + 1][1]) - init_r = dic_bubbles["NI"]["poly"][count][p1][index + 1][0] - avg_radius = avg_radius + np.array(r_list) / init_r - - avg_radius = (1 / len(index_list)) * avg_radius - - axs[0].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) - - zm.plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) - -# Incompressible interactions -axs[1].set_xlim(xmin=0.0,xmax=150.0) -axs[1].set_ylim(ymin=0.925,ymax=1.25) - -zm = axs[1].inset_axes([0.25, 0.5, 0.7, 0.45]) -zm.grid() -zm.set_xlim(xmax=37.5) - -for q in list(dic_polydisperse["IC"][count][p1].keys())[1:] : - index_list = dic_polydisperse["IC"][count][p1][q] - - t_list = 1.0e06 * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) - - r_list_0 = np.array(dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][1]) - init_r_0 = dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][0] - avg_radius = r_list_0 / init_r_0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - r_list = np.array(dic_bubbles["IC"]["poly"][count][p1][index + 1][1]) - init_r = dic_bubbles["IC"]["poly"][count][p1][index + 1][0] - avg_radius = avg_radius + np.array(r_list) / init_r - - avg_radius = (1 / len(index_list)) * avg_radius - - axs[1].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q], label=dic_label_q[q]) - - zm.plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) - -# Quasi-acoustic interactions -axs[2].set_xlim(xmin=0.0,xmax=150.0) -axs[2].set_ylim(ymin=0.925,ymax=1.25) - -zm = axs[2].inset_axes([0.25, 0.5, 0.7, 0.45]) -zm.grid() -zm.set_xlim(xmax=37.5) - -for q in list(dic_polydisperse["QA"][count][p1].keys())[1:] : - index_list = dic_polydisperse["QA"][count][p1][q] - - t_list = 1.0e06 * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) - - r_list_0 = np.array(dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][1]) - init_r_0 = dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][0] - avg_radius = r_list_0 / init_r_0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - r_list = np.array(dic_bubbles["QA"]["poly"][count][p1][index + 1][1]) - init_r = dic_bubbles["QA"]["poly"][count][p1][index + 1][0] - avg_radius = avg_radius + np.array(r_list) / init_r - - avg_radius = (1 / len(index_list)) * avg_radius - - axs[2].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) - - zm.plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) - -axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=n_quantiles, frameon=False) -fig.savefig("sphericalclustertensionwave_poly_radiusevolution.pdf", bbox_inches='tight',pad_inches=0.35) - -######### Averaged radius versus time evolution for polydispersed cluster (article) ############### - -count = 250 -p1 = -3.0e4 -t_i = r_ref * sqrt(rho_l / (p0 - p1)) - -nrow = 1 -ncol = 3 -fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) -for i in range(ncol) : - axs[i].set_xlabel(r"$ t$ [$\mu$s]", fontsize=27.5) - if i == 0 : axs[i].set_ylabel(r"$$", fontsize=27.5) - # axs[i].set_xlim(xmin=10.0, xmax=60.0) - axs[i].tick_params(axis="both", labelsize=25) - axs[i].grid() -plt.subplots_adjust(wspace=0.35*cm) - -axs[0].set_title(r"No interactions", fontsize=27.5, y=1.025) -axs[1].set_title(r"Incompressible interactions", fontsize=27.5, y=1.025) -axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5, y=1.025) - -color_list = ["black", "magenta", "blue", "green", "red"] -# linestyle_list = [(0, (1, 1)), (5, (10, 3)), (0, (5, 5)), (0, (3, 5, 1, 5)), (0, (3, 1, 1, 1, 1, 1))] -linestyle_list = ["solid" for i in range(5)] -dic_color_q = {} -dic_linestyle_q = {} -dic_label_q = {} -for i in range(n_quantiles) : - quantile = quantiles_list[i] - dic_color_q[quantile] = color_list[i] - dic_linestyle_q[quantile] = linestyle_list[i] - - dic_label_q[quantile] = "{}th-{}".format(i+1, quantile_name) - if i == 0 : - dic_label_q[quantile] = "1st-{}".format(quantile_name) - elif i == 1 : - dic_label_q[quantile] = "2nd-{}".format(quantile_name) - elif i == 2 : - dic_label_q[quantile] = "3rd-{}".format(quantile_name) - -# No interactions -axs[0].set_xlim(xmin=0.0,xmax=50.0) -axs[0].set_ylim(ymin=0.95,ymax=1.6) - -zm = axs[0].inset_axes([0.25, 0.25, 0.7, 0.7]) -zm.grid() -zm.set_xlim(xmin=0.0, xmax=10.0) -zm.tick_params(axis="both", labelsize=25) - -for q in list(dic_polydisperse["NI"][count][p1].keys())[1:] : - index_list = dic_polydisperse["NI"][count][p1][q] - - t_list = 1.0e06 * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) - - r_list_0 = np.array(dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][1]) - init_r_0 = dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][0] - avg_radius = r_list_0 / init_r_0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - r_list = np.array(dic_bubbles["NI"]["poly"][count][p1][index + 1][1]) - init_r = dic_bubbles["NI"]["poly"][count][p1][index + 1][0] - avg_radius = avg_radius + np.array(r_list) / init_r - - avg_radius = (1 / len(index_list)) * avg_radius - - axs[0].plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) - - zm.plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) - -# Incompressible interactions -axs[1].set_xlim(xmin=0.0,xmax=150.0) -axs[1].set_ylim(ymin=0.925,ymax=1.25) - -zm = axs[1].inset_axes([0.25, 0.5, 0.7, 0.45]) -zm.grid() -zm.set_xlim(xmax=37.5) -zm.tick_params(axis="both", labelsize=25) - -for q in list(dic_polydisperse["IC"][count][p1].keys())[1:] : - index_list = dic_polydisperse["IC"][count][p1][q] - - t_list = 1.0e06 * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) - - r_list_0 = np.array(dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][1]) - init_r_0 = dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][0] - avg_radius = r_list_0 / init_r_0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - r_list = np.array(dic_bubbles["IC"]["poly"][count][p1][index + 1][1]) - init_r = dic_bubbles["IC"]["poly"][count][p1][index + 1][0] - avg_radius = avg_radius + np.array(r_list) / init_r - - avg_radius = (1 / len(index_list)) * avg_radius - - axs[1].plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q], label=dic_label_q[q]) - - zm.plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) - -# Quasi-acoustic interactions -axs[2].set_xlim(xmin=0.0,xmax=150.0) -axs[2].set_ylim(ymin=0.925,ymax=1.25) - -zm = axs[2].inset_axes([0.25, 0.5, 0.7, 0.45]) -zm.grid() -zm.set_xlim(xmax=37.5) -zm.tick_params(axis="both", labelsize=25) - -for q in list(dic_polydisperse["QA"][count][p1].keys())[1:] : - index_list = dic_polydisperse["QA"][count][p1][q] - - t_list = 1.0e06 * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) - - r_list_0 = np.array(dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][1]) - init_r_0 = dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][0] - avg_radius = r_list_0 / init_r_0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - r_list = np.array(dic_bubbles["QA"]["poly"][count][p1][index + 1][1]) - init_r = dic_bubbles["QA"]["poly"][count][p1][index + 1][0] - avg_radius = avg_radius + np.array(r_list) / init_r - - avg_radius = (1 / len(index_list)) * avg_radius - - axs[2].plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) - - zm.plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) - -axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=26.5, ncol=n_quantiles, frameon=False) -fig.savefig("sphericalclustertensionwave_poly_radiusevolution_article.pdf", bbox_inches='tight',pad_inches=0.35) - -######### Averaged radius versus time for polydispersed cluster based on location ################# -count = 250 -p1 = -3.0e4 -t_i = r_ref * sqrt(rho_l / (p0 - p1)) - -nrow = 1 -ncol = 3 -fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) -for i in range(ncol) : - axs[i].set_xlabel(r"$ t$ [$\mu$s]", fontsize=15) - axs[i].set_ylabel(r"$ / R_{0}$", fontsize=15) - # axs[i].set_xlim(xmin=10.0, xmax=60.0) - axs[i].grid() - -axs[0].set_title(r"No interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) -axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) -axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) - -dic_color_loc = {0.0 : "blue", 0.25 : "magenta", 0.5 : "red", 0.75 : "green", 1.0 : "black"} -dic_lines_loc = {0.0 : "dotted", 0.25 : "dashed", 0.5 : "dashed", 0.75 : "dashed", 1.0 : "solid"} - -axs[0].set_xlim(xmin=0.0, xmax=250.0) -axs[1].set_xlim(xmin=-10.0, xmax=800.0) - -for k in [0.0, 0.5, 1.0] : - index_list = dic_loc_distrib_global[count][p1][k] - - # No interactions - t_list = 1.0e06 * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) - - r_list_0 = np.array(dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][1]) - init_r_0 = dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][0] - avg_radius = r_list_0 / init_r_0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - r_list = np.array(dic_bubbles["NI"]["poly"][count][p1][index + 1][1]) - init_r = dic_bubbles["NI"]["poly"][count][p1][index + 1][0] - avg_radius = avg_radius + np.array(r_list) / init_r - - avg_radius = (1 / len(index_list)) * avg_radius - - axs[0].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) - - # Incompressible interactions - t_list = 1.0e06 * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) - - r_list_0 = np.array(dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][1]) - init_r_0 = dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][0] - avg_radius = r_list_0 / init_r_0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - r_list = np.array(dic_bubbles["IC"]["poly"][count][p1][index + 1][1]) - init_r = dic_bubbles["IC"]["poly"][count][p1][index + 1][0] - avg_radius = avg_radius + np.array(r_list) / init_r - - avg_radius = (1 / len(index_list)) * avg_radius - - axs[1].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) - - # Quasi-acoustic interactions - t_list = 1.0e06 * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) - - r_list_0 = np.array(dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][1]) - init_r_0 = dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][0] - avg_radius = r_list_0 / init_r_0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - r_list = np.array(dic_bubbles["QA"]["poly"][count][p1][index + 1][1]) - init_r = dic_bubbles["QA"]["poly"][count][p1][index + 1][0] - avg_radius = avg_radius + np.array(r_list) / init_r - - avg_radius = (1 / len(index_list)) * avg_radius - - axs[2].plot(t_list, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) - - -axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=3, frameon=False) -fig.savefig("sphericalclustertensionwave_poly_radiusevolution_bis.pdf", bbox_inches='tight',pad_inches=0.35) - -######### Averaged pressure infinity versus time evolution for monodispersed clusters ############# - -count = 250 -p1 = -3.0e4 -p0 = 1.0e5 -t_i = r_ref * sqrt(rho_l / (p0 - p1)) - -nrow = 1 -ncol = 3 -fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) -for i in range(ncol) : - axs[i].set_xlabel(r"$ t$ [$\mu$s]", fontsize=15) - axs[i].set_ylabel(r"$ / p_{0}$", fontsize=15) - axs[i].set_xlim(xmin=0.0, xmax=15.0) - axs[i].grid() - -axs[0].set_title(r"No interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) -axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) -axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0}=2.0 \ \mu $m, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) - -dic_color_loc = {0.0 : "blue", 0.25 : "magenta", 0.5 : "red", 0.75 : "green", 1.0 : "black"} -dic_lines_loc = {0.0 : "dotted", 0.25 : "dashed", 0.5 : "dashed", 0.75 : "dashed", 1.0 : "solid"} - -for k in [0.0, 0.5, 1.0] : - index_list = dic_loc_distrib_global[count][p1][k] - - # No interactions - t_list = 1.0e06 * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) - - p_list_0 = np.array(dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][2]) - avg_pressure = p_list_0 / p0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - p_list = np.array(dic_bubbles["NI"]["mono"][count][p1][index + 1][2]) - avg_pressure = avg_pressure + np.array(p_list) / p0 - - avg_pressure = (1 / len(index_list)) * avg_pressure - - axs[0].plot(t_list, avg_pressure, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) - - # Incompressible interactions - t_list = 1.0e06 * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) - - p_list_0 = np.array(dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][2]) - avg_pressure = p_list_0 / p0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - p_list = np.array(dic_bubbles["IC"]["mono"][count][p1][index + 1][2]) - avg_pressure = avg_pressure + np.array(p_list) / p0 - - avg_pressure = (1 / len(index_list)) * avg_pressure - - axs[1].plot(t_list, avg_pressure, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) - - # Quasi-acoustic interactions - t_list = 1.0e06 * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) - - p_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][2]) - avg_pressure = p_list_0 / p0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - p_list = np.array(dic_bubbles["QA"]["mono"][count][p1][index + 1][2]) - avg_pressure = avg_pressure + np.array(p_list) / p0 - - avg_pressure = (1 / len(index_list)) * avg_pressure - - axs[2].plot(t_list, avg_pressure, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) - -axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=3, frameon=False) -fig.savefig("sphericalclustertensionwave_mono_pressureevolution.pdf", bbox_inches='tight',pad_inches=0.35) - -######### Averaged pressure infinity versus time evolution for monodispersed clusters (article) ### - -count = 250 -p1 = -3.0e4 -p0 = 1.0e5 -t_i = r_ref * sqrt(rho_l / (p0 - p1)) - -nrow = 1 -ncol = 3 -fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) -for i in range(ncol) : - axs[i].set_xlabel(r"$ t$ [$\mu$s]", fontsize=27.5) - if i == 0 : axs[i].set_ylabel(r"$ / p_{0}$", fontsize=27.5) - axs[i].set_xlim(xmin=0.0, xmax=15.0) - axs[i].tick_params(axis="both", labelsize=25) - axs[i].grid() - -plt.subplots_adjust(wspace=0.35*cm) - -axs[0].set_title(r"No interactions", fontsize=27.5, y=1.025) -axs[1].set_title(r"Incompressible interactions", fontsize=27.5, y=1.025) -axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5, y=1.025) - -dic_color_loc = {0.0 : "blue", 0.25 : "magenta", 0.5 : "red", 0.75 : "green", 1.0 : "black"} -dic_lines_loc = {0.0 : "dotted", 0.25 : "dashed", 0.5 : "dashed", 0.75 : "dashed", 1.0 : "solid"} - -zm_IC = axs[1].inset_axes([0.35, 0.35, 0.60, 0.60]) -zm_IC.grid() -zm_IC.set_xlim(xmin=0.0,xmax=5.0) -zm_IC.set_ylim(ymin=-0.5,ymax=2.0) -zm_IC.set_xticks([0, 2, 4]) -zm_IC.set_yticks([-0.267, 0.0, 1.0, 2.0]) -zm_IC.set_yticklabels([r"$p_{\mathrm{C}}$", 0, 1, 2]) -zm_IC.tick_params(axis="both", labelsize=25) - -zm_QA = axs[2].inset_axes([0.30, 0.4, 0.65, 0.55]) -zm_QA.grid() -zm_QA.set_xlim(xmin=0.0,xmax=5.0) -zm_QA.set_ylim(ymin=-0.5,ymax=2.0) -zm_QA.set_xticks([0, 2, 4]) -zm_QA.set_yticks([-0.267, 0.0, 1.0, 2.0]) -zm_QA.set_yticklabels([r"$p_{\mathrm{C}}$", 0, 1, 2]) -zm_QA.tick_params(axis="both", labelsize=25) - -for k in [0.0, 0.5, 1.0] : - index_list = dic_loc_distrib_global[count][p1][k] - - # No interactions - t_list = 1.0e06 * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) - - p_list_0 = np.array(dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][2]) - avg_pressure = p_list_0 / p0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - p_list = np.array(dic_bubbles["NI"]["mono"][count][p1][index + 1][2]) - avg_pressure = avg_pressure + np.array(p_list) / p0 - - avg_pressure = (1 / len(index_list)) * avg_pressure - - axs[0].plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) - - # Incompressible interactions - t_list = 1.0e06 * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) - - p_list_0 = np.array(dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][2]) - avg_pressure = p_list_0 / p0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - p_list = np.array(dic_bubbles["IC"]["mono"][count][p1][index + 1][2]) - avg_pressure = avg_pressure + np.array(p_list) / p0 - - avg_pressure = (1 / len(index_list)) * avg_pressure - - axs[1].plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) - - zm_IC.plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) - - # Quasi-acoustic interactions - t_list = 1.0e06 * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) - - p_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][2]) - avg_pressure = p_list_0 / p0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - p_list = np.array(dic_bubbles["QA"]["mono"][count][p1][index + 1][2]) - avg_pressure = avg_pressure + np.array(p_list) / p0 - - avg_pressure = (1 / len(index_list)) * avg_pressure - - axs[2].plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) - - zm_QA.plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) - -axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=26.5, ncol=3, frameon=False) -fig.savefig("sphericalclustertensionwave_mono_pressureevolution_article.pdf", bbox_inches='tight',pad_inches=0.35) - -######### Averaged pressure infinity versus time evolution for polydispersed clusters ############# +######### Step 3 : Plot results ##################################################################################################################### -count = 250 -p1 = -3.0e4 +#### General parameters ##### +rho_l = 1000.0 +r_ref = 2.0e-6 p0 = 1.0e5 -t_i = r_ref * sqrt(rho_l / (p0 - p1)) - -nrow = 1 -ncol = 3 -fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) -for i in range(ncol) : - axs[i].set_xlabel(r"$ t$ [$\mu$s]", fontsize=15) - axs[i].set_ylabel(r"$/p_{0}$", fontsize=15) - # axs[i].set_xlim(xmin=10.0, xmax=60.0) - axs[i].grid() - -axs[0].set_title(r"No interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) -axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) -axs[2].set_title(r"Quasi-acoustic interactions" + "\n" +r"($N = 250$, $R_{0, ref}=2.0 \ \mu $m, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{1} = -3.0 \times 10^{4} $ Pa)", fontsize=15, y=1.025) - -color_list = ["black", "magenta", "blue", "green", "red"] -dic_color_q = {} -dic_label_q = {} -for i in range(n_quantiles) : - quantile = quantiles_list[i] - dic_color_q[quantile] = color_list[i] - - dic_label_q[quantile] = "{}th-{}".format(i+1, quantile_name) - if i == 0 : - dic_label_q[quantile] = "1st-{}".format(quantile_name) - elif i == 1 : - dic_label_q[quantile] = "2nd-{}".format(quantile_name) - elif i == 2 : - dic_label_q[quantile] = "3rd-{}".format(quantile_name) - -# No interactions -for q in list(dic_polydisperse["NI"][count][p1].keys())[1:] : - index_list = dic_polydisperse["NI"][count][p1][q] - - t_list = 1.0e06 * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) - - p_list_0 = np.array(dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][2]) - avg_pressure = p_list_0 / p0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - p_list = np.array(dic_bubbles["NI"]["poly"][count][p1][index + 1][2]) - avg_pressure = avg_pressure + np.array(p_list) / p0 - - avg_pressure = (1 / len(index_list)) * avg_pressure - - axs[0].plot(t_list, avg_pressure, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) - -# Incompressible interactions -for q in list(dic_polydisperse["IC"][count][p1].keys())[1:] : - index_list = dic_polydisperse["IC"][count][p1][q] - - t_list = 1.0e06 * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) - - p_list_0 = np.array(dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][2]) - avg_pressure = p_list_0 / p0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - p_list = np.array(dic_bubbles["IC"]["poly"][count][p1][index + 1][2]) - avg_pressure = avg_pressure + np.array(p_list) / p0 - - avg_pressure = (1 / len(index_list)) * avg_pressure - - axs[1].plot(t_list, avg_pressure, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q], label=dic_label_q[q]) - -# Quasi-acoustic interactions -for q in list(dic_polydisperse["QA"][count][p1].keys())[1:] : - index_list = dic_polydisperse["QA"][count][p1][q] - - t_list = 1.0e06 * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) - - p_list_0 = np.array(dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][2]) - avg_pressure = p_list_0 / p0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - p_list = np.array(dic_bubbles["QA"]["poly"][count][p1][index + 1][2]) - avg_pressure = avg_pressure + np.array(p_list) / p0 - - avg_pressure = (1 / len(index_list)) * avg_pressure - - axs[2].plot(t_list, avg_pressure, linewidth=1.5, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) - -axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=n_quantiles, frameon=False) -fig.savefig("sphericalclustertensionwave_poly_pressureevolution.pdf", bbox_inches='tight',pad_inches=0.35) - -######### Averaged pressure infinity versus time evolution for polydispersed clusters (article) ### -count = 250 +######### Radius and minimum distance between bubbles in both configurations ###################### p1 = -3.0e4 -p0 = 1.0e5 -t_i = r_ref * sqrt(rho_l / (p0 - p1)) - -nrow = 1 -ncol = 3 -fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) -for i in range(ncol) : - axs[i].set_xlabel(r"$ t$ [$\mu$s]", fontsize=27.5) - if i == 0 : axs[i].set_ylabel(r"$/p_{0}$", fontsize=27.5) - # axs[i].set_xlim(xmin=10.0, xmax=60.0) - axs[i].tick_params(axis="both", labelsize=25) - axs[i].grid() -plt.subplots_adjust(wspace=0.35*cm) - -axs[0].set_title(r"No interactions", fontsize=27.5, y=1.025) -axs[1].set_title(r"Incompressible interactions", fontsize=27.5, y=1.025) -axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5, y=1.025) - -color_list = ["black", "magenta", "blue", "green", "red"] -dic_color_q = {} -dic_label_q = {} -for i in range(n_quantiles) : - quantile = quantiles_list[i] - dic_color_q[quantile] = color_list[i] - - dic_label_q[quantile] = "{}th-{}".format(i+1, quantile_name) - if i == 0 : - dic_label_q[quantile] = "1st-{}".format(quantile_name) - elif i == 1 : - dic_label_q[quantile] = "2nd-{}".format(quantile_name) - elif i == 2 : - dic_label_q[quantile] = "3rd-{}".format(quantile_name) - -# No interactions -for q in list(dic_polydisperse["NI"][count][p1].keys())[1:] : - index_list = dic_polydisperse["NI"][count][p1][q] - - t_list = 1.0e06 * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) - - p_list_0 = np.array(dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][2]) - avg_pressure = p_list_0 / p0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - p_list = np.array(dic_bubbles["NI"]["poly"][count][p1][index + 1][2]) - avg_pressure = avg_pressure + np.array(p_list) / p0 - - avg_pressure = (1 / len(index_list)) * avg_pressure - - axs[0].plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) - -# Incompressible interactions -for q in list(dic_polydisperse["IC"][count][p1].keys())[1:] : - index_list = dic_polydisperse["IC"][count][p1][q] - - t_list = 1.0e06 * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) - - p_list_0 = np.array(dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][2]) - avg_pressure = p_list_0 / p0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - p_list = np.array(dic_bubbles["IC"]["poly"][count][p1][index + 1][2]) - avg_pressure = avg_pressure + np.array(p_list) / p0 - - avg_pressure = (1 / len(index_list)) * avg_pressure - - axs[1].plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q], label=dic_label_q[q]) - -# Quasi-acoustic interactions -for q in list(dic_polydisperse["QA"][count][p1].keys())[1:] : - index_list = dic_polydisperse["QA"][count][p1][q] - - t_list = 1.0e06 * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) - - p_list_0 = np.array(dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][2]) - avg_pressure = p_list_0 / p0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - p_list = np.array(dic_bubbles["QA"]["poly"][count][p1][index + 1][2]) - avg_pressure = avg_pressure + np.array(p_list) / p0 - - avg_pressure = (1 / len(index_list)) * avg_pressure - - axs[2].plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) +for cluster in cluster_types : + dic_loc = dic_bubbles_loc[cluster] -axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=26.5, ncol=n_quantiles, frameon=False) -fig.savefig("sphericalclustertensionwave_poly_pressureevolution_article.pdf", bbox_inches='tight',pad_inches=0.35) + for count in list(dic_loc.keys()) : + min_dist = cluster_radius + loc_list = dic_loc[count][p1] + for i in range(count) : + x_i = loc_list[i][0] + y_i = loc_list[i][1] + z_i = loc_list[i][2] + min_dist_bubble = cluster_radius -######### Averaged radius versus time evolution for monodispersed cluster (article) ############### -######### More excitation pressure ################################################################ + for j in range(count) : + if (i != j) : + x_j = loc_list[j][0] + y_j = loc_list[j][1] + z_j = loc_list[j][2] + dist = sqrt((x_i - x_j)**2 + (y_i - y_j)**2 + (z_i - z_j)**2) + if dist < min_dist_bubble : + min_dist_bubble = dist + + if min_dist_bubble < min_dist : + min_dist = min_dist_bubble + + print("{} cluster with N={} bubbles, minimum distance between bubbles equals {:.2f} microns".format(cluster, count, min_dist*1.0e6)) +######### Averaged radius evolution ############### count = 250 -p1 = -1.0e5 +p1 = -3.0e4 t_i = r_ref * sqrt(rho_l / (p0 - p1)) nrow = 1 @@ -1216,13 +241,12 @@ axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=26.5, ncol=3, frameon=False) -fig.savefig("sphericalclustertensionwave_mono_radiusevolution_morepress_article.pdf", bbox_inches='tight',pad_inches=0.35) +fig.savefig("sphericalclustertensionwave_radiusevolution.pdf", bbox_inches='tight',pad_inches=0.35) -######### Averaged pressure infinity versus time evolution for monodispersed clusters (article) ### -######### More excitation pressure ################################################################ +######### Averaged pressure infinity evolution ### count = 250 -p1 = -1.0e5 +p1 = -3.0e4 p0 = 1.0e5 t_i = r_ref * sqrt(rho_l / (p0 - p1)) @@ -1243,7 +267,7 @@ axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5, y=1.025) dic_color_loc = {0.0 : "blue", 0.25 : "magenta", 0.5 : "red", 0.75 : "green", 1.0 : "black"} -dic_lines_loc = {0.0 : "dotted",0.25 : "dashed", 0.5 : "dashed", 0.75 : "dashed", 1.0 : "solid"} +dic_lines_loc = {0.0 : "dotted", 0.25 : "dashed", 0.5 : "dashed", 0.75 : "dashed", 1.0 : "solid"} zm_IC = axs[1].inset_axes([0.35, 0.35, 0.60, 0.60]) zm_IC.grid() @@ -1319,141 +343,4 @@ zm_QA.plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=26.5, ncol=3, frameon=False) -fig.savefig("sphericalclustertensionwave_mono_pressureevolution_morepress_article.pdf", bbox_inches='tight',pad_inches=0.35) - -######### Averaged radius versus time evolution for polydispersed cluster (article) ############### -######### More excitation pressure ################################################################ - -count = 250 -p1 = -1.0e5 -t_i = r_ref * sqrt(rho_l / (p0 - p1)) - -nrow = 1 -ncol = 3 -fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) -for i in range(ncol) : - axs[i].set_xlabel(r"$ t$ [$\mu$s]", fontsize=27.5) - if i == 0 : axs[i].set_ylabel(r"$$", fontsize=27.5) - # axs[i].set_xlim(xmin=10.0, xmax=60.0) - axs[i].tick_params(axis="both", labelsize=25) - axs[i].grid() -plt.subplots_adjust(wspace=0.35*cm) - -axs[0].set_title(r"No interactions", fontsize=27.5, y=1.025) -axs[1].set_title(r"Incompressible interactions", fontsize=27.5, y=1.025) -axs[2].set_title(r"Quasi-acoustic interactions", fontsize=27.5, y=1.025) - -color_list = ["black", "magenta", "blue", "green", "red"] -# linestyle_list = [(0, (1, 1)), (5, (10, 3)), (0, (5, 5)), (0, (3, 5, 1, 5)), (0, (3, 1, 1, 1, 1, 1))] -linestyle_list = ["solid" for i in range(5)] -dic_color_q = {} -dic_linestyle_q = {} -dic_label_q = {} -for i in range(n_quantiles) : - quantile = quantiles_list[i] - dic_color_q[quantile] = color_list[i] - dic_linestyle_q[quantile] = linestyle_list[i] - - dic_label_q[quantile] = "{}th-{}".format(i+1, quantile_name) - if i == 0 : - dic_label_q[quantile] = "1st-{}".format(quantile_name) - elif i == 1 : - dic_label_q[quantile] = "2nd-{}".format(quantile_name) - elif i == 2 : - dic_label_q[quantile] = "3rd-{}".format(quantile_name) - -# No interactions -axs[0].set_xlim(xmin=0.0,xmax=50.0) -axs[0].set_ylim(ymin=0.95,ymax=3.0) - -zm = axs[0].inset_axes([0.25, 0.25, 0.7, 0.7]) -zm.grid() -zm.set_xlim(xmin=0.0, xmax=10.0) -zm.tick_params(axis="both", labelsize=25) - -for q in list(dic_polydisperse["NI"][count][p1].keys())[1:] : - index_list = dic_polydisperse["NI"][count][p1][q] - - t_list = 1.0e06 * np.array(dic_bubbles["NI"]["poly"][count][p1][0]) - - r_list_0 = np.array(dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][1]) - init_r_0 = dic_bubbles["NI"]["poly"][count][p1][index_list[0] + 1][0] - avg_radius = r_list_0 / init_r_0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - r_list = np.array(dic_bubbles["NI"]["poly"][count][p1][index + 1][1]) - init_r = dic_bubbles["NI"]["poly"][count][p1][index + 1][0] - avg_radius = avg_radius + np.array(r_list) / init_r - - avg_radius = (1 / len(index_list)) * avg_radius - - axs[0].plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) - - zm.plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) - -# Incompressible interactions -axs[1].set_xlim(xmin=0.0,xmax=150.0) -axs[1].set_ylim(ymin=0.925,ymax=1.50) - -zm = axs[1].inset_axes([0.25, 0.5, 0.7, 0.45]) -zm.grid() -zm.set_xlim(xmax=37.5) -zm.tick_params(axis="both", labelsize=25) - -for q in list(dic_polydisperse["IC"][count][p1].keys())[1:] : - index_list = dic_polydisperse["IC"][count][p1][q] - - t_list = 1.0e06 * np.array(dic_bubbles["IC"]["poly"][count][p1][0]) - - r_list_0 = np.array(dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][1]) - init_r_0 = dic_bubbles["IC"]["poly"][count][p1][index_list[0] + 1][0] - avg_radius = r_list_0 / init_r_0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - r_list = np.array(dic_bubbles["IC"]["poly"][count][p1][index + 1][1]) - init_r = dic_bubbles["IC"]["poly"][count][p1][index + 1][0] - avg_radius = avg_radius + np.array(r_list) / init_r - - avg_radius = (1 / len(index_list)) * avg_radius - - axs[1].plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q], label=dic_label_q[q]) - - zm.plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) - -# Quasi-acoustic interactions -axs[2].set_xlim(xmin=0.0,xmax=150.0) -axs[2].set_ylim(ymin=0.925,ymax=1.50) - -zm = axs[2].inset_axes([0.25, 0.5, 0.7, 0.45]) -zm.grid() -zm.set_xlim(xmax=37.5) -zm.tick_params(axis="both", labelsize=25) - -for q in list(dic_polydisperse["QA"][count][p1].keys())[1:] : - index_list = dic_polydisperse["QA"][count][p1][q] - - t_list = 1.0e06 * np.array(dic_bubbles["QA"]["poly"][count][p1][0]) - - r_list_0 = np.array(dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][1]) - init_r_0 = dic_bubbles["QA"]["poly"][count][p1][index_list[0] + 1][0] - avg_radius = r_list_0 / init_r_0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - r_list = np.array(dic_bubbles["QA"]["poly"][count][p1][index + 1][1]) - init_r = dic_bubbles["QA"]["poly"][count][p1][index + 1][0] - avg_radius = avg_radius + np.array(r_list) / init_r - - avg_radius = (1 / len(index_list)) * avg_radius - - axs[2].plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) - - zm.plot(t_list, avg_radius, linewidth=2.0, linestyle=dic_linestyle_q[q], color=dic_color_q[q]) - -axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=26.5, ncol=n_quantiles, frameon=False) -fig.savefig("sphericalclustertensionwave_poly_radiusevolution_morepress_article.pdf", bbox_inches='tight',pad_inches=0.35) \ No newline at end of file +fig.savefig("sphericalclustertensionwave_pressureevolution.pdf", bbox_inches='tight',pad_inches=0.35) \ No newline at end of file From 194257fb6e0f0c059f16fffbb56533c62a0f711a Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 20 Sep 2024 15:14:13 -0400 Subject: [PATCH 122/138] sphericalclustertensionwave; adding a README file --- examples/sphericalclustertensionwave/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 examples/sphericalclustertensionwave/README.md diff --git a/examples/sphericalclustertensionwave/README.md b/examples/sphericalclustertensionwave/README.md new file mode 100644 index 0000000..699a6af --- /dev/null +++ b/examples/sphericalclustertensionwave/README.md @@ -0,0 +1,3 @@ +This example builds a standalone APECSS code for a monodispersed cluster of 250 interacting microbubbles. The cluster has a spherical shape with radius $R_{\mathrm{C}} = 232 \mu\mathrm{m}$, with the bubbles randomly distributed inside. The bubbles initial radius is $R_{0} = 2 \mu\mathrm{m}$. The incident wave is a single tension pulse defined by $p_{\mathrm{a}}(t) = -(p_{0} - p_{\mathrm{ng}})\sin^{2}\left(\pi t / \tau \right)$, with $\tau = 1.75 \mu\mathrm{s}$ and $p_{\mathrm{ng}} = -3.0 \times 10^{4} \mathrm{Pa}$. The computations are done when considering *no interactions* ("NI"), *incompressible interactions* ("IC") or *quasi-acoustic interactions* ("QA"), with each interaction model having its own repository for gathering data. The [run_sphericalclustertensionwave.sh](run_sphericalclustertensionwave.sh) file provides the whole execution command to run all computations, plot the results and clean the folders. + +The quasi-acoustic model computation is done using parallelization, and takes around **30 minutes** to finish when running on 12 cores of an Intel 13th-Gen i7-13700K x 24 processor. The number of cores used can be changed in the header section of [run_sphericalclustertensionwave.sh](run_sphericalclustertensionwave.sh). \ No newline at end of file From d2eafa33c80c865025186327a364dd4ac8cf4989 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 20 Sep 2024 15:16:02 -0400 Subject: [PATCH 123/138] cavitationonset ; adding two lines in gather_results.py in order to create the results folder if it does not exist already --- examples/cavitationonset/IC/gather_results.py | 2 ++ examples/cavitationonset/NI/gather_results.py | 2 ++ examples/cavitationonset/QA/gather_results.py | 2 ++ 3 files changed, 6 insertions(+) diff --git a/examples/cavitationonset/IC/gather_results.py b/examples/cavitationonset/IC/gather_results.py index 9eaed77..79929e0 100644 --- a/examples/cavitationonset/IC/gather_results.py +++ b/examples/cavitationonset/IC/gather_results.py @@ -14,6 +14,8 @@ working_path = os.getcwd() results_path = os.path.join(working_path, "results") +if not os.path.exists(results_path) : + os.makedirs(results_path) file_results = open(os.path.join(results_path, file_name), "w") for line in lines : diff --git a/examples/cavitationonset/NI/gather_results.py b/examples/cavitationonset/NI/gather_results.py index 9eaed77..79929e0 100644 --- a/examples/cavitationonset/NI/gather_results.py +++ b/examples/cavitationonset/NI/gather_results.py @@ -14,6 +14,8 @@ working_path = os.getcwd() results_path = os.path.join(working_path, "results") +if not os.path.exists(results_path) : + os.makedirs(results_path) file_results = open(os.path.join(results_path, file_name), "w") for line in lines : diff --git a/examples/cavitationonset/QA/gather_results.py b/examples/cavitationonset/QA/gather_results.py index 9eaed77..79929e0 100644 --- a/examples/cavitationonset/QA/gather_results.py +++ b/examples/cavitationonset/QA/gather_results.py @@ -14,6 +14,8 @@ working_path = os.getcwd() results_path = os.path.join(working_path, "results") +if not os.path.exists(results_path) : + os.makedirs(results_path) file_results = open(os.path.join(results_path, file_name), "w") for line in lines : From 6023e228cd8b4cc5e419cacd43f0065a32aad454 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Fri, 20 Sep 2024 15:17:17 -0400 Subject: [PATCH 124/138] cavitationonset ; deleting plot_temp.pyf file (not useful) --- examples/cavitationonset/IC/plot_temp.py | 71 ------------------------ 1 file changed, 71 deletions(-) delete mode 100644 examples/cavitationonset/IC/plot_temp.py diff --git a/examples/cavitationonset/IC/plot_temp.py b/examples/cavitationonset/IC/plot_temp.py deleted file mode 100644 index 0d8e866..0000000 --- a/examples/cavitationonset/IC/plot_temp.py +++ /dev/null @@ -1,71 +0,0 @@ -import os -import numpy as np -import matplotlib.pyplot as plt - -plt.rcParams['font.family']='serif' -plt.rcParams['font.serif']=['Times New Roman'] + plt.rcParams['font.serif'] -plt.rcParams['mathtext.fontset']='stix' -plt.rcParams['font.size']=10 - -cm = 1/2.54 - -count = 0 -for file in os.listdir() : - if "Bubble_" in file : - count += 1 - -Bubbles = [] -for i in range(count) : - Bubble_file = os.listdir(os.path.join(os.getcwd(), "Bubble_{}".format(i)))[0] - Bubble = np.genfromtxt("Bubble_{}/".format(i) + Bubble_file, delimiter=" ") - Bubbles.append(Bubble) - -Bubbles_A = [[]] -for i in range(count) : - Bubbles_A.append([]) - -file_results = open("Ida2009_results.txt", "r") -lines = file_results.readlines() -file_results.close() - -for line in lines[3:] : - data = line.split(" ") - t = float(data[0]) - Bubbles_A[0].append(t) - for i in range(count) : - Bubbles_A[1+i].append(float(data[1 + 2 * count + i])) - -fig1 = plt.figure(figsize=(21*cm,5*cm)) -ax1 = plt.subplot2grid((1,4),(0,0),colspan=1) -ax2 = plt.subplot2grid((1,4),(0,1),colspan=1) -ax3 = plt.subplot2grid((1,4),(0,2),colspan=1) -ax4 = plt.subplot2grid((1,4),(0,3),colspan=1) -plt.subplots_adjust(wspace=1.2*cm,hspace=1.2*cm) - -ax1.set_xlabel(r"t ($\mu$s)") -ax1.set_xlim(xmin=10.0, xmax=60.0) -ax2.set_xlabel(r"t ($\mu$s)") -ax2.set_xlim(xmin=10.0, xmax=60.0) -ax3.set_xlabel(r"t ($\mu$s)") -ax3.set_xlim(xmin=10.0, xmax=60.0) -ax4.set_xlabel(r"t ($\mu$s)") -ax4.set_xlim(xmin=10.0, xmax=60.0) - -ax1.set_ylabel(r"R ($\mu$m)") -ax2.set_ylabel(r"U (m.$s^{-1}$)") -ax3.set_ylabel(r"$p_{\infty}$ / $p_{0}$ (-)") -ax3.set_ylim(ymin=-0.25, ymax=0.0) -ax4.set_ylabel(r"A (m.$s^{-2}$)") - -ax1.grid() -ax2.grid() -ax3.grid() -ax4.grid() - -for i in range(count) : - ax1.plot(Bubbles[i][:, 1]*1e6, Bubbles[i][:, 3]*1e6) - ax2.plot(Bubbles[i][:, 1]*1e6, Bubbles[i][:, 4]) - ax3.plot(Bubbles[i][:, 1]*1e6, Bubbles[i][:, 7] * 1 / (101.3e03)) - ax4.plot(np.array(Bubbles_A[0])*1e6, np.array(Bubbles_A[1+i])) - -plt.show() \ No newline at end of file From 906d9da3899801418f2c14537e5cea713f6ca6b1 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 23 Sep 2024 13:16:20 -0400 Subject: [PATCH 125/138] sphericalclustertensionwave ; update of dictionnary dic_bubbles_loc to properly compute the average data for the plot --- .../plot_results.py | 63 ++++++++++--------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/examples/sphericalclustertensionwave/plot_results.py b/examples/sphericalclustertensionwave/plot_results.py index a87daf3..edf5f4b 100644 --- a/examples/sphericalclustertensionwave/plot_results.py +++ b/examples/sphericalclustertensionwave/plot_results.py @@ -24,11 +24,13 @@ for inttype in interaction_types : if inttype not in list(dic_bubbles.keys()) : dic_bubbles[inttype] = {} + if inttype not in list(dic_bubbles_loc.keys()) : + dic_bubbles_loc[inttype] = {} for cltype in cluster_types : if cltype not in list(dic_bubbles[inttype].keys()) : dic_bubbles[inttype][cltype] = {} - if cltype not in list(dic_bubbles_loc.keys()) : - dic_bubbles_loc[cltype] = {} + if cltype not in list(dic_bubbles_loc[inttype].keys()) : + dic_bubbles_loc[inttype][cltype] = {} working_path = os.getcwd() for inttype in interaction_types : @@ -53,7 +55,7 @@ p1 = float(firstline[5]) dic_res = dic_bubbles[inttype]["mono"] - dic_loc = dic_bubbles_loc["mono"] + dic_loc = dic_bubbles_loc[inttype]["mono"] if count not in list(dic_res.keys()) : dic_res[count] = {} @@ -93,28 +95,31 @@ interval_size = cluster_radius / 10 dic_loc_distrib_global = {} -dic_loc_distrib = {0.0 : [], 0.25 : [], 0.5 : [], 0.75 : [], 1.0 : []} -for count in list(dic_bubbles_loc["mono"].keys()) : - if count not in list(dic_loc_distrib_global.keys()) : - dic_loc_distrib_global[count] = {} - - for p1 in list(dic_bubbles_loc["mono"][count].keys()) : - if p1 not in list(dic_loc_distrib_global[count].keys()) : - dic_loc_distrib_global[count][p1] = dic_loc_distrib +for inttype in list(dic_bubbles_loc.keys()) : + if inttype not in list(dic_loc_distrib_global.keys()) : + dic_loc_distrib_global[inttype] = {} - for i in range(count) : - radius_to_center = sqrt(dic_bubbles_loc["mono"][count][p1][i][0]**2 + dic_bubbles_loc["mono"][count][p1][i][1]**2 + dic_bubbles_loc["mono"][count][p1][i][2]**2) - if radius_to_center < 0.0 * cluster_radius + interval_size : - dic_loc_distrib_global[count][p1][0.0].append(i) - elif 0.25 * cluster_radius - 0.5 * interval_size < radius_to_center < 0.25 * cluster_radius + 0.5 * interval_size : - dic_loc_distrib_global[count][p1][0.25].append(i) - elif 0.5 * (cluster_radius - interval_size) < radius_to_center < 0.5 * (cluster_radius + interval_size) : - dic_loc_distrib_global[count][p1][0.5].append(i) - elif 0.75 * cluster_radius - 0.5 * interval_size < radius_to_center < 0.75 * cluster_radius + 0.5 * interval_size : - dic_loc_distrib_global[count][p1][0.75].append(i) - elif 1.0 * cluster_radius - interval_size < radius_to_center : - dic_loc_distrib_global[count][p1][1.0].append(i) + for count in list(dic_bubbles_loc[inttype]["mono"].keys()) : + if count not in list(dic_loc_distrib_global[inttype].keys()) : + dic_loc_distrib_global[inttype][count] = {} + + for p1 in list(dic_bubbles_loc[inttype]["mono"][count].keys()) : + if p1 not in list(dic_loc_distrib_global[inttype][count].keys()) : + dic_loc_distrib_global[inttype][count][p1] = {0.0 : [], 0.25 : [], 0.5 : [], 0.75 : [], 1.0 : []} + + for i in range(count) : + radius_to_center = sqrt(dic_bubbles_loc[inttype]["mono"][count][p1][i][0]**2 + dic_bubbles_loc[inttype]["mono"][count][p1][i][1]**2 + dic_bubbles_loc[inttype]["mono"][count][p1][i][2]**2) + if radius_to_center < 0.0 * cluster_radius + interval_size : + dic_loc_distrib_global[inttype][count][p1][0.0].append(i) + elif 0.25 * cluster_radius - 0.5 * interval_size < radius_to_center < 0.25 * cluster_radius + 0.5 * interval_size : + dic_loc_distrib_global[inttype][count][p1][0.25].append(i) + elif 0.5 * (cluster_radius - interval_size) < radius_to_center < 0.5 * (cluster_radius + interval_size) : + dic_loc_distrib_global[inttype][count][p1][0.5].append(i) + elif 0.75 * cluster_radius - 0.5 * interval_size < radius_to_center < 0.75 * cluster_radius + 0.5 * interval_size : + dic_loc_distrib_global[inttype][count][p1][0.75].append(i) + elif 1.0 * cluster_radius - interval_size < radius_to_center : + dic_loc_distrib_global[inttype][count][p1][1.0].append(i) dic_loc_label = {1.0 : "{:.1f}".format(1.0 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f}".format(1.0), 0.75 : "{:.1f}".format(0.75 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f}".format(0.75 + interval_size/cluster_radius), @@ -133,7 +138,7 @@ p1 = -3.0e4 for cluster in cluster_types : - dic_loc = dic_bubbles_loc[cluster] + dic_loc = dic_bubbles_loc["NI"][cluster] for count in list(dic_loc.keys()) : min_dist = cluster_radius @@ -183,9 +188,8 @@ dic_lines_loc = {0.0 : "dotted", 0.25 : "dashed", 0.5 : "dashed", 0.75 : "dashed", 1.0 : "solid"} for k in [0.0, 0.5, 1.0] : - index_list = dic_loc_distrib_global[count][p1][k] - # No interactions + index_list = dic_loc_distrib_global["NI"][count][p1][k] t_list = 1.0e06 * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) r_list_0 = np.array(dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][1]) @@ -204,6 +208,7 @@ axs[0].plot(t_list, avg_radius, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) # Incompressible interactions + index_list = dic_loc_distrib_global["IC"][count][p1][k] t_list = 1.0e06 * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) r_list_0 = np.array(dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][1]) @@ -222,6 +227,7 @@ axs[1].plot(t_list, avg_radius, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=dic_loc_label[k]) # Quasi-acoustic interactions + index_list = dic_loc_distrib_global["QA"][count][p1][k] t_list = 1.0e06 * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) r_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][1]) @@ -288,9 +294,8 @@ zm_QA.tick_params(axis="both", labelsize=25) for k in [0.0, 0.5, 1.0] : - index_list = dic_loc_distrib_global[count][p1][k] - # No interactions + index_list = dic_loc_distrib_global["NI"][count][p1][k] t_list = 1.0e06 * np.array(dic_bubbles["NI"]["mono"][count][p1][0]) p_list_0 = np.array(dic_bubbles["NI"]["mono"][count][p1][index_list[0] + 1][2]) @@ -307,6 +312,7 @@ axs[0].plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) # Incompressible interactions + index_list = dic_loc_distrib_global["IC"][count][p1][k] t_list = 1.0e06 * np.array(dic_bubbles["IC"]["mono"][count][p1][0]) p_list_0 = np.array(dic_bubbles["IC"]["mono"][count][p1][index_list[0] + 1][2]) @@ -325,6 +331,7 @@ zm_IC.plot(t_list, avg_pressure, linewidth=3.0, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) # Quasi-acoustic interactions + index_list = dic_loc_distrib_global["QA"][count][p1][k] t_list = 1.0e06 * np.array(dic_bubbles["QA"]["mono"][count][p1][0]) p_list_0 = np.array(dic_bubbles["QA"]["mono"][count][p1][index_list[0] + 1][2]) From 89da40042069534ea1e38a5dea1b91d154f41ed0 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 23 Sep 2024 13:19:01 -0400 Subject: [PATCH 126/138] sphericalclustertensionwave ; small typo correction in caption for loc distributions (0.45<<0.55 instead of 0.4<<0.6) --- examples/sphericalclustertensionwave/plot_results.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/sphericalclustertensionwave/plot_results.py b/examples/sphericalclustertensionwave/plot_results.py index edf5f4b..94d8f3f 100644 --- a/examples/sphericalclustertensionwave/plot_results.py +++ b/examples/sphericalclustertensionwave/plot_results.py @@ -122,9 +122,9 @@ dic_loc_distrib_global[inttype][count][p1][1.0].append(i) dic_loc_label = {1.0 : "{:.1f}".format(1.0 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f}".format(1.0), - 0.75 : "{:.1f}".format(0.75 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f}".format(0.75 + interval_size/cluster_radius), - 0.5 : "{:.1f}".format(0.5 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f}".format(0.5 + interval_size/cluster_radius), - 0.25 : "{:.1f}".format(0.25 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f}".format(0.25 + interval_size/cluster_radius), + 0.75 : "{:.2f}".format(0.75 - 0.5 * interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.2f}".format(0.75 + 0.5 * interval_size/cluster_radius), + 0.5 : "{:.2f}".format(0.5 - 0.5 * interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.2f}".format(0.5 + 0.5 * interval_size/cluster_radius), + 0.25 : "{:.2f}".format(0.25 - 0.5 * interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.2f}".format(0.25 + 0.5 * interval_size/cluster_radius), 0.0 : "{:.1f}".format(0.0) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f}".format(interval_size/cluster_radius)} ######### Step 3 : Plot results ##################################################################################################################### From 398bf2bd6935fe9c1ad8b1d03cb90a3e0b693624 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 23 Sep 2024 13:31:17 -0400 Subject: [PATCH 127/138] bubblyscreen ; deleting folder --- examples/bubblyscreen/IC/build/CMakeLists.txt | 41 - examples/bubblyscreen/IC/build/compile.sh | 5 - examples/bubblyscreen/IC/gather_results.py | 31 - examples/bubblyscreen/IC/run.apecss | 38 - .../bubblyscreen/IC/src/bubblyscreen_apecss.c | 418 ---------- examples/bubblyscreen/QA/build/CMakeLists.txt | 41 - examples/bubblyscreen/QA/build/compile.sh | 5 - examples/bubblyscreen/QA/execmpi.sh | 19 - examples/bubblyscreen/QA/gather_results.py | 44 -- examples/bubblyscreen/QA/run.apecss | 38 - .../bubblyscreen/QA/src/bubblyscreen_apecss.c | 723 ------------------ examples/bubblyscreen/README.md | 1 - examples/bubblyscreen/plot_results.py | 243 ------ examples/bubblyscreen/run_bubblyscreen.sh | 76 -- 14 files changed, 1723 deletions(-) delete mode 100644 examples/bubblyscreen/IC/build/CMakeLists.txt delete mode 100755 examples/bubblyscreen/IC/build/compile.sh delete mode 100644 examples/bubblyscreen/IC/gather_results.py delete mode 100644 examples/bubblyscreen/IC/run.apecss delete mode 100644 examples/bubblyscreen/IC/src/bubblyscreen_apecss.c delete mode 100644 examples/bubblyscreen/QA/build/CMakeLists.txt delete mode 100755 examples/bubblyscreen/QA/build/compile.sh delete mode 100755 examples/bubblyscreen/QA/execmpi.sh delete mode 100644 examples/bubblyscreen/QA/gather_results.py delete mode 100644 examples/bubblyscreen/QA/run.apecss delete mode 100644 examples/bubblyscreen/QA/src/bubblyscreen_apecss.c delete mode 100644 examples/bubblyscreen/README.md delete mode 100644 examples/bubblyscreen/plot_results.py delete mode 100755 examples/bubblyscreen/run_bubblyscreen.sh diff --git a/examples/bubblyscreen/IC/build/CMakeLists.txt b/examples/bubblyscreen/IC/build/CMakeLists.txt deleted file mode 100644 index b7b74a5..0000000 --- a/examples/bubblyscreen/IC/build/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -cmake_minimum_required(VERSION 3.12) - -project (bubblyscreen_apecss) -set(CMAKE_C_COMPILER /usr/bin/gcc) - -include_directories($ENV{APECSS_DIR}/include) -FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) - -set (mylibs m apecss) -link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) - -foreach(arg ${myincludes}) - IF (arg MATCHES "-I") - STRING(REGEX REPLACE "-I" "" myinc ${arg}) - message("Additional include: ${myinc}") - include_directories(${myinc}) - ENDIF(arg MATCHES "-I") -endforeach(arg ${myincludes}) - -foreach(arg ${mylibs}) - STRING(REGEX REPLACE "lib" "" myl1 ${arg}) - STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) - set(mylibs ${myl2} ${mylibs} ${myl2}) -endforeach(arg ${mylibs}) - -if(NOT CMAKE_BUILD_TYPE) - message(STATUS "Optimization: No optimization specified.") - set(CMAKE_BUILD_TYPE Release) -endif() - -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - message(STATUS "Optimization: Debug") - set(CMAKE_C_FLAGS_DEBUG "-Wall -g") -elseif(CMAKE_BUILD_TYPE STREQUAL "Release") - message(STATUS "Optimization: Release") - add_definitions(-DNDEBUG) - set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") -endif() - -add_executable(bubblyscreen_apecss ${myfiles}) -target_link_libraries(bubblyscreen_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/bubblyscreen/IC/build/compile.sh b/examples/bubblyscreen/IC/build/compile.sh deleted file mode 100755 index 1569080..0000000 --- a/examples/bubblyscreen/IC/build/compile.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -rm bubblyscreen_apecss -cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release -make -rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/bubblyscreen/IC/gather_results.py b/examples/bubblyscreen/IC/gather_results.py deleted file mode 100644 index 7987f11..0000000 --- a/examples/bubblyscreen/IC/gather_results.py +++ /dev/null @@ -1,31 +0,0 @@ -import os - -# File designed to recover data for plotting results in bubbly screen case - -file_radii = open("bubblyscreen_radii.txt", "r") -lines_radii = file_radii.readlines() -file_radii.close() - -file_extremum = open("bubblyscreen_extremum.txt", "r") -lines_extremum = file_extremum.readlines() -file_extremum.close() - -firstline = lines_radii[0].split(" ") -f = float(firstline[3]) -p = float(firstline[5]) -d = float(firstline[7]) - -file_name = "bubblyscreen_{:.3E}_{:.2E}_{:.1f}".format(f, p, d) - -working_path = os.getcwd() -results_path = os.path.join(working_path, "results") - -results_radii = open(os.path.join(results_path, file_name + "_radii.txt"), "w") -for line in lines_radii : - results_radii.write(line) -results_radii.close() - -results_extremum = open(os.path.join(results_path, file_name + "_extremum.txt"), "w") -for line in lines_extremum : - results_extremum.write(line) -results_extremum.close() \ No newline at end of file diff --git a/examples/bubblyscreen/IC/run.apecss b/examples/bubblyscreen/IC/run.apecss deleted file mode 100644 index cf42dde..0000000 --- a/examples/bubblyscreen/IC/run.apecss +++ /dev/null @@ -1,38 +0,0 @@ -######################################################### -# # -# APECSS Options File # -# # -######################################################### - -BUBBLE -RPModel KM -Emissions IC 300.0e-6 -PressureAmbient 1.0e5 -END - -GAS -EoS IG -ReferencePressure 1.0e5 -ReferenceDensity 1.2 -PolytropicExponent 1.4 -END - -LIQUID -ReferencePressure 1.0e5 -ReferenceDensity 1000.0 -ReferenceSoundSpeed 1500.0 -Viscosity 0.00 -END - -INTERFACE -SurfaceTensionCoeff 0.00 -END - -RESULTS -Bubble -OutputFreqRP 5 -END - -ODESOLVER -tolerance 1.0e-10 -END diff --git a/examples/bubblyscreen/IC/src/bubblyscreen_apecss.c b/examples/bubblyscreen/IC/src/bubblyscreen_apecss.c deleted file mode 100644 index 165b6de..0000000 --- a/examples/bubblyscreen/IC/src/bubblyscreen_apecss.c +++ /dev/null @@ -1,418 +0,0 @@ -// This source file is part of APECSS, an open-source software toolbox -// for the computation of pressure-driven bubble dynamics and acoustic -// emissions in spherical symmetry. -// -// Copyright (C) 2022-2024 The APECSS Developers -// -// The APECSS Developers are listed in the README.md file available in -// the GitHub repository at https://github.com/polycfd/apecss. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// ------------------------------------------------------------------- -// APECSS standalone example of acoustically-interacting microbubbles -// in a finite bubbly screen based on Fan, Y., Li, H., & Fuster, -// D. (2021). Time-delayed interactions on acoustically driven bubbly -// screens. The Journal of the Acoustical Society of America, 150(6), -// 4219‑4231. https://doi.org/10.1121/10.0008905 -// ------------------------------------------------------------------- - -#include -#include "apecss.h" - -// Declaration of additional case-dependent functions -APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -int apecss_bubble_new_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble); - -APECSS_FLOAT maxR; -APECSS_FLOAT minR; - -int main(int argc, char **args) -{ - char OptionsDir[APECSS_STRINGLENGTH]; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Set the case-dependent simulation parameters - const int nBubbles_x = 51; - const int nBubbles = nBubbles_x * nBubbles_x; // Number of bubbles - APECSS_FLOAT bubble_bubble_dist = 400.0e-6; // Bubble-bubble distance - - // Interbubble time-step, defining the frequency with which the neighbor influence is updated - APECSS_FLOAT dt_interbubble = 1.0e-8; - - // Initialize the simulation parameters given by the execution command - double tEnd = 0.0; - double fa = 0.0; - double pa = 0.0; - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - apecss_infoscreen(); - - /* Read commandline options */ - sprintf(OptionsDir, "./run.apecss"); // This is the default - int j = 1; // First argument is the call to the executable - while (j < argc) - { - if (strcmp("-options", args[j]) == 0) - { - sprintf(OptionsDir, "%s", args[j + 1]); - j += 2; - } - else if (strcmp("-tend", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &tEnd); - j += 2; - } - else if (strcmp("-freq", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &fa); - j += 2; - } - else if (strcmp("-amp", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &pa); - j += 2; - } - else if (strcmp("-h", args[j]) == 0) - { - apecss_helpscreen(); - } - else - { - char str[APECSS_STRINGLENGTH_SPRINTF]; - sprintf(str, "Unknown command line options: %s", args[j]); - apecss_erroronscreen(1, str); - ++j; - } - } - - /* Allocate and initialize Bubble structure */ - struct APECSS_Bubble *Bubbles[nBubbles]; - for (register int i = 0; i < nBubbles; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(nBubbles * sizeof(struct APECSS_Bubble)); - for (register int i = 0; i < nBubbles; i++) apecss_bubble_initializestruct(Bubbles[i]); - - /* Set default options and read the options for the bubble */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); - for (register int i = 0; i < nBubbles; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); - - /* Allocate the structures for the fluid properties and ODE solver parameters */ - struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); - struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); - struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); - struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); - - /* Set the default options for the fluid properties and solver parameters */ - apecss_gas_setdefaultoptions(Gas); - apecss_liquid_setdefaultoptions(Liquid); - apecss_interface_setdefaultoptions(Interface); - apecss_odesolver_setdefaultoptions(NumericsODE); - - /* Read the options file for the fluid properties and solver parameters */ - apecss_gas_readoptions(Gas, OptionsDir); - apecss_liquid_readoptions(Liquid, OptionsDir); - apecss_interface_readoptions(Interface, OptionsDir); - apecss_odesolver_readoptions(NumericsODE, OptionsDir); - - /* Associate the bubble with the relevant fluid properties and solver parameters */ - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->Gas = Gas; - Bubbles[i]->Liquid = Liquid; - Bubbles[i]->Interface = Interface; - Bubbles[i]->NumericsODE = NumericsODE; - } - - /* Allocate and set the excitation parameters */ - struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); - Excitation->type = APECSS_EXCITATION_SIN; - Excitation->f = (APECSS_FLOAT) fa; - Excitation->dp = (APECSS_FLOAT) pa; - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Excitation = Excitation; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Create individual folders for the results of each bubble - for (register int i = 0; i < nBubbles; i++) - { - if (Bubbles[i]->Results != NULL) - { - sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", i); - struct stat st = {0}; - if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); - } - } - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - /* Process all options */ - apecss_gas_processoptions(Gas); - apecss_liquid_processoptions(Liquid); - apecss_interface_processoptions(Interface); - apecss_odesolver_processoptions(NumericsODE); - for (register int i = 0; i < nBubbles; i++) apecss_bubble_processoptions(Bubbles[i]); - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Use the revised pressure at infinity, including neighbor contributions - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressure_infinity = interaction_bubble_pressure_infinity; - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressurederivative_infinity = interaction_bubble_pressurederivative_infinity; - - // Initialize interaction structure - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); - - // Update interaction structure - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->Interaction->nBubbles = nBubbles; - Bubbles[i]->Interaction->dp_neighbor = 0.0; - Bubbles[i]->Interaction->last_t_1 = 0.0; - Bubbles[i]->Interaction->last_t_2 = 0.0; - Bubbles[i]->Interaction->last_p_1 = 0.0; - Bubbles[i]->Interaction->last_p_2 = 0.0; - } - - // Define the size of each bubble - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->R0 = 1.0e-6; - // Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; - } - - // Define center location for each bubble - int space = (int) (0.5 * (nBubbles_x - 1)); - int row = 0; - int col = 0; - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->Interaction->location[0] = (col - space) * bubble_bubble_dist; - Bubbles[i]->Interaction->location[1] = (row - space) * bubble_bubble_dist; - Bubbles[i]->Interaction->location[2] = 0.0; - if ((col < 2 * space) && (col >= 0)) - { - col += 1; - } - else - { - row += 1; - col = 0; - } - } - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - clock_t starttimebubble = clock(); - APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system - - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->tStart = tSim; - Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; - Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step - } - - /* Initialize the bubble based on the selected options */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_initialize(Bubbles[i]); - - /* Initialize */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_initialize(Bubbles[i]); - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Lists to gather maximum and minimum radius achieved by each bubble in steady state - APECSS_FLOAT max_radii[nBubbles]; - APECSS_FLOAT min_radii[nBubbles]; - - for (register int i = 0; i < nBubbles; i++) - { - max_radii[i] = Bubbles[i]->R; - min_radii[i] = Bubbles[i]->R; - } - - // File to retrieve the maximum and minimum radius evolution achieved in steady state - FILE *file_extremum; - file_extremum = fopen("bubblyscreen_extremum.txt", "w"); - - APECSS_FLOAT p0 = Bubbles[0]->p0; - APECSS_FLOAT poly = Gas->Gamma; - APECSS_FLOAT rho = Liquid->rhoref; - APECSS_FLOAT w0 = APECSS_SQRT((3 * poly * p0) / (APECSS_POW2(Bubbles[0]->R0) * rho)); - - fprintf(file_extremum, "w0(rad/s) %e f(Hz) %e p(Pa) %e D/R0 %e\n", w0, fa, pa, bubble_bubble_dist / Bubbles[0]->R0); - fprintf(file_extremum, "label x(m) y(m) z(m) R0(m) Rmin(m) Rmax(m)\n"); - - // File to retrieve the radius evolution during computation - FILE *file_radii; - file_radii = fopen("bubblyscreen_radii.txt", "w"); - fprintf(file_radii, "w0(rad/s) %e f(Hz) %e p(Pa) %e D/R0 %e\n", w0, fa, pa, bubble_bubble_dist / Bubbles[0]->R0); - fprintf(file_radii, "t(s) R(m)\n"); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - /* Solve the bubble dynamics */ - while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered - { - APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); - tSim += dtSim; - - for (register int i = 0; i < nBubbles; i++) - { - maxR = 0.0; - minR = Bubbles[i]->R0; - apecss_bubble_new_solver_run(tSim, tEnd, Bubbles[i]); - - if (maxR > max_radii[i]) - { - max_radii[i] = maxR; - } - if (minR < min_radii[i]) - { - min_radii[i] = minR; - } - } - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Update the contribution of the neighbor bubble - apecss_interactions_instantaneous(Bubbles); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - fprintf(file_radii, "%e", tSim); - for (register int i = 0; i < nBubbles; i++) - { - fprintf(file_radii, " %e", Bubbles[i]->R); - } - fprintf(file_radii, "\n"); - - // for (register int i = 0; i < nBubbles; i++) - // { - // Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; - // Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; - - // Bubbles[i]->Interaction->last_t_1 = tSim; - // Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; - // } - } - - /* Complete results file */ - for (register int i = 0; i < nBubbles; i++) - { - fprintf(file_extremum, "%d %e %e %e %e %e %e\n", i, Bubbles[i]->Interaction->location[0], Bubbles[i]->Interaction->location[1], - Bubbles[i]->Interaction->location[2], Bubbles[i]->R0, min_radii[i], max_radii[i]); - } - fclose(file_extremum); - - fclose(file_radii); - - /* Finalize the simulation*/ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_finalize(Bubbles[i]); - - char str[APECSS_STRINGLENGTH_SPRINTF]; - for (register int i = 0; i < nBubbles; i++) - { - sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", i, Bubbles[i]->dtNumber, Bubbles[i]->nSubIter, - (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); - apecss_writeonscreen(str); - } - - for (register int i = 0; i < nBubbles; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); - for (register int i = 0; i < nBubbles; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); - - /* Make sure all allocated memory is freed */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_freestruct(Bubbles[i]); - - for (register int i = 0; i < nBubbles; i++) free(Bubbles[i]); - free(Gas); - free(Liquid); - free(Interface); - free(NumericsODE); - free(Excitation); - - return (0); -} - -APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * t) + Bubble->Interaction->dp_neighbor); -} - -APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - // Approximate numerical computation of p_infinity derivative - // APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; - APECSS_FLOAT derivative = -Bubble->Excitation->dp * 2.0 * APECSS_PI * Bubble->Excitation->f * APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * t); - return (derivative); - // if (delta_t > Bubble->dt) - // { - // return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) / (Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2))); - // } - // else - // { - // return (derivative); - // } -} - -int apecss_bubble_new_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble) -{ - while (Bubble->t < tend - 0.01 * Bubble->NumericsODE->dtMin) - { - // Store the previous solution for sub-iterations - for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSolOld[i] = Bubble->ODEsSol[i]; - - // Check what comes next: the end of the solver run or, if applicable, a time instance to output the emissions - APECSS_FLOAT next_event_time = Bubble->results_emissionstime_check(tend, Bubble); - - // Set the time-step for the ODEs - apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); - - // Solve the ODEs - Bubble->err = apecss_odesolver(Bubble); - - // Perform sub-iterations on the control of the time-step when err > tol - register int subiter = 0; - while ((Bubble->err > Bubble->NumericsODE->tol) && (subiter < Bubble->NumericsODE->maxSubIter)) - { - ++subiter; - // Rewind the solution - for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSol[i] = Bubble->ODEsSolOld[i]; - // Set the time-step for the ODEs - apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); - // Solve the ODEs again - Bubble->err = apecss_odesolver(Bubble); - } - Bubble->nSubIter += subiter; - - // Set new values - ++(Bubble->dtNumber); - Bubble->t += Bubble->dt; - Bubble->U = Bubble->ODEsSol[0]; - Bubble->R = Bubble->ODEsSol[1]; - - // Retrieve data to compute radius oscillation amplitude during - if (Bubble->t > tEnd - 10.0 / Bubble->Excitation->f) - { - maxR = APECSS_MAX(maxR, Bubble->R); - } - if (Bubble->t > tEnd - 10.0 / Bubble->Excitation->f) - { - minR = APECSS_MIN(minR, Bubble->R); - } - - // Update allocation of the results (if necessary) - Bubble->results_emissionsnodeminmax_identify(Bubble); - Bubble->results_emissionsnode_alloc(Bubble); - - // Acoustic emissions (if applicable) - Bubble->emissions_update(Bubble); - - // Store results (if applicable) - Bubble->results_rayleighplesset_store(Bubble); - Bubble->results_emissionsspace_store(Bubble); - - // Write one-off results (if applicable) - Bubble->results_emissionstime_write(Bubble); - - // Update the last-step solution of the RK54 scheme - for (register int i = 0; i < Bubble->nODEs; i++) Bubble->kLast[i] = Bubble->k7[i]; - - // Update progress screen in the terminal (if applicable) - Bubble->progress_update(&(*Bubble).progress, Bubble->t - Bubble->tStart, Bubble->tEnd - Bubble->tStart); - } - - return (0); -} \ No newline at end of file diff --git a/examples/bubblyscreen/QA/build/CMakeLists.txt b/examples/bubblyscreen/QA/build/CMakeLists.txt deleted file mode 100644 index 2335399..0000000 --- a/examples/bubblyscreen/QA/build/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -cmake_minimum_required(VERSION 3.12) - -project (bubblyscreen_apecss) -set(CMAKE_C_COMPILER mpicc) - -include_directories($ENV{APECSS_DIR}/include) -FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) - -set (mylibs m apecss) -link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) - -foreach(arg ${myincludes}) - IF (arg MATCHES "-I") - STRING(REGEX REPLACE "-I" "" myinc ${arg}) - message("Additional include: ${myinc}") - include_directories(${myinc}) - ENDIF(arg MATCHES "-I") -endforeach(arg ${myincludes}) - -foreach(arg ${mylibs}) - STRING(REGEX REPLACE "lib" "" myl1 ${arg}) - STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) - set(mylibs ${myl2} ${mylibs} ${myl2}) -endforeach(arg ${mylibs}) - -if(NOT CMAKE_BUILD_TYPE) - message(STATUS "Optimization: No optimization specified.") - set(CMAKE_BUILD_TYPE Release) -endif() - -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - message(STATUS "Optimization: Debug") - set(CMAKE_C_FLAGS_DEBUG "-Wall -g") -elseif(CMAKE_BUILD_TYPE STREQUAL "Release") - message(STATUS "Optimization: Release") - add_definitions(-DNDEBUG) - set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") -endif() - -add_executable(bubblyscreen_apecss ${myfiles}) -target_link_libraries(bubblyscreen_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/bubblyscreen/QA/build/compile.sh b/examples/bubblyscreen/QA/build/compile.sh deleted file mode 100755 index 1569080..0000000 --- a/examples/bubblyscreen/QA/build/compile.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -rm bubblyscreen_apecss -cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release -make -rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/bubblyscreen/QA/execmpi.sh b/examples/bubblyscreen/QA/execmpi.sh deleted file mode 100755 index 08ff9e3..0000000 --- a/examples/bubblyscreen/QA/execmpi.sh +++ /dev/null @@ -1,19 +0,0 @@ -ncore=15 -nbubble=2601 - -cd build -./compile.sh -cd .. -mpiexec -n $ncore ./build/bubblyscreen_apecss -options run.apecss -freq 1.631e6 -amp 100.0 -tend 35.0e-6 -coeff 1.0 -python3 gather_results.py - -for ((c=0; c<$nbubble; c++)) -do - rm -rf Bubble_$c -done - -rm -rf bubblyscreen_radii.txt -for ((c=0; c<$ncore; c++)) -do - rm -rf bubblyscreen_extremum_$c.txt -done \ No newline at end of file diff --git a/examples/bubblyscreen/QA/gather_results.py b/examples/bubblyscreen/QA/gather_results.py deleted file mode 100644 index 71cc38c..0000000 --- a/examples/bubblyscreen/QA/gather_results.py +++ /dev/null @@ -1,44 +0,0 @@ -import os - -# File designed to recover data for plotting results in bubbly screen case - -file_radii = open("bubblyscreen_radii.txt", "r") -lines_radii = file_radii.readlines() -file_radii.close() - -count_core = 0 -for file in os.listdir() : - if "bubblyscreen_extremum_" in file : - count_core += 1 - -lines_extremum = [] -for i in range(count_core) : - file_extremum = open("bubblyscreen_extremum_{}.txt".format(i), "r") - lines = file_extremum.readlines() - file_extremum.close() - lines_extremum.append(lines) - -firstline = lines_radii[0].split(" ") -f = float(firstline[3]) -p = float(firstline[5]) -d = float(firstline[7]) - -file_name = "bubblyscreen_{:.3E}_{:.2E}_{:.1f}".format(f, p, d) - -working_path = os.getcwd() -results_path = os.path.join(working_path, "results") - -results_radii = open(os.path.join(results_path, file_name + "_radii.txt"), "w") -for line in lines_radii : - results_radii.write(line) -results_radii.close() - -results_extremum = open(os.path.join(results_path, file_name + "_extremum.txt"), "w") -for i in range(len(lines_extremum)) : - if i == 0 : - for line in lines_extremum[i] : - results_extremum.write(line) - else : - for line in lines_extremum[i][2:] : - results_extremum.write(line) -results_extremum.close() \ No newline at end of file diff --git a/examples/bubblyscreen/QA/run.apecss b/examples/bubblyscreen/QA/run.apecss deleted file mode 100644 index 5c2d8d9..0000000 --- a/examples/bubblyscreen/QA/run.apecss +++ /dev/null @@ -1,38 +0,0 @@ -######################################################### -# # -# APECSS Options File # -# # -######################################################### - -BUBBLE -RPModel KM -Emissions QA 250.0e-6 -PressureAmbient 1.0e5 -END - -GAS -EoS IG -ReferencePressure 1.0e5 -ReferenceDensity 1.2 -PolytropicExponent 1.4 -END - -LIQUID -ReferencePressure 1.0e5 -ReferenceDensity 1000.0 -ReferenceSoundSpeed 1500.0 -Viscosity 0.00 -END - -INTERFACE -SurfaceTensionCoeff 0.00 -END - -RESULTS -Bubble -OutputFreqRP 5 -END - -ODESOLVER -tolerance 1.0e-10 -END diff --git a/examples/bubblyscreen/QA/src/bubblyscreen_apecss.c b/examples/bubblyscreen/QA/src/bubblyscreen_apecss.c deleted file mode 100644 index adf575e..0000000 --- a/examples/bubblyscreen/QA/src/bubblyscreen_apecss.c +++ /dev/null @@ -1,723 +0,0 @@ -// This source file is part of APECSS, an open-source software toolbox -// for the computation of pressure-driven bubble dynamics and acoustic -// emissions in spherical symmetry. -// -// Copyright (C) 2022-2024 The APECSS Developers -// -// The APECSS Developers are listed in the README.md file available in -// the GitHub repository at https://github.com/polycfd/apecss. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// ------------------------------------------------------------------- -// APECSS standalone example of acoustically-interacting microbubbles, -// demonstrating a simple parallelization of APECSS. -// ------------------------------------------------------------------- - -#include -#include -#include "apecss.h" - -struct APECSS_Parallel_Cluster -{ - int rank, size; - int nBubbles_local, nBubbles_global; - - int *bubblerank; // max id of bubbles for each rank - APECSS_FLOAT *bubbleglobal_R, *bubbleglobal_x, *bubbleglobal_y, *bubbleglobal_z; // Radius and x,y,z location of all bubbles - APECSS_FLOAT *sumGU_rank; // Contributions from local bubbles to all bubbles -}; - -// Declaration of additional case-dependent functions -APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubble[], struct APECSS_Parallel_Cluster *RankInfo); -int parallel_interactions_proper_cutoffdistance(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo); -int apecss_bubble_new_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble, APECSS_FLOAT coeff); -int apecss_emissions_new_prunelist(struct APECSS_Bubble *Bubble, APECSS_FLOAT coeff); -int apecss_emissions_new_updatelinkedlist(struct APECSS_Bubble *Bubble, APECSS_FLOAT coeff); - -APECSS_FLOAT maxR; -APECSS_FLOAT minR; - -int main(int argc, char **args) -{ - /* Initialize MPI */ - int mpi_rank, mpi_size; - MPI_Init(&argc, &args); - MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); - MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); - - char OptionsDir[APECSS_STRINGLENGTH]; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Set the case-dependent simulation parameters - const int nBubbles_x = 51; - const int nBubbles = nBubbles_x * nBubbles_x; // Number of bubbles - APECSS_FLOAT bubble_bubble_dist = 400.0e-6; // Bubble-bubble distance - - // Interbubble time-step, defining the frequency with which the neighbor influence is updated - APECSS_FLOAT dt_interbubble = 1.0e-8; - - // Initialize the simulation parameters given by the execution command - double tEnd = 0.0; - double fa = 0.0; - double pa = 0.0; - double coeff_pruning = 1.0; - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - apecss_infoscreen(); - - /* Read commandline options */ - sprintf(OptionsDir, "./run.apecss"); // This is the default - int j = 1; // First argument is the call to the executable - while (j < argc) - { - if (strcmp("-options", args[j]) == 0) - { - sprintf(OptionsDir, "%s", args[j + 1]); - j += 2; - } - else if (strcmp("-tend", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &tEnd); - j += 2; - } - else if (strcmp("-freq", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &fa); - j += 2; - } - else if (strcmp("-amp", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &pa); - j += 2; - } - else if (strcmp("-coeff", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &coeff_pruning); - j += 2; - } - else if (strcmp("-h", args[j]) == 0) - { - apecss_helpscreen(); - } - else - { - char str[APECSS_STRINGLENGTH_SPRINTF]; - sprintf(str, "Unknown command line options: %s", args[j]); - apecss_erroronscreen(1, str); - ++j; - } - } - - /* Allocate structure for parallel data */ - struct APECSS_Parallel_Cluster *RankInfo = (struct APECSS_Parallel_Cluster *) malloc(sizeof(struct APECSS_Parallel_Cluster)); - RankInfo->rank = mpi_rank; - RankInfo->size = mpi_size; - - /* Determine the number of bubbles per rank */ - int max_per_rank = ceil((double) nBubbles / (double) mpi_size); - RankInfo->nBubbles_local = APECSS_MAX(0, APECSS_MIN(max_per_rank, nBubbles - mpi_rank * max_per_rank)); - - /* Share the parallel distribution of bubbles with all ranks */ - RankInfo->bubblerank = malloc((RankInfo->size + 1) * sizeof(int)); - - RankInfo->nBubbles_global = 0; - RankInfo->bubblerank[0] = 0; - for (int r = 0; r < RankInfo->size; r++) - { - int temp = RankInfo->nBubbles_local; - MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); - RankInfo->bubblerank[r + 1] = RankInfo->bubblerank[r] + temp; - RankInfo->nBubbles_global += temp; - } - - /* Allocate and initialize Bubble structure */ - struct APECSS_Bubble *Bubbles[RankInfo->nBubbles_local]; - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(sizeof(struct APECSS_Bubble)); - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_initializestruct(Bubbles[i]); - - /* Set default options and read the options for the bubble */ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); - - /* Allocate the structures for the fluid properties and ODE solver parameters */ - struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); - struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); - struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); - struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); - - /* Set the default options for the fluid properties and solver parameters */ - apecss_gas_setdefaultoptions(Gas); - apecss_liquid_setdefaultoptions(Liquid); - apecss_interface_setdefaultoptions(Interface); - apecss_odesolver_setdefaultoptions(NumericsODE); - - /* Read the options file for the fluid properties and solver parameters */ - apecss_gas_readoptions(Gas, OptionsDir); - apecss_liquid_readoptions(Liquid, OptionsDir); - apecss_interface_readoptions(Interface, OptionsDir); - apecss_odesolver_readoptions(NumericsODE, OptionsDir); - - /* Associate the bubble with the relevant fluid properties and solver parameters */ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->Gas = Gas; - Bubbles[i]->Liquid = Liquid; - Bubbles[i]->Interface = Interface; - Bubbles[i]->NumericsODE = NumericsODE; - } - - /* Allocate and set the excitation parameters */ - struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); - Excitation->type = APECSS_EXCITATION_SIN; - Excitation->f = (APECSS_FLOAT) fa; - Excitation->dp = (APECSS_FLOAT) pa; - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Excitation = Excitation; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Create individual folders for the results of each bubble - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - if (Bubbles[i]->Results != NULL) - { - sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", RankInfo->bubblerank[RankInfo->rank] + i); - struct stat st = {0}; - if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); - } - } - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - /* Process all options */ - apecss_gas_processoptions(Gas); - apecss_liquid_processoptions(Liquid); - apecss_interface_processoptions(Interface); - apecss_odesolver_processoptions(NumericsODE); - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_processoptions(Bubbles[i]); - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Use the revised pressure at infinity, including neighbor contributions - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->get_pressure_infinity = parallel_interactions_bubble_pressure_infinity; - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - Bubbles[i]->get_pressurederivative_infinity = parallel_interactions_bubble_pressurederivative_infinity; - - // Allocate interaction structure - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); - Bubbles[i]->Interaction->dp_neighbor = 0.0; - Bubbles[i]->Interaction->last_t_1 = 0.0; - Bubbles[i]->Interaction->last_t_2 = 0.0; - Bubbles[i]->Interaction->last_p_1 = 0.0; - Bubbles[i]->Interaction->last_p_2 = 0.0; - } - - // Update interaction structure - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->nBubbles = nBubbles; // Not used? - - // Define the size of each bubble - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->R0 = 1.0e-6; - Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; - } - - // Define center location for each bubble - - int ri = 0, rj = 0; - if (mpi_rank) - { - ri = mpi_rank * max_per_rank % nBubbles_x; - rj = mpi_rank * max_per_rank / nBubbles_x; - } - - for (register int n = 0; n < RankInfo->nBubbles_local; n++) - { - Bubbles[n]->Interaction->location[0] = ((APECSS_FLOAT) ri) * bubble_bubble_dist - (0.5 * (nBubbles_x - 1)) * bubble_bubble_dist; - Bubbles[n]->Interaction->location[1] = ((APECSS_FLOAT) rj) * bubble_bubble_dist - (0.5 * (nBubbles_x - 1)) * bubble_bubble_dist; - Bubbles[n]->Interaction->location[2] = 0.0; - - if (ri < nBubbles_x - 1) - { - ri++; - } - else - { - ri = 0; - rj++; - } - } - - // Share the location of each bubble with all ranks - - RankInfo->bubbleglobal_R = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - RankInfo->bubbleglobal_x = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - RankInfo->bubbleglobal_y = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - RankInfo->bubbleglobal_z = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - - for (int r = 0; r < RankInfo->size; r++) - { - int temp = RankInfo->nBubbles_local; - MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); - - APECSS_FLOAT temp_array[4]; - - for (int i = 0; i < temp; i++) - { - if (r == RankInfo->rank) - { - temp_array[0] = Bubbles[i]->Interaction->location[0]; - temp_array[1] = Bubbles[i]->Interaction->location[1]; - temp_array[2] = Bubbles[i]->Interaction->location[2]; - temp_array[3] = Bubbles[i]->R; - } - - MPI_Bcast(temp_array, 4, MPI_DOUBLE, r, MPI_COMM_WORLD); - - RankInfo->bubbleglobal_x[RankInfo->bubblerank[r] + i] = temp_array[0]; - RankInfo->bubbleglobal_y[RankInfo->bubblerank[r] + i] = temp_array[1]; - RankInfo->bubbleglobal_z[RankInfo->bubblerank[r] + i] = temp_array[2]; - RankInfo->bubbleglobal_R[RankInfo->bubblerank[r] + i] = temp_array[3]; - } - } - - // Update cut off distance for each bubble - parallel_interactions_proper_cutoffdistance(Bubbles, RankInfo); - - // Update pruning options - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->Emissions->pruneList = 1; - // Simple allocation to prevent the warning message with no pruning to pop up - Bubbles[i]->Emissions->prune_test = apecss_emissions_prune_no_node; - } - - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - clock_t starttimebubble = clock(); - APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->tStart = tSim; - Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; - Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step - } - - /* Initialize the bubble based on the selected options */ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_initialize(Bubbles[i]); - - /* Initialize */ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_initialize(Bubbles[i]); - - // Allocate the pressure contribution array - RankInfo->sumGU_rank = malloc(2 * RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Lists to gather maximum and minimum radius achieved by each bubble in steady state - APECSS_FLOAT max_radii[RankInfo->nBubbles_local]; - APECSS_FLOAT min_radii[RankInfo->nBubbles_local]; - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - max_radii[i] = Bubbles[i]->R; - min_radii[i] = Bubbles[i]->R; - } - - // File to retrieve the maximum and minimum radius evolution achieved in steady state - FILE *file_extremum; - char file_name[APECSS_STRINGLENGTH_SPRINTF_LONG]; - sprintf(file_name, "bubblyscreen_extremum_%d.txt", RankInfo->rank); - file_extremum = fopen(file_name, "w"); - - APECSS_FLOAT p0 = Bubbles[0]->p0; - APECSS_FLOAT poly = Gas->Gamma; - APECSS_FLOAT rho = Liquid->rhoref; - APECSS_FLOAT w0 = APECSS_SQRT((3 * poly * p0) / (APECSS_POW2(Bubbles[0]->R0) * rho)); - - fprintf(file_extremum, "w0(rad/s) %e f(Hz) %e p(Pa) %e D/R0 %e\n", w0, fa, pa, bubble_bubble_dist / Bubbles[0]->R0); - fprintf(file_extremum, "label x(m) y(m) z(m) R0(m) Rmin(m) Rmax(m)\n"); - - // File to retrieve the radius evolution during computation - FILE *file_radii; - file_radii = fopen("bubblyscreen_radii.txt", "w"); - fprintf(file_radii, "w0(rad/s) %e f(Hz) %e p(Pa) %e D/R0 %e\n", w0, fa, pa, bubble_bubble_dist / Bubbles[0]->R0); - fprintf(file_radii, "t(s) R(m)\n"); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - /* Solve the bubble dynamics */ - while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered - { - APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); - tSim += dtSim; - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - maxR = 0.0; - minR = Bubbles[i]->R0; - apecss_bubble_new_solver_run(tSim, tEnd, Bubbles[i], (APECSS_FLOAT) coeff_pruning); - - if (maxR > max_radii[i]) - { - max_radii[i] = maxR; - } - if (minR < min_radii[i]) - { - min_radii[i] = minR; - } - } - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Update the contribution of the neighbor bubble - parallel_interactions_quasi_acoustic(Bubbles, RankInfo); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - if (RankInfo->rank == 0) - { - fprintf(file_radii, "%e", tSim); - for (register int i = 0; i < RankInfo->nBubbles_global; i++) - { - fprintf(file_radii, " %e", RankInfo->bubbleglobal_R[i]); - } - fprintf(file_radii, "\n"); - } - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; - Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; - - Bubbles[i]->Interaction->last_t_1 = tSim; - Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; - } - } - - /* Complete results file */ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - fprintf(file_extremum, "%d %e %e %e %e %e %e\n", RankInfo->bubblerank[RankInfo->rank] + i, Bubbles[i]->Interaction->location[0], - Bubbles[i]->Interaction->location[1], Bubbles[i]->Interaction->location[2], Bubbles[i]->R0, min_radii[i], max_radii[i]); - } - fclose(file_extremum); - - fclose(file_radii); - - /* Finalize the simulation*/ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_finalize(Bubbles[i]); - - char str[APECSS_STRINGLENGTH_SPRINTF]; - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", RankInfo->bubblerank[RankInfo->rank] + i, Bubbles[i]->dtNumber, - Bubbles[i]->nSubIter, (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); - apecss_writeonscreen(str); - } - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); - - /* Make sure all allocated memory is freed */ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_freestruct(Bubbles[i]); - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) free(Bubbles[i]); - free(Gas); - free(Liquid); - free(Interface); - free(NumericsODE); - free(Excitation); - - free(RankInfo->bubblerank); - RankInfo->bubblerank = NULL; - free(RankInfo->bubbleglobal_R); - RankInfo->bubbleglobal_R = NULL; - free(RankInfo->bubbleglobal_x); - RankInfo->bubbleglobal_x = NULL; - free(RankInfo->bubbleglobal_y); - RankInfo->bubbleglobal_y = NULL; - free(RankInfo->bubbleglobal_z); - RankInfo->bubbleglobal_z = NULL; - free(RankInfo->sumGU_rank); - RankInfo->sumGU_rank = NULL; - free(RankInfo); - - MPI_Finalize(); - - return (0); -} - -APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * t) + Bubble->Interaction->dp_neighbor); -} - -APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - APECSS_FLOAT derivative = -2.0 * APECSS_PI * Bubble->Excitation->f * Bubble->Excitation->dp * APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * t); - APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; - if (delta_t > Bubble->dt) - { - return (derivative + (Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) / delta_t); - } - else - { - return (derivative); - } -} - -int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo) -{ - // All bubbles are supposed to be in the same liquid - struct APECSS_Liquid *Liquid = Bubbles[0]->Liquid; - - // Update bubble radii info - APECSS_FLOAT *tempR = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - for (register int j = 0; j < RankInfo->nBubbles_global; j++) tempR[j] = 0.0; - for (register int i = 0; i < RankInfo->nBubbles_local; i++) tempR[RankInfo->bubblerank[RankInfo->rank] + i] = Bubbles[i]->R; - MPI_Allreduce(tempR, RankInfo->bubbleglobal_R, RankInfo->nBubbles_global, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - free(tempR); - - // Reset pressure contributions of the neighours - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; - - // Locally compute the contribution to each bubble - for (register int j = 0; j < RankInfo->nBubbles_global; j++) - { - APECSS_FLOAT x_j = RankInfo->bubbleglobal_x[j]; - APECSS_FLOAT y_j = RankInfo->bubbleglobal_y[j]; - APECSS_FLOAT z_j = RankInfo->bubbleglobal_z[j]; - - RankInfo->sumGU_rank[j] = 0.0; - RankInfo->sumGU_rank[j + RankInfo->nBubbles_global] = 0.0; - - double R_j = RankInfo->bubbleglobal_R[j]; - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - if (j != RankInfo->bubblerank[RankInfo->rank] + i) - { - APECSS_FLOAT sumU_bubble = 0.0; - APECSS_FLOAT sumG_bubble = 0.0; - int nodecount_bubble = 0; - - APECSS_FLOAT x_i = Bubbles[i]->Interaction->location[0]; - APECSS_FLOAT y_i = Bubbles[i]->Interaction->location[1]; - APECSS_FLOAT z_i = Bubbles[i]->Interaction->location[2]; - - APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); - - // The loop over the emission nodes begins with the most far away from the emitting bubble - struct APECSS_EmissionNode *Current = Bubbles[i]->Emissions->LastNode; - while (Current != NULL) - { - if (Current->r < interbubble_dist - R_j) - { - // The following emission nodes have not yet reached the bubble of interest - Current = NULL; - } - else if (Current->r > interbubble_dist + R_j) - { - // The bubble of interest is still not reached - Current = Current->backward; - } - else - { - // The current emission node is located inside the bubble of interest - APECSS_FLOAT gr = Current->g / Current->r; - sumU_bubble += (Current->f / APECSS_POW2(Current->r)) + gr / Liquid->cref; - sumG_bubble += gr; - nodecount_bubble++; - Current = Current->backward; - } - } - - if (nodecount_bubble) - { - APECSS_FLOAT inv_nodecount = 1.0 / (APECSS_FLOAT) nodecount_bubble; - RankInfo->sumGU_rank[j] += sumG_bubble * inv_nodecount; - RankInfo->sumGU_rank[j + RankInfo->nBubbles_global] += sumU_bubble * inv_nodecount; - } - } - } - } - - APECSS_FLOAT *sumGU_all = malloc(2 * RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - MPI_Allreduce(RankInfo->sumGU_rank, sumGU_all, 2 * RankInfo->nBubbles_global, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - - // Compute the total pressure contributions of the neighbours for all local bubbles - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->Interaction->dp_neighbor = - Liquid->rhoref * (sumGU_all[RankInfo->bubblerank[RankInfo->rank] + i] - - 0.5 * APECSS_POW2(sumGU_all[RankInfo->nBubbles_global + RankInfo->bubblerank[RankInfo->rank] + i])); - } - - free(sumGU_all); - - return (0); -} - -int parallel_interactions_proper_cutoffdistance(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo) -{ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - APECSS_FLOAT x_i = Bubbles[i]->Interaction->location[0]; - APECSS_FLOAT y_i = Bubbles[i]->Interaction->location[1]; - APECSS_FLOAT z_i = Bubbles[i]->Interaction->location[2]; - APECSS_FLOAT dist = 0.0; - - for (register int j = 0; j < RankInfo->nBubbles_global; j++) - { - APECSS_FLOAT x_j = RankInfo->bubbleglobal_x[j]; - APECSS_FLOAT y_j = RankInfo->bubbleglobal_y[j]; - APECSS_FLOAT z_j = RankInfo->bubbleglobal_z[j]; - - APECSS_FLOAT dist_ij = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); - - if (dist_ij > dist) - { - dist = dist_ij; - } - } - if (Bubbles[i]->Emissions != NULL) Bubbles[i]->Emissions->CutOffDistance = 1.25 * dist; - } - return (0); -} - -int apecss_bubble_new_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble, APECSS_FLOAT coeff) -{ - while (Bubble->t < tend - 0.01 * Bubble->NumericsODE->dtMin) - { - // Store the previous solution for sub-iterations - for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSolOld[i] = Bubble->ODEsSol[i]; - - // Check what comes next: the end of the solver run or, if applicable, a time instance to output the emissions - APECSS_FLOAT next_event_time = Bubble->results_emissionstime_check(tend, Bubble); - - // Set the time-step for the ODEs - apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); - - // Solve the ODEs - Bubble->err = apecss_odesolver(Bubble); - - // Perform sub-iterations on the control of the time-step when err > tol - register int subiter = 0; - while ((Bubble->err > Bubble->NumericsODE->tol) && (subiter < Bubble->NumericsODE->maxSubIter)) - { - ++subiter; - // Rewind the solution - for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSol[i] = Bubble->ODEsSolOld[i]; - // Set the time-step for the ODEs - apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); - // Solve the ODEs again - Bubble->err = apecss_odesolver(Bubble); - } - Bubble->nSubIter += subiter; - - // Set new values - ++(Bubble->dtNumber); - Bubble->t += Bubble->dt; - Bubble->U = Bubble->ODEsSol[0]; - Bubble->R = Bubble->ODEsSol[1]; - - // Retrieve data to compute radius oscillation amplitude during - if (Bubble->t > tEnd - 10.0 / Bubble->Excitation->f) - { - maxR = APECSS_MAX(maxR, Bubble->R); - } - if (Bubble->t > tEnd - 10.0 / Bubble->Excitation->f) - { - minR = APECSS_MIN(minR, Bubble->R); - } - - // Update allocation of the results (if necessary) - Bubble->results_emissionsnodeminmax_identify(Bubble); - Bubble->results_emissionsnode_alloc(Bubble); - - // Acoustic emissions with pruning (if applicable) - apecss_emissions_new_updatelinkedlist(Bubble, coeff); - - // Store results (if applicable) - Bubble->results_rayleighplesset_store(Bubble); - Bubble->results_emissionsspace_store(Bubble); - - // Write one-off results (if applicable) - Bubble->results_emissionstime_write(Bubble); - - // Update the last-step solution of the RK54 scheme - for (register int i = 0; i < Bubble->nODEs; i++) Bubble->kLast[i] = Bubble->k7[i]; - - // Update progress screen in the terminal (if applicable) - Bubble->progress_update(&(*Bubble).progress, Bubble->t - Bubble->tStart, Bubble->tEnd - Bubble->tStart); - } - - return (0); -} - -int apecss_emissions_new_prunelist(struct APECSS_Bubble *Bubble, APECSS_FLOAT coeff) -{ - struct APECSS_EmissionNode *Current = Bubble->Emissions->LastNode; - - APECSS_FLOAT inv_nBubbles = 1 / (APECSS_FLOAT) Bubble->Interaction->nBubbles; - APECSS_FLOAT pinfinity = Bubble->get_pressure_infinity(Bubble->t, Bubble); - - APECSS_FLOAT pressure_treshold = coeff * pinfinity * inv_nBubbles; - - while (Current != NULL) - { - if (APECSS_ABS(Current->p - pinfinity) < pressure_treshold) - { - // Delete the node if it satisfies the pruning condition - struct APECSS_EmissionNode *Obsolete = Current; - if ((Current->backward != NULL) && (Current->forward != NULL)) - { - Current->backward->forward = Current->forward; - Current->forward->backward = Current->backward; - Current = Current->backward; - Bubble->Emissions->nNodes -= 1; - } - else if ((Current->backward != NULL) && (Current->forward == NULL)) - { - Current->backward->forward = NULL; - Bubble->Emissions->LastNode = Current->backward; - Current = Current->backward; - Bubble->Emissions->nNodes -= 1; - } - else if ((Current->backward == NULL) && (Current->forward != NULL)) - { - Current->forward->backward = NULL; - Bubble->Emissions->FirstNode = Current->forward; - Current = NULL; - Bubble->Emissions->nNodes -= 1; - } - else - { - Bubble->Emissions->FirstNode = NULL; - Bubble->Emissions->LastNode = NULL; - Bubble->Emissions->nNodes = 0; - Current = NULL; - } - free(Obsolete); - // apecss_emissions_deletenode(Bubble, Current); - } - else - { - // Move to the next node - Current = Current->backward; - } - } - - return (0); -} - -int apecss_emissions_new_updatelinkedlist(struct APECSS_Bubble *Bubble, APECSS_FLOAT coeff) -{ - if (Bubble->Emissions->nNodes) Bubble->Emissions->advance(Bubble); - apecss_emissions_addnode(Bubble); - if (Bubble->Emissions->LastNode->r > Bubble->Emissions->CutOffDistance) apecss_emissions_removenode(Bubble); - if (Bubble->Emissions->pruneList) apecss_emissions_new_prunelist(Bubble, coeff); - - return (0); -} \ No newline at end of file diff --git a/examples/bubblyscreen/README.md b/examples/bubblyscreen/README.md deleted file mode 100644 index 8059ba6..0000000 --- a/examples/bubblyscreen/README.md +++ /dev/null @@ -1 +0,0 @@ -This example builds a standalone APECSS code for a 51x51 finite bubbly screen of interacting microbubbles, inspired by [Fan, Y., Li, H., & Fuster, D. (2021). Time-delayed interactions on acoustically driven bubbly screens. The Journal of the Acoustical Society of America, 150(6), 4219‑4231.](https://doi.org/10.1121/10.0008905). Two interaction type are considered : either the _standard incompressible model_ ("IC") or the newly developped _quasi acoustic model_ ("QA"). In order to optimize computational costs, the quasi acoustic computations are run by using parallelization. The computations are quite heavy because steady state must be achieved, leading to large enough computed times (IC interactions are taking around an hour for 35 microseconds of computed times, while it's around with 15 cores of an Intel 13th gen I7 13700K x24). The displayed results are for each excitation frequency tested the normalized radius oscillation amplitude of each bubble in steady state. \ No newline at end of file diff --git a/examples/bubblyscreen/plot_results.py b/examples/bubblyscreen/plot_results.py deleted file mode 100644 index 578528e..0000000 --- a/examples/bubblyscreen/plot_results.py +++ /dev/null @@ -1,243 +0,0 @@ -import os -import numpy as np -import matplotlib.pyplot as plt -from math import pi -from matplotlib.patches import Circle - -fontsize = 20.5 - -plt.rcParams['font.family']='serif' -plt.rcParams['font.serif']=['Times New Roman'] + plt.rcParams['font.serif'] -plt.rcParams['mathtext.fontset']='stix' -plt.rcParams['font.size']=fontsize - -cm = 1/2.54 - -# This file is designed to gather data in order to reproduce the average radius evolution -# This exemple is a reproduction from the test from Fig.5 in 2021 Fan's article -# DOI : 10.1121/10.0008905 - -######### Step 1 : Retrieving data ################################################################################################################## -interaction_types = ["IC", "QA"] -excitation_w = [0.5, 0.9, 1.0, 1.5] -ratio_D_R0 = [400] - -dic_bubbly_screen = {} -dic_radii = {} -dic_radii_index = {} -index = 1301 -for intype in interaction_types : - dic_bubbly_screen[intype] = {} - dic_radii[intype] = {} - dic_radii_index[intype] = {} - for w in excitation_w : - dic_bubbly_screen[intype][w] = {} - dic_radii[intype][w] = {} - dic_radii_index[intype][w] = {} - for r in ratio_D_R0 : - dic_bubbly_screen[intype][w][r] = np.zeros((51,51),dtype=float) - dic_radii[intype][w][r] = [[] for i in range(51*51 + 1)] - dic_radii_index[intype][w][r] = [[], []] - -for intype in interaction_types : - path = os.path.join(os.getcwd(), intype) - path = os.path.join(path, "results") - for file in os.listdir(path) : - if "_extremum" in file : - data = open(os.path.join(path, file), "r") - lines = data.readlines() - data.close() - - firstline = lines[0].split(" ") - w0 = float(firstline[1]) - fa = float(firstline[3]) - pa = float(firstline[5]) - ratio = int(float(firstline[7])) - - R0 = float(lines[2].split(" ")[4]) - D = ratio * R0 - - w = float("{:.1f}".format(2 * pi * fa / w0)) - - if pa == 10**2 : - for line in lines[2:] : - x = float(line.split(" ")[1]) - y = float(line.split(" ")[2]) - r_amp = (float(line.split(" ")[6]) - float(line.split(" ")[5])) / (2 * float(line.split(" ")[4])) - - i = int((y/D)) + 25 - j = int((x/D)) + 25 - - dic_bubbly_screen[intype][w][ratio][i][j] = r_amp - - if "_radii" in file : - print(file) - data = open(os.path.join(path, file), "r") - lines = data.readlines() - data.close() - - firstline = lines[0].split(" ") - w0 = float(firstline[1]) - fa = float(firstline[3]) - pa = float(firstline[5]) - ratio = int(float(firstline[7])) - - R0 = float(lines[2].split(" ")[1]) - D = ratio * R0 - - w = float("{:.1f}".format(2 * pi * fa / w0)) - - if pa == 10**2 : - # for i in range(2, len(lines), 25) : - # line = lines[i] - # t = float(line.split(" ")[0]) - # dic_radii[intype][w][ratio][0].append(t) - - # for i in range(51*51) : - # r = (float(line.split(" ")[i + 1]) - R0) / R0 - # dic_radii[intype][w][ratio][i + 1].append(r) - - for i in range(2, len(lines)) : - line = lines[i] - t = float(line.split(" ")[0]) - dic_radii_index[intype][w][ratio][0].append(t) - # r = (float(line.split(" ")[index]) - R0) / R0 - r = float(line.split(" ")[index]) - dic_radii_index[intype][w][ratio][1].append(r) - -######### Functions ################################################################################################################################# - -def plot_oscillation_distribution(fig, axs, row, col, nbubbles_x, inttype, ratio_w, ratio_d, order=0, clear=False) : - space = int(0.5 * (nbubbles_x - 1)) - X = [-space + j for j in range(nbubbles_x)] - Y = [-space + i for i in range(nbubbles_x)] - X, Y = np.meshgrid(X, Y) - - axs[row, col].set_title(r"$\omega/\omega_{0}$ = " + "{:.1f}".format(ratio_w)) - cset = plt.pcolormesh(X, Y, dic_bubbly_screen[inttype][ratio_w][ratio_d]*10**(order)) - - # Clearing options to not show pcolormesh (only used for the last plotted distribution on each figure) - if clear : - axs[row, col].clear() - axs[row, col].set_xlabel(r"x/D") - axs[row, col].set_xlim(xmin=-(space + 0.5),xmax=(space + 0.5)) - axs[row, col].set_ylabel(r"y/D") - axs[row, col].set_ylim(ymin=-(space + 0.5),ymax=(space + 0.5)) - axs[row, col].set_title(r"$\omega/\omega_{0}$ = " + "{:.1f}".format(ratio_w)) - axs[row, col].set_aspect("equal") - - clb = fig.colorbar(cset, ax=axs[row, col], pad=0.025, shrink=0.665) - if order > 0 : - clb.ax.set_title(r"$|r'| \times 10^{-order}$".replace("order", str(order)), fontsize=fontsize+1.0) - else : - clb.ax.set_title(r"$|r'|$", fontsize=fontsize+1.0) - colors = cset.cmap(cset.norm(cset.get_array())) - for i in range(nbubbles_x) : - for j in range(nbubbles_x) : - # index = nbubbles_x * i + j - index_color = colors[j][i] - x = j - space - y = i - space - circle = Circle((x, y), 0.4, facecolor=(index_color[0], index_color[1], index_color[2])) - axs[row, col].add_patch(circle) - -def identify_oscillation_amplitude(t_list, r_list) : - # t_list and r_list must be 1D-arrays - # Determine the evolution of the oscillation amplitude by decomposing the entry signal - r_mean = np.mean(r_list) - r_mmean_list = r_list - r_mean - - index = 0 - index_positive_list = [] - while index < len(t_list) : - if r_mmean_list[index] > 0 : - index_positive_list.append(index) - index += 1 - - periods_index = [] - list_index = 1 - periods_index.append([index_positive_list[0]]) - while list_index < len(index_positive_list) : - if index_positive_list[list_index] - index_positive_list[list_index - 1] > 1 : - # A step larger than one in index means a new period has been reached - periods_index[-1].append(index_positive_list[list_index] - 1) - periods_index.append([index_positive_list[list_index]]) - list_index += 1 - - if len(periods_index[-1]) == 1 : - periods_index = periods_index[:len(periods_index)-1] - - t_amp_list = [] - r_amp_list = [] - for i in range(len(periods_index)) : - start_index = periods_index[i][0] - stop_index = periods_index[i][1] - - mean_index = int(0.5 * (start_index + stop_index)) - t_amp_list.append(t_list[mean_index]) - - r_slice_list = r_list[start_index : stop_index + 1] - r_max = np.max(r_slice_list) - r_min = np.min(r_slice_list) - r_amp_list.append(0.5 * (r_max - r_min)) - - return t_amp_list, r_amp_list - -######### Step 2 : Plot results ##################################################################################################################### - -######### D/R0 = 400 : Comparison between QA and IC ############################################### - -nrow = 2 -ncol = 4 -fig, axs = plt.subplots(nrow,ncol,figsize=(55*cm, 27.5*cm)) -for i in range(nrow) : - for j in range(ncol) : - axs[i,j].set_xlabel(r"y/D") - axs[i,j].set_xlim(xmin=-25.5,xmax=25.5) - axs[i,j].set_ylabel(r"z/D") - axs[i,j].set_ylim(ymin=-25.5,ymax=25.5) - axs[i,j].set_aspect("equal") - -### First row : QA ### -plt.figtext(0.5, 0.875, r"(a) QA", fontsize=25.0, horizontalalignment="center") -plot_oscillation_distribution(fig, axs, 0, 0, 51, "QA", 0.5, 400, order=4) -plot_oscillation_distribution(fig, axs, 0, 1, 51, "QA", 0.9, 400, order=3) -plot_oscillation_distribution(fig, axs, 0, 2, 51, "QA", 1.0, 400, order=2) -plot_oscillation_distribution(fig, axs, 0, 3, 51, "QA", 1.5, 400, order=4) - -### Second row : IC ### -plt.figtext(0.5, 0.475, r"(b) IC", fontsize=25.0, horizontalalignment="center") -plot_oscillation_distribution(fig, axs, 1, 0, 51, "IC", 0.5, 400, order=4) -plot_oscillation_distribution(fig, axs, 1, 1, 51, "IC", 0.9, 400, order=3) -plot_oscillation_distribution(fig, axs, 1, 2, 51, "IC", 1.0, 400, order=3) -plot_oscillation_distribution(fig, axs, 1, 3, 51, "IC", 1.5, 400, order=4, clear=True) - -fig.subplots_adjust(hspace=0.01*cm, wspace=0.95*cm) -fig.savefig("bubblyscreen_ComparisonQAIC.pdf", bbox_inches="tight",pad_inches=0.035) - -######### D/R0 = 400 : Radius evolution ########################################################### - -fig, ax = plt.subplots(1, 1, figsize=(27.5*cm, 12.5*cm)) -ax.set_xlabel(r"$t$ [$\mu$s]") -ax.set_xlim(xmin=0.0, xmax=35.0) -ax.set_ylabel(r"$|r'|$") -ax.set_yscale("log") -ax.set_ylim(ymin=10**(-4), ymax=5.0e-2) -ax.grid() - -### QA ### -t_list, r_list = identify_oscillation_amplitude(np.array(dic_radii_index["QA"][1.0][400][0]), np.array(dic_radii_index["QA"][1.0][400][1])) -ax.plot(np.array(t_list)*1.0e6, np.array(r_list)/R0, linewidth=2.0, color="black", linestyle="dashed", label="QA") -# ax.plot(np.array(dic_radii_index["QA"][1.0][400][0])*1.0e6, np.array(dic_radii_index["QA"][1.0][400][1]), linewidth=2.0, color="black", linestyle="dashed", label="QA") -# ax.plot(np.array(dic_radii["QA"][1.0][400][0])*1.0e6, np.array(dic_radii["QA"][1.0][400][1301]), linewidth=2.0, color="black", linestyle="dashed", label="QA") -# ax.plot(np.array(dic_radii["QA"][1.0][400][0])*1.0e6, np.array(dic_radii["QA"][1.0][400][1]), linewidth=1.5, marker="s", markersize=5.0, markevery=1500, color="black", linestyle="dashed", label="QA, corner") - -### IC ### -t_list, r_list = identify_oscillation_amplitude(np.array(dic_radii_index["IC"][1.0][400][0]), np.array(dic_radii_index["IC"][1.0][400][1])) -ax.plot(np.array(t_list)*1.0e6, np.array(r_list)/R0, linewidth=2.0, color="red", linestyle="solid", label="IC") -# ax.plot(np.array(dic_radii_index["IC"][1.0][400][0])*1.0e6, np.array(dic_radii_index["IC"][1.0][400][1]), linewidth=2.0, color="red", linestyle="solid", label="IC") -# ax.plot(np.array(dic_radii["IC"][1.0][400][0])*1.0e6, np.array(dic_radii["IC"][1.0][400][1301]), linewidth=2.0, color="red", linestyle="solid", label="IC") -# ax.plot(np.array(dic_radii["IC"][1.0][400][0])*1.0e6, np.array(dic_radii["IC"][1.0][400][1]), linewidth=1.5, marker="s", markersize=5.0, markevery=1500, color="red", linestyle="solid", label="IC, corner") - -ax.legend(bbox_to_anchor=(0.5, 1.05), loc="center", frameon=False, ncol=2) -fig.savefig("bubblyscreen_radiievolution.pdf", bbox_inches="tight",pad_inches=0.035) \ No newline at end of file diff --git a/examples/bubblyscreen/run_bubblyscreen.sh b/examples/bubblyscreen/run_bubblyscreen.sh deleted file mode 100755 index e1728ae..0000000 --- a/examples/bubblyscreen/run_bubblyscreen.sh +++ /dev/null @@ -1,76 +0,0 @@ -######### Parameters ################################################################################################################################ - -ncore=20 -nbubbles=2601 - -######### Incompressible computations ############################################################################################################### - -cd IC/build -./compile.sh -cd .. - -f_list=(1.631e06 2.934e06 3.262e06 4.893e06) -for f in "${f_list[@]}" -do - ./build/bubblyscreen_apecss -options run.apecss -freq $f -amp 100.0 -tend 60.0e-6 - python3 gather_results.py -done - -cd .. - -echo "" -echo "Incompressible test cases passed" -echo "" - -######### Quasi acoustic computations ############################################################################################################### - -cd QA/build -./compile.sh -cd .. - -f_list=(1.631e06 2.934e06 3.262e06 4.893e06) -c_list=(0.0005 0.005 0.05 0.001) -for ((i=0; i<5; i++)) -do - mpiexec -n $ncore ./build/bubblyscreen_apecss -options run.apecss -freq ${f_list[$i]} -amp 100.0 -tend 60.0e-6 -coeff ${c_list[$i]} - python3 gather_results.py -done -cd .. - -echo "" -echo "Quasi acoustic test cases passed" -echo "" - -######### Plotting results ########################################################################################################################## - -python3 plot_results.py - -echo "" -echo "Results plotted" -echo "" - -######### Cleaning ################################################################################################################################## - -cd IC -for ((c=0; c<$nbubbles; c++)) -do - rm -rf Bubble_$c -done -rm -rf bubblyscreen_radii.txt bubblyscreen_extremum.txt -cd .. - -cd QA -for ((c=0; c<$nbubbles; c++)) -do - rm -rf Bubble_$c -done -rm -rf bubblyscreen_radii.txt -for ((c=0; c<$ncore; c++)) -do - rm -rf bubblyscreen_extremum_$c.txt -done -cd .. - -echo "" -echo "Cleaning completed" -echo "" \ No newline at end of file From 41b46e322cc77e9a91dee9694607862bd1e9720d Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 23 Sep 2024 13:31:59 -0400 Subject: [PATCH 128/138] frequencyresponse ; deleting folder --- .../frequencyresponse/IC/build/CMakeLists.txt | 41 -- .../frequencyresponse/IC/build/compile.sh | 5 - .../frequencyresponse/IC/gather_results.py | 35 -- examples/frequencyresponse/IC/run.apecss | 36 -- .../IC/src/frequencyresponse_apecss.c | 430 ----------------- .../frequencyresponse/NI/build/CMakeLists.txt | 41 -- .../frequencyresponse/NI/build/compile.sh | 5 - .../frequencyresponse/NI/gather_results.py | 35 -- examples/frequencyresponse/NI/run.apecss | 36 -- .../NI/src/frequencyresponse_apecss.c | 421 ----------------- .../frequencyresponse/QA/build/CMakeLists.txt | 41 -- .../frequencyresponse/QA/build/compile.sh | 5 - .../frequencyresponse/QA/gather_results.py | 35 -- examples/frequencyresponse/QA/run.apecss | 36 -- .../QA/src/frequencyresponse_apecss.c | 447 ------------------ examples/frequencyresponse/plot_results.py | 390 --------------- .../run_frequencyresponse.sh | 144 ------ 17 files changed, 2183 deletions(-) delete mode 100644 examples/frequencyresponse/IC/build/CMakeLists.txt delete mode 100755 examples/frequencyresponse/IC/build/compile.sh delete mode 100644 examples/frequencyresponse/IC/gather_results.py delete mode 100644 examples/frequencyresponse/IC/run.apecss delete mode 100644 examples/frequencyresponse/IC/src/frequencyresponse_apecss.c delete mode 100644 examples/frequencyresponse/NI/build/CMakeLists.txt delete mode 100755 examples/frequencyresponse/NI/build/compile.sh delete mode 100644 examples/frequencyresponse/NI/gather_results.py delete mode 100644 examples/frequencyresponse/NI/run.apecss delete mode 100644 examples/frequencyresponse/NI/src/frequencyresponse_apecss.c delete mode 100644 examples/frequencyresponse/QA/build/CMakeLists.txt delete mode 100755 examples/frequencyresponse/QA/build/compile.sh delete mode 100644 examples/frequencyresponse/QA/gather_results.py delete mode 100644 examples/frequencyresponse/QA/run.apecss delete mode 100644 examples/frequencyresponse/QA/src/frequencyresponse_apecss.c delete mode 100644 examples/frequencyresponse/plot_results.py delete mode 100755 examples/frequencyresponse/run_frequencyresponse.sh diff --git a/examples/frequencyresponse/IC/build/CMakeLists.txt b/examples/frequencyresponse/IC/build/CMakeLists.txt deleted file mode 100644 index 7e6cde8..0000000 --- a/examples/frequencyresponse/IC/build/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -cmake_minimum_required(VERSION 3.12) - -project (frequencyresponse_apecss) -set(CMAKE_C_COMPILER /usr/bin/gcc) - -include_directories($ENV{APECSS_DIR}/include) -FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) - -set (mylibs m apecss) -link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) - -foreach(arg ${myincludes}) - IF (arg MATCHES "-I") - STRING(REGEX REPLACE "-I" "" myinc ${arg}) - message("Additional include: ${myinc}") - include_directories(${myinc}) - ENDIF(arg MATCHES "-I") -endforeach(arg ${myincludes}) - -foreach(arg ${mylibs}) - STRING(REGEX REPLACE "lib" "" myl1 ${arg}) - STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) - set(mylibs ${myl2} ${mylibs} ${myl2}) -endforeach(arg ${mylibs}) - -if(NOT CMAKE_BUILD_TYPE) - message(STATUS "Optimization: No optimization specified.") - set(CMAKE_BUILD_TYPE Release) -endif() - -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - message(STATUS "Optimization: Debug") - set(CMAKE_C_FLAGS_DEBUG "-Wall -g") -elseif(CMAKE_BUILD_TYPE STREQUAL "Release") - message(STATUS "Optimization: Release") - add_definitions(-DNDEBUG) - set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") -endif() - -add_executable(frequencyresponse_apecss ${myfiles}) -target_link_libraries(frequencyresponse_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/frequencyresponse/IC/build/compile.sh b/examples/frequencyresponse/IC/build/compile.sh deleted file mode 100755 index 55dab1c..0000000 --- a/examples/frequencyresponse/IC/build/compile.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -rm frequencyresponse_apecss -cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release -make -rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/frequencyresponse/IC/gather_results.py b/examples/frequencyresponse/IC/gather_results.py deleted file mode 100644 index 7362d5a..0000000 --- a/examples/frequencyresponse/IC/gather_results.py +++ /dev/null @@ -1,35 +0,0 @@ -import os - -######### File designed to retrieve and gather in the "results" folder the data obtained with frequency response computations - -working_path = os.getcwd() - -results_file = open(os.path.join(working_path, "max_radius.txt"), "r") -lines = results_file.readlines() -results_file.close() - -firstline = lines[0].split(" ") -nBubbles = int(firstline[1]) -pa = float(firstline[5]) -dist = float(firstline[7]) -ode = int(firstline[9]) - -gather_path = os.path.join(working_path, "results") - -file_name = "{}_p{:.5E}_d{:.2E}_{}.txt".format(nBubbles, pa, dist, ode) - -data_file = open(os.path.join(gather_path, file_name), "w") -data_file.write("nb {} p(Pa) {:.5E} dist {:.2E} ODE {}\n".format(nBubbles, pa, dist, ode)) -data_file.write("#f(Hz) R0(m);R(m)\n") - -for line in lines : - if line != "" : - data = line.split(" ") - f = float(data[3]) - data_file.write("{:.5E}".format(f)) - - r_list = data[11:] - for r in r_list : - data_file.write(" {}".format(r)) - -data_file.close() \ No newline at end of file diff --git a/examples/frequencyresponse/IC/run.apecss b/examples/frequencyresponse/IC/run.apecss deleted file mode 100644 index 67300c7..0000000 --- a/examples/frequencyresponse/IC/run.apecss +++ /dev/null @@ -1,36 +0,0 @@ -######################################################### -# # -# APECSS Options File # -# # -######################################################### - -BUBBLE -RPModel KM -Emissions IC 300.0e-6 -PressureAmbient 1.0e5 -END - -GAS -EoS IG -ReferenceDensity 1.2 -PolytropicExponent 1.4 -END - -LIQUID -ReferencePressure 1.0e5 -ReferenceDensity 1000.0 -ReferenceSoundSpeed 1500.0 -Viscosity 1.002e-3 -END - -INTERFACE -SurfaceTensionCoeff 0.0728 -END - -RESULTS -Bubble -END - -ODESOLVER -tolerance 1.0e-10 -END diff --git a/examples/frequencyresponse/IC/src/frequencyresponse_apecss.c b/examples/frequencyresponse/IC/src/frequencyresponse_apecss.c deleted file mode 100644 index 9cf0f16..0000000 --- a/examples/frequencyresponse/IC/src/frequencyresponse_apecss.c +++ /dev/null @@ -1,430 +0,0 @@ -// This source file is part of APECSS, an open-source software toolbox -// for the computation of pressure-driven bubble dynamics and acoustic -// emissions in spherical symmetry. -// -// Copyright (C) 2022-2024 The APECSS Developers -// -// The APECSS Developers are listed in the README.md file available in -// the GitHub repository at https://github.com/polycfd/apecss. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// ------------------------------------------------------------------- -// APECSS standalone example of acoustically-interacting microbubbles, -// based on Jiang et al., Ultrasonics Sonochemistry 34 (2017), 90-97. -// ------------------------------------------------------------------- - -#include -#include "apecss.h" - -// Declaration of additional case-dependent functions -APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -APECSS_FLOAT apecss_rp_kellermiksisvelocity_ode_simplified(APECSS_FLOAT *Sol, APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -int apecss_new_bubble_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble); - -APECSS_FLOAT APECSS_TAN(APECSS_FLOAT x) { return APECSS_SIN(x) / APECSS_COS(x); } - -APECSS_FLOAT maxR; - -int main(int argc, char **args) -{ - char OptionsDir[APECSS_STRINGLENGTH]; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Set the case-dependent simulation parameters - int nBubbles = 3; // Number of bubbles - APECSS_FLOAT bubble_bubble_dist = 5.0e-6; // Bubble-bubble distance - - // Interbubble time-step, defining the frequency with which the neighbor influence is updated - APECSS_FLOAT dt_interbubble = 1.0e-8; - - // Initialize the simulation parameters given by the execution command - double tEnd = 0.0; - double fa = 0.0; - double pa = 0.0; - double dist = 5.0e-6; - double dt_inter = 1.0e-8; - int ode = 0; - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - apecss_infoscreen(); - - /* Read commandline options */ - sprintf(OptionsDir, "./run.apecss"); // This is the default - int j = 1; // First argument is the call to the executable - while (j < argc) - { - if (strcmp("-options", args[j]) == 0) - { - sprintf(OptionsDir, "%s", args[j + 1]); - j += 2; - } - else if (strcmp("-nb", args[j]) == 0) - { - sscanf(args[j + 1], "%d", &nBubbles); - j += 2; - } - else if (strcmp("-tend", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &tEnd); - j += 2; - } - else if (strcmp("-freq", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &fa); - j += 2; - } - else if (strcmp("-amp", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &pa); - j += 2; - } - else if (strcmp("-dist", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &dist); - j += 2; - } - else if (strcmp("-dt_inter", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &dt_inter); - j += 2; - } - else if (strcmp("-ode", args[j]) == 0) - { - sscanf(args[j + 1], "%d", &ode); - j += 2; - } - else if (strcmp("-h", args[j]) == 0) - { - apecss_helpscreen(); - } - else - { - char str[APECSS_STRINGLENGTH_SPRINTF]; - sprintf(str, "Unknown command line options: %s", args[j]); - apecss_erroronscreen(1, str); - ++j; - } - } - - /* Properly update parameters with commandline options */ - bubble_bubble_dist = (APECSS_FLOAT) dist; - dt_interbubble = (APECSS_FLOAT) dt_inter; - tEnd = 30 / fa; - - /* Check if the number of bubbles is right */ - if ((nBubbles != 3) && (nBubbles != 4)) - { - nBubbles = 3; - } - - /* Allocate and initialize Bubble structure */ - struct APECSS_Bubble *Bubbles[nBubbles]; - for (register int i = 0; i < nBubbles; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(nBubbles * sizeof(struct APECSS_Bubble)); - for (register int i = 0; i < nBubbles; i++) apecss_bubble_initializestruct(Bubbles[i]); - - /* Set default options and read the options for the bubble */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); - for (register int i = 0; i < nBubbles; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); - - /* Allocate the structures for the fluid properties and ODE solver parameters */ - struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); - struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); - struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); - struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); - - /* Set the default options for the fluid properties and solver parameters */ - apecss_gas_setdefaultoptions(Gas); - apecss_liquid_setdefaultoptions(Liquid); - apecss_interface_setdefaultoptions(Interface); - apecss_odesolver_setdefaultoptions(NumericsODE); - - /* Read the options file for the fluid properties and solver parameters */ - apecss_gas_readoptions(Gas, OptionsDir); - apecss_liquid_readoptions(Liquid, OptionsDir); - apecss_interface_readoptions(Interface, OptionsDir); - apecss_odesolver_readoptions(NumericsODE, OptionsDir); - - /* Associate the bubble with the relevant fluid properties and solver parameters */ - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->Gas = Gas; - Bubbles[i]->Liquid = Liquid; - Bubbles[i]->Interface = Interface; - Bubbles[i]->NumericsODE = NumericsODE; - } - - /* Allocate and set the excitation parameters */ - struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); - Excitation->type = APECSS_EXCITATION_SIN; - Excitation->f = (APECSS_FLOAT) fa; - Excitation->dp = (APECSS_FLOAT) pa; - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Excitation = Excitation; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Create individual folders for the results of each bubble - for (register int i = 0; i < nBubbles; i++) - { - if (Bubbles[i]->Results != NULL) - { - sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", i); - struct stat st = {0}; - if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); - } - } - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - /* Process all options */ - apecss_gas_processoptions(Gas); - apecss_liquid_processoptions(Liquid); - apecss_interface_processoptions(Interface); - apecss_odesolver_processoptions(NumericsODE); - for (register int i = 0; i < nBubbles; i++) apecss_bubble_processoptions(Bubbles[i]); - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Use the revised pressure at infinity, including neighbor contributions - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressure_infinity = interaction_bubble_pressure_infinity; - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressurederivative_infinity = interaction_bubble_pressurederivative_infinity; - - // Update the Keller-Miksis ODE - if (ode == 1) - { - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->ode[0] = apecss_rp_kellermiksisvelocity_ode_simplified; - } - - // Initialize interaction structure - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); - - // Update interaction structure - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->Interaction->nBubbles = nBubbles; - Bubbles[i]->Interaction->dp_neighbor = 0.0; - Bubbles[i]->Interaction->last_t_1 = 0.0; - Bubbles[i]->Interaction->last_t_2 = 0.0; - Bubbles[i]->Interaction->last_p_1 = 0.0; - Bubbles[i]->Interaction->last_p_2 = 0.0; - } - - // Define the size of each bubble - for (register int i = 0; i < nBubbles; i++) - { - if (0 == i) - Bubbles[i]->R0 = 1.0e-6; - else if (1 == i) - Bubbles[i]->R0 = 0.8e-6; - else if (2 == i) - Bubbles[i]->R0 = 0.5e-6; - else if (3 == i) - Bubbles[i]->R0 = 1.5e-6; - } - - // Define center location for each bubble - for (register int i = 0; i < nBubbles; i++) - { - if (0 == i) - { - Bubbles[i]->Interaction->location[0] = 0.0; - Bubbles[i]->Interaction->location[1] = 0.0; - Bubbles[i]->Interaction->location[2] = 0.0; - } - else if (1 == i) - { - Bubbles[i]->Interaction->location[0] = bubble_bubble_dist; - Bubbles[i]->Interaction->location[1] = 0.0; - Bubbles[i]->Interaction->location[2] = 0.0; - } - else if (2 == i) - { - Bubbles[i]->Interaction->location[0] = 0.5 * bubble_bubble_dist; - Bubbles[i]->Interaction->location[1] = -APECSS_SIN(APECSS_PI / 3) * bubble_bubble_dist; - Bubbles[i]->Interaction->location[2] = 0.0; - } - else if (3 == i) - { - Bubbles[i]->Interaction->location[0] = 0.5 * bubble_bubble_dist; - Bubbles[i]->Interaction->location[1] = -APECSS_TAN(APECSS_PI / 6) * 0.5 * bubble_bubble_dist; - Bubbles[i]->Interaction->location[2] = APECSS_SQRT(APECSS_POW2(bubble_bubble_dist) - APECSS_POW2(0.5 * bubble_bubble_dist) - - APECSS_POW2(APECSS_TAN(APECSS_PI / 6) * 0.5 * bubble_bubble_dist)); - } - } - - // Create array to gather maximum radius value for each bubble - APECSS_FLOAT max_bubble[nBubbles]; - for (register int i = 0; i < nBubbles; i++) - { - max_bubble[i] = Bubbles[i]->R0; - } - - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - clock_t starttimebubble = clock(); - APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system - - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->tStart = tSim; - Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; - Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step - } - - /* Initialize the bubble based on the selected options */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_initialize(Bubbles[i]); - - /* Initialize */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_initialize(Bubbles[i]); - - /* Solve the bubble dynamics */ - while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered - { - APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); - tSim += dtSim; - - for (register int i = 0; i < nBubbles; i++) - { - maxR = Bubbles[i]->R0; - apecss_new_bubble_solver_run(tSim, (APECSS_FLOAT) tEnd, Bubbles[i]); - if (maxR > max_bubble[i]) - { - max_bubble[i] = maxR; - } - } - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Update the contribution of the neighbor bubbles - apecss_interactions_instantaneous(Bubbles); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - } - - /* Retrieve results */ - FILE *file_max_radius; - file_max_radius = fopen("max_radius.txt", "a"); - fprintf(file_max_radius, "nb %d f(Hz) %e p(Pa) %e dist %e ODE %d R0(m);Rmax(m)", nBubbles, fa, pa, dist, ode); - for (register int i = 0; i < nBubbles; i++) - { - fprintf(file_max_radius, " %e;%e", Bubbles[i]->R0, max_bubble[i]); - } - fprintf(file_max_radius, "\n"); - fclose(file_max_radius); - - /* Finalize the simulation*/ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_finalize(Bubbles[i]); - - char str[APECSS_STRINGLENGTH_SPRINTF]; - for (register int i = 0; i < nBubbles; i++) - { - sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", i, Bubbles[i]->dtNumber, Bubbles[i]->nSubIter, - (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); - apecss_writeonscreen(str); - } - - for (register int i = 0; i < nBubbles; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); - for (register int i = 0; i < nBubbles; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); - - /* Make sure all allocated memory is freed */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_freestruct(Bubbles[i]); - - for (register int i = 0; i < nBubbles; i++) free(Bubbles[i]); - free(Gas); - free(Liquid); - free(Interface); - free(NumericsODE); - free(Excitation); - - return (0); -} - -APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - APECSS_FLOAT x = Bubble->Interaction->location[0]; - return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * (t - x / Bubble->Liquid->cref)) + - Bubble->Interaction->dp_neighbor); -} - -APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - // Approximate numerical computation of p_infinity derivative - APECSS_FLOAT x = Bubble->Interaction->location[0]; - APECSS_FLOAT derivative = - -Bubble->Excitation->dp * 2.0 * APECSS_PI * Bubble->Excitation->f * APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * (t - x / Bubble->Liquid->cref)); - return (derivative); -} - -APECSS_FLOAT apecss_rp_kellermiksisvelocity_ode_simplified(APECSS_FLOAT *Sol, APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - /** Simplified model for comparison with Haghi **/ - APECSS_FLOAT inv_c = 1.0 / Bubble->Liquid->cref; - APECSS_FLOAT inv_rho = 1.0 / Bubble->Liquid->rhoref; - - APECSS_FLOAT rhs = ((Bubble->Liquid->get_pressure_bubblewall(Sol, t, Bubble) - Bubble->get_pressure_infinity(t, Bubble)) * inv_rho - - 1.5 * (1.0 - (Sol[0] * APECSS_ONETHIRD * inv_c)) * APECSS_POW2(Sol[0])) / - Sol[1]; - - return (rhs / (1.0 - Sol[0] * inv_c)); -} - -int apecss_new_bubble_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble) -{ - while (Bubble->t < tend - 0.01 * Bubble->NumericsODE->dtMin) - { - // Store the previous solution for sub-iterations - for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSolOld[i] = Bubble->ODEsSol[i]; - - // Check what comes next: the end of the solver run or, if applicable, a time instance to output the emissions - APECSS_FLOAT next_event_time = Bubble->results_emissionstime_check(tend, Bubble); - - // Set the time-step for the ODEs - apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); - - // Solve the ODEs - Bubble->err = apecss_odesolver(Bubble); - - // Perform sub-iterations on the control of the time-step when err > tol - register int subiter = 0; - while ((Bubble->err > Bubble->NumericsODE->tol) && (subiter < Bubble->NumericsODE->maxSubIter)) - { - ++subiter; - // Rewind the solution - for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSol[i] = Bubble->ODEsSolOld[i]; - // Set the time-step for the ODEs - apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); - // Solve the ODEs again - Bubble->err = apecss_odesolver(Bubble); - } - Bubble->nSubIter += subiter; - - // Set new values - ++(Bubble->dtNumber); - Bubble->t += Bubble->dt; - Bubble->U = Bubble->ODEsSol[0]; - Bubble->R = Bubble->ODEsSol[1]; - - // Detect max value of radius - if (Bubble->t > tEnd - 10 / Bubble->Excitation->f) maxR = APECSS_MAX(maxR, Bubble->R); - - // Update allocation of the results (if necessary) - Bubble->results_emissionsnodeminmax_identify(Bubble); - Bubble->results_emissionsnode_alloc(Bubble); - - // Acoustic emissions (if applicable) - Bubble->emissions_update(Bubble); - - // Store results (if applicable) - Bubble->results_rayleighplesset_store(Bubble); - Bubble->results_emissionsspace_store(Bubble); - - // Write one-off results (if applicable) - Bubble->results_emissionstime_write(Bubble); - - // Update the last-step solution of the RK54 scheme - for (register int i = 0; i < Bubble->nODEs; i++) Bubble->kLast[i] = Bubble->k7[i]; - - // Update progress screen in the terminal (if applicable) - Bubble->progress_update(&(*Bubble).progress, Bubble->t - Bubble->tStart, Bubble->tEnd - Bubble->tStart); - } - - return (0); -} \ No newline at end of file diff --git a/examples/frequencyresponse/NI/build/CMakeLists.txt b/examples/frequencyresponse/NI/build/CMakeLists.txt deleted file mode 100644 index 7e6cde8..0000000 --- a/examples/frequencyresponse/NI/build/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -cmake_minimum_required(VERSION 3.12) - -project (frequencyresponse_apecss) -set(CMAKE_C_COMPILER /usr/bin/gcc) - -include_directories($ENV{APECSS_DIR}/include) -FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) - -set (mylibs m apecss) -link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) - -foreach(arg ${myincludes}) - IF (arg MATCHES "-I") - STRING(REGEX REPLACE "-I" "" myinc ${arg}) - message("Additional include: ${myinc}") - include_directories(${myinc}) - ENDIF(arg MATCHES "-I") -endforeach(arg ${myincludes}) - -foreach(arg ${mylibs}) - STRING(REGEX REPLACE "lib" "" myl1 ${arg}) - STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) - set(mylibs ${myl2} ${mylibs} ${myl2}) -endforeach(arg ${mylibs}) - -if(NOT CMAKE_BUILD_TYPE) - message(STATUS "Optimization: No optimization specified.") - set(CMAKE_BUILD_TYPE Release) -endif() - -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - message(STATUS "Optimization: Debug") - set(CMAKE_C_FLAGS_DEBUG "-Wall -g") -elseif(CMAKE_BUILD_TYPE STREQUAL "Release") - message(STATUS "Optimization: Release") - add_definitions(-DNDEBUG) - set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") -endif() - -add_executable(frequencyresponse_apecss ${myfiles}) -target_link_libraries(frequencyresponse_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/frequencyresponse/NI/build/compile.sh b/examples/frequencyresponse/NI/build/compile.sh deleted file mode 100755 index 55dab1c..0000000 --- a/examples/frequencyresponse/NI/build/compile.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -rm frequencyresponse_apecss -cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release -make -rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/frequencyresponse/NI/gather_results.py b/examples/frequencyresponse/NI/gather_results.py deleted file mode 100644 index 7362d5a..0000000 --- a/examples/frequencyresponse/NI/gather_results.py +++ /dev/null @@ -1,35 +0,0 @@ -import os - -######### File designed to retrieve and gather in the "results" folder the data obtained with frequency response computations - -working_path = os.getcwd() - -results_file = open(os.path.join(working_path, "max_radius.txt"), "r") -lines = results_file.readlines() -results_file.close() - -firstline = lines[0].split(" ") -nBubbles = int(firstline[1]) -pa = float(firstline[5]) -dist = float(firstline[7]) -ode = int(firstline[9]) - -gather_path = os.path.join(working_path, "results") - -file_name = "{}_p{:.5E}_d{:.2E}_{}.txt".format(nBubbles, pa, dist, ode) - -data_file = open(os.path.join(gather_path, file_name), "w") -data_file.write("nb {} p(Pa) {:.5E} dist {:.2E} ODE {}\n".format(nBubbles, pa, dist, ode)) -data_file.write("#f(Hz) R0(m);R(m)\n") - -for line in lines : - if line != "" : - data = line.split(" ") - f = float(data[3]) - data_file.write("{:.5E}".format(f)) - - r_list = data[11:] - for r in r_list : - data_file.write(" {}".format(r)) - -data_file.close() \ No newline at end of file diff --git a/examples/frequencyresponse/NI/run.apecss b/examples/frequencyresponse/NI/run.apecss deleted file mode 100644 index 67300c7..0000000 --- a/examples/frequencyresponse/NI/run.apecss +++ /dev/null @@ -1,36 +0,0 @@ -######################################################### -# # -# APECSS Options File # -# # -######################################################### - -BUBBLE -RPModel KM -Emissions IC 300.0e-6 -PressureAmbient 1.0e5 -END - -GAS -EoS IG -ReferenceDensity 1.2 -PolytropicExponent 1.4 -END - -LIQUID -ReferencePressure 1.0e5 -ReferenceDensity 1000.0 -ReferenceSoundSpeed 1500.0 -Viscosity 1.002e-3 -END - -INTERFACE -SurfaceTensionCoeff 0.0728 -END - -RESULTS -Bubble -END - -ODESOLVER -tolerance 1.0e-10 -END diff --git a/examples/frequencyresponse/NI/src/frequencyresponse_apecss.c b/examples/frequencyresponse/NI/src/frequencyresponse_apecss.c deleted file mode 100644 index ecbaf3d..0000000 --- a/examples/frequencyresponse/NI/src/frequencyresponse_apecss.c +++ /dev/null @@ -1,421 +0,0 @@ -// This source file is part of APECSS, an open-source software toolbox -// for the computation of pressure-driven bubble dynamics and acoustic -// emissions in spherical symmetry. -// -// Copyright (C) 2022-2024 The APECSS Developers -// -// The APECSS Developers are listed in the README.md file available in -// the GitHub repository at https://github.com/polycfd/apecss. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// ------------------------------------------------------------------- -// APECSS standalone example of acoustically-interacting microbubbles, -// based on Jiang et al., Ultrasonics Sonochemistry 34 (2017), 90-97. -// ------------------------------------------------------------------- - -#include -#include "apecss.h" - -// Declaration of additional case-dependent functions -APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -APECSS_FLOAT apecss_rp_kellermiksisvelocity_ode_simplified(APECSS_FLOAT *Sol, APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -int apecss_new_bubble_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble); - -APECSS_FLOAT maxR; - -int main(int argc, char **args) -{ - char OptionsDir[APECSS_STRINGLENGTH]; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Set the case-dependent simulation parameters - int nBubbles = 3; // Number of bubbles - APECSS_FLOAT bubble_bubble_dist = 5.0e-6; // Bubble-bubble distance - - // Interbubble time-step, defining the frequency with which the neighbor influence is updated - APECSS_FLOAT dt_interbubble = 1.0e-8; - - // Initialize the simulation parameters given by the execution command - double tEnd = 0.0; - double fa = 0.0; - double pa = 0.0; - double dist = 5.0e-6; - double dt_inter = 1.0e-8; - int ode = 0; - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - apecss_infoscreen(); - - /* Read commandline options */ - sprintf(OptionsDir, "./run.apecss"); // This is the default - int j = 1; // First argument is the call to the executable - while (j < argc) - { - if (strcmp("-options", args[j]) == 0) - { - sprintf(OptionsDir, "%s", args[j + 1]); - j += 2; - } - else if (strcmp("-nb", args[j]) == 0) - { - sscanf(args[j + 1], "%d", &nBubbles); - j += 2; - } - else if (strcmp("-tend", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &tEnd); - j += 2; - } - else if (strcmp("-freq", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &fa); - j += 2; - } - else if (strcmp("-amp", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &pa); - j += 2; - } - else if (strcmp("-dist", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &dist); - j += 2; - } - else if (strcmp("-dt_inter", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &dt_inter); - j += 2; - } - else if (strcmp("-ode", args[j]) == 0) - { - sscanf(args[j + 1], "%d", &ode); - j += 2; - } - else if (strcmp("-h", args[j]) == 0) - { - apecss_helpscreen(); - } - else - { - char str[APECSS_STRINGLENGTH_SPRINTF]; - sprintf(str, "Unknown command line options: %s", args[j]); - apecss_erroronscreen(1, str); - ++j; - } - } - - /* Properly update parameters with commandline options */ - bubble_bubble_dist = (APECSS_FLOAT) dist; - dt_interbubble = (APECSS_FLOAT) dt_inter; - tEnd = 30 / fa; - - /* Check if the number of bubbles is right */ - if ((nBubbles != 3) && (nBubbles != 4)) - { - nBubbles = 3; - } - - /* Allocate and initialize Bubble structure */ - struct APECSS_Bubble *Bubbles[nBubbles]; - for (register int i = 0; i < nBubbles; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(nBubbles * sizeof(struct APECSS_Bubble)); - for (register int i = 0; i < nBubbles; i++) apecss_bubble_initializestruct(Bubbles[i]); - - /* Set default options and read the options for the bubble */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); - for (register int i = 0; i < nBubbles; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); - - /* Allocate the structures for the fluid properties and ODE solver parameters */ - struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); - struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); - struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); - struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); - - /* Set the default options for the fluid properties and solver parameters */ - apecss_gas_setdefaultoptions(Gas); - apecss_liquid_setdefaultoptions(Liquid); - apecss_interface_setdefaultoptions(Interface); - apecss_odesolver_setdefaultoptions(NumericsODE); - - /* Read the options file for the fluid properties and solver parameters */ - apecss_gas_readoptions(Gas, OptionsDir); - apecss_liquid_readoptions(Liquid, OptionsDir); - apecss_interface_readoptions(Interface, OptionsDir); - apecss_odesolver_readoptions(NumericsODE, OptionsDir); - - /* Associate the bubble with the relevant fluid properties and solver parameters */ - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->Gas = Gas; - Bubbles[i]->Liquid = Liquid; - Bubbles[i]->Interface = Interface; - Bubbles[i]->NumericsODE = NumericsODE; - } - - /* Allocate and set the excitation parameters */ - struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); - Excitation->type = APECSS_EXCITATION_SIN; - Excitation->f = (APECSS_FLOAT) fa; - Excitation->dp = (APECSS_FLOAT) pa; - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Excitation = Excitation; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Create individual folders for the results of each bubble - for (register int i = 0; i < nBubbles; i++) - { - if (Bubbles[i]->Results != NULL) - { - sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", i); - struct stat st = {0}; - if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); - } - } - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - /* Process all options */ - apecss_gas_processoptions(Gas); - apecss_liquid_processoptions(Liquid); - apecss_interface_processoptions(Interface); - apecss_odesolver_processoptions(NumericsODE); - for (register int i = 0; i < nBubbles; i++) apecss_bubble_processoptions(Bubbles[i]); - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Use the revised pressure at infinity, including neighbor contributions - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressure_infinity = interaction_bubble_pressure_infinity; - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressurederivative_infinity = interaction_bubble_pressurederivative_infinity; - - // Update the Keller-Miksis ODE - if (ode == 1) - { - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->ode[0] = apecss_rp_kellermiksisvelocity_ode_simplified; - } - - // Initialize interaction structure - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); - - // Update interaction structure - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->Interaction->nBubbles = nBubbles; - Bubbles[i]->Interaction->dp_neighbor = 0.0; - Bubbles[i]->Interaction->last_t_1 = 0.0; - Bubbles[i]->Interaction->last_t_2 = 0.0; - Bubbles[i]->Interaction->last_p_1 = 0.0; - Bubbles[i]->Interaction->last_p_2 = 0.0; - } - - // Define the size of each bubble - for (register int i = 0; i < nBubbles; i++) - { - if (0 == i) - Bubbles[i]->R0 = 1.0e-6; - else if (1 == i) - Bubbles[i]->R0 = 0.8e-6; - else if (2 == i) - Bubbles[i]->R0 = 0.5e-6; - else if (3 == i) - Bubbles[i]->R0 = 1.5e-6; - } - - // Define center location for each bubble (only x is important for this test case) - for (register int i = 0; i < nBubbles; i++) - { - if (0 == i) - { - Bubbles[i]->Interaction->location[0] = 0.0; - Bubbles[i]->Interaction->location[1] = 0.0; - Bubbles[i]->Interaction->location[2] = 0.0; - } - else if (1 == i) - { - Bubbles[i]->Interaction->location[0] = bubble_bubble_dist; - Bubbles[i]->Interaction->location[1] = 0.0; - Bubbles[i]->Interaction->location[2] = 0.0; - } - else if (2 == i) - { - Bubbles[i]->Interaction->location[0] = 0.5 * bubble_bubble_dist; - Bubbles[i]->Interaction->location[1] = 0.0; - Bubbles[i]->Interaction->location[2] = 0.0; - } - else if (3 == i) - { - Bubbles[i]->Interaction->location[0] = 0.5 * bubble_bubble_dist; - Bubbles[i]->Interaction->location[1] = 0.0; - Bubbles[i]->Interaction->location[2] = 0.0; - } - } - - // Create array to gather maximum radius value for each bubble - APECSS_FLOAT max_bubble[nBubbles]; - for (register int i = 0; i < nBubbles; i++) - { - max_bubble[i] = Bubbles[i]->R0; - } - - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - clock_t starttimebubble = clock(); - APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system - - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->tStart = tSim; - Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; - Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step - } - - /* Initialize the bubble based on the selected options */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_initialize(Bubbles[i]); - - /* Initialize */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_initialize(Bubbles[i]); - - /* Solve the bubble dynamics */ - while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered - { - APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); - tSim += dtSim; - - for (register int i = 0; i < nBubbles; i++) - { - maxR = Bubbles[i]->R0; - apecss_new_bubble_solver_run(tSim, (APECSS_FLOAT) tEnd, Bubbles[i]); - if (maxR > max_bubble[i]) - { - max_bubble[i] = maxR; - } - } - } - - /* Retrieve results */ - FILE *file_max_radius; - file_max_radius = fopen("max_radius.txt", "a"); - fprintf(file_max_radius, "nb %d f(Hz) %e p(Pa) %e dist %e ODE %d R0(m);Rmax(m)", nBubbles, fa, pa, dist, ode); - for (register int i = 0; i < nBubbles; i++) - { - fprintf(file_max_radius, " %e;%e", Bubbles[i]->R0, max_bubble[i]); - } - fprintf(file_max_radius, "\n"); - fclose(file_max_radius); - - /* Finalize the simulation*/ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_finalize(Bubbles[i]); - - char str[APECSS_STRINGLENGTH_SPRINTF]; - for (register int i = 0; i < nBubbles; i++) - { - sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", i, Bubbles[i]->dtNumber, Bubbles[i]->nSubIter, - (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); - apecss_writeonscreen(str); - } - - for (register int i = 0; i < nBubbles; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); - for (register int i = 0; i < nBubbles; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); - - /* Make sure all allocated memory is freed */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_freestruct(Bubbles[i]); - - for (register int i = 0; i < nBubbles; i++) free(Bubbles[i]); - free(Gas); - free(Liquid); - free(Interface); - free(NumericsODE); - free(Excitation); - - return (0); -} - -APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - APECSS_FLOAT x = Bubble->Interaction->location[0]; - return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * (t - x / Bubble->Liquid->cref))); -} - -APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - // Approximate numerical computation of p_infinity derivative - APECSS_FLOAT x = Bubble->Interaction->location[0]; - APECSS_FLOAT derivative = - -Bubble->Excitation->dp * 2.0 * APECSS_PI * Bubble->Excitation->f * APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * (t - x / Bubble->Liquid->cref)); - return (derivative); -} - -APECSS_FLOAT apecss_rp_kellermiksisvelocity_ode_simplified(APECSS_FLOAT *Sol, APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - /** Simplified model for comparison with Haghi **/ - APECSS_FLOAT inv_c = 1.0 / Bubble->Liquid->cref; - APECSS_FLOAT inv_rho = 1.0 / Bubble->Liquid->rhoref; - - APECSS_FLOAT rhs = ((Bubble->Liquid->get_pressure_bubblewall(Sol, t, Bubble) - Bubble->get_pressure_infinity(t, Bubble)) * inv_rho - - 1.5 * (1.0 - (Sol[0] * APECSS_ONETHIRD * inv_c)) * APECSS_POW2(Sol[0])) / - Sol[1]; - - return (rhs / (1.0 - Sol[0] * inv_c)); -} - -int apecss_new_bubble_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble) -{ - while (Bubble->t < tend - 0.01 * Bubble->NumericsODE->dtMin) - { - // Store the previous solution for sub-iterations - for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSolOld[i] = Bubble->ODEsSol[i]; - - // Check what comes next: the end of the solver run or, if applicable, a time instance to output the emissions - APECSS_FLOAT next_event_time = Bubble->results_emissionstime_check(tend, Bubble); - - // Set the time-step for the ODEs - apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); - - // Solve the ODEs - Bubble->err = apecss_odesolver(Bubble); - - // Perform sub-iterations on the control of the time-step when err > tol - register int subiter = 0; - while ((Bubble->err > Bubble->NumericsODE->tol) && (subiter < Bubble->NumericsODE->maxSubIter)) - { - ++subiter; - // Rewind the solution - for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSol[i] = Bubble->ODEsSolOld[i]; - // Set the time-step for the ODEs - apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); - // Solve the ODEs again - Bubble->err = apecss_odesolver(Bubble); - } - Bubble->nSubIter += subiter; - - // Set new values - ++(Bubble->dtNumber); - Bubble->t += Bubble->dt; - Bubble->U = Bubble->ODEsSol[0]; - Bubble->R = Bubble->ODEsSol[1]; - - // Detect max value of radius - if (Bubble->t > tEnd - 10 / Bubble->Excitation->f) maxR = APECSS_MAX(maxR, Bubble->R); - - // Update allocation of the results (if necessary) - Bubble->results_emissionsnodeminmax_identify(Bubble); - Bubble->results_emissionsnode_alloc(Bubble); - - // Acoustic emissions (if applicable) - Bubble->emissions_update(Bubble); - - // Store results (if applicable) - Bubble->results_rayleighplesset_store(Bubble); - Bubble->results_emissionsspace_store(Bubble); - - // Write one-off results (if applicable) - Bubble->results_emissionstime_write(Bubble); - - // Update the last-step solution of the RK54 scheme - for (register int i = 0; i < Bubble->nODEs; i++) Bubble->kLast[i] = Bubble->k7[i]; - - // Update progress screen in the terminal (if applicable) - Bubble->progress_update(&(*Bubble).progress, Bubble->t - Bubble->tStart, Bubble->tEnd - Bubble->tStart); - } - - return (0); -} \ No newline at end of file diff --git a/examples/frequencyresponse/QA/build/CMakeLists.txt b/examples/frequencyresponse/QA/build/CMakeLists.txt deleted file mode 100644 index 7e6cde8..0000000 --- a/examples/frequencyresponse/QA/build/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -cmake_minimum_required(VERSION 3.12) - -project (frequencyresponse_apecss) -set(CMAKE_C_COMPILER /usr/bin/gcc) - -include_directories($ENV{APECSS_DIR}/include) -FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) - -set (mylibs m apecss) -link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) - -foreach(arg ${myincludes}) - IF (arg MATCHES "-I") - STRING(REGEX REPLACE "-I" "" myinc ${arg}) - message("Additional include: ${myinc}") - include_directories(${myinc}) - ENDIF(arg MATCHES "-I") -endforeach(arg ${myincludes}) - -foreach(arg ${mylibs}) - STRING(REGEX REPLACE "lib" "" myl1 ${arg}) - STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) - set(mylibs ${myl2} ${mylibs} ${myl2}) -endforeach(arg ${mylibs}) - -if(NOT CMAKE_BUILD_TYPE) - message(STATUS "Optimization: No optimization specified.") - set(CMAKE_BUILD_TYPE Release) -endif() - -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - message(STATUS "Optimization: Debug") - set(CMAKE_C_FLAGS_DEBUG "-Wall -g") -elseif(CMAKE_BUILD_TYPE STREQUAL "Release") - message(STATUS "Optimization: Release") - add_definitions(-DNDEBUG) - set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") -endif() - -add_executable(frequencyresponse_apecss ${myfiles}) -target_link_libraries(frequencyresponse_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/frequencyresponse/QA/build/compile.sh b/examples/frequencyresponse/QA/build/compile.sh deleted file mode 100755 index 55dab1c..0000000 --- a/examples/frequencyresponse/QA/build/compile.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -rm frequencyresponse_apecss -cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release -make -rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/frequencyresponse/QA/gather_results.py b/examples/frequencyresponse/QA/gather_results.py deleted file mode 100644 index 7362d5a..0000000 --- a/examples/frequencyresponse/QA/gather_results.py +++ /dev/null @@ -1,35 +0,0 @@ -import os - -######### File designed to retrieve and gather in the "results" folder the data obtained with frequency response computations - -working_path = os.getcwd() - -results_file = open(os.path.join(working_path, "max_radius.txt"), "r") -lines = results_file.readlines() -results_file.close() - -firstline = lines[0].split(" ") -nBubbles = int(firstline[1]) -pa = float(firstline[5]) -dist = float(firstline[7]) -ode = int(firstline[9]) - -gather_path = os.path.join(working_path, "results") - -file_name = "{}_p{:.5E}_d{:.2E}_{}.txt".format(nBubbles, pa, dist, ode) - -data_file = open(os.path.join(gather_path, file_name), "w") -data_file.write("nb {} p(Pa) {:.5E} dist {:.2E} ODE {}\n".format(nBubbles, pa, dist, ode)) -data_file.write("#f(Hz) R0(m);R(m)\n") - -for line in lines : - if line != "" : - data = line.split(" ") - f = float(data[3]) - data_file.write("{:.5E}".format(f)) - - r_list = data[11:] - for r in r_list : - data_file.write(" {}".format(r)) - -data_file.close() \ No newline at end of file diff --git a/examples/frequencyresponse/QA/run.apecss b/examples/frequencyresponse/QA/run.apecss deleted file mode 100644 index 73dab5c..0000000 --- a/examples/frequencyresponse/QA/run.apecss +++ /dev/null @@ -1,36 +0,0 @@ -######################################################### -# # -# APECSS Options File # -# # -######################################################### - -BUBBLE -RPModel KM -Emissions QA 60.0e-6 -PressureAmbient 1.0e5 -END - -GAS -EoS IG -ReferenceDensity 1.2 -PolytropicExponent 1.4 -END - -LIQUID -ReferencePressure 1.0e5 -ReferenceDensity 1000.0 -ReferenceSoundSpeed 1500.0 -Viscosity 1.002e-3 -END - -INTERFACE -SurfaceTensionCoeff 0.0728 -END - -RESULTS -Bubble -END - -ODESOLVER -tolerance 1.0e-10 -END diff --git a/examples/frequencyresponse/QA/src/frequencyresponse_apecss.c b/examples/frequencyresponse/QA/src/frequencyresponse_apecss.c deleted file mode 100644 index 632f9d8..0000000 --- a/examples/frequencyresponse/QA/src/frequencyresponse_apecss.c +++ /dev/null @@ -1,447 +0,0 @@ -// This source file is part of APECSS, an open-source software toolbox -// for the computation of pressure-driven bubble dynamics and acoustic -// emissions in spherical symmetry. -// -// Copyright (C) 2022-2024 The APECSS Developers -// -// The APECSS Developers are listed in the README.md file available in -// the GitHub repository at https://github.com/polycfd/apecss. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// ------------------------------------------------------------------- -// APECSS standalone example of acoustically-interacting microbubbles, -// based on Jiang et al., Ultrasonics Sonochemistry 34 (2017), 90-97. -// ------------------------------------------------------------------- - -#include -#include "apecss.h" - -// Declaration of additional case-dependent functions -APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -APECSS_FLOAT apecss_rp_kellermiksisvelocity_ode_simplified(APECSS_FLOAT *Sol, APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -int apecss_new_bubble_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble); - -APECSS_FLOAT APECSS_TAN(APECSS_FLOAT x) { return APECSS_SIN(x) / APECSS_COS(x); } - -APECSS_FLOAT maxR; - -int main(int argc, char **args) -{ - char OptionsDir[APECSS_STRINGLENGTH]; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Set the case-dependent simulation parameters - int nBubbles = 3; // Number of bubbles - APECSS_FLOAT bubble_bubble_dist = 5.0e-6; // Bubble-bubble distance - - // Interbubble time-step, defining the frequency with which the neighbor influence is updated - APECSS_FLOAT dt_interbubble = 1.0e-8; - - // Initialize the simulation parameters given by the execution command - double tEnd = 0.0; - double fa = 0.0; - double pa = 0.0; - double dist = 5.0e-6; - double dt_inter = 1.0e-8; - int ode = 0; - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - apecss_infoscreen(); - - /* Read commandline options */ - sprintf(OptionsDir, "./run.apecss"); // This is the default - int j = 1; // First argument is the call to the executable - while (j < argc) - { - if (strcmp("-options", args[j]) == 0) - { - sprintf(OptionsDir, "%s", args[j + 1]); - j += 2; - } - else if (strcmp("-nb", args[j]) == 0) - { - sscanf(args[j + 1], "%d", &nBubbles); - j += 2; - } - else if (strcmp("-tend", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &tEnd); - j += 2; - } - else if (strcmp("-freq", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &fa); - j += 2; - } - else if (strcmp("-amp", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &pa); - j += 2; - } - else if (strcmp("-dist", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &dist); - j += 2; - } - else if (strcmp("-dt_inter", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &dt_inter); - j += 2; - } - else if (strcmp("-ode", args[j]) == 0) - { - sscanf(args[j + 1], "%d", &ode); - j += 2; - } - else if (strcmp("-h", args[j]) == 0) - { - apecss_helpscreen(); - } - else - { - char str[APECSS_STRINGLENGTH_SPRINTF]; - sprintf(str, "Unknown command line options: %s", args[j]); - apecss_erroronscreen(1, str); - ++j; - } - } - - /* Properly update parameters with commandline options */ - bubble_bubble_dist = (APECSS_FLOAT) dist; - dt_interbubble = (APECSS_FLOAT) dt_inter; - tEnd = 30 / fa; - - /* Check if the number of bubbles is right */ - if ((nBubbles != 3) && (nBubbles != 4)) - { - nBubbles = 3; - } - - /* Allocate and initialize Bubble structure */ - struct APECSS_Bubble *Bubbles[nBubbles]; - for (register int i = 0; i < nBubbles; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(nBubbles * sizeof(struct APECSS_Bubble)); - for (register int i = 0; i < nBubbles; i++) apecss_bubble_initializestruct(Bubbles[i]); - - /* Set default options and read the options for the bubble */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); - for (register int i = 0; i < nBubbles; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); - - /* Allocate the structures for the fluid properties and ODE solver parameters */ - struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); - struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); - struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); - struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); - - /* Set the default options for the fluid properties and solver parameters */ - apecss_gas_setdefaultoptions(Gas); - apecss_liquid_setdefaultoptions(Liquid); - apecss_interface_setdefaultoptions(Interface); - apecss_odesolver_setdefaultoptions(NumericsODE); - - /* Read the options file for the fluid properties and solver parameters */ - apecss_gas_readoptions(Gas, OptionsDir); - apecss_liquid_readoptions(Liquid, OptionsDir); - apecss_interface_readoptions(Interface, OptionsDir); - apecss_odesolver_readoptions(NumericsODE, OptionsDir); - - /* Associate the bubble with the relevant fluid properties and solver parameters */ - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->Gas = Gas; - Bubbles[i]->Liquid = Liquid; - Bubbles[i]->Interface = Interface; - Bubbles[i]->NumericsODE = NumericsODE; - } - - /* Allocate and set the excitation parameters */ - struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); - Excitation->type = APECSS_EXCITATION_SIN; - Excitation->f = (APECSS_FLOAT) fa; - Excitation->dp = (APECSS_FLOAT) pa; - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Excitation = Excitation; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Create individual folders for the results of each bubble - for (register int i = 0; i < nBubbles; i++) - { - if (Bubbles[i]->Results != NULL) - { - sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", i); - struct stat st = {0}; - if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); - } - } - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - /* Process all options */ - apecss_gas_processoptions(Gas); - apecss_liquid_processoptions(Liquid); - apecss_interface_processoptions(Interface); - apecss_odesolver_processoptions(NumericsODE); - for (register int i = 0; i < nBubbles; i++) apecss_bubble_processoptions(Bubbles[i]); - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Use the revised pressure at infinity, including neighbor contributions - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressure_infinity = interaction_bubble_pressure_infinity; - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressurederivative_infinity = interaction_bubble_pressurederivative_infinity; - - // Update the Keller-Miksis ODE - if (ode == 1) - { - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->ode[0] = apecss_rp_kellermiksisvelocity_ode_simplified; - } - - // Initialize interaction structure - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); - - // Update interaction structure - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->Interaction->nBubbles = nBubbles; - Bubbles[i]->Interaction->dp_neighbor = 0.0; - Bubbles[i]->Interaction->last_t_1 = 0.0; - Bubbles[i]->Interaction->last_t_2 = 0.0; - Bubbles[i]->Interaction->last_p_1 = 0.0; - Bubbles[i]->Interaction->last_p_2 = 0.0; - } - - // Define the size of each bubble - for (register int i = 0; i < nBubbles; i++) - { - if (0 == i) - Bubbles[i]->R0 = 1.0e-6; - else if (1 == i) - Bubbles[i]->R0 = 0.8e-6; - else if (2 == i) - Bubbles[i]->R0 = 0.5e-6; - else if (3 == i) - Bubbles[i]->R0 = 1.5e-6; - } - - // Define center location for each bubble - for (register int i = 0; i < nBubbles; i++) - { - if (0 == i) - { - Bubbles[i]->Interaction->location[0] = 0.0; - Bubbles[i]->Interaction->location[1] = 0.0; - Bubbles[i]->Interaction->location[2] = 0.0; - } - else if (1 == i) - { - Bubbles[i]->Interaction->location[0] = bubble_bubble_dist; - Bubbles[i]->Interaction->location[1] = 0.0; - Bubbles[i]->Interaction->location[2] = 0.0; - } - else if (2 == i) - { - Bubbles[i]->Interaction->location[0] = 0.5 * bubble_bubble_dist; - Bubbles[i]->Interaction->location[1] = -APECSS_SIN(APECSS_PI / 3) * bubble_bubble_dist; - Bubbles[i]->Interaction->location[2] = 0.0; - } - else if (3 == i) - { - Bubbles[i]->Interaction->location[0] = 0.5 * bubble_bubble_dist; - Bubbles[i]->Interaction->location[1] = -APECSS_TAN(APECSS_PI / 6) * 0.5 * bubble_bubble_dist; - Bubbles[i]->Interaction->location[2] = APECSS_SQRT(APECSS_POW2(bubble_bubble_dist) - APECSS_POW2(0.5 * bubble_bubble_dist) - - APECSS_POW2(APECSS_TAN(APECSS_PI / 6) * 0.5 * bubble_bubble_dist)); - } - } - - // Create array to gather maximum radius value for each bubble - APECSS_FLOAT max_bubble[nBubbles]; - for (register int i = 0; i < nBubbles; i++) - { - max_bubble[i] = Bubbles[i]->R0; - } - - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - clock_t starttimebubble = clock(); - APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system - - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->tStart = tSim; - Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; - Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step - } - - /* Initialize the bubble based on the selected options */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_initialize(Bubbles[i]); - - /* Initialize */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_initialize(Bubbles[i]); - - /* Solve the bubble dynamics */ - while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered - { - APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); - tSim += dtSim; - - for (register int i = 0; i < nBubbles; i++) - { - maxR = Bubbles[i]->R0; - apecss_new_bubble_solver_run(tSim, (APECSS_FLOAT) tEnd, Bubbles[i]); - if (maxR > max_bubble[i]) - { - max_bubble[i] = maxR; - } - } - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Update the contribution of the neighbor bubbles - apecss_interactions_quasi_acoustic(Bubbles); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; - Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; - - Bubbles[i]->Interaction->last_t_1 = tSim; - Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; - } - } - - /* Retrieve results */ - FILE *file_max_radius; - file_max_radius = fopen("max_radius.txt", "a"); - fprintf(file_max_radius, "nb %d f(Hz) %e p(Pa) %e dist %e ODE %d R0(m);Rmax(m)", nBubbles, fa, pa, dist, ode); - for (register int i = 0; i < nBubbles; i++) - { - fprintf(file_max_radius, " %e;%e", Bubbles[i]->R0, max_bubble[i]); - } - fprintf(file_max_radius, "\n"); - fclose(file_max_radius); - - /* Finalize the simulation*/ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_finalize(Bubbles[i]); - - char str[APECSS_STRINGLENGTH_SPRINTF]; - for (register int i = 0; i < nBubbles; i++) - { - sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", i, Bubbles[i]->dtNumber, Bubbles[i]->nSubIter, - (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); - apecss_writeonscreen(str); - } - - for (register int i = 0; i < nBubbles; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); - for (register int i = 0; i < nBubbles; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); - - /* Make sure all allocated memory is freed */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_freestruct(Bubbles[i]); - - for (register int i = 0; i < nBubbles; i++) free(Bubbles[i]); - free(Gas); - free(Liquid); - free(Interface); - free(NumericsODE); - free(Excitation); - - return (0); -} - -APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - APECSS_FLOAT x = Bubble->Interaction->location[0]; - return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * (t - x / Bubble->Liquid->cref)) + - Bubble->Interaction->dp_neighbor); -} - -APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - // Approximate numerical computation of p_infinity derivative - APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; - APECSS_FLOAT x = Bubble->Interaction->location[0]; - APECSS_FLOAT derivative = - -Bubble->Excitation->dp * 2.0 * APECSS_PI * Bubble->Excitation->f * APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * (t - x / Bubble->Liquid->cref)); - if (delta_t > Bubble->dt) - { - return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) / (Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2))); - } - else - { - return (derivative); - } -} - -APECSS_FLOAT apecss_rp_kellermiksisvelocity_ode_simplified(APECSS_FLOAT *Sol, APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - /** Simplified model for comparison with Haghi **/ - APECSS_FLOAT inv_c = 1.0 / Bubble->Liquid->cref; - APECSS_FLOAT inv_rho = 1.0 / Bubble->Liquid->rhoref; - - APECSS_FLOAT rhs = ((Bubble->Liquid->get_pressure_bubblewall(Sol, t, Bubble) - Bubble->get_pressure_infinity(t, Bubble)) * inv_rho - - 1.5 * (1.0 - (Sol[0] * APECSS_ONETHIRD * inv_c)) * APECSS_POW2(Sol[0])) / - Sol[1]; - - return (rhs / (1.0 - Sol[0] * inv_c)); -} - -int apecss_new_bubble_solver_run(APECSS_FLOAT tend, APECSS_FLOAT tEnd, struct APECSS_Bubble *Bubble) -{ - while (Bubble->t < tend - 0.01 * Bubble->NumericsODE->dtMin) - { - // Store the previous solution for sub-iterations - for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSolOld[i] = Bubble->ODEsSol[i]; - - // Check what comes next: the end of the solver run or, if applicable, a time instance to output the emissions - APECSS_FLOAT next_event_time = Bubble->results_emissionstime_check(tend, Bubble); - - // Set the time-step for the ODEs - apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); - - // Solve the ODEs - Bubble->err = apecss_odesolver(Bubble); - - // Perform sub-iterations on the control of the time-step when err > tol - register int subiter = 0; - while ((Bubble->err > Bubble->NumericsODE->tol) && (subiter < Bubble->NumericsODE->maxSubIter)) - { - ++subiter; - // Rewind the solution - for (register int i = 0; i < Bubble->nODEs; i++) Bubble->ODEsSol[i] = Bubble->ODEsSolOld[i]; - // Set the time-step for the ODEs - apecss_odesolver_settimestep(Bubble->NumericsODE, Bubble->err, next_event_time - Bubble->t, &(*Bubble).dt); - // Solve the ODEs again - Bubble->err = apecss_odesolver(Bubble); - } - Bubble->nSubIter += subiter; - - // Set new values - ++(Bubble->dtNumber); - Bubble->t += Bubble->dt; - Bubble->U = Bubble->ODEsSol[0]; - Bubble->R = Bubble->ODEsSol[1]; - - // Detect max value of radius - if (Bubble->t > tEnd - 10 / Bubble->Excitation->f) maxR = APECSS_MAX(maxR, Bubble->R); - - // Update allocation of the results (if necessary) - Bubble->results_emissionsnodeminmax_identify(Bubble); - Bubble->results_emissionsnode_alloc(Bubble); - - // Acoustic emissions (if applicable) - Bubble->emissions_update(Bubble); - - // Store results (if applicable) - Bubble->results_rayleighplesset_store(Bubble); - Bubble->results_emissionsspace_store(Bubble); - - // Write one-off results (if applicable) - Bubble->results_emissionstime_write(Bubble); - - // Update the last-step solution of the RK54 scheme - for (register int i = 0; i < Bubble->nODEs; i++) Bubble->kLast[i] = Bubble->k7[i]; - - // Update progress screen in the terminal (if applicable) - Bubble->progress_update(&(*Bubble).progress, Bubble->t - Bubble->tStart, Bubble->tEnd - Bubble->tStart); - } - - return (0); -} \ No newline at end of file diff --git a/examples/frequencyresponse/plot_results.py b/examples/frequencyresponse/plot_results.py deleted file mode 100644 index 64f7605..0000000 --- a/examples/frequencyresponse/plot_results.py +++ /dev/null @@ -1,390 +0,0 @@ -import os -import numpy as np -import matplotlib.pyplot as plt - -######### Graphical parameters #################################################################### -fontsize = 27.5 - -plt.rcParams['font.family']='serif' -plt.rcParams['font.serif']=['Times New Roman'] + plt.rcParams['font.serif'] -plt.rcParams['mathtext.fontset']='stix' -plt.rcParams['font.size']=fontsize - -cm = 1/2.54 - -######### Step 1 : Retrieving data ################################################################ - -#### Original paper results ##################### -paper_results_NI = {} -paper_results_IC_3 = {} -paper_results_IC_4 = {} - -working_path = os.getcwd() - -# No interactions (NI) -paper_path = os.path.join(working_path, "articleresults") -paper_path = os.path.join(paper_path, "NI") - -for file in os.listdir(paper_path) : - file_path = os.path.join(paper_path, file) - - text = open(file_path, "r") - lines = text.readlines() - text.close() - - r_init = float(lines[1].split(" : ")[-1]) - f_list = [] - r_list = [] - for i in range(3, len(lines)) : - line = lines[i].split(" ") - f_list.append(float(line[0].replace(",", "."))) - r_list.append(float(line[1].replace(",", "."))) - - paper_results_NI[r_init] = [f_list, r_list] - -# Incompressible interactions (IC) with 3 bubbles -paper_path = os.path.join(working_path, "articleresults") -paper_path = os.path.join(paper_path, "IC") -paper_path = os.path.join(paper_path, "3MBs") - -for file in os.listdir(paper_path) : - file_path = os.path.join(paper_path, file) - - text = open(file_path, "r") - lines = text.readlines() - text.close() - - r_init = float(lines[1].split(" : ")[-1]) - f_list = [] - r_list = [] - for i in range(3, len(lines)) : - line = lines[i].split(" ") - f_list.append(float(line[0].replace(",", "."))) - r_list.append(float(line[1].replace(",", "."))) - - paper_results_IC_3[r_init] = [f_list, r_list] - -# Incompressible interactions (IC) with 4 bubbles -paper_path = os.path.join(working_path, "articleresults") -paper_path = os.path.join(paper_path, "IC") -paper_path = os.path.join(paper_path, "4MBs") - -for file in os.listdir(paper_path) : - file_path = os.path.join(paper_path, file) - - text = open(file_path, "r") - lines = text.readlines() - text.close() - - r_init = float(lines[1].split(" : ")[-1]) - f_list = [] - r_list = [] - for i in range(3, len(lines)) : - line = lines[i].split(" ") - f_list.append(float(line[0].replace(",", "."))) - r_list.append(float(line[1].replace(",", "."))) - - paper_results_IC_4[r_init] = [f_list, r_list] - -#### Computation results ######################## -# Key distribution : Inttype->ODE->nBubbles->pressure->distance -dic_results = {} - -inttype_list = ["NI", "IC", "QA"] -for inttype in inttype_list : - dic_results[inttype] = {} - inttype_path = os.path.join(working_path, inttype) - inttype_path = os.path.join(inttype_path, "results") - - for file in os.listdir(inttype_path) : - # Finding computation results - file_path = os.path.join(inttype_path, file) - file = open(file_path, "r") - lines = file.readlines() - file.close() - - # Updating the keys in the dictionnary - firstline = lines[0].split(" ") - nBubbles = int(firstline[1]) - pa = float(firstline[3]) - dist = float(firstline[5]) - ode = int(firstline[7]) - - # Small correction for ode number (only 0 and 1 are accepted values) - if (ode != 0 and ode != 1) : ode = 0 - - if ode not in list(dic_results[inttype].keys()) : - dic_results[inttype][ode] = {} - if nBubbles not in list(dic_results[inttype][ode].keys()) : - dic_results[inttype][ode][nBubbles] = {} - if pa not in list(dic_results[inttype][ode][nBubbles].keys()) : - dic_results[inttype][ode][nBubbles][pa] = {} - if dist not in list(dic_results[inttype][ode][nBubbles][pa].keys()) : - dic_results[inttype][ode][nBubbles][pa][dist] = [] - - # Adding computation results to the dictionnary - for i in range(nBubbles) : - # Format of the results in the dictionnary : for each bubble, [r_init, [f_list], [r_list]] - r_init = float(lines[2].split(" ")[1+i].split(";")[0]) - dic_results[inttype][ode][nBubbles][pa][dist].append([r_init, [], []]) - - for i in range(2, len(lines)) : - data = lines[i].split(" ") - f = float(data[0]) - for j in range(nBubbles) : - r = float(lines[i].split(" ")[1+j].split(";")[1]) - dic_results[inttype][ode][nBubbles][pa][dist][j][1].append(f) - dic_results[inttype][ode][nBubbles][pa][dist][j][2].append(r) - -######### Step 2 : Validation plots ############################################################### - -#### No interactions #### -n_row = 1 -n_col = 2 - -fig, axs = plt.subplots(n_row, n_col, figsize=(n_col*25.0*cm, n_row*12.5*cm), sharey=True) -for i in range(n_col) : - axs[i].set_xlabel(r"$f$ [MHz]") - axs[i].set_xlim(xmin=0.5, xmax=10.0) - axs[i].grid() -axs[0].set_ylabel(r"$R_{\mathrm{max}}/R_{0}$") -fig.subplots_adjust(hspace=0.0, wspace=0.05*cm) - -axs[0].set_title(r"full Keller-Miksis ODE") -axs[1].set_title(r"partial Keller-Miksis ODE") - -data_list = dic_results["NI"][0][4][1.2e5][5e-6] -axs[0].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.0$ $\mu$m") -axs[0].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.8$ $\mu$m") -axs[0].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.5$ $\mu$m") -axs[0].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.5$ $\mu$m") - -data_list = dic_results["NI"][1][4][1.2e5][5e-6] -axs[1].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid") -axs[1].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid") -axs[1].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid") -axs[1].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid") - -for i in range(n_col) : - axs[i].plot(paper_results_NI[1.0][0], paper_results_NI[1.0][1], color="blue", linewidth=2.5, linestyle="dashed") - axs[i].plot(paper_results_NI[0.8][0], paper_results_NI[0.8][1], color="magenta", linewidth=2.5, linestyle="dashed") - axs[i].plot(paper_results_NI[0.5][0], paper_results_NI[0.5][1], color="red", linewidth=2.5, linestyle="dashed") - axs[i].plot(paper_results_NI[1.5][0], paper_results_NI[1.5][1], color="black", linewidth=2.5, linestyle="dashed") - -axs[0].legend(loc="upper right", frameon=False) -fig.savefig("frequencyresponse_comparison_NI.pdf", bbox_inches='tight',pad_inches=0.35) - -#### Incompressible interactions #### -n_row = 2 -n_col = 2 - -fig, axs = plt.subplots(n_row, n_col, figsize=(n_col*25.0*cm, n_row*12.5*cm), sharey=True, sharex=True) -for i in range(n_row) : - for j in range(n_col) : - axs[i, j].grid() - if i == 1 : - axs[i, j].set_xlabel(r"$f$ [MHz]") - axs[i, j].set_xlim(xmin=0.5, xmax=10.0) - if j == 0 : - axs[i, j].set_ylabel(r"$R_{\mathrm{max}}/R_{0}$") -fig.subplots_adjust(hspace=0.1*cm, wspace=0.05*cm) - -axs[0, 0].set_title(r"full Keller-Miksis ODE") -axs[0, 1].set_title(r"partial Keller-Miksis ODE") - -# 3 MBs -data_list = dic_results["IC"][0][3][1.2e5][5e-6] -axs[0, 0].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.0$ $\mu$m") -axs[0, 0].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.8$ $\mu$m") -axs[0, 0].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.5$ $\mu$m") - -data_list = dic_results["IC"][1][3][1.2e5][5e-6] -axs[0, 1].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid") -axs[0, 1].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid") -axs[0, 1].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid") - -# 4 MBs -data_list = dic_results["IC"][0][4][1.2e5][5e-6] -axs[1, 0].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.0$ $\mu$m") -axs[1, 0].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.8$ $\mu$m") -axs[1, 0].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.5$ $\mu$m") -axs[1, 0].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.5$ $\mu$m") - -data_list = dic_results["IC"][1][4][1.2e5][5e-6] -axs[1, 1].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.0$ $\mu$m") -axs[1, 1].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.8$ $\mu$m") -axs[1, 1].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.5$ $\mu$m") -axs[1, 1].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.5$ $\mu$m") - -for j in range(n_col) : - axs[0, j].plot(paper_results_IC_3[1.0][0], paper_results_IC_3[1.0][1], color="blue", linewidth=2.5, linestyle="dashed") - axs[0, j].plot(paper_results_IC_3[0.8][0], paper_results_IC_3[0.8][1], color="magenta", linewidth=2.5, linestyle="dashed") - axs[0, j].plot(paper_results_IC_3[0.5][0], paper_results_IC_3[0.5][1], color="red", linewidth=2.5, linestyle="dashed") - - axs[1, j].plot(paper_results_IC_4[1.0][0], paper_results_IC_4[1.0][1], color="blue", linewidth=2.5, linestyle="dashed") - axs[1, j].plot(paper_results_IC_4[0.8][0], paper_results_IC_4[0.8][1], color="magenta", linewidth=2.5, linestyle="dashed") - axs[1, j].plot(paper_results_IC_4[0.5][0], paper_results_IC_4[0.5][1], color="red", linewidth=2.5, linestyle="dashed") - axs[1, j].plot(paper_results_IC_4[1.5][0], paper_results_IC_4[1.5][1], color="black", linewidth=2.5, linestyle="dashed") - -axs[0, 0].legend(loc="upper right", frameon=False) -axs[1, 0].legend(loc="upper right", frameon=False) -fig.savefig("frequencyresponse_comparison_IC.pdf", bbox_inches='tight',pad_inches=0.35) - -######### Step 3 : Article plots ################################################################## - -######## Reproduction of Haghi's results ################################# -n_row = 3 -n_col = 2 - -fig, axs = plt.subplots(n_row, n_col, figsize=(n_col*25.0*cm, n_row*12.5*cm), sharey=True, sharex=True) -for i in range(n_row) : - for j in range(n_col) : - axs[i, j].grid() - if i == 2 : - axs[i, j].set_xlabel(r"$f$ [MHz]") - axs[i, j].set_xlim(xmin=0.5, xmax=10.0) - if j == 0 : - axs[i, j].set_ylabel(r"$R_{\mathrm{max}}/R_{0}$") -fig.subplots_adjust(hspace=0.1*cm, wspace=0.05*cm) - -axs[0, 0].set_title(r"(a) 3MBs") -axs[0, 1].set_title(r"(b) 4MBs") - -# 3 MBs -data_list = dic_results["NI"][0][4][1.2e5][5e-6] -axs[0, 0].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.0$ $\mu$m") -axs[0, 0].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.8$ $\mu$m") -axs[0, 0].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.5$ $\mu$m") -axs[0, 0].text(2.75, 2.25,r"No interactions") - -data_list = dic_results["IC"][0][3][1.2e5][5e-6] -axs[1, 0].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid") -axs[1, 0].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid") -axs[1, 0].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid") -axs[1, 0].text(2.75, 2.25,r"Incompressible interactions") - -data_list = dic_results["QA"][0][3][1.2e5][5e-6] -axs[2, 0].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid") -axs[2, 0].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid") -axs[2, 0].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid") -axs[2, 0].text(2.75, 2.25,r"Quasi-acoustic interactions") - -# 4 MBs -data_list = dic_results["NI"][0][4][1.2e5][5e-6] -axs[0, 1].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.0$ $\mu$m") -axs[0, 1].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.8$ $\mu$m") -axs[0, 1].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.5$ $\mu$m") -axs[0, 1].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.5$ $\mu$m") -axs[0, 1].text(2.75, 2.25,r"No interactions") - -data_list = dic_results["IC"][0][4][1.2e5][5e-6] -axs[1, 1].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid") -axs[1, 1].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid") -axs[1, 1].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid") -axs[1, 1].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid") -axs[1, 1].text(2.75, 2.25,r"Incompressible interactions") - -data_list = dic_results["QA"][0][4][1.2e5][5e-6] -axs[2, 1].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid") -axs[2, 1].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid") -axs[2, 1].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid") -axs[2, 1].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid") -axs[2, 1].text(2.75, 2.25,r"Quasi-acoustic interactions") - -# Reference values -axs[0, 0].plot(paper_results_NI[1.0][0], paper_results_NI[1.0][1], color="blue", linewidth=2.5, linestyle="dashed") -axs[0, 0].plot(paper_results_NI[0.8][0], paper_results_NI[0.8][1], color="magenta", linewidth=2.5, linestyle="dashed") -axs[0, 0].plot(paper_results_NI[0.5][0], paper_results_NI[0.5][1], color="red", linewidth=2.5, linestyle="dashed") - -axs[0, 1].plot(paper_results_NI[1.0][0], paper_results_NI[1.0][1], color="blue", linewidth=2.5, linestyle="dashed") -axs[0, 1].plot(paper_results_NI[0.8][0], paper_results_NI[0.8][1], color="magenta", linewidth=2.5, linestyle="dashed") -axs[0, 1].plot(paper_results_NI[0.5][0], paper_results_NI[0.5][1], color="red", linewidth=2.5, linestyle="dashed") -axs[0, 1].plot(paper_results_NI[1.5][0], paper_results_NI[1.5][1], color="black", linewidth=2.5, linestyle="dashed") - -axs[1, 0].plot(paper_results_IC_3[1.0][0], paper_results_IC_3[1.0][1], color="blue", linewidth=2.5, linestyle="dashed") -axs[1, 0].plot(paper_results_IC_3[0.8][0], paper_results_IC_3[0.8][1], color="magenta", linewidth=2.5, linestyle="dashed") -axs[1, 0].plot(paper_results_IC_3[0.5][0], paper_results_IC_3[0.5][1], color="red", linewidth=2.5, linestyle="dashed") - -axs[1, 1].plot(paper_results_IC_4[1.0][0], paper_results_IC_4[1.0][1], color="blue", linewidth=2.5, linestyle="dashed") -axs[1, 1].plot(paper_results_IC_4[0.8][0], paper_results_IC_4[0.8][1], color="magenta", linewidth=2.5, linestyle="dashed") -axs[1, 1].plot(paper_results_IC_4[0.5][0], paper_results_IC_4[0.5][1], color="red", linewidth=2.5, linestyle="dashed") -axs[1, 1].plot(paper_results_IC_4[1.5][0], paper_results_IC_4[1.5][1], color="black", linewidth=2.5, linestyle="dashed") - -axs[0, 0].legend(loc="upper right", frameon=False) -axs[0, 1].legend(loc="upper right", frameon=False) -fig.savefig("frequencyresponse.pdf", bbox_inches='tight',pad_inches=0.35) - -######## Interaction distance study ###################################### -n_row = 2 -n_col = 2 - -fig, axs = plt.subplots(n_row, n_col, figsize=(n_col*25.0*cm, n_row*12.5*cm), sharey=True, sharex=True) -for i in range(n_row) : - for j in range(n_col) : - axs[i, j].grid() - if i == 1 : - axs[i, j].set_xlabel(r"$f$ [MHz]") - axs[i, j].set_xlim(xmin=0.5, xmax=8.0) - if j == 0 : - axs[i, j].set_ylabel(r"$R_{\mathrm{max}}/R_{0}$") -fig.subplots_adjust(hspace=0.55*cm, wspace=0.05*cm) - -axs[0, 0].set_title(r"$d = 5$ $\mu$m") -axs[0, 1].set_title(r"$d = 10$ $\mu$m") -axs[1, 0].set_title(r"$d = 25$ $\mu$m") -axs[1, 1].set_title(r"$d = 50$ $\mu$m") - -# 5 microns -data_list = dic_results["QA"][0][4][1.2e5][5e-6] -axs[0, 0].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.0$ $\mu$m") -axs[0, 0].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.8$ $\mu$m") -axs[0, 0].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid", label=r"$R_{0}=0.5$ $\mu$m") -axs[0, 0].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid", label=r"$R_{0}=1.5$ $\mu$m") - -data_list = dic_results["IC"][0][4][1.2e5][5e-6] -axs[0, 0].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="dashed") -axs[0, 0].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="dashed") -axs[0, 0].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="dashed") -axs[0, 0].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="dashed") - -# 10 microns -data_list = dic_results["QA"][0][4][1.2e5][10e-6] -axs[0, 1].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid") -axs[0, 1].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid") -axs[0, 1].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid") -axs[0, 1].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid") - -data_list = dic_results["IC"][0][4][1.2e5][10e-6] -axs[0, 1].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="dashed") -axs[0, 1].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="dashed") -axs[0, 1].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="dashed") -axs[0, 1].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="dashed") - -# 25 microns -data_list = dic_results["QA"][0][4][1.2e5][25e-6] -axs[1, 0].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid") -axs[1, 0].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid") -axs[1, 0].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid") -axs[1, 0].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid") - -data_list = dic_results["IC"][0][4][1.2e5][25e-6] -axs[1, 0].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="dashed") -axs[1, 0].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="dashed") -axs[1, 0].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="dashed") -axs[1, 0].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="dashed") - -# 50 microns -data_list = dic_results["QA"][0][4][1.2e5][50e-6] -axs[1, 1].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="solid") -axs[1, 1].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="solid") -axs[1, 1].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="solid") -axs[1, 1].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="solid") - -data_list = dic_results["IC"][0][4][1.2e5][50e-6] -axs[1, 1].plot(np.array(data_list[0][1])*1e-6, np.array(data_list[0][2])/data_list[0][0], color="blue", linewidth=2.5, linestyle="dashed") -axs[1, 1].plot(np.array(data_list[1][1])*1e-6, np.array(data_list[1][2])/data_list[1][0], color="magenta", linewidth=2.5, linestyle="dashed") -axs[1, 1].plot(np.array(data_list[2][1])*1e-6, np.array(data_list[2][2])/data_list[2][0], color="red", linewidth=2.5, linestyle="dashed") -axs[1, 1].plot(np.array(data_list[3][1])*1e-6, np.array(data_list[3][2])/data_list[3][0], color="black", linewidth=2.5, linestyle="dashed") - -axs[0, 0].legend(loc="upper right", frameon=False) -fig.savefig("frequencyresponse_distancestudy.pdf", bbox_inches='tight',pad_inches=0.35) \ No newline at end of file diff --git a/examples/frequencyresponse/run_frequencyresponse.sh b/examples/frequencyresponse/run_frequencyresponse.sh deleted file mode 100755 index 9661a59..0000000 --- a/examples/frequencyresponse/run_frequencyresponse.sh +++ /dev/null @@ -1,144 +0,0 @@ -set -e - -######################## No interactions (NI) ##################################################### - -cd NI/build -./compile.sh -cd .. - -for ((f=500000;f<=10000000;f+=3000)) -do - ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -done -python3 gather_results.py -rm -rf max_radius.txt - -for ((f=500000;f<=10000000;f+=3000)) -do - ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -ode 1 -dt_inter 5.0e-10 -done -python3 gather_results.py -rm -rf max_radius.txt - -cd .. - -######################## Incompressible interactions (IC) ######################################### - -cd IC/build -./compile.sh -cd .. - -for ((f=500000;f<=10000000;f+=3000)) -do - ./build/frequencyresponse_apecss -options run.apecss -nb 3 -freq $f -amp 120e3 -dt_inter 1e-9 -done -python3 gather_results.py -rm -rf max_radius.txt - -for ((f=500000;f<=10000000;f+=3000)) -do - ./build/frequencyresponse_apecss -options run.apecss -nb 3 -freq $f -amp 120e3 -ode 1 -dt_inter 5.0e-10 -done -python3 gather_results.py -rm -rf max_radius.txt - -for ((f=500000;f<=10000000;f+=3000)) -do - ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -dt_inter 1e-9 -done -python3 gather_results.py -rm -rf max_radius.txt - -for ((f=500000;f<=10000000;f+=3000)) -do - ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -ode 1 -dt_inter 5.0e-10 -done -python3 gather_results.py -rm -rf max_radius.txt - -# Distance study -dist_list=(10e-6 25e-6 50e-6) -for dist in "${dist_list[@]}" -do - for ((f=500000;f<=10000000;f+=3000)) - do - ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -dt_inter 1e-9 -dist $dist - done - python3 gather_results.py - rm -rf max_radius.txt -done - -cd .. - -######################## Quasi-acoustic interactions (QA) ######################################### - -cd QA/build -./compile.sh -cd .. - -for ((f=500000;f<=10000000;f+=3000)) -do - ./build/frequencyresponse_apecss -options run.apecss -nb 3 -freq $f -amp 120e3 -dt_inter 1e-9 -done -python3 gather_results.py -rm -rf max_radius.txt - -for ((f=500000;f<1900000;f+=3000)) -do - ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -dt_inter 1e-9 -done -for ((f=1900000;f<2900000;f+=3000)) -do - ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -dt_inter 5.0e-10 -done -for ((f=2900000;f<=10000000;f+=3000)) -do - ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -dt_inter 1e-9 -done -python3 gather_results.py -rm -rf max_radius.txt - -# Distance study -dist_list=(10e-6 25e-6 50e-6) -for dist in "${dist_list[@]}" -do - for ((f=500000;f<1900000;f+=3000)) - do - ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -dt_inter 1e-9 -dist $dist - done - for ((f=1900000;f<2900000;f+=3000)) - do - ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -dt_inter 5.0e-10 -dist $dist - done - for ((f=2900000;f<=10000000;f+=3000)) - do - ./build/frequencyresponse_apecss -options run.apecss -nb 4 -freq $f -amp 120e3 -dt_inter 1e-9 -dist $dist - done - python3 gather_results.py - rm -rf max_radius.txt -done - -cd .. - -######################## Cleaning ################################################################# - -cd NI -for ((c=0;c<=4;c++)) -do - rm -rf Bubble_$c -done -cd .. - -cd IC -for ((c=0;c<=4;c++)) -do - rm -rf Bubble_$c -done -cd .. - -cd QA -for ((c=0;c<=4;c++)) -do - rm -rf Bubble_$c -done -cd .. \ No newline at end of file From 53f679fc41c630f1895d541df044b24a68ca15d7 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 23 Sep 2024 13:36:20 -0400 Subject: [PATCH 129/138] parallelinteraction ; deleting folder --- .../parallelinteraction/build/CMakeLists.txt | 41 -- examples/parallelinteraction/build/compile.sh | 5 - examples/parallelinteraction/execmpi.sh | 13 - examples/parallelinteraction/run.apecss | 38 -- .../src/parallelinteraction_apecss.c | 477 ------------------ 5 files changed, 574 deletions(-) delete mode 100644 examples/parallelinteraction/build/CMakeLists.txt delete mode 100755 examples/parallelinteraction/build/compile.sh delete mode 100755 examples/parallelinteraction/execmpi.sh delete mode 100644 examples/parallelinteraction/run.apecss delete mode 100644 examples/parallelinteraction/src/parallelinteraction_apecss.c diff --git a/examples/parallelinteraction/build/CMakeLists.txt b/examples/parallelinteraction/build/CMakeLists.txt deleted file mode 100644 index 6d24867..0000000 --- a/examples/parallelinteraction/build/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -cmake_minimum_required(VERSION 3.12) - -project (parallelinteraction_apecss) -set(CMAKE_C_COMPILER mpicc) - -include_directories($ENV{APECSS_DIR}/include) -FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) - -set (mylibs m apecss) -link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) - -foreach(arg ${myincludes}) - IF (arg MATCHES "-I") - STRING(REGEX REPLACE "-I" "" myinc ${arg}) - message("Additional include: ${myinc}") - include_directories(${myinc}) - ENDIF(arg MATCHES "-I") -endforeach(arg ${myincludes}) - -foreach(arg ${mylibs}) - STRING(REGEX REPLACE "lib" "" myl1 ${arg}) - STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) - set(mylibs ${myl2} ${mylibs} ${myl2}) -endforeach(arg ${mylibs}) - -if(NOT CMAKE_BUILD_TYPE) - message(STATUS "Optimization: No optimization specified.") - set(CMAKE_BUILD_TYPE Release) -endif() - -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - message(STATUS "Optimization: Debug") - set(CMAKE_C_FLAGS_DEBUG "-Wall -g") -elseif(CMAKE_BUILD_TYPE STREQUAL "Release") - message(STATUS "Optimization: Release") - add_definitions(-DNDEBUG) - set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") -endif() - -add_executable(parallelinteraction_apecss ${myfiles}) -target_link_libraries(parallelinteraction_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/parallelinteraction/build/compile.sh b/examples/parallelinteraction/build/compile.sh deleted file mode 100755 index ae9493a..0000000 --- a/examples/parallelinteraction/build/compile.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -rm parallelinteraction_apecss -cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release -make -rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/parallelinteraction/execmpi.sh b/examples/parallelinteraction/execmpi.sh deleted file mode 100755 index ed503b3..0000000 --- a/examples/parallelinteraction/execmpi.sh +++ /dev/null @@ -1,13 +0,0 @@ -cd build -./compile.sh -cd .. -mpiexec -n 5 ./build/parallelinteraction_apecss -options run.apecss -freq 15.7e3 -amp -120e3 -tend 7.5e-4 - -#mpiexec -n 2 valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valout.txt ./build/parallelinteraction_apecss -options run.apecss -freq 15.7e3 -amp -120e3 -tend 7.5e-8 -#valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valout.txt ./build/parallelinteraction_apecss -options run.apecss -freq 15.7e3 -amp -120e3 -tend 7.5e-8 -#valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valout.txt mpiexec -n 2 ./build/parallelinteraction_apecss -options run.apecss -freq 15.7e3 -amp -120e3 -tend 7.5e-8 - -for ((c=0; c<25; c++)) -do - rm -rf Bubble_$c -done \ No newline at end of file diff --git a/examples/parallelinteraction/run.apecss b/examples/parallelinteraction/run.apecss deleted file mode 100644 index 9d8552a..0000000 --- a/examples/parallelinteraction/run.apecss +++ /dev/null @@ -1,38 +0,0 @@ -######################################################### -# # -# APECSS Options File # -# # -######################################################### - -BUBBLE -RPModel KM -Emissions QA 250.0e-6 -PressureAmbient 1.0e5 -END - -GAS -EoS IG -ReferencePressure 1.0e5 -ReferenceDensity 1.2 -PolytropicExponent 1.4 -END - -LIQUID -ReferencePressure 1.0e5 -ReferenceDensity 1000.0 -ReferenceSoundSpeed 1500.0 -Viscosity 1.002e-3 -END - -INTERFACE -SurfaceTensionCoeff 0.0728 -END - -RESULTS -Bubble -OutputFreqRP 5 -END - -ODESOLVER -tolerance 1.0e-10 -END diff --git a/examples/parallelinteraction/src/parallelinteraction_apecss.c b/examples/parallelinteraction/src/parallelinteraction_apecss.c deleted file mode 100644 index 93ed069..0000000 --- a/examples/parallelinteraction/src/parallelinteraction_apecss.c +++ /dev/null @@ -1,477 +0,0 @@ -// This source file is part of APECSS, an open-source software toolbox -// for the computation of pressure-driven bubble dynamics and acoustic -// emissions in spherical symmetry. -// -// Copyright (C) 2022-2024 The APECSS Developers -// -// The APECSS Developers are listed in the README.md file available in -// the GitHub repository at https://github.com/polycfd/apecss. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// ------------------------------------------------------------------- -// APECSS standalone example of acoustically-interacting microbubbles, -// demonstrating a simple parallelization of APECSS. -// ------------------------------------------------------------------- - -#include -#include -#include "apecss.h" - -struct APECSS_Parallel_Cluster -{ - int rank, size; - int nBubbles_local, nBubbles_global; - - int *bubblerank; // max id of bubbles for each rank - APECSS_FLOAT *bubbleglobal_R, *bubbleglobal_x, *bubbleglobal_y, *bubbleglobal_z; // Radius and x,y,z location of all bubbles - APECSS_FLOAT *sumGU_rank; // Contributions from local bubbles to all bubbles -}; - -// Declaration of additional case-dependent functions -APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubble[], struct APECSS_Parallel_Cluster *RankInfo); - -int main(int argc, char **args) -{ - /* Initialize MPI */ - int mpi_rank, mpi_size; - MPI_Init(&argc, &args); - MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); - MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); - - char OptionsDir[APECSS_STRINGLENGTH]; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Set the case-dependent simulation parameters - const int nBubbles_x = 5; - const int nBubbles = nBubbles_x * nBubbles_x; // Number of bubbles - APECSS_FLOAT bubble_bubble_dist = 200.0e-6; // Bubble-bubble distance - - // Interbubble time-step, defining the frequency with which the neighbor influence is updated - APECSS_FLOAT dt_interbubble = 1.0e-8; - - // Initialize the simulation parameters given by the execution command - double tEnd = 0.0; - double fa = 0.0; - double pa = 0.0; - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - apecss_infoscreen(); - - /* Read commandline options */ - sprintf(OptionsDir, "./run.apecss"); // This is the default - int j = 1; // First argument is the call to the executable - while (j < argc) - { - if (strcmp("-options", args[j]) == 0) - { - sprintf(OptionsDir, "%s", args[j + 1]); - j += 2; - } - else if (strcmp("-tend", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &tEnd); - j += 2; - } - else if (strcmp("-freq", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &fa); - j += 2; - } - else if (strcmp("-amp", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &pa); - j += 2; - } - else if (strcmp("-h", args[j]) == 0) - { - apecss_helpscreen(); - } - else - { - char str[APECSS_STRINGLENGTH_SPRINTF]; - sprintf(str, "Unknown command line options: %s", args[j]); - apecss_erroronscreen(1, str); - ++j; - } - } - - /* Allocate structure for parallel data */ - struct APECSS_Parallel_Cluster *RankInfo = (struct APECSS_Parallel_Cluster *) malloc(sizeof(struct APECSS_Parallel_Cluster)); - RankInfo->rank = mpi_rank; - RankInfo->size = mpi_size; - - /* Determine the number of bubbles per rank */ - int max_per_rank = ceil((double) nBubbles / (double) mpi_size); - RankInfo->nBubbles_local = APECSS_MAX(0, APECSS_MIN(max_per_rank, nBubbles - mpi_rank * max_per_rank)); - // printf("[%i] %i\n", mpi_rank, RankInfo->nBubbles_local); - /* Share the parallel distribution of bubbles with all ranks */ - - RankInfo->bubblerank = malloc((RankInfo->size + 1) * sizeof(int)); - - RankInfo->nBubbles_global = 0; - RankInfo->bubblerank[0] = 0; - for (int r = 0; r < RankInfo->size; r++) - { - int temp = RankInfo->nBubbles_local; - MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); - RankInfo->bubblerank[r + 1] = RankInfo->bubblerank[r] + temp; - RankInfo->nBubbles_global += temp; - } - - /* Allocate and initialize Bubble structure */ - struct APECSS_Bubble *Bubbles[RankInfo->nBubbles_local]; - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(sizeof(struct APECSS_Bubble)); - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_initializestruct(Bubbles[i]); - - /* Set default options and read the options for the bubble */ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); - - /* Allocate the structures for the fluid properties and ODE solver parameters */ - struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); - struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); - struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); - struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); - - /* Set the default options for the fluid properties and solver parameters */ - apecss_gas_setdefaultoptions(Gas); - apecss_liquid_setdefaultoptions(Liquid); - apecss_interface_setdefaultoptions(Interface); - apecss_odesolver_setdefaultoptions(NumericsODE); - - /* Read the options file for the fluid properties and solver parameters */ - apecss_gas_readoptions(Gas, OptionsDir); - apecss_liquid_readoptions(Liquid, OptionsDir); - apecss_interface_readoptions(Interface, OptionsDir); - apecss_odesolver_readoptions(NumericsODE, OptionsDir); - - /* Associate the bubble with the relevant fluid properties and solver parameters */ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->Gas = Gas; - Bubbles[i]->Liquid = Liquid; - Bubbles[i]->Interface = Interface; - Bubbles[i]->NumericsODE = NumericsODE; - } - - /* Allocate and set the excitation parameters */ - struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); - Excitation->type = APECSS_EXCITATION_SIN; - Excitation->f = (APECSS_FLOAT) fa; - Excitation->dp = (APECSS_FLOAT) pa; - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Excitation = Excitation; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Create individual folders for the results of each bubble - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - if (Bubbles[i]->Results != NULL) - { - sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", RankInfo->bubblerank[RankInfo->rank] + i); - struct stat st = {0}; - if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); - } - } - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - /* Process all options */ - apecss_gas_processoptions(Gas); - apecss_liquid_processoptions(Liquid); - apecss_interface_processoptions(Interface); - apecss_odesolver_processoptions(NumericsODE); - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_processoptions(Bubbles[i]); - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Use the revised pressure at infinity, including neighbor contributions - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->get_pressure_infinity = parallel_interactions_bubble_pressure_infinity; - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - Bubbles[i]->get_pressurederivative_infinity = parallel_interactions_bubble_pressurederivative_infinity; - - // Allocate interaction structure - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); - Bubbles[i]->Interaction->dp_neighbor = 0.0; - Bubbles[i]->Interaction->last_t_1 = 0.0; - Bubbles[i]->Interaction->last_t_2 = 0.0; - Bubbles[i]->Interaction->last_p_1 = 0.0; - Bubbles[i]->Interaction->last_p_2 = 0.0; - } - - // Update interaction structure - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->nBubbles = nBubbles; // Not used? - - // Define the size of each bubble - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - if ((i + mpi_rank * max_per_rank) % 2) - Bubbles[i]->R0 = 5.0e-6; - else - Bubbles[i]->R0 = 10.0e-6; - - Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; - } - - // Define center location for each bubble - - int ri = 0, rj = 0; - if (mpi_rank) - { - ri = mpi_rank * max_per_rank % nBubbles_x; - rj = mpi_rank * max_per_rank / nBubbles_x; - } - - for (register int n = 0; n < RankInfo->nBubbles_local; n++) - { - Bubbles[n]->Interaction->location[0] = ((APECSS_FLOAT) ri) * bubble_bubble_dist; - Bubbles[n]->Interaction->location[1] = ((APECSS_FLOAT) rj) * bubble_bubble_dist; - Bubbles[n]->Interaction->location[2] = 0.0; - - if (ri < nBubbles_x - 1) - { - ri++; - } - else - { - ri = 0; - rj++; - } - } - - // Share the location of each bubble with all ranks - - RankInfo->bubbleglobal_R = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - RankInfo->bubbleglobal_x = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - RankInfo->bubbleglobal_y = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - RankInfo->bubbleglobal_z = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - - for (int r = 0; r < RankInfo->size; r++) - { - int temp = RankInfo->nBubbles_local; - MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); - - APECSS_FLOAT temp_array[4]; - - for (int i = 0; i < temp; i++) - { - if (r == RankInfo->rank) - { - temp_array[0] = Bubbles[i]->Interaction->location[0]; - temp_array[1] = Bubbles[i]->Interaction->location[1]; - temp_array[2] = Bubbles[i]->Interaction->location[2]; - temp_array[3] = Bubbles[i]->R; - } - - MPI_Bcast(temp_array, 4, MPI_DOUBLE, r, MPI_COMM_WORLD); - - RankInfo->bubbleglobal_x[RankInfo->bubblerank[r] + i] = temp_array[0]; - RankInfo->bubbleglobal_y[RankInfo->bubblerank[r] + i] = temp_array[1]; - RankInfo->bubbleglobal_z[RankInfo->bubblerank[r] + i] = temp_array[2]; - RankInfo->bubbleglobal_R[RankInfo->bubblerank[r] + i] = temp_array[3]; - } - } - - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - clock_t starttimebubble = clock(); - APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->tStart = tSim; - Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; - Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step - } - - /* Initialize the bubble based on the selected options */ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_initialize(Bubbles[i]); - - /* Initialize */ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_initialize(Bubbles[i]); - - // Allocate the pressure contribution array - RankInfo->sumGU_rank = malloc(2 * RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - - /* Solve the bubble dynamics */ - while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered - { - APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); - tSim += dtSim; - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Update the contribution of the neighbor bubble - parallel_interactions_quasi_acoustic(Bubbles, RankInfo); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; - Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; - - Bubbles[i]->Interaction->last_t_1 = tSim; - Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; - } - } - - /* Finalize the simulation*/ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_finalize(Bubbles[i]); - - char str[APECSS_STRINGLENGTH_SPRINTF]; - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", RankInfo->bubblerank[RankInfo->rank] + i, Bubbles[i]->dtNumber, - Bubbles[i]->nSubIter, (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); - apecss_writeonscreen(str); - } - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); - - /* Make sure all allocated memory is freed */ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_freestruct(Bubbles[i]); - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) free(Bubbles[i]); - free(Gas); - free(Liquid); - free(Interface); - free(NumericsODE); - free(Excitation); - - free(RankInfo->bubblerank); - RankInfo->bubblerank = NULL; - free(RankInfo->bubbleglobal_R); - RankInfo->bubbleglobal_R = NULL; - free(RankInfo->bubbleglobal_x); - RankInfo->bubbleglobal_x = NULL; - free(RankInfo->bubbleglobal_y); - RankInfo->bubbleglobal_y = NULL; - free(RankInfo->bubbleglobal_z); - RankInfo->bubbleglobal_z = NULL; - free(RankInfo->sumGU_rank); - RankInfo->sumGU_rank = NULL; - free(RankInfo); - - MPI_Finalize(); - - return (0); -} - -APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - return (Bubble->p0 - Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * t) + Bubble->Interaction->dp_neighbor); -} - -APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - APECSS_FLOAT derivative = -2.0 * APECSS_PI * Bubble->Excitation->f * Bubble->Excitation->dp * APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * t); - APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; - if (delta_t > Bubble->dt) - { - return (derivative + (Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) / delta_t); - } - else - { - return (derivative); - } -} - -int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo) -{ - // All bubbles are supposed to be in the same liquid - struct APECSS_Liquid *Liquid = Bubbles[0]->Liquid; - - // Update bubble radii info - APECSS_FLOAT *tempR = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - for (register int j = 0; j < RankInfo->nBubbles_global; j++) tempR[j] = 0.0; - for (register int i = 0; i < RankInfo->nBubbles_local; i++) tempR[RankInfo->bubblerank[RankInfo->rank] + i] = Bubbles[i]->R; - MPI_Allreduce(tempR, RankInfo->bubbleglobal_R, RankInfo->nBubbles_global, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - free(tempR); - - // Reset pressure contributions of the neighours - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0; - - // Locally compute the contribution to each bubble - for (register int j = 0; j < RankInfo->nBubbles_global; j++) - { - APECSS_FLOAT x_j = RankInfo->bubbleglobal_x[j]; - APECSS_FLOAT y_j = RankInfo->bubbleglobal_y[j]; - APECSS_FLOAT z_j = RankInfo->bubbleglobal_z[j]; - - RankInfo->sumGU_rank[j] = 0.0; - RankInfo->sumGU_rank[j + RankInfo->nBubbles_global] = 0.0; - - double R_j = RankInfo->bubbleglobal_R[j]; - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - if (j != RankInfo->bubblerank[RankInfo->rank] + i) - { - APECSS_FLOAT sumU_bubble = 0.0; - APECSS_FLOAT sumG_bubble = 0.0; - int nodecount_bubble = 0; - - APECSS_FLOAT x_i = Bubbles[i]->Interaction->location[0]; - APECSS_FLOAT y_i = Bubbles[i]->Interaction->location[1]; - APECSS_FLOAT z_i = Bubbles[i]->Interaction->location[2]; - - APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); - - // The loop over the emission nodes begins with the most far away from the emitting bubble - struct APECSS_EmissionNode *Current = Bubbles[i]->Emissions->LastNode; - while (Current != NULL) - { - if (Current->r < interbubble_dist - R_j) - { - // The following emission nodes have not yet reached the bubble of interest - Current = NULL; - } - else if (Current->r > interbubble_dist + R_j) - { - // The bubble of interest is still not reached - Current = Current->backward; - } - else - { - // The current emission node is located inside the bubble of interest - APECSS_FLOAT gr = Current->g / Current->r; - sumU_bubble += (Current->f / APECSS_POW2(Current->r)) + gr / Liquid->cref; - sumG_bubble += gr; - nodecount_bubble++; - Current = Current->backward; - } - } - - if (nodecount_bubble) - { - APECSS_FLOAT inv_nodecount = 1.0 / (APECSS_FLOAT) nodecount_bubble; - RankInfo->sumGU_rank[j] += sumG_bubble * inv_nodecount; - RankInfo->sumGU_rank[j + RankInfo->nBubbles_global] += sumU_bubble * inv_nodecount; - } - } - } - } - - APECSS_FLOAT *sumGU_all = malloc(2 * RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - MPI_Allreduce(RankInfo->sumGU_rank, sumGU_all, 2 * RankInfo->nBubbles_global, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - - // Compute the total pressure contributions of the neighbours for all local bubbles - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->Interaction->dp_neighbor = - Liquid->rhoref * (sumGU_all[RankInfo->bubblerank[RankInfo->rank] + i] - - 0.5 * APECSS_POW2(sumGU_all[RankInfo->nBubbles_global + RankInfo->bubblerank[RankInfo->rank] + i])); - } - - free(sumGU_all); - - return (0); -} \ No newline at end of file From e15664fc2d481bf9d6d41a4d747fbb02203ef07e Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 23 Sep 2024 13:37:19 -0400 Subject: [PATCH 130/138] sphericalclustercavitationonset ; deleting folder --- .../IC/build/CMakeLists.txt | 41 -- .../IC/build/compile.sh | 5 - .../IC/gather_results.py | 53 -- .../IC/run.apecss | 32 - .../sphericalclustercavitationonset_apecss.c | 428 ------------ .../NI/build/CMakeLists.txt | 41 -- .../NI/build/compile.sh | 5 - .../NI/gather_results.py | 47 -- .../NI/run.apecss | 32 - .../sphericalclustercavitationonset_apecss.c | 396 ----------- .../QA/build/CMakeLists.txt | 41 -- .../QA/build/compile.sh | 5 - .../QA/execmpi.sh | 18 - .../QA/gather_results.py | 85 --- .../QA/run.apecss | 32 - .../sphericalclustercavitationonset_apecss.c | 655 ------------------ .../sphericalclustercavitationonset/README.md | 1 - .../plot_results.py | 466 ------------- .../run_sphericalclustercavitationonset.sh | 84 --- .../test_distribution.py | 44 -- 20 files changed, 2511 deletions(-) delete mode 100644 examples/sphericalclustercavitationonset/IC/build/CMakeLists.txt delete mode 100755 examples/sphericalclustercavitationonset/IC/build/compile.sh delete mode 100644 examples/sphericalclustercavitationonset/IC/gather_results.py delete mode 100644 examples/sphericalclustercavitationonset/IC/run.apecss delete mode 100644 examples/sphericalclustercavitationonset/IC/src/sphericalclustercavitationonset_apecss.c delete mode 100644 examples/sphericalclustercavitationonset/NI/build/CMakeLists.txt delete mode 100755 examples/sphericalclustercavitationonset/NI/build/compile.sh delete mode 100644 examples/sphericalclustercavitationonset/NI/gather_results.py delete mode 100644 examples/sphericalclustercavitationonset/NI/run.apecss delete mode 100644 examples/sphericalclustercavitationonset/NI/src/sphericalclustercavitationonset_apecss.c delete mode 100644 examples/sphericalclustercavitationonset/QA/build/CMakeLists.txt delete mode 100755 examples/sphericalclustercavitationonset/QA/build/compile.sh delete mode 100755 examples/sphericalclustercavitationonset/QA/execmpi.sh delete mode 100644 examples/sphericalclustercavitationonset/QA/gather_results.py delete mode 100644 examples/sphericalclustercavitationonset/QA/run.apecss delete mode 100644 examples/sphericalclustercavitationonset/QA/src/sphericalclustercavitationonset_apecss.c delete mode 100644 examples/sphericalclustercavitationonset/README.md delete mode 100644 examples/sphericalclustercavitationonset/plot_results.py delete mode 100755 examples/sphericalclustercavitationonset/run_sphericalclustercavitationonset.sh delete mode 100644 examples/sphericalclustercavitationonset/test_distribution.py diff --git a/examples/sphericalclustercavitationonset/IC/build/CMakeLists.txt b/examples/sphericalclustercavitationonset/IC/build/CMakeLists.txt deleted file mode 100644 index ff672ba..0000000 --- a/examples/sphericalclustercavitationonset/IC/build/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -cmake_minimum_required(VERSION 3.12) - -project (sphericalclustercavitationonset_apecss) -set(CMAKE_C_COMPILER /usr/bin/gcc) - -include_directories($ENV{APECSS_DIR}/include) -FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) - -set (mylibs m apecss) -link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) - -foreach(arg ${myincludes}) - IF (arg MATCHES "-I") - STRING(REGEX REPLACE "-I" "" myinc ${arg}) - message("Additional include: ${myinc}") - include_directories(${myinc}) - ENDIF(arg MATCHES "-I") -endforeach(arg ${myincludes}) - -foreach(arg ${mylibs}) - STRING(REGEX REPLACE "lib" "" myl1 ${arg}) - STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) - set(mylibs ${myl2} ${mylibs} ${myl2}) -endforeach(arg ${mylibs}) - -if(NOT CMAKE_BUILD_TYPE) - message(STATUS "Optimization: No optimization specified.") - set(CMAKE_BUILD_TYPE Release) -endif() - -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - message(STATUS "Optimization: Debug") - set(CMAKE_C_FLAGS_DEBUG "-Wall -g") -elseif(CMAKE_BUILD_TYPE STREQUAL "Release") - message(STATUS "Optimization: Release") - add_definitions(-DNDEBUG) - set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") -endif() - -add_executable(sphericalclustercavitationonset_apecss ${myfiles}) -target_link_libraries(sphericalclustercavitationonset_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/IC/build/compile.sh b/examples/sphericalclustercavitationonset/IC/build/compile.sh deleted file mode 100755 index 33147c8..0000000 --- a/examples/sphericalclustercavitationonset/IC/build/compile.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -rm sphericalclustercavitationonset_apecss -cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release -make -rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/IC/gather_results.py b/examples/sphericalclustercavitationonset/IC/gather_results.py deleted file mode 100644 index 570d247..0000000 --- a/examples/sphericalclustercavitationonset/IC/gather_results.py +++ /dev/null @@ -1,53 +0,0 @@ -import os - -# File designed to recover data for plotting results in cavitation onset case - -file = open("onset_results.txt", "r") -lines = file.readlines() -file.close() - -count = int(lines[0].split(" ")[0]) -png = float(lines[0].split(" ")[5]) -cl_distrib = int(lines[0].split(" ")[7]) - -if cl_distrib == 0 : - # monodispersed spherical cluster - file_name = "mono_{}_{:.4E}.txt".format(count, png) - -else : - # polydispersed spherical cluster - file_name = "poly_{}_{:.4E}.txt".format(count, png) - -working_path = os.getcwd() -results_path = os.path.join(working_path, "results") -file_results = open(os.path.join(results_path, file_name), "w") - -# for line in lines : -# if "nan" not in line : -# file_results.write(line) - -index = 0 -while index < len(lines) and "nan" not in lines[index] : - file_results.write(lines[index]) - index += 1 - -file_results.close() - -file_loc = open("bubble_loc.txt", "r") -lines_loc = file_loc.readlines() -file_loc.close() - -if cl_distrib == 0 : - # monodispersed spherical cluster - file_name_loc = "mono_{}_{:.4E}_loc.txt".format(count, png) - -else : - # polydispersed spherical cluster - file_name_loc = "poly_{}_{:.4E}_loc.txt".format(count, png) - -file_loc_results = open(os.path.join(results_path, file_name_loc), "w") - -for line in lines_loc : - file_loc_results.write(line) - -file_loc_results.close() \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/IC/run.apecss b/examples/sphericalclustercavitationonset/IC/run.apecss deleted file mode 100644 index 50eac9b..0000000 --- a/examples/sphericalclustercavitationonset/IC/run.apecss +++ /dev/null @@ -1,32 +0,0 @@ -######################################################### -# # -# APECSS Options File # -# # -######################################################### - -BUBBLE -RPModel KM -Emissions IC 300.0e-6 -PressureAmbient 0.1013e6 -END - -GAS -EoS IG -ReferenceDensity 1.2 -PolytropicExponent 1.4 -END - -LIQUID -ReferencePressure 0.1013e6 -ReferenceDensity 1000.0 -ReferenceSoundSpeed 1500.0 -Viscosity 1.002e-3 -END - -INTERFACE -SurfaceTensionCoeff 0.0728 -END - -ODESOLVER -tolerance 1.0e-10 -END diff --git a/examples/sphericalclustercavitationonset/IC/src/sphericalclustercavitationonset_apecss.c b/examples/sphericalclustercavitationonset/IC/src/sphericalclustercavitationonset_apecss.c deleted file mode 100644 index ee0bdf3..0000000 --- a/examples/sphericalclustercavitationonset/IC/src/sphericalclustercavitationonset_apecss.c +++ /dev/null @@ -1,428 +0,0 @@ -// This source file is part of APECSS, an open-source software toolbox -// for the computation of pressure-driven bubble dynamics and acoustic -// emissions in spherical symmetry. -// -// Copyright (C) 2022-2024 The APECSS Developers -// -// The APECSS Developers are listed in the README.md file available in -// the GitHub repository at https://github.com/polycfd/apecss. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// ------------------------------------------------------------------- -// APECSS standalone example of acoustically-interacting microbubbles -// in a spherical cluster with the goal to study cavitation onset -// ------------------------------------------------------------------- - -#include -#include "apecss.h" - -APECSS_FLOAT rand_range(double min, double max) -{ - double random = (drand48()); - double range = (max - min) * random; - double number = min + range; - - return (APECSS_FLOAT) number; -} - -APECSS_FLOAT normal_distribution(double mu, double sigma) -{ - // Generating a normal distribution using Box-Muller transform, with mu as mean and sigma**2 as variance - double u1 = (drand48()); - while (u1 == 0.0) u1 = (drand48()); - double u2 = (drand48()); - - double mag = sigma * APECSS_SQRT(-2.0 * APECSS_LOG(u1)); - double z1 = mag * APECSS_COS(2 * APECSS_PI * u2) + mu; - return (APECSS_FLOAT) z1; -} - -// Declaration of additional case-dependent functions -APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); - -// Declaration of the structure holding the interaction variables of each bubble -struct Interaction -{ - APECSS_FLOAT dp_neighbor; -}; - -int main(int argc, char **args) -{ - char OptionsDir[APECSS_STRINGLENGTH]; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Set the case-dependent simulation parameters - const int nBubbles = 2500; // Number of bubbles - APECSS_FLOAT bubble_bubble_dist = 100.0e-6; // Bubble-bubble minimal distance - APECSS_FLOAT cluster_radius = 2.5e-3; // Spherical cluster radius - - // Interbubble time-step, defining the frequency with which the neighbor influence is updated - APECSS_FLOAT dt_interbubble = 1.0e-8; - - // Initialize the simulation parameters given by the execution command - double tEnd = 0.0; - double fa = 0.0; - double pa = 0.0; - int cluster_distrib = 0; - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - apecss_infoscreen(); - - /* Read commandline options */ - sprintf(OptionsDir, "./run.apecss"); // This is the default - int j = 1; // First argument is the call to the executable - while (j < argc) - { - if (strcmp("-options", args[j]) == 0) - { - sprintf(OptionsDir, "%s", args[j + 1]); - j += 2; - } - else if (strcmp("-tend", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &tEnd); - j += 2; - } - else if (strcmp("-freq", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &fa); - j += 2; - } - else if (strcmp("-amp", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &pa); - j += 2; - } - else if (strcmp("-cldistrib", args[j]) == 0) - { - sscanf(args[j + 1], "%d", &cluster_distrib); - j += 2; - } - else if (strcmp("-h", args[j]) == 0) - { - apecss_helpscreen(); - } - else - { - char str[APECSS_STRINGLENGTH_SPRINTF]; - sprintf(str, "Unknown command line options: %s", args[j]); - apecss_erroronscreen(1, str); - ++j; - } - } - - /* Allocate and initialize Bubble structure */ - struct APECSS_Bubble *Bubbles[nBubbles]; - for (register int i = 0; i < nBubbles; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(nBubbles * sizeof(struct APECSS_Bubble)); - for (register int i = 0; i < nBubbles; i++) apecss_bubble_initializestruct(Bubbles[i]); - - /* Set default options and read the options for the bubble */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); - for (register int i = 0; i < nBubbles; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); - - /* Allocate the structures for the fluid properties and ODE solver parameters */ - struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); - struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); - struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); - struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); - - /* Set the default options for the fluid properties and solver parameters */ - apecss_gas_setdefaultoptions(Gas); - apecss_liquid_setdefaultoptions(Liquid); - apecss_interface_setdefaultoptions(Interface); - apecss_odesolver_setdefaultoptions(NumericsODE); - - /* Read the options file for the fluid properties and solver parameters */ - apecss_gas_readoptions(Gas, OptionsDir); - apecss_liquid_readoptions(Liquid, OptionsDir); - apecss_interface_readoptions(Interface, OptionsDir); - apecss_odesolver_readoptions(NumericsODE, OptionsDir); - - /* Associate the bubble with the relevant fluid properties and solver parameters */ - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->Gas = Gas; - Bubbles[i]->Liquid = Liquid; - Bubbles[i]->Interface = Interface; - Bubbles[i]->NumericsODE = NumericsODE; - } - - /* Allocate and set the excitation parameters */ - struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); - Excitation->type = APECSS_EXCITATION_SIN; - Excitation->f = (APECSS_FLOAT) fa; - Excitation->dp = (APECSS_FLOAT) pa; - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Excitation = Excitation; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Create individual folders for the results of each bubble - for (register int i = 0; i < nBubbles; i++) - { - if (Bubbles[i]->Results != NULL) - { - sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", i); - struct stat st = {0}; - if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); - } - } - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - /* Process all options */ - apecss_gas_processoptions(Gas); - apecss_liquid_processoptions(Liquid); - apecss_interface_processoptions(Interface); - apecss_odesolver_processoptions(NumericsODE); - for (register int i = 0; i < nBubbles; i++) apecss_bubble_processoptions(Bubbles[i]); - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Use the revised pressure at infinity, including neighbor contributions - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressure_infinity = interaction_bubble_pressure_infinity; - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressurederivative_infinity = interaction_bubble_pressurederivative_infinity; - - // Initialize interaction structure - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); - - // Update interaction structure - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->Interaction->nBubbles = nBubbles; - Bubbles[i]->Interaction->dp_neighbor = 0.0; - Bubbles[i]->Interaction->last_t_1 = 0.0; - Bubbles[i]->Interaction->last_t_2 = 0.0; - Bubbles[i]->Interaction->last_p_1 = 0.0; - Bubbles[i]->Interaction->last_p_2 = 0.0; - } - - // Define the size of each bubble - if (cluster_distrib == 0) - { - // Monodispersed cluster - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->R0 = 10.0e-6; - // Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; - } - } - else - { - // Polydispersed cluster (radii distribution is following a log normal law) - double mu = 0.0; - double sigma = 0.7; - APECSS_FLOAT radius_ref = 10.0e-6; - for (register int i = 0; i < nBubbles; i++) - { - APECSS_FLOAT radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); - while ((radius > 20 * radius_ref) || (radius < 0.5 * radius_ref)) - { - // Small step to ensure no too big nor too small bubbles are generated (the distribution is conserved still) - radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); - } - Bubbles[i]->R0 = radius; - // Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; - } - } - - // Define center location for each bubble - for (register int i = 0; i < nBubbles; i++) - { - if (i == 0) - { - Bubbles[i]->Interaction->location[0] = 0.0; - Bubbles[i]->Interaction->location[1] = 0.0; - Bubbles[i]->Interaction->location[2] = 0.0; - } - else - { - APECSS_FLOAT x = rand_range((double) -cluster_radius, (double) cluster_radius); - APECSS_FLOAT y = rand_range((double) -cluster_radius, (double) cluster_radius); - APECSS_FLOAT z = rand_range((double) -cluster_radius, (double) cluster_radius); - - APECSS_FLOAT radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); - - while (radius > cluster_radius) - { - x = rand_range((double) -cluster_radius, (double) cluster_radius); - y = rand_range((double) -cluster_radius, (double) cluster_radius); - z = rand_range((double) -cluster_radius, (double) cluster_radius); - - radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); - } - - Bubbles[i]->Interaction->location[0] = x; - Bubbles[i]->Interaction->location[1] = y; - Bubbles[i]->Interaction->location[2] = z; - - for (register int k = 0; k < i; k++) - { - APECSS_FLOAT bubbledist = APECSS_SQRT(APECSS_POW2(Bubbles[i]->Interaction->location[0] - Bubbles[k]->Interaction->location[0]) + - APECSS_POW2(Bubbles[i]->Interaction->location[1] - Bubbles[k]->Interaction->location[1]) + - APECSS_POW2(Bubbles[i]->Interaction->location[2] - Bubbles[k]->Interaction->location[2])); - if (bubbledist < bubble_bubble_dist) - { - i--; - break; - } - } - } - } - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - clock_t starttimebubble = clock(); - APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system - - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->tStart = tSim; - Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; - Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step - } - - /* Initialize the bubble based on the selected options */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_initialize(Bubbles[i]); - - /* Initialize */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_initialize(Bubbles[i]); - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Files to retrieve all valuable information for cavitation onset test case - FILE *file_loc; - file_loc = fopen("bubble_loc.txt", "w"); - fprintf(file_loc, "#number x(m) y(m) z(m)\n"); - for (register int i = 0; i < nBubbles; i++) - { - fprintf(file_loc, "%d %e %e %e\n", i, Bubbles[i]->Interaction->location[0], Bubbles[i]->Interaction->location[1], Bubbles[i]->Interaction->location[2]); - } - fclose(file_loc); - - FILE *file_onset; - file_onset = fopen("onset_results.txt", "w"); - fprintf(file_onset, "%d Bubbles p0(pa) %e png(Pa) %e cl_distrib %d\n", nBubbles, Liquid->pref, pa, cluster_distrib); - fprintf(file_onset, "Initial_radii(m)"); - for (register int i = 0; i < nBubbles; i++) fprintf(file_onset, " %e", Bubbles[i]->R0); - fprintf(file_onset, "\n"); - fprintf(file_onset, "#Time(s) R(m) Pt(Pa)\n"); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - /* Solve the bubble dynamics */ - while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered - { - APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); - tSim += dtSim; - - for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); - - // for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Update the contribution of the neighbor bubble - apecss_interactions_instantaneous(Bubbles); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - // printf("%e %e %e %e %e\n", tSim, Bubbles[0]->Liquid->get_pressurederivative_bubblewall_expl(Bubbles[0]->ODEsSol, Bubbles[0]->t, Bubbles[0]), - // Bubbles[0]->get_pressurederivative_infinity(Bubbles[0]->t, Bubbles[0]), Bubbles[0]->Interaction->dp_neighbor, - // Bubbles[0]->Interaction->last_p_1 - Bubbles[0]->Interaction->last_p_2); - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Retrieve data - fprintf(file_onset, "%e", tSim); - for (register int i = 0; i < nBubbles; i++) - { - fprintf(file_onset, " %e", Bubbles[i]->R); - } - for (register int i = 0; i < nBubbles; i++) - { - fprintf(file_onset, " %e", Bubbles[i]->get_pressure_infinity(Bubbles[i]->t, Bubbles[i])); - } - fprintf(file_onset, "\n"); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - // for (register int i = 0; i < nBubbles; i++) - // { - // Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; - // Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; - - // Bubbles[i]->Interaction->last_t_1 = tSim; - // Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; - // } - } - - fclose(file_onset); - - /* Finalize the simulation*/ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_finalize(Bubbles[i]); - - char str[APECSS_STRINGLENGTH_SPRINTF]; - for (register int i = 0; i < nBubbles; i++) - { - sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", i, Bubbles[i]->dtNumber, Bubbles[i]->nSubIter, - (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); - apecss_writeonscreen(str); - } - - for (register int i = 0; i < nBubbles; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); - for (register int i = 0; i < nBubbles; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); - - /* Make sure all allocated memory is freed */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_freestruct(Bubbles[i]); - - for (register int i = 0; i < nBubbles; i++) free(Bubbles[i]); - free(Gas); - free(Liquid); - free(Interface); - free(NumericsODE); - free(Excitation); - - return (0); -} - -APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - APECSS_FLOAT T = 10.0e-06; - if (t < T) - { - return (Bubble->p0 + Bubble->Interaction->dp_neighbor); - } - else if (t > 2 * T) - { - return (Bubble->Excitation->dp + Bubble->Interaction->dp_neighbor); - } - else - { - APECSS_FLOAT W = 0.5 * (1 - APECSS_COS((t + T) * APECSS_PI / T)); - return (Bubble->p0 + W * (Bubble->Excitation->dp - Bubble->p0) + Bubble->Interaction->dp_neighbor); - } -} - -APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - // Approximate numerical computation of p_infinity derivative - APECSS_FLOAT T = 10.0e-06; - if (t < T) - { - return (0.0); - } - else - { - APECSS_FLOAT derivative = 0.0; - if (t < 2 * T) - { - APECSS_FLOAT inv_T = 1 / T; - derivative = 0.5 * APECSS_PI * inv_T * APECSS_SIN(APECSS_PI * (t + T) * inv_T) * (Bubble->Excitation->dp - Bubble->p0); - } - return (derivative); - // APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; - // if ((delta_t > Bubble->dt) && (t > time_treshold)) - // { - // APECSS_FLOAT inv_delta_t = 1 / delta_t; - // return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) * inv_delta_t)); - // } - // else - // { - // return (derivative); - // } - } -} \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/NI/build/CMakeLists.txt b/examples/sphericalclustercavitationonset/NI/build/CMakeLists.txt deleted file mode 100644 index ff672ba..0000000 --- a/examples/sphericalclustercavitationonset/NI/build/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -cmake_minimum_required(VERSION 3.12) - -project (sphericalclustercavitationonset_apecss) -set(CMAKE_C_COMPILER /usr/bin/gcc) - -include_directories($ENV{APECSS_DIR}/include) -FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) - -set (mylibs m apecss) -link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) - -foreach(arg ${myincludes}) - IF (arg MATCHES "-I") - STRING(REGEX REPLACE "-I" "" myinc ${arg}) - message("Additional include: ${myinc}") - include_directories(${myinc}) - ENDIF(arg MATCHES "-I") -endforeach(arg ${myincludes}) - -foreach(arg ${mylibs}) - STRING(REGEX REPLACE "lib" "" myl1 ${arg}) - STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) - set(mylibs ${myl2} ${mylibs} ${myl2}) -endforeach(arg ${mylibs}) - -if(NOT CMAKE_BUILD_TYPE) - message(STATUS "Optimization: No optimization specified.") - set(CMAKE_BUILD_TYPE Release) -endif() - -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - message(STATUS "Optimization: Debug") - set(CMAKE_C_FLAGS_DEBUG "-Wall -g") -elseif(CMAKE_BUILD_TYPE STREQUAL "Release") - message(STATUS "Optimization: Release") - add_definitions(-DNDEBUG) - set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") -endif() - -add_executable(sphericalclustercavitationonset_apecss ${myfiles}) -target_link_libraries(sphericalclustercavitationonset_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/NI/build/compile.sh b/examples/sphericalclustercavitationonset/NI/build/compile.sh deleted file mode 100755 index 33147c8..0000000 --- a/examples/sphericalclustercavitationonset/NI/build/compile.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -rm sphericalclustercavitationonset_apecss -cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release -make -rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/NI/gather_results.py b/examples/sphericalclustercavitationonset/NI/gather_results.py deleted file mode 100644 index 6e44890..0000000 --- a/examples/sphericalclustercavitationonset/NI/gather_results.py +++ /dev/null @@ -1,47 +0,0 @@ -import os - -# File designed to recover data for plotting results in cavitation onset case - -file = open("onset_results.txt", "r") -lines = file.readlines() -file.close() - -count = int(lines[0].split(" ")[0]) -png = float(lines[0].split(" ")[5]) -cl_distrib = int(lines[0].split(" ")[7]) - -if cl_distrib == 0 : - # monodispersed spherical cluster - file_name = "mono_{}_{:.4E}.txt".format(count, png) - -else : - # polydispersed spherical cluster - file_name = "poly_{}_{:.4E}.txt".format(count, png) - -working_path = os.getcwd() -results_path = os.path.join(working_path, "results") -file_results = open(os.path.join(results_path, file_name), "w") - -for line in lines : - file_results.write(line) - -file_results.close() - -file_loc = open("bubble_loc.txt", "r") -lines_loc = file_loc.readlines() -file_loc.close() - -if cl_distrib == 0 : - # monodispersed spherical cluster - file_name_loc = "mono_{}_{:.4E}_loc.txt".format(count, png) - -else : - # polydispersed spherical cluster - file_name_loc = "poly_{}_{:.4E}_loc.txt".format(count, png) - -file_loc_results = open(os.path.join(results_path, file_name_loc), "w") - -for line in lines_loc : - file_loc_results.write(line) - -file_loc_results.close() \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/NI/run.apecss b/examples/sphericalclustercavitationonset/NI/run.apecss deleted file mode 100644 index 50eac9b..0000000 --- a/examples/sphericalclustercavitationonset/NI/run.apecss +++ /dev/null @@ -1,32 +0,0 @@ -######################################################### -# # -# APECSS Options File # -# # -######################################################### - -BUBBLE -RPModel KM -Emissions IC 300.0e-6 -PressureAmbient 0.1013e6 -END - -GAS -EoS IG -ReferenceDensity 1.2 -PolytropicExponent 1.4 -END - -LIQUID -ReferencePressure 0.1013e6 -ReferenceDensity 1000.0 -ReferenceSoundSpeed 1500.0 -Viscosity 1.002e-3 -END - -INTERFACE -SurfaceTensionCoeff 0.0728 -END - -ODESOLVER -tolerance 1.0e-10 -END diff --git a/examples/sphericalclustercavitationonset/NI/src/sphericalclustercavitationonset_apecss.c b/examples/sphericalclustercavitationonset/NI/src/sphericalclustercavitationonset_apecss.c deleted file mode 100644 index 001e26f..0000000 --- a/examples/sphericalclustercavitationonset/NI/src/sphericalclustercavitationonset_apecss.c +++ /dev/null @@ -1,396 +0,0 @@ -// This source file is part of APECSS, an open-source software toolbox -// for the computation of pressure-driven bubble dynamics and acoustic -// emissions in spherical symmetry. -// -// Copyright (C) 2022-2024 The APECSS Developers -// -// The APECSS Developers are listed in the README.md file available in -// the GitHub repository at https://github.com/polycfd/apecss. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// ------------------------------------------------------------------- -// APECSS standalone example of acoustically-interacting microbubbles -// in a spherical cluster with the goal to study cavitation onset -// ------------------------------------------------------------------- - -#include -#include "apecss.h" - -APECSS_FLOAT rand_range(double min, double max) -{ - double random = (drand48()); - double range = (max - min) * random; - double number = min + range; - - return (APECSS_FLOAT) number; -} - -APECSS_FLOAT normal_distribution(double mu, double sigma) -{ - // Generating a normal distribution using Box-Muller transform, with mu as mean and sigma**2 as variance - double u1 = (drand48()); - while (u1 == 0.0) u1 = (drand48()); - double u2 = (drand48()); - - double mag = sigma * APECSS_SQRT(-2.0 * APECSS_LOG(u1)); - double z1 = mag * APECSS_COS(2 * APECSS_PI * u2) + mu; - return (APECSS_FLOAT) z1; -} - -// Declaration of additional case-dependent functions -APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); - -// Declaration of the structure holding the interaction variables of each bubble -struct Interaction -{ - APECSS_FLOAT dp_neighbor; -}; - -int main(int argc, char **args) -{ - char OptionsDir[APECSS_STRINGLENGTH]; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Set the case-dependent simulation parameters - const int nBubbles = 2500; // Number of bubbles - APECSS_FLOAT bubble_bubble_dist = 100.0e-6; // Bubble-bubble minimal distance - APECSS_FLOAT cluster_radius = 2.5e-3; // Spherical cluster radius - - // Interbubble time-step, defining the frequency with which the neighbor influence is updated - APECSS_FLOAT dt_interbubble = 1.0e-8; - - // Initialize the simulation parameters given by the execution command - double tEnd = 0.0; - double fa = 0.0; - double pa = 0.0; - int cluster_distrib = 0; - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - apecss_infoscreen(); - - /* Read commandline options */ - sprintf(OptionsDir, "./run.apecss"); // This is the default - int j = 1; // First argument is the call to the executable - while (j < argc) - { - if (strcmp("-options", args[j]) == 0) - { - sprintf(OptionsDir, "%s", args[j + 1]); - j += 2; - } - else if (strcmp("-tend", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &tEnd); - j += 2; - } - else if (strcmp("-freq", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &fa); - j += 2; - } - else if (strcmp("-amp", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &pa); - j += 2; - } - else if (strcmp("-cldistrib", args[j]) == 0) - { - sscanf(args[j + 1], "%d", &cluster_distrib); - j += 2; - } - else if (strcmp("-h", args[j]) == 0) - { - apecss_helpscreen(); - } - else - { - char str[APECSS_STRINGLENGTH_SPRINTF]; - sprintf(str, "Unknown command line options: %s", args[j]); - apecss_erroronscreen(1, str); - ++j; - } - } - - /* Allocate and initialize Bubble structure */ - struct APECSS_Bubble *Bubbles[nBubbles]; - for (register int i = 0; i < nBubbles; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(nBubbles * sizeof(struct APECSS_Bubble)); - for (register int i = 0; i < nBubbles; i++) apecss_bubble_initializestruct(Bubbles[i]); - - /* Set default options and read the options for the bubble */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); - for (register int i = 0; i < nBubbles; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); - - /* Allocate the structures for the fluid properties and ODE solver parameters */ - struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); - struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); - struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); - struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); - - /* Set the default options for the fluid properties and solver parameters */ - apecss_gas_setdefaultoptions(Gas); - apecss_liquid_setdefaultoptions(Liquid); - apecss_interface_setdefaultoptions(Interface); - apecss_odesolver_setdefaultoptions(NumericsODE); - - /* Read the options file for the fluid properties and solver parameters */ - apecss_gas_readoptions(Gas, OptionsDir); - apecss_liquid_readoptions(Liquid, OptionsDir); - apecss_interface_readoptions(Interface, OptionsDir); - apecss_odesolver_readoptions(NumericsODE, OptionsDir); - - /* Associate the bubble with the relevant fluid properties and solver parameters */ - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->Gas = Gas; - Bubbles[i]->Liquid = Liquid; - Bubbles[i]->Interface = Interface; - Bubbles[i]->NumericsODE = NumericsODE; - } - - /* Allocate and set the excitation parameters */ - struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); - Excitation->type = APECSS_EXCITATION_SIN; - Excitation->f = (APECSS_FLOAT) fa; - Excitation->dp = (APECSS_FLOAT) pa; - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Excitation = Excitation; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Create individual folders for the results of each bubble - for (register int i = 0; i < nBubbles; i++) - { - if (Bubbles[i]->Results != NULL) - { - sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", i); - struct stat st = {0}; - if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); - } - } - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - /* Process all options */ - apecss_gas_processoptions(Gas); - apecss_liquid_processoptions(Liquid); - apecss_interface_processoptions(Interface); - apecss_odesolver_processoptions(NumericsODE); - for (register int i = 0; i < nBubbles; i++) apecss_bubble_processoptions(Bubbles[i]); - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Use the revised pressure at infinity, including neighbor contributions - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressure_infinity = interaction_bubble_pressure_infinity; - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->get_pressurederivative_infinity = interaction_bubble_pressurederivative_infinity; - - // Initialize interaction structure - for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); - - // Update interaction structure - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->Interaction->nBubbles = nBubbles; - Bubbles[i]->Interaction->dp_neighbor = 0.0; - Bubbles[i]->Interaction->last_t_1 = 0.0; - Bubbles[i]->Interaction->last_t_2 = 0.0; - Bubbles[i]->Interaction->last_p_1 = 0.0; - Bubbles[i]->Interaction->last_p_2 = 0.0; - } - - // Define the size of each bubble - if (cluster_distrib == 0) - { - // Monodispersed cluster - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->R0 = 10.0e-6; - } - } - else - { - // Polydispersed cluster (radii distribution is following a log normal law) - double mu = 0.0; - double sigma = 0.7; - APECSS_FLOAT radius_ref = 10.0e-6; - for (register int i = 0; i < nBubbles; i++) - { - APECSS_FLOAT radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); - while ((radius > 20 * radius_ref) || (radius < 0.5 * radius_ref)) - { - // Small step to ensure no too big nor too small bubbles are generated (the distribution is conserved still) - radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); - } - Bubbles[i]->R0 = radius; - } - } - - // Define center location for each bubble - for (register int i = 0; i < nBubbles; i++) - { - if (i == 0) - { - Bubbles[i]->Interaction->location[0] = 0.0; - Bubbles[i]->Interaction->location[1] = 0.0; - Bubbles[i]->Interaction->location[2] = 0.0; - } - else - { - APECSS_FLOAT x = rand_range((double) -cluster_radius, (double) cluster_radius); - APECSS_FLOAT y = rand_range((double) -cluster_radius, (double) cluster_radius); - APECSS_FLOAT z = rand_range((double) -cluster_radius, (double) cluster_radius); - - APECSS_FLOAT radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); - - while (radius > cluster_radius) - { - x = rand_range((double) -cluster_radius, (double) cluster_radius); - y = rand_range((double) -cluster_radius, (double) cluster_radius); - z = rand_range((double) -cluster_radius, (double) cluster_radius); - - radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); - } - - Bubbles[i]->Interaction->location[0] = x; - Bubbles[i]->Interaction->location[1] = y; - Bubbles[i]->Interaction->location[2] = z; - - for (register int k = 0; k < i; k++) - { - APECSS_FLOAT bubbledist = APECSS_SQRT(APECSS_POW2(Bubbles[i]->Interaction->location[0] - Bubbles[k]->Interaction->location[0]) + - APECSS_POW2(Bubbles[i]->Interaction->location[1] - Bubbles[k]->Interaction->location[1]) + - APECSS_POW2(Bubbles[i]->Interaction->location[2] - Bubbles[k]->Interaction->location[2])); - if (bubbledist < bubble_bubble_dist) - { - i--; - break; - } - } - } - } - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - clock_t starttimebubble = clock(); - APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system - - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->tStart = tSim; - Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; - Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step - } - - /* Initialize the bubble based on the selected options */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_initialize(Bubbles[i]); - - /* Initialize */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_initialize(Bubbles[i]); - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Files to retrieve all valuable information for cavitation onset test case - FILE *file_loc; - file_loc = fopen("bubble_loc.txt", "w"); - fprintf(file_loc, "#number x(m) y(m) z(m)\n"); - for (register int i = 0; i < nBubbles; i++) - { - fprintf(file_loc, "%d %e %e %e\n", i, Bubbles[i]->Interaction->location[0], Bubbles[i]->Interaction->location[1], Bubbles[i]->Interaction->location[2]); - } - fclose(file_loc); - - FILE *file_onset; - file_onset = fopen("onset_results.txt", "w"); - fprintf(file_onset, "%d Bubbles p0(pa) %e png(Pa) %e cl_distrib %d\n", nBubbles, Liquid->pref, pa, cluster_distrib); - fprintf(file_onset, "Initial_radii(m)"); - for (register int i = 0; i < nBubbles; i++) fprintf(file_onset, " %e", Bubbles[i]->R0); - fprintf(file_onset, "\n"); - fprintf(file_onset, "#Time(s) R(m) Pt(Pa)\n"); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - /* Solve the bubble dynamics */ - while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered - { - APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); - tSim += dtSim; - - for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Retrieve data - fprintf(file_onset, "%e", tSim); - for (register int i = 0; i < nBubbles; i++) - { - fprintf(file_onset, " %e", Bubbles[i]->R); - } - for (register int i = 0; i < nBubbles; i++) - { - fprintf(file_onset, " %e", Bubbles[i]->get_pressure_infinity(Bubbles[i]->t, Bubbles[i])); - } - fprintf(file_onset, "\n"); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - } - - fclose(file_onset); - - /* Finalize the simulation*/ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_finalize(Bubbles[i]); - - char str[APECSS_STRINGLENGTH_SPRINTF]; - for (register int i = 0; i < nBubbles; i++) - { - sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", i, Bubbles[i]->dtNumber, Bubbles[i]->nSubIter, - (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); - apecss_writeonscreen(str); - } - - for (register int i = 0; i < nBubbles; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); - for (register int i = 0; i < nBubbles; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); - - /* Make sure all allocated memory is freed */ - for (register int i = 0; i < nBubbles; i++) apecss_bubble_freestruct(Bubbles[i]); - - for (register int i = 0; i < nBubbles; i++) free(Bubbles[i]); - free(Gas); - free(Liquid); - free(Interface); - free(NumericsODE); - free(Excitation); - - return (0); -} - -APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - APECSS_FLOAT T = 10.0e-06; - if (t < T) - { - return (Bubble->p0 + Bubble->Interaction->dp_neighbor); - } - else if (t > 2 * T) - { - return (Bubble->Excitation->dp + Bubble->Interaction->dp_neighbor); - } - else - { - APECSS_FLOAT W = 0.5 * (1 - APECSS_COS((t + T) * APECSS_PI / T)); - return (Bubble->p0 + W * (Bubble->Excitation->dp - Bubble->p0) + Bubble->Interaction->dp_neighbor); - } -} - -APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - // Approximate numerical computation of p_infinity derivative - APECSS_FLOAT T = 10.0e-06; - if (t < T) - { - return (0.0); - } - else - { - APECSS_FLOAT derivative = 0.0; - if (t < 2 * T) - { - APECSS_FLOAT inv_T = 1 / T; - derivative = 0.5 * APECSS_PI * inv_T * APECSS_SIN(APECSS_PI * (t + T) * inv_T) * (Bubble->Excitation->dp - Bubble->p0); - } - return (derivative); - } -} \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/QA/build/CMakeLists.txt b/examples/sphericalclustercavitationonset/QA/build/CMakeLists.txt deleted file mode 100644 index 6fece97..0000000 --- a/examples/sphericalclustercavitationonset/QA/build/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -cmake_minimum_required(VERSION 3.12) - -project (sphericalclustercavitationonset_apecss) -set(CMAKE_C_COMPILER mpicc) - -include_directories($ENV{APECSS_DIR}/include) -FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) - -set (mylibs m apecss) -link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) - -foreach(arg ${myincludes}) - IF (arg MATCHES "-I") - STRING(REGEX REPLACE "-I" "" myinc ${arg}) - message("Additional include: ${myinc}") - include_directories(${myinc}) - ENDIF(arg MATCHES "-I") -endforeach(arg ${myincludes}) - -foreach(arg ${mylibs}) - STRING(REGEX REPLACE "lib" "" myl1 ${arg}) - STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) - set(mylibs ${myl2} ${mylibs} ${myl2}) -endforeach(arg ${mylibs}) - -if(NOT CMAKE_BUILD_TYPE) - message(STATUS "Optimization: No optimization specified.") - set(CMAKE_BUILD_TYPE Release) -endif() - -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - message(STATUS "Optimization: Debug") - set(CMAKE_C_FLAGS_DEBUG "-Wall -g") -elseif(CMAKE_BUILD_TYPE STREQUAL "Release") - message(STATUS "Optimization: Release") - add_definitions(-DNDEBUG) - set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") -endif() - -add_executable(sphericalclustercavitationonset_apecss ${myfiles}) -target_link_libraries(sphericalclustercavitationonset_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/QA/build/compile.sh b/examples/sphericalclustercavitationonset/QA/build/compile.sh deleted file mode 100755 index 33147c8..0000000 --- a/examples/sphericalclustercavitationonset/QA/build/compile.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -rm sphericalclustercavitationonset_apecss -cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release -make -rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/QA/execmpi.sh b/examples/sphericalclustercavitationonset/QA/execmpi.sh deleted file mode 100755 index 09cb14d..0000000 --- a/examples/sphericalclustercavitationonset/QA/execmpi.sh +++ /dev/null @@ -1,18 +0,0 @@ -nbubbles=2500 -ncores=20 - -cd build -./compile.sh -cd .. -mpiexec -n $ncores ./build/sphericalclustercavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-06 -cldistrib 1 -python3 gather_results.py - -# rm -rf bubble_loc.txt -# for ((c=0; c<$ncores; c++)) -# do -# rm -rf onset_results_$c.txt -# done -# for ((c=0; c<$nbubbles; c++)) -# do -# rm -rf Bubble_$c -# done \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/QA/gather_results.py b/examples/sphericalclustercavitationonset/QA/gather_results.py deleted file mode 100644 index b23c0c3..0000000 --- a/examples/sphericalclustercavitationonset/QA/gather_results.py +++ /dev/null @@ -1,85 +0,0 @@ -import os - -# File designed to recover data for plotting results in cavitation onset case - -count_core = 0 -for file in os.listdir() : - if "onset_results_" in file : - count_core += 1 - -lines_onset = [] -for i in range(count_core) : - file_onset = open("onset_results_{}.txt".format(i), "r") - lines = file_onset.readlines() - file_onset.close() - lines_onset.append(lines) - -firstline = lines_onset[0][0].split(" ") -count = int(firstline[0]) -png = float(firstline[5]) -cl_distrib = int(firstline[7]) - -if cl_distrib == 0 : - # monodispersed spherical cluster - file_name = "mono_{}_{:.4E}.txt".format(count, png) - -else : - # polydispersed spherical cluster - file_name = "poly_{}_{:.4E}.txt".format(count, png) - -working_path = os.getcwd() -results_path = os.path.join(working_path, "results") -file_results = open(os.path.join(results_path, file_name), "w") - -results_onset = open(os.path.join(results_path, file_name), "w") -# Header -for line in lines_onset[0][:3] : - results_onset.write(line) - -# Combining with the good format the values located in the files associated with the cores used for computation -for t in range(3, len(lines_onset[0])) : - time = lines_onset[0][t].split(" ")[0] - r_list = [] - p_list = [] - - for i in range(len(lines_onset)) : - data = lines_onset[i][t].split(" ") - nbubble_core = int((len(data) - 1) / 2) - r_list_file = data[1:nbubble_core+1] - p_list_file = data[nbubble_core+1:2*nbubble_core+1] - - for r in r_list_file : - r_list.append(r) - - for p in p_list_file : - if "\n" in p : - p = p.split("\n")[0] - p_list.append(p) - - results_onset.write(time) - for rad in r_list : - results_onset.write(" {}".format(rad)) - for pres in p_list : - results_onset.write(" {}".format(pres)) - results_onset.write("\n") - -results_onset.close() - -file_loc = open("bubble_loc.txt", "r") -lines_loc = file_loc.readlines() -file_loc.close() - -if cl_distrib == 0 : - # monodispersed spherical cluster - file_name_loc = "mono_{}_{:.4E}_loc.txt".format(count, png) - -else : - # polydispersed spherical cluster - file_name_loc = "poly_{}_{:.4E}_loc.txt".format(count, png) - -file_loc_results = open(os.path.join(results_path, file_name_loc), "w") - -for line in lines_loc : - file_loc_results.write(line) - -file_loc_results.close() \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/QA/run.apecss b/examples/sphericalclustercavitationonset/QA/run.apecss deleted file mode 100644 index 44da63b..0000000 --- a/examples/sphericalclustercavitationonset/QA/run.apecss +++ /dev/null @@ -1,32 +0,0 @@ -######################################################### -# # -# APECSS Options File # -# # -######################################################### - -BUBBLE -RPModel KM -Emissions QA 250.0e-6 -PressureAmbient 0.1013e6 -END - -GAS -EoS IG -ReferenceDensity 1.2 -PolytropicExponent 1.4 -END - -LIQUID -ReferencePressure 0.1013e6 -ReferenceDensity 1000.0 -ReferenceSoundSpeed 1500.0 -Viscosity 1.002e-3 -END - -INTERFACE -SurfaceTensionCoeff 0.0728 -END - -ODESOLVER -tolerance 1.0e-10 -END diff --git a/examples/sphericalclustercavitationonset/QA/src/sphericalclustercavitationonset_apecss.c b/examples/sphericalclustercavitationonset/QA/src/sphericalclustercavitationonset_apecss.c deleted file mode 100644 index def6f99..0000000 --- a/examples/sphericalclustercavitationonset/QA/src/sphericalclustercavitationonset_apecss.c +++ /dev/null @@ -1,655 +0,0 @@ -// This source file is part of APECSS, an open-source software toolbox -// for the computation of pressure-driven bubble dynamics and acoustic -// emissions in spherical symmetry. -// -// Copyright (C) 2022-2024 The APECSS Developers -// -// The APECSS Developers are listed in the README.md file available in -// the GitHub repository at https://github.com/polycfd/apecss. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// ------------------------------------------------------------------- -// APECSS standalone example of acoustically-interacting microbubbles -// in a spherical cluster with the goal to study cavitation onset -// ------------------------------------------------------------------- - -#include -#include -#include "apecss.h" - -APECSS_FLOAT rand_range(double min, double max) -{ - double random = (drand48()); - double range = (max - min) * random; - double number = min + range; - - return (APECSS_FLOAT) number; -} - -APECSS_FLOAT normal_distribution(double mu, double sigma) -{ - // Generating a normal distribution using Box-Muller transform, with mu as mean and sigma**2 as variance - double u1 = (drand48()); - while (u1 == 0.0) u1 = (drand48()); - double u2 = (drand48()); - - double mag = sigma * APECSS_SQRT(-2.0 * APECSS_LOG(u1)); - double z1 = mag * APECSS_COS(2 * APECSS_PI * u2) + mu; - return (APECSS_FLOAT) z1; -} - -struct APECSS_Parallel_Cluster -{ - int rank, size; - int nBubbles_local, nBubbles_global; - - int *bubblerank; // max id of bubbles for each rank - APECSS_FLOAT *bubbleglobal_R, *bubbleglobal_x, *bubbleglobal_y, *bubbleglobal_z; // Radius and x,y,z location of all bubbles - APECSS_FLOAT *sumGU_rank; // Contributions from local bubbles to all bubbles -}; - -// Declaration of additional case-dependent functions -APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); - -int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubble[], struct APECSS_Parallel_Cluster *RankInfo); -int parallel_interactions_proper_cutoffdistance(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo); - -int main(int argc, char **args) -{ - /* Initialize MPI */ - int mpi_rank, mpi_size; - MPI_Init(&argc, &args); - MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); - MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); - - char OptionsDir[APECSS_STRINGLENGTH]; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Set the case-dependent simulation parameters - const int nBubbles = 2500; // Number of bubbles - APECSS_FLOAT bubble_bubble_dist = 100.0e-6; // Bubble-bubble minimal distance - APECSS_FLOAT cluster_radius = 2.5e-3; // Spherical cluster radius - - // Interbubble time-step, defining the frequency with which the neighbor influence is updated - APECSS_FLOAT dt_interbubble = 1.0e-8; - - // Initialize the simulation parameters given by the execution command - double tEnd = 0.0; - double fa = 0.0; - double pa = 0.0; - int cluster_distrib = 0; - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - apecss_infoscreen(); - - /* Read commandline options */ - sprintf(OptionsDir, "./run.apecss"); // This is the default - int j = 1; // First argument is the call to the executable - while (j < argc) - { - if (strcmp("-options", args[j]) == 0) - { - sprintf(OptionsDir, "%s", args[j + 1]); - j += 2; - } - else if (strcmp("-tend", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &tEnd); - j += 2; - } - else if (strcmp("-freq", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &fa); - j += 2; - } - else if (strcmp("-amp", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &pa); - j += 2; - } - else if (strcmp("-cldistrib", args[j]) == 0) - { - sscanf(args[j + 1], "%d", &cluster_distrib); - j += 2; - } - else if (strcmp("-h", args[j]) == 0) - { - apecss_helpscreen(); - } - else - { - char str[APECSS_STRINGLENGTH_SPRINTF]; - sprintf(str, "Unknown command line options: %s", args[j]); - apecss_erroronscreen(1, str); - ++j; - } - } - - /* Allocate structure for parallel data */ - struct APECSS_Parallel_Cluster *RankInfo = (struct APECSS_Parallel_Cluster *) malloc(sizeof(struct APECSS_Parallel_Cluster)); - RankInfo->rank = mpi_rank; - RankInfo->size = mpi_size; - - /* Determine the number of bubbles per rank */ - int max_per_rank = ceil((double) nBubbles / (double) mpi_size); - RankInfo->nBubbles_local = APECSS_MAX(0, APECSS_MIN(max_per_rank, nBubbles - mpi_rank * max_per_rank)); - - /* Share the parallel distribution of bubbles with all ranks */ - RankInfo->bubblerank = malloc((RankInfo->size + 1) * sizeof(int)); - - RankInfo->nBubbles_global = 0; - RankInfo->bubblerank[0] = 0; - for (int r = 0; r < RankInfo->size; r++) - { - int temp = RankInfo->nBubbles_local; - MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); - RankInfo->bubblerank[r + 1] = RankInfo->bubblerank[r] + temp; - RankInfo->nBubbles_global += temp; - } - - /* Allocate and initialize Bubble structure */ - struct APECSS_Bubble *Bubbles[RankInfo->nBubbles_local]; - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(sizeof(struct APECSS_Bubble)); - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_initializestruct(Bubbles[i]); - - /* Set default options and read the options for the bubble */ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); - - /* Allocate the structures for the fluid properties and ODE solver parameters */ - struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); - struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); - struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); - struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); - - /* Set the default options for the fluid properties and solver parameters */ - apecss_gas_setdefaultoptions(Gas); - apecss_liquid_setdefaultoptions(Liquid); - apecss_interface_setdefaultoptions(Interface); - apecss_odesolver_setdefaultoptions(NumericsODE); - - /* Read the options file for the fluid properties and solver parameters */ - apecss_gas_readoptions(Gas, OptionsDir); - apecss_liquid_readoptions(Liquid, OptionsDir); - apecss_interface_readoptions(Interface, OptionsDir); - apecss_odesolver_readoptions(NumericsODE, OptionsDir); - - /* Associate the bubble with the relevant fluid properties and solver parameters */ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->Gas = Gas; - Bubbles[i]->Liquid = Liquid; - Bubbles[i]->Interface = Interface; - Bubbles[i]->NumericsODE = NumericsODE; - } - - /* Allocate and set the excitation parameters */ - struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); - Excitation->type = APECSS_EXCITATION_SIN; - Excitation->f = (APECSS_FLOAT) fa; - Excitation->dp = (APECSS_FLOAT) pa; - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Excitation = Excitation; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Create individual folders for the results of each bubble - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - if (Bubbles[i]->Results != NULL) - { - sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", RankInfo->bubblerank[RankInfo->rank] + i); - struct stat st = {0}; - if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); - } - } - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - /* Process all options */ - apecss_gas_processoptions(Gas); - apecss_liquid_processoptions(Liquid); - apecss_interface_processoptions(Interface); - apecss_odesolver_processoptions(NumericsODE); - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_processoptions(Bubbles[i]); - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Use the revised pressure at infinity, including neighbor contributions - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->get_pressure_infinity = parallel_interactions_bubble_pressure_infinity; - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - Bubbles[i]->get_pressurederivative_infinity = parallel_interactions_bubble_pressurederivative_infinity; - - // Allocate interaction structure - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); - Bubbles[i]->Interaction->dp_neighbor = 0.0; - Bubbles[i]->Interaction->last_t_1 = 0.0; - Bubbles[i]->Interaction->last_t_2 = 0.0; - Bubbles[i]->Interaction->last_p_1 = 0.0; - Bubbles[i]->Interaction->last_p_2 = 0.0; - } - - // Update interaction structure - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->nBubbles = nBubbles; // Not used? - - // Define the size of each bubble - if (cluster_distrib == 0) - { - // Monodispersed cluster - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->R0 = 10.0e-6; - Bubbles[i]->R = Bubbles[i]->R0; - } - } - else - { - // Polydispersed cluster (radii distribution is following a log normal law) - double mu = 0.0; - double sigma = 0.7; - APECSS_FLOAT radius_ref = 10.0e-6; - APECSS_FLOAT Bubble_Radius[nBubbles]; - for (register int i = 0; i < nBubbles; i++) - { - APECSS_FLOAT radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); - while ((radius > 20 * radius_ref) || (radius < 0.5 * radius_ref)) - { - // Small step to ensure no too big bubbles nor too small are generated (the distribution is conserved still) - radius = radius_ref * APECSS_EXP(normal_distribution(mu, sigma)); - } - Bubble_Radius[i] = radius; - } - - for (register int n = 0; n < RankInfo->nBubbles_local; n++) - { - Bubbles[n]->R0 = Bubble_Radius[RankInfo->bubblerank[RankInfo->rank] + n]; - Bubbles[n]->R = Bubble_Radius[RankInfo->bubblerank[RankInfo->rank] + n]; - } - } - - // Define center location for each bubble - APECSS_FLOAT Bubble_Center[nBubbles][3]; - - for (register int i = 0; i < nBubbles; i++) - { - if (i == 0) - { - Bubble_Center[i][0] = 0.0; - Bubble_Center[i][1] = 0.0; - Bubble_Center[i][2] = 0.0; - } - else - { - APECSS_FLOAT x = rand_range((double) -cluster_radius, (double) cluster_radius); - APECSS_FLOAT y = rand_range((double) -cluster_radius, (double) cluster_radius); - APECSS_FLOAT z = rand_range((double) -cluster_radius, (double) cluster_radius); - - APECSS_FLOAT radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); - - while (radius > cluster_radius) - { - x = rand_range((double) -cluster_radius, (double) cluster_radius); - y = rand_range((double) -cluster_radius, (double) cluster_radius); - z = rand_range((double) -cluster_radius, (double) cluster_radius); - - radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); - } - - Bubble_Center[i][0] = x; - Bubble_Center[i][1] = y; - Bubble_Center[i][2] = z; - - for (register int k = 0; k < i; k++) - { - APECSS_FLOAT bubbledist = APECSS_SQRT(APECSS_POW2(Bubble_Center[i][0] - Bubble_Center[k][0]) + APECSS_POW2(Bubble_Center[i][1] - Bubble_Center[k][1]) + - APECSS_POW2(Bubble_Center[i][2] - Bubble_Center[k][2])); - if (bubbledist < bubble_bubble_dist) - { - i--; - break; - } - } - } - } - - for (register int n = 0; n < RankInfo->nBubbles_local; n++) - { - Bubbles[n]->Interaction->location[0] = Bubble_Center[RankInfo->bubblerank[RankInfo->rank] + n][0]; - Bubbles[n]->Interaction->location[1] = Bubble_Center[RankInfo->bubblerank[RankInfo->rank] + n][1]; - Bubbles[n]->Interaction->location[2] = Bubble_Center[RankInfo->bubblerank[RankInfo->rank] + n][2]; - } - - // Share the location of each bubble with all ranks - - RankInfo->bubbleglobal_R = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - RankInfo->bubbleglobal_x = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - RankInfo->bubbleglobal_y = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - RankInfo->bubbleglobal_z = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - - for (int r = 0; r < RankInfo->size; r++) - { - int temp = RankInfo->nBubbles_local; - MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); - - APECSS_FLOAT temp_array[4]; - - for (int i = 0; i < temp; i++) - { - if (r == RankInfo->rank) - { - temp_array[0] = Bubbles[i]->Interaction->location[0]; - temp_array[1] = Bubbles[i]->Interaction->location[1]; - temp_array[2] = Bubbles[i]->Interaction->location[2]; - temp_array[3] = Bubbles[i]->R; - } - - MPI_Bcast(temp_array, 4, MPI_DOUBLE, r, MPI_COMM_WORLD); - - RankInfo->bubbleglobal_x[RankInfo->bubblerank[r] + i] = temp_array[0]; - RankInfo->bubbleglobal_y[RankInfo->bubblerank[r] + i] = temp_array[1]; - RankInfo->bubbleglobal_z[RankInfo->bubblerank[r] + i] = temp_array[2]; - RankInfo->bubbleglobal_R[RankInfo->bubblerank[r] + i] = temp_array[3]; - } - } - - // Update cut off distance for each bubble - parallel_interactions_proper_cutoffdistance(Bubbles, RankInfo); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - clock_t starttimebubble = clock(); - APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->tStart = tSim; - Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; - Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step - } - - /* Initialize the bubble based on the selected options */ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_initialize(Bubbles[i]); - - /* Initialize */ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_initialize(Bubbles[i]); - - // Allocate the pressure contribution array - RankInfo->sumGU_rank = malloc(2 * RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Files to retrieve all valuable information for cavitation onset test case - // Bubbles locations - FILE *file_loc = fopen("bubble_loc.txt", "w"); - fprintf(file_loc, "#number x(m) y(m) z(m)\n"); - for (register int i = 0; i < RankInfo->nBubbles_global; i++) - { - fprintf(file_loc, "%d %e %e %e\n", i, RankInfo->bubbleglobal_x[i], RankInfo->bubbleglobal_y[i], RankInfo->bubbleglobal_z[i]); - } - fclose(file_loc); - - // Radius and pressure evolution for each bubble during computation - FILE *file_onset; - char file_name[APECSS_STRINGLENGTH_SPRINTF_LONG]; - sprintf(file_name, "onset_results_%d.txt", RankInfo->rank); - file_onset = fopen(file_name, "w"); - - fprintf(file_onset, "%d Bubbles p0(pa) %e png(Pa) %e cl_distrib %d\n", nBubbles, Liquid->pref, pa, cluster_distrib); - fprintf(file_onset, "Initial_radii(m)"); - for (register int i = 0; i < RankInfo->nBubbles_global; i++) - { - fprintf(file_onset, " %e", RankInfo->bubbleglobal_R[i]); - } - fprintf(file_onset, "\n"); - fprintf(file_onset, "#Time(s) R(m) Pt(Pa)\n"); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - /* Solve the bubble dynamics */ - while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered - { - APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); - tSim += dtSim; - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); - - // for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Update the contribution of the neighbor bubble - parallel_interactions_quasi_acoustic(Bubbles, RankInfo); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Retrieve data - fprintf(file_onset, "%e", tSim); - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - fprintf(file_onset, " %e", Bubbles[i]->R); - } - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - fprintf(file_onset, " %e", Bubbles[i]->get_pressure_infinity(Bubbles[i]->t, Bubbles[i])); - } - fprintf(file_onset, "\n"); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; - Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; - - Bubbles[i]->Interaction->last_t_1 = tSim; - Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; - } - } - - fclose(file_onset); - - /* Finalize the simulation*/ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_finalize(Bubbles[i]); - - char str[APECSS_STRINGLENGTH_SPRINTF]; - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", RankInfo->bubblerank[RankInfo->rank] + i, Bubbles[i]->dtNumber, - Bubbles[i]->nSubIter, (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); - apecss_writeonscreen(str); - } - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); - - /* Make sure all allocated memory is freed */ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_freestruct(Bubbles[i]); - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) free(Bubbles[i]); - free(Gas); - free(Liquid); - free(Interface); - free(NumericsODE); - free(Excitation); - - free(RankInfo->bubblerank); - RankInfo->bubblerank = NULL; - free(RankInfo->bubbleglobal_R); - RankInfo->bubbleglobal_R = NULL; - free(RankInfo->bubbleglobal_x); - RankInfo->bubbleglobal_x = NULL; - free(RankInfo->bubbleglobal_y); - RankInfo->bubbleglobal_y = NULL; - free(RankInfo->bubbleglobal_z); - RankInfo->bubbleglobal_z = NULL; - free(RankInfo->sumGU_rank); - RankInfo->sumGU_rank = NULL; - free(RankInfo); - - MPI_Finalize(); - - return (0); -} - -APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - APECSS_FLOAT T = 10.0e-06; - if (t < T) - { - return (Bubble->p0 + Bubble->Interaction->dp_neighbor); - } - else if (t > 2 * T) - { - return (Bubble->Excitation->dp + Bubble->Interaction->dp_neighbor); - } - else - { - APECSS_FLOAT W = 0.5 * (1 - APECSS_COS((t + T) * APECSS_PI / T)); - return (Bubble->p0 + W * (Bubble->Excitation->dp - Bubble->p0) + Bubble->Interaction->dp_neighbor); - } -} - -APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - // Approximate numerical computation of p_infinity derivative - APECSS_FLOAT T = 10.0e-06; - if (t < T) - { - return (0.0); - } - else - { - APECSS_FLOAT derivative = 0.0; - if (t < 2 * T) - { - APECSS_FLOAT inv_T = 1 / T; - derivative = 0.5 * APECSS_PI * inv_T * APECSS_SIN(APECSS_PI * (t + T) * inv_T) * (Bubble->Excitation->dp - Bubble->p0); - } - APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; - if (delta_t > Bubble->dt) - { - APECSS_FLOAT inv_delta_t = 1 / delta_t; - return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) * inv_delta_t)); - } - else - { - return (derivative); - } - } -} - -int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo) -{ - // All bubbles are supposed to be in the same liquid - struct APECSS_Liquid *Liquid = Bubbles[0]->Liquid; - - // Update bubble radii info - APECSS_FLOAT *tempR = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - for (register int j = 0; j < RankInfo->nBubbles_global; j++) tempR[j] = 0.0; - for (register int i = 0; i < RankInfo->nBubbles_local; i++) tempR[RankInfo->bubblerank[RankInfo->rank] + i] = Bubbles[i]->R; - MPI_Allreduce(tempR, RankInfo->bubbleglobal_R, RankInfo->nBubbles_global, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - free(tempR); - - // Reset pressure contributions of the neighours - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; - - // Locally compute the contribution to each bubble - for (register int j = 0; j < RankInfo->nBubbles_global; j++) - { - APECSS_FLOAT x_j = RankInfo->bubbleglobal_x[j]; - APECSS_FLOAT y_j = RankInfo->bubbleglobal_y[j]; - APECSS_FLOAT z_j = RankInfo->bubbleglobal_z[j]; - - RankInfo->sumGU_rank[j] = 0.0; - RankInfo->sumGU_rank[j + RankInfo->nBubbles_global] = 0.0; - - double R_j = RankInfo->bubbleglobal_R[j]; - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - if (j != RankInfo->bubblerank[RankInfo->rank] + i) - { - APECSS_FLOAT sumU_bubble = 0.0; - APECSS_FLOAT sumG_bubble = 0.0; - int nodecount_bubble = 0; - - APECSS_FLOAT x_i = Bubbles[i]->Interaction->location[0]; - APECSS_FLOAT y_i = Bubbles[i]->Interaction->location[1]; - APECSS_FLOAT z_i = Bubbles[i]->Interaction->location[2]; - - APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); - - // The loop over the emission nodes begins with the most far away from the emitting bubble - struct APECSS_EmissionNode *Current = Bubbles[i]->Emissions->LastNode; - while (Current != NULL) - { - if (Current->r < interbubble_dist - R_j) - { - // The following emission nodes have not yet reached the bubble of interest - Current = NULL; - } - else if (Current->r > interbubble_dist + R_j) - { - // The bubble of interest is still not reached - Current = Current->backward; - } - else - { - // The current emission node is located inside the bubble of interest - APECSS_FLOAT gr = Current->g / Current->r; - sumU_bubble += (Current->f / APECSS_POW2(Current->r)) + gr / Liquid->cref; - sumG_bubble += gr; - nodecount_bubble++; - Current = Current->backward; - } - } - - if (nodecount_bubble) - { - APECSS_FLOAT inv_nodecount = 1.0 / (APECSS_FLOAT) nodecount_bubble; - RankInfo->sumGU_rank[j] += sumG_bubble * inv_nodecount; - RankInfo->sumGU_rank[j + RankInfo->nBubbles_global] += sumU_bubble * inv_nodecount; - } - } - } - } - - APECSS_FLOAT *sumGU_all = malloc(2 * RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - MPI_Allreduce(RankInfo->sumGU_rank, sumGU_all, 2 * RankInfo->nBubbles_global, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - - // Compute the total pressure contributions of the neighbours for all local bubbles - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->Interaction->dp_neighbor = - Liquid->rhoref * (sumGU_all[RankInfo->bubblerank[RankInfo->rank] + i] - - 0.5 * APECSS_POW2(sumGU_all[RankInfo->nBubbles_global + RankInfo->bubblerank[RankInfo->rank] + i])); - } - - free(sumGU_all); - - return (0); -} - -int parallel_interactions_proper_cutoffdistance(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo) -{ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - APECSS_FLOAT x_i = Bubbles[i]->Interaction->location[0]; - APECSS_FLOAT y_i = Bubbles[i]->Interaction->location[1]; - APECSS_FLOAT z_i = Bubbles[i]->Interaction->location[2]; - APECSS_FLOAT dist = 0.0; - - for (register int j = 0; j < RankInfo->nBubbles_global; j++) - { - APECSS_FLOAT x_j = RankInfo->bubbleglobal_x[j]; - APECSS_FLOAT y_j = RankInfo->bubbleglobal_y[j]; - APECSS_FLOAT z_j = RankInfo->bubbleglobal_z[j]; - - APECSS_FLOAT dist_ij = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); - - if (dist_ij > dist) - { - dist = dist_ij; - } - } - if (Bubbles[i]->Emissions != NULL) Bubbles[i]->Emissions->CutOffDistance = 1.25 * dist; - } - return (0); -} \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/README.md b/examples/sphericalclustercavitationonset/README.md deleted file mode 100644 index e543eb3..0000000 --- a/examples/sphericalclustercavitationonset/README.md +++ /dev/null @@ -1 +0,0 @@ -This example builds a standalone APECSS code for a cluster of 2500 interacting bubbles. The cluster can be monodispersed (with 10.0 microns as bubbles initial radius) or polydispersed (with the radii distribution following a log normal law such as $ln(R/R_{0,ref}) \sim N(0,0.7)$, with $R_{0,ref} = 10.0$ microns, as described in [Maeda, K., & Colonius, T. (2019). Bubble cloud dynamics in an ultrasound field. Journal of Fluid Mechanics, 862, 1105‑1134](https://doi.org/10.1017/jfm.2018.968)). The excitation wave is the same as the one described in [Ida, M. (2009). Multibubble cavitation inception. Physics of Fluids, 21(11), 113302.](https://doi.org/10.1063/1.3265547) and used in the example "cavitationonset". The computations can be done using the _standard incompressible model_ ("IC") or the newly developped _quasi acoustic model_ (QA). Since the latter one is a preatty heavy computation, parallelization using *OpenMPI* is adopted (around hours/days on 15 cores of an Intel i7-13700K x24 processor). Concerning the displayed results, the bubbles in the monodispersed cluster are studied based on their location in the cluster (like the "sphericalclusterinteractions" example), while for the polydispersed one, a repartition based on their initial radius is considered. \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/plot_results.py b/examples/sphericalclustercavitationonset/plot_results.py deleted file mode 100644 index 73200d4..0000000 --- a/examples/sphericalclustercavitationonset/plot_results.py +++ /dev/null @@ -1,466 +0,0 @@ -import os -import numpy as np -import matplotlib.pyplot as plt -from math import sqrt - -fontsize = 15 - -plt.rcParams['font.family']='serif' -plt.rcParams['font.serif']=['Times New Roman'] + plt.rcParams['font.serif'] -plt.rcParams['mathtext.fontset']='stix' -plt.rcParams['font.size']=fontsize - -cm = 1/2.54 - -# File designed to plot the results for the cavitation onset test case with a spherical cluster - -######### Step 1 : Retrieving data ################################################################################################################## -interaction_types = ["NI", "IC", "QA"] -cluster_types = ["mono", "poly"] - -dic_bubbles = {} -dic_bubbles_loc = {} - -for inttype in interaction_types : - if inttype not in list(dic_bubbles.keys()) : - dic_bubbles[inttype] = {} - for cltype in cluster_types : - if cltype not in list(dic_bubbles[inttype].keys()) : - dic_bubbles[inttype][cltype] = {} - if cltype not in list(dic_bubbles_loc.keys()) : - dic_bubbles_loc[cltype] = {} - -working_path = os.getcwd() -for inttype in interaction_types : - interaction_path = os.path.join(working_path, inttype) - interaction_path = os.path.join(interaction_path, "results") - for file in os.listdir(interaction_path) : - if "_loc.txt" in file : - file_name = file.split("_loc.txt")[0] - - file_loc_path = os.path.join(interaction_path, file) - file_loc = open(file_loc_path, "r") - lines_loc = file_loc.readlines() - file_loc.close() - - file_path = os.path.join(interaction_path, file_name + ".txt") - file_res = open(file_path, "r") - lines_res = file_res.readlines() - file_res.close() - - firstline = lines_res[0].split(" ") - count = int(firstline[0]) - png = float(firstline[5]) - - if "mono" in file_name : - dic_res = dic_bubbles[inttype]["mono"] - dic_loc = dic_bubbles_loc["mono"] - else : - dic_res = dic_bubbles[inttype]["poly"] - dic_loc = dic_bubbles_loc["poly"] - - if count not in list(dic_res.keys()) : - dic_res[count] = {} - if count not in list(dic_loc.keys()) : - dic_loc[count] = {} - - if png not in list(dic_res[count].keys()) : - dic_res[count][png] = [] - if png not in list(dic_loc[count].keys()) : - dic_loc[count][png] = [] - - dic_res[count][png].append([]) - for i in range(count) : - init_radius = float(lines_res[1].split(" ")[1 + i]) - x = float(lines_loc[1 + i].split(" ")[1]) - y = float(lines_loc[1 + i].split(" ")[2]) - z = float(lines_loc[1 + i].split(" ")[3]) - - dic_loc[count][png].append([x, y, z]) - dic_res[count][png].append([init_radius, [], []]) - - for line in lines_res[3:] : - data = line.split(" ") - t = float(data[0]) - dic_res[count][png][0].append(t) - - for i in range(count) : - r = float(data[1 + i]) - p = float(data[1 + count + i]) - dic_res[count][png][i+1][1].append(r) - dic_res[count][png][i+1][2].append(p) - -######### Step 2 : Define bubble distributions ###################################################################################################### - -# For monodispersed cluster, results are plotted based on bubbles locations -cluster_radius = 2.5e-03 -interval_size = 0.20e-03 - -dic_loc_distrib_global = {} -dic_loc_distrib = {0.0 : [], 0.5 : [], 1.0 : []} - -for count in list(dic_bubbles_loc["mono"].keys()) : - if count not in list(dic_loc_distrib_global.keys()) : - dic_loc_distrib_global[count] = {} - - for png in list(dic_bubbles_loc["mono"][count].keys()) : - if png not in list(dic_loc_distrib_global[count].keys()) : - dic_loc_distrib_global[count][png] = dic_loc_distrib - - for i in range(count) : - radius_to_center = sqrt(dic_bubbles_loc["mono"][count][png][i][0]**2 + dic_bubbles_loc["mono"][count][png][i][1]**2 + dic_bubbles_loc["mono"][count][png][i][2]**2) - if radius_to_center < 0.0 * cluster_radius + interval_size : - dic_loc_distrib_global[count][png][0.0].append(i) - elif 0.5 * (cluster_radius - interval_size) < radius_to_center < 0.5 * (cluster_radius + interval_size) : - dic_loc_distrib_global[count][png][0.5].append(i) - elif 1.0 * cluster_radius - interval_size < radius_to_center : - dic_loc_distrib_global[count][png][1.0].append(i) - -# For polydispersed cluster, results are plotted based on bubbles initial radii -n_quantiles = 5 -quantile_name_dic = {4 : "quartile", 5 : "quintile"} -quantile_name = quantile_name_dic[n_quantiles] -quantiles_list = [] -for i in range(1, n_quantiles + 1) : - quantiles_list.append(i / n_quantiles) -quantiles_list = np.array(quantiles_list) - -dic_polydisperse = {} - -for inttype in interaction_types : - dic_polydisperse[inttype] = {} - for count in list(dic_bubbles[inttype]["poly"].keys()) : - if count not in list(dic_polydisperse[inttype].keys()) : - dic_polydisperse[inttype][count] = {} - for png in list(dic_bubbles[inttype]["poly"][count].keys()) : - if png not in list(dic_polydisperse[inttype][count].keys()) : - dic_polydisperse[inttype][count][png] = {"quantiles" : []} - for q in quantiles_list : - dic_polydisperse[inttype][count][png][q] = [] - - initial_radius_list = [] - for i in range(count) : - initial_radius_list.append(dic_bubbles[inttype]["poly"][count][png][i][0]) - - quantiles = np.quantile(np.array(initial_radius_list), quantiles_list) - for q in quantiles : dic_polydisperse[inttype][count][png]["quantiles"].append(q) - - for i in range(count) : - initial_radius = dic_bubbles[inttype]["poly"][count][png][i][0] - - index = 0 - while initial_radius > dic_polydisperse[inttype][count][png]["quantiles"][index] : - index += 1 - dic_polydisperse[inttype][count][png][quantiles_list[index]].append(i) - -######### Step 3 : Plot results ##################################################################################################################### - -######### Averaged radius versus time evolution for monodispersed cluster ######################### -count = 2500 -png = -25325 - -nrow = 1 -ncol = 3 -fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) -for i in range(ncol) : - axs[i].set_xlabel(r"t ($\mu$s)", fontsize=15) - axs[i].set_ylabel(r"$ / R_{0}$ (-)", fontsize=15) - axs[i].set_xlim(xmin=10.0, xmax=60.0) - axs[i].grid() - -axs[0].set_title(r"No interaction" + "\n" +r"($N = 2500$, $R_{0}=10.0 \ \mu m$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) -axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 2500$, $R_{0}=10.0 \ \mu m$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) -axs[2].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 2500$, $R_{0}=10.0 \ \mu m$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) - -dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} -dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} - -for k in dic_loc_distrib_global[count][png].keys() : - index_list = dic_loc_distrib_global[count][png][k] - - # No interaction - t_list = np.array(dic_bubbles["NI"]["mono"][count][png][0]) - - r_list_0 = np.array(dic_bubbles["NI"]["mono"][count][png][index_list[0] + 1][1]) - init_r_0 = dic_bubbles["NI"]["mono"][count][png][index_list[0] + 1][0] - avg_radius = r_list_0 / init_r_0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - r_list = np.array(dic_bubbles["NI"]["mono"][count][png][index + 1][1]) - init_r = dic_bubbles["NI"]["mono"][count][png][index + 1][0] - avg_radius = avg_radius + np.array(r_list) / init_r - - avg_radius = (1 / len(index_list)) * avg_radius - - axs[0].plot(t_list*1.0e6, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) - - # Incompressible interactions - t_list = np.array(dic_bubbles["IC"]["mono"][count][png][0]) - - r_list_0 = np.array(dic_bubbles["IC"]["mono"][count][png][index_list[0] + 1][1]) - init_r_0 = dic_bubbles["IC"]["mono"][count][png][index_list[0] + 1][0] - avg_radius = r_list_0 / init_r_0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - r_list = np.array(dic_bubbles["IC"]["mono"][count][png][index + 1][1]) - init_r = dic_bubbles["IC"]["mono"][count][png][index + 1][0] - avg_radius = avg_radius + np.array(r_list) / init_r - - avg_radius = (1 / len(index_list)) * avg_radius - - axs[1].plot(t_list*1.0e6, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=r"$r/R_{C} \approx$" + " {:.1f}".format(k)) - - # Quasi acoustic interactions - t_list = np.array(dic_bubbles["QA"]["mono"][count][png][0]) - - r_list_0 = np.array(dic_bubbles["QA"]["mono"][count][png][index_list[0] + 1][1]) - init_r_0 = dic_bubbles["QA"]["mono"][count][png][index_list[0] + 1][0] - avg_radius = r_list_0 / init_r_0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - r_list = np.array(dic_bubbles["QA"]["mono"][count][png][index + 1][1]) - init_r = dic_bubbles["QA"]["mono"][count][png][index + 1][0] - avg_radius = avg_radius + np.array(r_list) / init_r - - avg_radius = (1 / len(index_list)) * avg_radius - - axs[2].plot(t_list*1.0e6, avg_radius, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) - - -axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=3, frameon=False) -fig.savefig("sphericalclustercavitationonset_mono_radiusevolution.pdf", bbox_inches='tight',pad_inches=0.35) - -######### Averaged radius versus time evolution for polydispersed cluster ######################### - -count = 2500 -png = -25325 - -nrow = 1 -ncol = 3 -fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) -for i in range(ncol) : - axs[i].set_xlabel(r"t ($\mu$s)", fontsize=15) - axs[i].set_ylabel(r"$$ (-)", fontsize=15) - axs[i].set_xlim(xmin=10.0, xmax=60.0) - axs[i].grid() - -axs[0].set_title(r"No interaction" + "\n" +r"($N = 2500$, $R_{0, ref}=10.0 \ \mu m$, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) -axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 2500$, $R_{0, ref}=10.0 \ \mu m$, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) -axs[2].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 2500$, $R_{0, ref}=10.0 \ \mu m$, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) - -color_list = ["black", "magenta", "blue", "green", "red"] -dic_color_q = {} -dic_label_q = {} -for i in range(n_quantiles) : - quantile = quantiles_list[i] - dic_color_q[quantile] = color_list[i] - - dic_label_q[quantile] = "{}th-{}".format(i+1, quantile_name) - if i == 0 : - dic_label_q[quantile] = "1st-{}".format(quantile_name) - elif i == 1 : - dic_label_q[quantile] = "2nd-{}".format(quantile_name) - elif i == 2 : - dic_label_q[quantile] = "3rd-{}".format(quantile_name) - -# No interaction -for q in list(dic_polydisperse["NI"][count][png].keys())[1:] : - index_list = dic_polydisperse["NI"][count][png][q] - - t_list = np.array(dic_bubbles["NI"]["poly"][count][png][0]) - - r_list_0 = np.array(dic_bubbles["NI"]["poly"][count][png][index_list[0] + 1][1]) - init_r_0 = dic_bubbles["NI"]["poly"][count][png][index_list[0] + 1][0] - avg_radius = r_list_0 / init_r_0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - r_list = np.array(dic_bubbles["NI"]["poly"][count][png][index + 1][1]) - init_r = dic_bubbles["NI"]["poly"][count][png][index + 1][0] - avg_radius = avg_radius + np.array(r_list) / init_r - - avg_radius = (1 / len(index_list)) * avg_radius - - axs[0].plot(t_list*1.0e6, avg_radius, linewidth=1.5, linestyle="solid", color=dic_color_q[q]) - -# Incompressible interactions -for q in list(dic_polydisperse["IC"][count][png].keys())[1:] : - index_list = dic_polydisperse["IC"][count][png][q] - - t_list = np.array(dic_bubbles["IC"]["poly"][count][png][0]) - - r_list_0 = np.array(dic_bubbles["IC"]["poly"][count][png][index_list[0] + 1][1]) - init_r_0 = dic_bubbles["IC"]["poly"][count][png][index_list[0] + 1][0] - avg_radius = r_list_0 / init_r_0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - r_list = np.array(dic_bubbles["IC"]["poly"][count][png][index + 1][1]) - init_r = dic_bubbles["IC"]["poly"][count][png][index + 1][0] - avg_radius = avg_radius + np.array(r_list) / init_r - - avg_radius = (1 / len(index_list)) * avg_radius - - axs[1].plot(t_list*1.0e6, avg_radius, linewidth=1.5, linestyle="solid", color=dic_color_q[q], label=dic_label_q[q]) - -axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=n_quantiles, frameon=False) -fig.savefig("sphericalclustercavitationonset_poly_radiusevolution.pdf", bbox_inches='tight',pad_inches=0.35) - -######### Averaged pressure infinity versus time evolution for monodispersed clusters ############# - -count = 2500 -png = -25325 -p0 = 101.3e3 - -nrow = 1 -ncol = 3 -fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) -for i in range(ncol) : - axs[i].set_xlabel(r"t ($\mu$s)", fontsize=15) - axs[i].set_ylabel(r"$ / p_{0}$ (-)", fontsize=15) - axs[i].set_xlim(xmin=10.0, xmax=60.0) - axs[i].grid() - -axs[0].set_title(r"No interaction" + "\n" +r"($N = 2500$, $R_{0}=10.0 \ \mu m$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) -axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 2500$, $R_{0}=10.0 \ \mu m$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) -axs[2].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 2500$, $R_{0}=10.0 \ \mu m$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) - -dic_color_loc = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} -dic_lines_loc = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} - -for k in dic_loc_distrib_global[count][png].keys() : - index_list = dic_loc_distrib_global[count][png][k] - - # No interaction - t_list = np.array(dic_bubbles["NI"]["mono"][count][png][0]) - - p_list_0 = np.array(dic_bubbles["NI"]["mono"][count][png][index_list[0] + 1][2]) - avg_pressure = p_list_0 / p0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - p_list = np.array(dic_bubbles["NI"]["mono"][count][png][index + 1][2]) - avg_pressure = avg_pressure + np.array(p_list) / p0 - - avg_pressure = (1 / len(index_list)) * avg_pressure - - axs[0].plot(t_list*1.0e6, avg_pressure, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) - - # Incompressible interactions - t_list = np.array(dic_bubbles["IC"]["mono"][count][png][0]) - - p_list_0 = np.array(dic_bubbles["IC"]["mono"][count][png][index_list[0] + 1][2]) - avg_pressure = p_list_0 / p0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - p_list = np.array(dic_bubbles["IC"]["mono"][count][png][index + 1][2]) - avg_pressure = avg_pressure + np.array(p_list) / p0 - - avg_pressure = (1 / len(index_list)) * avg_pressure - - axs[1].plot(t_list*1.0e6, avg_pressure, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k], label=r"$r/R_{C} \approx$" + " {:.1f}".format(k)) - - # Quasi acoustic interactions - t_list = np.array(dic_bubbles["QA"]["mono"][count][png][0]) - - p_list_0 = np.array(dic_bubbles["QA"]["mono"][count][png][index_list[0] + 1][2]) - avg_pressure = p_list_0 / p0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - p_list = np.array(dic_bubbles["QA"]["mono"][count][png][index + 1][2]) - avg_pressure = avg_pressure + np.array(p_list) / p0 - - avg_pressure = (1 / len(index_list)) * avg_pressure - - axs[2].plot(t_list*1.0e6, avg_pressure, linewidth=1.5, linestyle=dic_lines_loc[k], color=dic_color_loc[k]) - -axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=3, frameon=False) -fig.savefig("sphericalclustercavitationonset_mono_pressureevolution.pdf", bbox_inches='tight',pad_inches=0.35) - -######### Averaged pressure infinity versus time evolution for monodispersed clusters ############# - -count = 2500 -png = -25325 -p0 = 101.3e3 - -nrow = 1 -ncol = 3 -fig, axs = plt.subplots(nrow,ncol,figsize=(ncol*17.5*cm, nrow*12.5*cm)) -for i in range(ncol) : - axs[i].set_xlabel(r"t ($\mu$s)", fontsize=15) - axs[i].set_ylabel(r"$/p_{0}$ (-)", fontsize=15) - axs[i].set_xlim(xmin=10.0, xmax=60.0) - axs[i].grid() - -axs[0].set_title(r"No interaction" + "\n" +r"($N = 2500$, $R_{0, ref}=10.0 \ \mu m$, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) -axs[1].set_title(r"Incompressible interactions" + "\n" +r"($N = 2500$, $R_{0, ref}=10.0 \ \mu m$, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) -axs[2].set_title(r"Quasi acoustic interactions" + "\n" +r"($N = 2500$, $R_{0, ref}=10.0 \ \mu m$, $\overline{m} = 0$, $\varsigma = 0.7$, $p_{ng} / p_{0} = -0.25$)", fontsize=15) - -color_list = ["black", "magenta", "blue", "green", "red"] -dic_color_q = {} -dic_label_q = {} -for i in range(n_quantiles) : - quantile = quantiles_list[i] - dic_color_q[quantile] = color_list[i] - - dic_label_q[quantile] = "{}th-{}".format(i+1, quantile_name) - if i == 0 : - dic_label_q[quantile] = "1st-{}".format(quantile_name) - elif i == 1 : - dic_label_q[quantile] = "2nd-{}".format(quantile_name) - elif i == 2 : - dic_label_q[quantile] = "3rd-{}".format(quantile_name) - -# No interaction -for q in list(dic_polydisperse["NI"][count][png].keys())[1:] : - index_list = dic_polydisperse["NI"][count][png][q] - - t_list = np.array(dic_bubbles["NI"]["poly"][count][png][0]) - - p_list_0 = np.array(dic_bubbles["NI"]["poly"][count][png][index_list[0] + 1][2]) - avg_pressure = p_list_0 / p0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - p_list = np.array(dic_bubbles["NI"]["poly"][count][png][index + 1][2]) - avg_pressure = avg_pressure + np.array(p_list) / p0 - - avg_pressure = (1 / len(index_list)) * avg_pressure - - axs[0].plot(t_list*1.0e6, avg_pressure, linewidth=1.5, linestyle="solid", color=dic_color_q[q]) - -# Incompressible interactions -for q in list(dic_polydisperse["IC"][count][png].keys())[1:] : - index_list = dic_polydisperse["IC"][count][png][q] - - t_list = np.array(dic_bubbles["IC"]["poly"][count][png][0]) - - p_list_0 = np.array(dic_bubbles["IC"]["poly"][count][png][index_list[0] + 1][2]) - avg_pressure = p_list_0 / p0 - - for i in range(1, len(index_list)) : - index = index_list[i] - - p_list = np.array(dic_bubbles["IC"]["poly"][count][png][index + 1][2]) - avg_pressure = avg_pressure + np.array(p_list) / p0 - - avg_pressure = (1 / len(index_list)) * avg_pressure - - axs[1].plot(t_list*1.0e6, avg_pressure, linewidth=1.5, linestyle="solid", color=dic_color_q[q], label=dic_label_q[q]) - -axs[1].legend(bbox_to_anchor=(0.5, 1.175), loc="center", fontsize=15, ncol=n_quantiles, frameon=False) -fig.savefig("sphericalclustercavitationonset_poly_pressureevolution.pdf", bbox_inches='tight',pad_inches=0.35) \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/run_sphericalclustercavitationonset.sh b/examples/sphericalclustercavitationonset/run_sphericalclustercavitationonset.sh deleted file mode 100755 index 2ed1c5c..0000000 --- a/examples/sphericalclustercavitationonset/run_sphericalclustercavitationonset.sh +++ /dev/null @@ -1,84 +0,0 @@ -######### Parameters ################################################################################################################################ - -ncores=17 -nbubbles=2500 - -######### No interaction computations ############################################################################################################### - -cd NI/build -./compile.sh -cd .. - -######### Monodispersed system #################################################################### -./build/sphericalclustercavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-6 -cldistrib 0 -python3 gather_results.py - -######### Polydispersed system #################################################################### -./build/sphericalclustercavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-6 -cldistrib 1 -python3 gather_results.py - -cd .. - -echo "" -echo "No interaction test cases passed" -echo "" - -######### Incompressible computations ############################################################################################################### - -cd IC/build -./compile.sh -cd .. - -######### Monodispersed system #################################################################### -./build/sphericalclustercavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-6 -cldistrib 0 -python3 gather_results.py - -######### Polydispersed system #################################################################### -./build/sphericalclustercavitationonset_apecss -options run.apecss -amp -25325 -tend 60.0e-6 -cldistrib 1 -python3 gather_results.py - -cd .. - -echo "" -echo "Incompressible test cases passed" -echo "" - -######### Incompressible computations ############################################################################################################### - -######### Plot results ############################################################################################################################## - -python3 plot_results.py - -######### Cleaning ################################################################################################################################## - -cd NI -rm -rf "onset_results.txt" "bubble_loc.txt" -for ((c=0; c<$nbubbles; c++)) -do - rm -rf Bubble_$c -done -cd .. - -cd IC -rm -rf "onset_results.txt" "bubble_loc.txt" -for ((c=0; c<$nbubbles; c++)) -do - rm -rf Bubble_$c -done -cd .. - -cd QA -rm -rf "bubble_loc.txt" -for ((c=0; c<$ncores; c++)) -do - rm -rf onset_results_$c.txt -done -for ((c=0; c<$nbubbles; c++)) -do - rm -rf Bubble_$c -done -cd .. - -echo "" -echo "Cleaning completed" -echo "" \ No newline at end of file diff --git a/examples/sphericalclustercavitationonset/test_distribution.py b/examples/sphericalclustercavitationonset/test_distribution.py deleted file mode 100644 index 620d814..0000000 --- a/examples/sphericalclustercavitationonset/test_distribution.py +++ /dev/null @@ -1,44 +0,0 @@ -import random -import numpy as np -import matplotlib.pyplot as plt -from math import pi, sqrt, cos, log, exp - -# Small file to test if the distribution used for the polydispersed cluster follows a log-normal distribution - -def normal_distribution (mu, sigma) : - u1 = random.random() - while u1 == 0.0 : - u1 = random.random() - u2 = random.random() - - mag = sigma * sqrt(-2 * log(u1)) - z1 = mag * cos(2 * pi * u2) + mu - return z1 - -mu = 0.0 -sigma = 0.7 -nBubbles = 2500 -r_ref = 10.0e-6 - -distrib = [] -for i in range(nBubbles) : - r = r_ref * exp(normal_distribution(mu, sigma)) - while r > 20 * r_ref and r < 0.5 * r_ref : - r = r_ref * exp(normal_distribution(mu, sigma)) - distrib.append(r) -distrib = np.array(distrib) / r_ref - -fig, ax = plt.subplots(1, 1, figsize=((15, 12.5))) -ax.set_title("Test for the proposed radii distribution") - -ax.set_xlabel(r"$R/R_{ref}$") -ax.grid() - -count, bins, ignored = ax.hist(distrib, 100, density=True, align='mid') -x = np.linspace(min(bins), max(bins), 10000) - -pdf = (np.exp(-(np.log(x) - mu)**2 / (2 * sigma**2)) / (x * sigma * np.sqrt(2 * np.pi))) - -ax.plot(x, pdf, color="red", linewidth=2) - -plt.show() \ No newline at end of file From 735d977c1a60641d82d25f2f509c1aaf4c90638d Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 23 Sep 2024 13:38:43 -0400 Subject: [PATCH 131/138] sphericalclusterinteractions ; deleting folder --- .../sphericalclusterinteractions/README.md | 1 - .../build/CMakeLists.txt | 41 -- .../build/compile.sh | 5 - .../sphericalclusterinteractions/execmpi.sh | 10 - .../plot_results.py | 407 ------------ .../sphericalclusterinteractions/run.apecss | 39 -- .../src/sphericalclusterinteractions_apecss.c | 591 ------------------ 7 files changed, 1094 deletions(-) delete mode 100644 examples/sphericalclusterinteractions/README.md delete mode 100644 examples/sphericalclusterinteractions/build/CMakeLists.txt delete mode 100755 examples/sphericalclusterinteractions/build/compile.sh delete mode 100755 examples/sphericalclusterinteractions/execmpi.sh delete mode 100644 examples/sphericalclusterinteractions/plot_results.py delete mode 100644 examples/sphericalclusterinteractions/run.apecss delete mode 100644 examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c diff --git a/examples/sphericalclusterinteractions/README.md b/examples/sphericalclusterinteractions/README.md deleted file mode 100644 index fe473e1..0000000 --- a/examples/sphericalclusterinteractions/README.md +++ /dev/null @@ -1 +0,0 @@ -This example builds a standalone APECSS code for a spherical cluster of 2500 bubbles (the number can be modified in the [.c source file](./build/sphericalclusterinteractions_apecss)) interacting with each other using the quasi acoustic interaction model and excited by a sinusoidal propagating wave (propagating along the x-axis from negative to positive values). This example is inspired by one of the first clusters presented in [Maeda, K., & Colonius, T. (2019). Bubble cloud dynamics in an ultrasound field. Journal of Fluid Mechanics, 862, 1105‑1134](https://doi.org/10.1017/jfm.2018.968). In order to optimize computational costs, parallelization is used. The computation took around 4 complete days (96 hours) by running on 15 cores from a 13th Gen Intel i7-13700K x24. The results displayed at the end are the global cluster evolution at different times and the averaged radius evolution of bubbles depending on their location inside the cluster. \ No newline at end of file diff --git a/examples/sphericalclusterinteractions/build/CMakeLists.txt b/examples/sphericalclusterinteractions/build/CMakeLists.txt deleted file mode 100644 index 937ef70..0000000 --- a/examples/sphericalclusterinteractions/build/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -cmake_minimum_required(VERSION 3.12) - -project (sphericalclusterinteractions_apecss) -set(CMAKE_C_COMPILER mpicc) - -include_directories($ENV{APECSS_DIR}/include) -FILE (GLOB_RECURSE myfiles ABSOLUTE ../src/*.c) - -set (mylibs m apecss) -link_directories($ENV{USRLIB_DIR} $ENV{APECSS_DIR}/lib) - -foreach(arg ${myincludes}) - IF (arg MATCHES "-I") - STRING(REGEX REPLACE "-I" "" myinc ${arg}) - message("Additional include: ${myinc}") - include_directories(${myinc}) - ENDIF(arg MATCHES "-I") -endforeach(arg ${myincludes}) - -foreach(arg ${mylibs}) - STRING(REGEX REPLACE "lib" "" myl1 ${arg}) - STRING(REGEX REPLACE ".a$" "" myl2 ${myl1}) - set(mylibs ${myl2} ${mylibs} ${myl2}) -endforeach(arg ${mylibs}) - -if(NOT CMAKE_BUILD_TYPE) - message(STATUS "Optimization: No optimization specified.") - set(CMAKE_BUILD_TYPE Release) -endif() - -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - message(STATUS "Optimization: Debug") - set(CMAKE_C_FLAGS_DEBUG "-Wall -g") -elseif(CMAKE_BUILD_TYPE STREQUAL "Release") - message(STATUS "Optimization: Release") - add_definitions(-DNDEBUG) - set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -O3") -endif() - -add_executable(sphericalclusterinteractions_apecss ${myfiles}) -target_link_libraries(sphericalclusterinteractions_apecss ${mylibs}) \ No newline at end of file diff --git a/examples/sphericalclusterinteractions/build/compile.sh b/examples/sphericalclusterinteractions/build/compile.sh deleted file mode 100755 index 863779a..0000000 --- a/examples/sphericalclusterinteractions/build/compile.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -rm sphericalclusterinteractions_apecss -cmake CMakeLists.txt -DCMAKE_BUILD_TYPE=Release -make -rm -r CMakeCache.txt CMakeFiles Makefile cmake_install.cmake \ No newline at end of file diff --git a/examples/sphericalclusterinteractions/execmpi.sh b/examples/sphericalclusterinteractions/execmpi.sh deleted file mode 100755 index 7a2edfd..0000000 --- a/examples/sphericalclusterinteractions/execmpi.sh +++ /dev/null @@ -1,10 +0,0 @@ -cd build -./compile.sh -cd .. -mpiexec -n 15 ./build/sphericalclusterinteractions_apecss -options run.apecss -freq 50.0e03 -amp -2.5e5 -tend 30.0e-06 - -# rm -rf bubble_loc.txt -# for ((c=0; c<2500; c++)) -# do -# rm -rf Bubble_$c -# done \ No newline at end of file diff --git a/examples/sphericalclusterinteractions/plot_results.py b/examples/sphericalclusterinteractions/plot_results.py deleted file mode 100644 index 32cd794..0000000 --- a/examples/sphericalclusterinteractions/plot_results.py +++ /dev/null @@ -1,407 +0,0 @@ -import os -import numpy as np -import matplotlib.pyplot as plt -import matplotlib.colors as mcolors -from math import sqrt -from scipy.interpolate import interp1d - -plt.rcParams['font.family']='serif' -plt.rcParams['font.serif']=['Times New Roman'] + plt.rcParams['font.serif'] -plt.rcParams['mathtext.fontset']='stix' -plt.rcParams['font.size']=25 - -color_names = list(mcolors.XKCD_COLORS) - -cm = 1/2.54 - -# The goal of this scrip is to plot a 3D visualization of the computed cluster -# Later, the interest is to vizualise the temporal evolution of the cluster - -######### Step 0 : Retrieving initial data ########################################################################################################## - -# Count the number of bubbles simulated -count = 0 -listdir = os.listdir() -for f in listdir: - if "Bubble_" in f and os.path.isdir(f): - count += 1 - -# Retrieve data for each bubble -Bubbles = [] -for i in range(count): - path = os.path.join(os.getcwd(), "Bubble_{}".format(i)) - for file in os.listdir(path): - if "KellerMiksis" in file : - Bubbles.append(np.genfromtxt("Bubble_{}/".format(i) + file, delimiter=" ")) - -# Retrieve location data for each bubble and determine cluster radius -file_loc = open("bubble_loc.txt","r") -loc_lines = file_loc.readlines() - -Bubbles_loc = [] -R_c = 0 -for i in range(count): - line = loc_lines[i+1].split(" ") - Bubbles_loc.append([float(line[1]), float(line[2]), float(line[3])]) - R_b = sqrt((float(line[1])**2)+ (float(line[2])**2)+ (float(line[3])**2)) - if R_c < R_b : - R_c = R_b - -file_loc.close() - -print("Data retrieved\n") - -######### Step 1 : Functions ######################################################################################################################## - -### signal sampling (for signal with non uniform timestep) ######################################## -# return two lists : t_signal and y_signal (with uniform timestep) -def _sample(t_signal_nuni, y_signal_nuni, delta_t_uni_exp, subref) : - # t_signal_nuni (list/1D array) represents computation time - # y_signal_nuni (list/1D array) represents the function y(t) we need to sample - # delta_t_uni_exp (float/int) is the power wanted for the time step of the uniform signal - # subref (bool) indicates if you want to refine the uniform signal obtained - - # Need to check the size of both y_signal_nuni and t_signal_nuni - if len(t_signal_nuni) != len(y_signal_nuni) : raise NameError("No matching size for sampling") - - delta_t_uni = 10.0**(-delta_t_uni_exp) - N_points_signal_nuni = len(t_signal_nuni) - - t_start = t_signal_nuni[0] - t_end = t_signal_nuni[-1] - TS = t_end - t_start - N_points_signal_uni = int(TS/delta_t_uni + 1) - - t_signal_uni = np.linspace(t_start, t_end, N_points_signal_uni) - t_signal_nuni_round = [0]*N_points_signal_nuni - - for i in range(0, N_points_signal_nuni): - t_signal_nuni_round[i] = round(t_signal_nuni[i], delta_t_uni_exp) - - y_signal_nuni_round_fw = [0]*N_points_signal_nuni - amp = -1e100 - for i in range(1, N_points_signal_nuni): - if y_signal_nuni[i] >= 0: - if t_signal_nuni_round[i] == t_signal_nuni_round[i-1]: - if y_signal_nuni[i] > amp: - amp = y_signal_nuni[i] - y_signal_nuni_round_fw[i] = amp - else: - amp = y_signal_nuni[i] - y_signal_nuni_round_fw[i] = amp - amp = -1e100 - - y_signal_nuni_round_bw = [0]*N_points_signal_nuni - amp = -1e100 - for i in range(N_points_signal_nuni-2,-1, -1): - if y_signal_nuni[i] >= 0: - if t_signal_nuni_round[i] == t_signal_nuni_round[i+1]: - if y_signal_nuni[i] > amp: - amp = y_signal_nuni[i] - y_signal_nuni_round_bw[i] = amp - else: - amp = y_signal_nuni[i] - y_signal_nuni_round_bw[i] = amp - amp = -1e100 - - y_signal_nuni_round = [0]*N_points_signal_nuni - for i in range(0, N_points_signal_nuni): - y_signal_nuni_round[i] = max(y_signal_nuni_round_fw[i], y_signal_nuni_round_bw[i]) - - buff = [y_signal_nuni_round[0]] - for i in range(1, N_points_signal_nuni): - if t_signal_nuni_round[i] == t_signal_nuni_round[i-1]: - buff.append(y_signal_nuni_round[i]) - else: - maxBuff = max(buff) - for j in range(i-len(buff),i): - y_signal_nuni_round[j] = maxBuff - buff = [y_signal_nuni_round[i]] - - i = 1 - while i < N_points_signal_nuni: - if i == len(t_signal_nuni_round) - 1: - break - if t_signal_nuni_round[i] == t_signal_nuni_round[i-1]: - t_signal_nuni_round.pop(i) - y_signal_nuni_round.pop(i) - i -= 1 - i += 1 - - fint = interp1d(t_signal_nuni_round, y_signal_nuni_round, kind='nearest') - y_signal_uni = fint(t_signal_uni) - - t_signal = t_signal_uni - y_signal = y_signal_uni - - if (subref == 'true'): - ref_factor = 10 - N_points_signal_ref = (N_points_signal_uni - 1)*ref_factor + 1 - - t_signal_uni_ref = np.linspace(0.0, TS, N_points_signal_ref) - y_signal_uni_ref = [] - for i in range(1, N_points_signal_uni): - t_ref = 0.0 - delta_t = t_signal_uni[i] - t_signal_uni[i-1] - y = y_signal_uni[i] - y_old = y_signal_uni[i-1] - for j in range(0, ref_factor): - t_ref = delta_t/float(ref_factor)*float(j) - y_ref = 0.5*((y_old-y)*np.cos(np.pi/delta_t*t_ref) + y + y_old) - y_signal_uni_ref.append(y_ref) - y_signal_uni_ref.append(y_signal_uni[-1]) - t_signal = t_signal_uni_ref - y_signal = y_signal_uni_ref - - return t_signal, y_signal - -def plot_cluster(ax, Bubbles, Bubbles_loc, t=0, figtitle ="Bubble cluster 3D visualisation",grid="True", show="False", legend="False", radius_vis="True") : - # # fig (figure) is a figure object where to plot the cluster - # ax is the ax where you want to plot the 3D cluster - # Bubbles is a list containing all data gathered by APECSS on every bubble computed - # Bubbles_loc is a list containing the center location of each bubble - # t represents the time at which the cluster should be displayed - # figtitle (str) is the title of the figure - # grid (bool) indicates if grid shall be displayed or not - # show (bool) indicates if the plot should be shown or not (high cost for a big cluster) - # legend (bool) indicates if the legend should be displayed or not - # radius_vis indicates if the displayed radius should be different than the true radius (to properly see even small bubbles) - # ax = fig.add_subplot(projection='3d') - - u = np.linspace(0, 2*np.pi, 100) - v = np.linspace(0, np.pi, 100) - - dic_color = {} - j = 0 - - max_l = np.max([np.max(np.array(Bubbles_loc)[:, 0]), np.max(np.array(Bubbles_loc)[:, 1]), np.max(np.array(Bubbles_loc)[:, 2])])*1e6 - - time_index_list = [0 for i in range(count)] - if t > 0 : - for i in range(count) : - time_list = Bubbles[i][:, 1] - index = 0 - while time_list[index] < t and index < len(time_list) : - index += 1 - time_index_list[i] = index - - for i in range(count) : - r = Bubbles[i][:, 3][0]*1e6 - if r not in list(dic_color.keys()) : - dic_color[r] = [1, color_names[j], "", 0, 0] - j += 1 - else : - dic_color[r][0] += 1 - - sorted_radius = sorted(list(dic_color.keys())) - - for j in range(len(sorted_radius)) : - key = sorted_radius[j] - dic_color[key][2] = r"$R_{0}=$" + "{:.2f}".format(key) + r" $\mu$m" + " ({})".format(dic_color[key][0]) - if 0.1 * max_l < key < max_l : dic_color[key][4] = key - else : dic_color[key][4] = max_l / (7.5 * (len(sorted_radius) - j)) - - radius_vis_list = [] - for i in range(count) : - if t == 0 : - r = Bubbles[i][:, 3][0]*1e6 - radius_vis_list.append(r) - else : - r = Bubbles[i][:, 3][time_index_list[i]]*1e6 - radius_vis_list.append(r) - - x_b, y_b, z_b = [], [], [] - for i in range(count): - r = Bubbles[i][:, 3][0]*1e6 - - x_b.append(Bubbles_loc[i][0]*1e6) - y_b.append(Bubbles_loc[i][1]*1e6) - z_b.append(Bubbles_loc[i][2]*1e6) - - if (radius_vis == "True") : r_visu = dic_color[r][4] - else : r_visu = r - - r_visu = radius_vis_list[i] - - x = r_visu * np.outer(np.cos(u), np.sin(v)) + x_b[-1] - y = r_visu * np.outer(np.sin(u), np.sin(v)) + y_b[-1] - z = r_visu * np.outer(np.ones(np.size(u)), np.cos(v)) + z_b[-1] - - # Display bubbles with colors depending on their location in the cluster - interval_size = 0.20e-03 - cluster_radius = 2.5e-03 - color = "grey" - - radius_center = sqrt(Bubbles_loc[i][0]**2 + Bubbles_loc[i][1]**2 + Bubbles_loc[i][2]**2) - if radius_center < interval_size : - color = "blue" - elif radius_center > cluster_radius - interval_size : - color = "black" - elif 0.5 * (cluster_radius - interval_size) < radius_center < 0.5 * (cluster_radius + interval_size) : - color = "red" - - if dic_color[r][3] == 0 : - c = ax.plot_surface(x, y, z, rstride=5, cstride=5, color=color, label=dic_color[r][2]) - dic_color[r][3] = 1 - else : - c = ax.plot_surface(x, y, z, rstride=5, cstride=5, color=color) - - c._facecolors2d=c._facecolor3d - c._edgecolors2d=c._edgecolor3d - - if figtitle != "" : ax.set_title(figtitle) - ax.set_xlabel(r"$x$ [$\mu$m]") - ax.set_ylabel(r"$y$ [$\mu$m]") - ax.set_zlabel(r"$z$ [$\mu$m]") - if legend != "False" : ax.legend() - - if grid : plt.grid() - if show == "True" : plt.show() - -def savefig(fig, filename="Cluster", format="pdf", path=None) : - # fig is a figure object you want to save - # filename (str) is the future filename - # format (str) is the format in which you want to save the figure (pdf by default) - # path (str) is the absolute path in which you want to store the figure - if path == None : savepath = "" - elif os.path.isdir(path) : savepath = path - else : savepath = "" - - fig.savefig(os.path.join(savepath, filename + "." + format), bbox_inches='tight',pad_inches=0.35) - -######### Step 2 : Plot / Savefig ################################################################################################################### - -## Radii evolution depending on the location in the cluster ######################################################################################## -dic_radii = {0.0 : [], 0.5 : [], 1.0 : []} -interval_size = 0.20e-03 - -cluster_radius = 2.5e-03 -interval_size = cluster_radius / 10 -fa = 50e03 - -max_radius_to_center = 0.0 - -for i in range(count) : - radius_to_center = sqrt(Bubbles_loc[i][0]**2 + Bubbles_loc[i][1]**2 + Bubbles_loc[i][2]**2) - if radius_to_center < 0.0 * cluster_radius + interval_size : - dic_radii[0.0].append(i) - elif 0.5 * (cluster_radius - interval_size) < radius_to_center < 0.5 * (cluster_radius + interval_size) : - dic_radii[0.5].append(i) - elif 1.0 * cluster_radius - interval_size < radius_to_center : - dic_radii[1.0].append(i) - - if radius_to_center > max_radius_to_center : - max_radius_to_center = radius_to_center - -print("Repartition of bubbles done\n") - -dic_color_key = {0.0 : "blue", 0.5 : "red", 1.0 : "black"} -dic_style_key = {0.0 : "dotted", 0.5 : "dashed", 1.0 : "solid"} -dic_label_key = {1.0 : "{:.1f}".format(1.0 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f}".format(1.0), - 0.5 : "{:.1f}".format(0.5 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f} (average)".format(0.5 + interval_size/cluster_radius), - 0.0 : "{:.1f}".format(0.0) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f} (average)".format(interval_size/cluster_radius)} - -fig = plt.figure(figsize=(37*cm, 17.5*cm)) -ax = fig.add_subplot(1, 1, 1) -ax.set_xlabel(r"$t^{*}$", fontsize=27.5) -ax.set_xlim(xmin=0.0, xmax=1.5) -ax.set_ylabel(r"$R/R_{0}$", fontsize=27.5) -ax.grid() - -dic_radius_evolution = {1.0 : [], 0.5 : [], 0.0 : []} - -for k in list(dic_radii.keys()) : - index_list = dic_radii[k] - for i in range(len(index_list)) : - print("{}, {}".format(k, i)) - index = index_list[i] - t_uni, r_uni = _sample(Bubbles[index][:, 1], Bubbles[index][:, 3], 8, False) - if i == 0 : - avg_radii = np.array(r_uni) - else : - avg_radii = avg_radii + np.array(r_uni) - if i == len(index_list) - 1 : - dic_radius_evolution[k].append(np.array(t_uni)) - dic_radius_evolution[k].append(avg_radii / len(index_list)) - -print("Sampling and averaging completed") - -label_edge_front = 0 -label_edge_back = 0 - -for index in dic_radii[1.0] : - if -cluster_radius < Bubbles_loc[index][0] < -cluster_radius + interval_size : - label_edge_front = index - elif cluster_radius - interval_size < Bubbles_loc[index][0] < cluster_radius : - label_edge_back = index - - -# for k in list(dic_radii.keys()) : -# index_list = dic_radii[k] -# if len(index_list) > 1 : -# for i in index_list[1:] : -# ax.plot(Bubbles[i][:, 1]*fa, Bubbles[i][:, 3]/Bubbles[i][:, 3][0], linestyle=dic_style_key[k], color=dic_color_key[k], linewidth=3.0) -# ax.plot(Bubbles[index_list[0]][:, 1]*fa, Bubbles[index_list[0]][:, 3]/Bubbles[i][:, 3][0], linestyle=dic_style_key[k], color=dic_color_key[k], linewidth=3.0, label=r"$r/R_{c} \approx$"+"{:.1f}".format(k)) -# else : -# for i in index_list : -# ax.plot(Bubbles[i][:, 1]*fa, Bubbles[i][:, 3]/Bubbles[i][:, 3][0], linestyle=dic_style_key[k], color=dic_color_key[k], linewidth=3.0, label=r"$r/R_{c} \approx$"+"{:.1f}".format(k)) - -ax.plot(Bubbles[label_edge_front][:, 1]*fa, Bubbles[label_edge_front][:, 3]/Bubbles[label_edge_front][:, 3][0], linestyle="solid", color="black", - marker="*", markersize=11.5, markevery=2500, linewidth=3.0, label="{:.1f}".format(1.0 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f} (one bubble, front)".format(1.0)) -ax.plot(Bubbles[label_edge_back][:, 1]*fa, Bubbles[label_edge_back][:, 3]/Bubbles[label_edge_back][:, 3][0], linestyle="solid", color="grey", - marker="D", markersize=11.5, markevery=2500, linewidth=3.0, label="{:.1f}".format(1.0 - interval_size/cluster_radius) + r" $\leq$ $r/R_{C}$ $\leq$ " + "{:.1f} (one bubble, back)".format(1.0)) - -for k in list(dic_radius_evolution.keys())[1:] : - ax.plot(dic_radius_evolution[k][0]*fa, dic_radius_evolution[k][1]/dic_radius_evolution[k][1][0], linestyle=dic_style_key[k], color=dic_color_key[k], linewidth=3.0, label=dic_label_key[k]) - -ax.legend(bbox_to_anchor=(0.5, 1.175),loc="center", ncol=2, fontsize=26.5, frameon=False) -savefig(fig, filename="sphericalclusterinteractions_radiievolution") - -print("Radius evolution plotted") - -## Cluster evolution vizualisation ################################################################################################################## -plt.rcParams['font.size']=27.5 - -fig = plt.figure(figsize=(4*15*cm,15*cm)) -plt.subplots_adjust(wspace=0, hspace=0) - -t_star = 0 -ax = fig.add_subplot(1, 4, 1, projection='3d') -plot_cluster(ax, Bubbles, Bubbles_loc, t=t_star/fa, figtitle="", grid="False", radius_vis="False") -ax.view_init(elev=90, azim=-90) -ax.set_aspect('equal') -ax.set_box_aspect(None, zoom=1.5) -ax.set_axis_off() -ax.set_title(r"$t^{*}$ = " + "{:.1f}".format(t_star)) - -t_star = 0.5 -ax = fig.add_subplot(1, 4, 2, projection='3d') -plot_cluster(ax, Bubbles, Bubbles_loc, t=t_star/fa, figtitle="", grid="False", radius_vis="False") -ax.view_init(elev=90, azim=-90) -ax.set_aspect('equal') -ax.set_box_aspect(None, zoom=1.5) -ax.set_axis_off() -ax.set_title(r"$t^{*}$ = " + "{:.1f}".format(t_star)) - -t_star = 1.0 -ax = fig.add_subplot(1, 4, 3, projection='3d') -plot_cluster(ax, Bubbles, Bubbles_loc, t=t_star/fa, figtitle="", grid="False", radius_vis="False") -ax.view_init(elev=90, azim=-90) -ax.set_aspect('equal') -ax.set_box_aspect(None, zoom=1.5) -ax.set_axis_off() -ax.set_title(r"$t^{*}$ = " + "{:.1f}".format(t_star)) - -t_star = 1.5 -ax = fig.add_subplot(1, 4, 4, projection='3d') -plot_cluster(ax, Bubbles, Bubbles_loc, t=t_star/fa, figtitle="", grid="False", radius_vis="False") -ax.view_init(elev=90, azim=-90) -ax.set_aspect('equal') -ax.set_box_aspect(None, zoom=1.5) -ax.set_axis_off() -ax.set_title(r"$t^{*}$ = " + "{:.1f}".format(t_star)) - -# plot_cluster(fig, Bubbles, Bubbles_loc) -savefig(fig, filename="sphericalclusterinteractions_clusterevolution", format="png") - -print("Cluster temporal evolution plotted\n") \ No newline at end of file diff --git a/examples/sphericalclusterinteractions/run.apecss b/examples/sphericalclusterinteractions/run.apecss deleted file mode 100644 index f341619..0000000 --- a/examples/sphericalclusterinteractions/run.apecss +++ /dev/null @@ -1,39 +0,0 @@ -######################################################### -# # -# APECSS Options File # -# # -######################################################### - -BUBBLE -RPModel KM -Emissions QA 250.0e-6 -PressureAmbient 1.0e5 -END - -GAS -EoS IG -ReferencePressure 1.0e5 -ReferenceDensity 1.2 -PolytropicExponent 1.4 -END - -LIQUID -ReferencePressure 1.0e5 -ReferenceDensity 1000.0 -ReferenceSoundSpeed 1500.0 -Viscosity 1.002e-3 -END - -INTERFACE -SurfaceTensionCoeff 0.0728 -END - -RESULTS -Bubble -END - -ODESOLVER -tolerance 1.0e-10 -MinTimeStep 1.0e-14 -MaxTimeStep 1.0e-05 -END diff --git a/examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c b/examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c deleted file mode 100644 index 6536b7d..0000000 --- a/examples/sphericalclusterinteractions/src/sphericalclusterinteractions_apecss.c +++ /dev/null @@ -1,591 +0,0 @@ -// This source file is part of APECSS, an open-source software toolbox -// for the computation of pressure-driven bubble dynamics and acoustic -// emissions in spherical symmetry. -// -// Copyright (C) 2022-2024 The APECSS Developers -// -// The APECSS Developers are listed in the README.md file available in -// the GitHub repository at https://github.com/polycfd/apecss. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// ------------------------------------------------------------------- -// APECSS standalone example of acoustically-interacting microbubbles -// in a spherical cluster based on Maeda, K., & Colonius, T. (2019). -// Bubble cloud dynamics in an ultrasound field. Journal of Fluid -// Mechanics, 862, 1105‑1134 -// DOI : https://doi.org/10.1017/jfm.2018.968 -// ------------------------------------------------------------------- - -#include -#include -#include "apecss.h" - -APECSS_FLOAT rand_range(double min, double max) -{ - double random = (drand48()); - double range = (max - min) * random; - double number = min + range; - - return (APECSS_FLOAT) number; -} - -struct APECSS_Parallel_Cluster -{ - int rank, size; - int nBubbles_local, nBubbles_global; - - int *bubblerank; // max id of bubbles for each rank - APECSS_FLOAT *bubbleglobal_R, *bubbleglobal_x, *bubbleglobal_y, *bubbleglobal_z; // Radius and x,y,z location of all bubbles - APECSS_FLOAT *sumGU_rank; // Contributions from local bubbles to all bubbles -}; - -// Declaration of additional case-dependent functions -APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); -APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble); - -int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubble[], struct APECSS_Parallel_Cluster *RankInfo); -int parallel_interactions_proper_cutoffdistance(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo); - -int main(int argc, char **args) -{ - /* Initialize MPI */ - int mpi_rank, mpi_size; - MPI_Init(&argc, &args); - MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); - MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); - - char OptionsDir[APECSS_STRINGLENGTH]; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Set the case-dependent simulation parameters - const int nBubbles = 2500; // Number of bubbles - APECSS_FLOAT bubble_bubble_dist = 100.0e-6; // Bubble-bubble minimal distance - APECSS_FLOAT cluster_radius = 2.5e-3; // Spherical cluster radius - - // Interbubble time-step, defining the frequency with which the neighbor influence is updated - APECSS_FLOAT dt_interbubble = 1.0e-8; - - // Initialize the simulation parameters given by the execution command - double tEnd = 0.0; - double fa = 0.0; - double pa = 0.0; - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - apecss_infoscreen(); - - /* Read commandline options */ - sprintf(OptionsDir, "./run.apecss"); // This is the default - int j = 1; // First argument is the call to the executable - while (j < argc) - { - if (strcmp("-options", args[j]) == 0) - { - sprintf(OptionsDir, "%s", args[j + 1]); - j += 2; - } - else if (strcmp("-tend", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &tEnd); - j += 2; - } - else if (strcmp("-freq", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &fa); - j += 2; - } - else if (strcmp("-amp", args[j]) == 0) - { - sscanf(args[j + 1], "%le", &pa); - j += 2; - } - else if (strcmp("-h", args[j]) == 0) - { - apecss_helpscreen(); - } - else - { - char str[APECSS_STRINGLENGTH_SPRINTF]; - sprintf(str, "Unknown command line options: %s", args[j]); - apecss_erroronscreen(1, str); - ++j; - } - } - - /* Allocate structure for parallel data */ - struct APECSS_Parallel_Cluster *RankInfo = (struct APECSS_Parallel_Cluster *) malloc(sizeof(struct APECSS_Parallel_Cluster)); - RankInfo->rank = mpi_rank; - RankInfo->size = mpi_size; - - /* Determine the number of bubbles per rank */ - int max_per_rank = ceil((double) nBubbles / (double) mpi_size); - RankInfo->nBubbles_local = APECSS_MAX(0, APECSS_MIN(max_per_rank, nBubbles - mpi_rank * max_per_rank)); - - /* Share the parallel distribution of bubbles with all ranks */ - RankInfo->bubblerank = malloc((RankInfo->size + 1) * sizeof(int)); - - RankInfo->nBubbles_global = 0; - RankInfo->bubblerank[0] = 0; - for (int r = 0; r < RankInfo->size; r++) - { - int temp = RankInfo->nBubbles_local; - MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); - RankInfo->bubblerank[r + 1] = RankInfo->bubblerank[r] + temp; - RankInfo->nBubbles_global += temp; - } - - /* Allocate and initialize Bubble structure */ - struct APECSS_Bubble *Bubbles[RankInfo->nBubbles_local]; - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i] = (struct APECSS_Bubble *) malloc(sizeof(struct APECSS_Bubble)); - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_initializestruct(Bubbles[i]); - - /* Set default options and read the options for the bubble */ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); - - /* Allocate the structures for the fluid properties and ODE solver parameters */ - struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); - struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); - struct APECSS_Interface *Interface = (struct APECSS_Interface *) malloc(sizeof(struct APECSS_Interface)); - struct APECSS_NumericsODE *NumericsODE = (struct APECSS_NumericsODE *) malloc(sizeof(struct APECSS_NumericsODE)); - - /* Set the default options for the fluid properties and solver parameters */ - apecss_gas_setdefaultoptions(Gas); - apecss_liquid_setdefaultoptions(Liquid); - apecss_interface_setdefaultoptions(Interface); - apecss_odesolver_setdefaultoptions(NumericsODE); - - /* Read the options file for the fluid properties and solver parameters */ - apecss_gas_readoptions(Gas, OptionsDir); - apecss_liquid_readoptions(Liquid, OptionsDir); - apecss_interface_readoptions(Interface, OptionsDir); - apecss_odesolver_readoptions(NumericsODE, OptionsDir); - - /* Associate the bubble with the relevant fluid properties and solver parameters */ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->Gas = Gas; - Bubbles[i]->Liquid = Liquid; - Bubbles[i]->Interface = Interface; - Bubbles[i]->NumericsODE = NumericsODE; - } - - /* Allocate and set the excitation parameters */ - struct APECSS_Excitation *Excitation = (struct APECSS_Excitation *) malloc(sizeof(struct APECSS_Excitation)); - Excitation->type = APECSS_EXCITATION_SIN; - Excitation->f = (APECSS_FLOAT) fa; - Excitation->dp = (APECSS_FLOAT) pa; - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Excitation = Excitation; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Create individual folders for the results of each bubble - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - if (Bubbles[i]->Results != NULL) - { - sprintf(Bubbles[i]->Results->dir, "./Bubble_%i/", RankInfo->bubblerank[RankInfo->rank] + i); - struct stat st = {0}; - if (stat(Bubbles[i]->Results->dir, &st) == -1) mkdir(Bubbles[i]->Results->dir, 0700); - } - } - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - /* Process all options */ - apecss_gas_processoptions(Gas); - apecss_liquid_processoptions(Liquid); - apecss_interface_processoptions(Interface); - apecss_odesolver_processoptions(NumericsODE); - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_processoptions(Bubbles[i]); - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Use the revised pressure at infinity, including neighbor contributions - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->get_pressure_infinity = parallel_interactions_bubble_pressure_infinity; - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - Bubbles[i]->get_pressurederivative_infinity = parallel_interactions_bubble_pressurederivative_infinity; - - // Allocate interaction structure - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->Interaction = (struct APECSS_Interaction *) malloc(sizeof(struct APECSS_Interaction)); - Bubbles[i]->Interaction->dp_neighbor = 0.0; - Bubbles[i]->Interaction->last_t_1 = 0.0; - Bubbles[i]->Interaction->last_t_2 = 0.0; - Bubbles[i]->Interaction->last_p_1 = 0.0; - Bubbles[i]->Interaction->last_p_2 = 0.0; - } - - // Update interaction structure - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->nBubbles = nBubbles; // Not used? - - // Define the size of each bubble - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->R0 = 10.0e-6; - Bubbles[i]->r_hc = Bubbles[i]->R0 / 8.54; - } - - // Define center location for each bubble - APECSS_FLOAT Bubble_Center[nBubbles][3]; - - for (register int i = 0; i < nBubbles; i++) - { - if (i == 0) - { - Bubble_Center[i][0] = 0.0; - Bubble_Center[i][1] = 0.0; - Bubble_Center[i][2] = 0.0; - } - else - { - APECSS_FLOAT x = rand_range((double) -cluster_radius, (double) cluster_radius); - APECSS_FLOAT y = rand_range((double) -cluster_radius, (double) cluster_radius); - APECSS_FLOAT z = rand_range((double) -cluster_radius, (double) cluster_radius); - - APECSS_FLOAT radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); - - while (radius > cluster_radius) - { - x = rand_range((double) -cluster_radius, (double) cluster_radius); - y = rand_range((double) -cluster_radius, (double) cluster_radius); - z = rand_range((double) -cluster_radius, (double) cluster_radius); - - radius = APECSS_SQRT(APECSS_POW2(x) + APECSS_POW2(y) + APECSS_POW2(z)); - } - - Bubble_Center[i][0] = x; - Bubble_Center[i][1] = y; - Bubble_Center[i][2] = z; - - for (register int k = 0; k < i; k++) - { - APECSS_FLOAT bubbledist = APECSS_SQRT(APECSS_POW2(Bubble_Center[i][0] - Bubble_Center[k][0]) + APECSS_POW2(Bubble_Center[i][1] - Bubble_Center[k][1]) + - APECSS_POW2(Bubble_Center[i][2] - Bubble_Center[k][2])); - if (bubbledist < bubble_bubble_dist) - { - i--; - break; - } - } - } - } - - for (register int n = 0; n < RankInfo->nBubbles_local; n++) - { - Bubbles[n]->Interaction->location[0] = Bubble_Center[RankInfo->bubblerank[RankInfo->rank] + n][0]; - Bubbles[n]->Interaction->location[1] = Bubble_Center[RankInfo->bubblerank[RankInfo->rank] + n][1]; - Bubbles[n]->Interaction->location[2] = Bubble_Center[RankInfo->bubblerank[RankInfo->rank] + n][2]; - } - - // Share the location of each bubble with all ranks - - RankInfo->bubbleglobal_R = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - RankInfo->bubbleglobal_x = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - RankInfo->bubbleglobal_y = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - RankInfo->bubbleglobal_z = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - - for (int r = 0; r < RankInfo->size; r++) - { - int temp = RankInfo->nBubbles_local; - MPI_Bcast(&temp, 1, MPI_INT, r, MPI_COMM_WORLD); - - APECSS_FLOAT temp_array[4]; - - for (int i = 0; i < temp; i++) - { - if (r == RankInfo->rank) - { - temp_array[0] = Bubbles[i]->Interaction->location[0]; - temp_array[1] = Bubbles[i]->Interaction->location[1]; - temp_array[2] = Bubbles[i]->Interaction->location[2]; - temp_array[3] = Bubbles[i]->R; - } - - MPI_Bcast(temp_array, 4, MPI_DOUBLE, r, MPI_COMM_WORLD); - - RankInfo->bubbleglobal_x[RankInfo->bubblerank[r] + i] = temp_array[0]; - RankInfo->bubbleglobal_y[RankInfo->bubblerank[r] + i] = temp_array[1]; - RankInfo->bubbleglobal_z[RankInfo->bubblerank[r] + i] = temp_array[2]; - RankInfo->bubbleglobal_R[RankInfo->bubblerank[r] + i] = temp_array[3]; - } - } - - // Update cut off distance for each bubble - parallel_interactions_proper_cutoffdistance(Bubbles, RankInfo); - - // File to retrieve the locations of bubble centers - if (RankInfo->rank == 0) - { - FILE *file_loc; - file_loc = fopen("bubble_loc.txt", "w"); - fprintf(file_loc, "#number x(m) y(m) z(m)\n"); - for (register int i = 0; i < nBubbles; i++) - { - fprintf(file_loc, "%d %e %e %e\n", i, Bubble_Center[i][0], Bubble_Center[i][1], Bubble_Center[i][2]); - } - fclose(file_loc); - } - - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - clock_t starttimebubble = clock(); - APECSS_FLOAT tSim = 0.0; // Simulation time of the coupled system - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->tStart = tSim; - Bubbles[i]->tEnd = (APECSS_FLOAT) tEnd; - Bubbles[i]->dt = APECSS_MIN(1.0e-11, dt_interbubble); // Initial time-step - } - - /* Initialize the bubble based on the selected options */ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_initialize(Bubbles[i]); - - /* Initialize */ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_initialize(Bubbles[i]); - - // Allocate the pressure contribution array - RankInfo->sumGU_rank = malloc(2 * RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - - /* Solve the bubble dynamics */ - while (tSim < (APECSS_FLOAT) tEnd) // Interaction loop, corresponding to the time-intervals at which interactions are considered - { - APECSS_FLOAT dtSim = APECSS_MIN(dt_interbubble, (APECSS_FLOAT) tEnd - tSim); - tSim += dtSim; - - // To follow computations progress - if (RankInfo->rank == 0) - { - printf("%e\n", tSim); - } - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); - - // for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; - - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // Update the contribution of the neighbor bubble - parallel_interactions_quasi_acoustic(Bubbles, RankInfo); - // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; - Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; - - Bubbles[i]->Interaction->last_t_1 = tSim; - Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; - } - } - - /* Finalize the simulation*/ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_solver_finalize(Bubbles[i]); - - char str[APECSS_STRINGLENGTH_SPRINTF]; - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - sprintf(str, "Bubble %i: Solver concluded %i time-steps and %i sub-iterations in %.3f s.", RankInfo->bubblerank[RankInfo->rank] + i, Bubbles[i]->dtNumber, - Bubbles[i]->nSubIter, (double) (clock() - starttimebubble) / CLOCKS_PER_SEC); - apecss_writeonscreen(str); - } - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_results_rayleighplesset_write(Bubbles[i], APECSS_RESULTS_WRITE); - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_results_emissionsspace_write(Bubbles[i], APECSS_RESULTS_WRITE); - - /* Make sure all allocated memory is freed */ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) apecss_bubble_freestruct(Bubbles[i]); - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) free(Bubbles[i]); - free(Gas); - free(Liquid); - free(Interface); - free(NumericsODE); - free(Excitation); - - free(RankInfo->bubblerank); - RankInfo->bubblerank = NULL; - free(RankInfo->bubbleglobal_R); - RankInfo->bubbleglobal_R = NULL; - free(RankInfo->bubbleglobal_x); - RankInfo->bubbleglobal_x = NULL; - free(RankInfo->bubbleglobal_y); - RankInfo->bubbleglobal_y = NULL; - free(RankInfo->bubbleglobal_z); - RankInfo->bubbleglobal_z = NULL; - free(RankInfo->sumGU_rank); - RankInfo->sumGU_rank = NULL; - free(RankInfo); - - MPI_Finalize(); - - return (0); -} - -APECSS_FLOAT parallel_interactions_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - // return (Bubble->p0 - - // Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * Bubble->Excitation->f * (t - Bubble->Interaction->location[0] / Bubble->Liquid->cref)) + - // Bubble->Interaction->dp_neighbor); - APECSS_FLOAT wavelength = Bubble->Liquid->cref / Bubble->Excitation->f; - APECSS_FLOAT wavefront = Bubble->Liquid->cref * t - 2.5e-03; - APECSS_FLOAT p_infty = Bubble->p0 + Bubble->Interaction->dp_neighbor; - - if (Bubble->Interaction->location[0] > wavefront) - { - return (p_infty); - } - else if (Bubble->Interaction->location[0] < wavefront - wavelength) - { - return (p_infty); - } - else - { - return (p_infty + Bubble->Excitation->dp * APECSS_SIN(2.0 * APECSS_PI * (wavefront - Bubble->Interaction->location[0]) / wavelength)); - } -} - -APECSS_FLOAT parallel_interactions_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) -{ - APECSS_FLOAT wavelength = Bubble->Liquid->cref / Bubble->Excitation->f; - APECSS_FLOAT wavefront = Bubble->Liquid->cref * t - 2.5e-03; - APECSS_FLOAT derivative = 0.0; - if ((Bubble->Interaction->location[0] > wavefront - wavelength) && (Bubble->Interaction->location[0] < wavefront)) - { - APECSS_FLOAT inv_wavelength = 1 / wavelength; - derivative += 2.0 * APECSS_PI * inv_wavelength * Bubble->Excitation->dp * - APECSS_COS(2.0 * APECSS_PI * inv_wavelength * (wavefront - Bubble->Interaction->location[0])); - } - - // APECSS_FLOAT derivative = -2.0 * APECSS_PI * Bubble->Excitation->f * Bubble->Excitation->dp * - // APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * (t - Bubble->Interaction->location[0] / Bubble->Liquid->cref)); - - APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; - if (delta_t > Bubble->dt) - { - return (derivative + (Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) / delta_t); - } - else - { - return (derivative); - } -} - -int parallel_interactions_quasi_acoustic(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo) -{ - // All bubbles are supposed to be in the same liquid - struct APECSS_Liquid *Liquid = Bubbles[0]->Liquid; - - // Update bubble radii info - APECSS_FLOAT *tempR = malloc(RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - for (register int j = 0; j < RankInfo->nBubbles_global; j++) tempR[j] = 0.0; - for (register int i = 0; i < RankInfo->nBubbles_local; i++) tempR[RankInfo->bubblerank[RankInfo->rank] + i] = Bubbles[i]->R; - MPI_Allreduce(tempR, RankInfo->bubbleglobal_R, RankInfo->nBubbles_global, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - free(tempR); - - // Reset pressure contributions of the neighours - for (register int i = 0; i < RankInfo->nBubbles_local; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; - - // Locally compute the contribution to each bubble - for (register int j = 0; j < RankInfo->nBubbles_global; j++) - { - APECSS_FLOAT x_j = RankInfo->bubbleglobal_x[j]; - APECSS_FLOAT y_j = RankInfo->bubbleglobal_y[j]; - APECSS_FLOAT z_j = RankInfo->bubbleglobal_z[j]; - - RankInfo->sumGU_rank[j] = 0.0; - RankInfo->sumGU_rank[j + RankInfo->nBubbles_global] = 0.0; - - double R_j = RankInfo->bubbleglobal_R[j]; - - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - if (j != RankInfo->bubblerank[RankInfo->rank] + i) - { - APECSS_FLOAT sumU_bubble = 0.0; - APECSS_FLOAT sumG_bubble = 0.0; - int nodecount_bubble = 0; - - APECSS_FLOAT x_i = Bubbles[i]->Interaction->location[0]; - APECSS_FLOAT y_i = Bubbles[i]->Interaction->location[1]; - APECSS_FLOAT z_i = Bubbles[i]->Interaction->location[2]; - - APECSS_FLOAT interbubble_dist = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); - - // The loop over the emission nodes begins with the most far away from the emitting bubble - struct APECSS_EmissionNode *Current = Bubbles[i]->Emissions->LastNode; - while (Current != NULL) - { - if (Current->r < interbubble_dist - R_j) - { - // The following emission nodes have not yet reached the bubble of interest - Current = NULL; - } - else if (Current->r > interbubble_dist + R_j) - { - // The bubble of interest is still not reached - Current = Current->backward; - } - else - { - // The current emission node is located inside the bubble of interest - APECSS_FLOAT gr = Current->g / Current->r; - sumU_bubble += (Current->f / APECSS_POW2(Current->r)) + gr / Liquid->cref; - sumG_bubble += gr; - nodecount_bubble++; - Current = Current->backward; - } - } - - if (nodecount_bubble) - { - APECSS_FLOAT inv_nodecount = 1.0 / (APECSS_FLOAT) nodecount_bubble; - RankInfo->sumGU_rank[j] += sumG_bubble * inv_nodecount; - RankInfo->sumGU_rank[j + RankInfo->nBubbles_global] += sumU_bubble * inv_nodecount; - } - } - } - } - - APECSS_FLOAT *sumGU_all = malloc(2 * RankInfo->nBubbles_global * sizeof(APECSS_FLOAT)); - MPI_Allreduce(RankInfo->sumGU_rank, sumGU_all, 2 * RankInfo->nBubbles_global, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - - // Compute the total pressure contributions of the neighbours for all local bubbles - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - Bubbles[i]->Interaction->dp_neighbor = - Liquid->rhoref * (sumGU_all[RankInfo->bubblerank[RankInfo->rank] + i] - - 0.5 * APECSS_POW2(sumGU_all[RankInfo->nBubbles_global + RankInfo->bubblerank[RankInfo->rank] + i])); - } - - free(sumGU_all); - - return (0); -} - -int parallel_interactions_proper_cutoffdistance(struct APECSS_Bubble *Bubbles[], struct APECSS_Parallel_Cluster *RankInfo) -{ - for (register int i = 0; i < RankInfo->nBubbles_local; i++) - { - APECSS_FLOAT x_i = Bubbles[i]->Interaction->location[0]; - APECSS_FLOAT y_i = Bubbles[i]->Interaction->location[1]; - APECSS_FLOAT z_i = Bubbles[i]->Interaction->location[2]; - APECSS_FLOAT dist = 0.0; - - for (register int j = 0; j < RankInfo->nBubbles_global; j++) - { - APECSS_FLOAT x_j = RankInfo->bubbleglobal_x[j]; - APECSS_FLOAT y_j = RankInfo->bubbleglobal_y[j]; - APECSS_FLOAT z_j = RankInfo->bubbleglobal_z[j]; - - APECSS_FLOAT dist_ij = APECSS_SQRT(APECSS_POW2(x_i - x_j) + APECSS_POW2(y_i - y_j) + APECSS_POW2(z_i - z_j)); - - if (dist_ij > dist) - { - dist = dist_ij; - } - } - if (Bubbles[i]->Emissions != NULL) Bubbles[i]->Emissions->CutOffDistance = 1.25 * dist; - } - return (0); -} \ No newline at end of file From 0c40093053eeef541bc2a7db32aa5267bdb0b139 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 23 Sep 2024 13:58:21 -0400 Subject: [PATCH 132/138] sphericalclustertensionwave ; update in README for better clarity --- examples/sphericalclustertensionwave/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/sphericalclustertensionwave/README.md b/examples/sphericalclustertensionwave/README.md index 699a6af..127679e 100644 --- a/examples/sphericalclustertensionwave/README.md +++ b/examples/sphericalclustertensionwave/README.md @@ -1,3 +1,3 @@ -This example builds a standalone APECSS code for a monodispersed cluster of 250 interacting microbubbles. The cluster has a spherical shape with radius $R_{\mathrm{C}} = 232 \mu\mathrm{m}$, with the bubbles randomly distributed inside. The bubbles initial radius is $R_{0} = 2 \mu\mathrm{m}$. The incident wave is a single tension pulse defined by $p_{\mathrm{a}}(t) = -(p_{0} - p_{\mathrm{ng}})\sin^{2}\left(\pi t / \tau \right)$, with $\tau = 1.75 \mu\mathrm{s}$ and $p_{\mathrm{ng}} = -3.0 \times 10^{4} \mathrm{Pa}$. The computations are done when considering *no interactions* ("NI"), *incompressible interactions* ("IC") or *quasi-acoustic interactions* ("QA"), with each interaction model having its own repository for gathering data. The [run_sphericalclustertensionwave.sh](run_sphericalclustertensionwave.sh) file provides the whole execution command to run all computations, plot the results and clean the folders. +This example builds a standalone APECSS code for a monodispersed cluster of 250 interacting microbubbles. The cluster has a spherical shape with radius $R_{\mathrm{C}} = 232 \ \mu\mathrm{m}$, with the bubbles randomly distributed inside. The bubbles initial radius is $R_{0} = 2 \mu\mathrm{m}$. The incident wave is a single tension pulse defined by $p_{\mathrm{a}}(t) = -(p_{0} - p_{\mathrm{ng}})\sin^{2}\left(\pi t / \tau \right)$, with $\tau = 1.75 \ \mu\mathrm{s}$ and $p_{\mathrm{ng}} = -3.0 \times 10^{4} \ \mathrm{Pa}$. The computations are done with several interaction models : *no interactions* ("NI"), *incompressible interactions* ("IC") or *quasi-acoustic interactions* ("QA"). Each interaction model has its own repository for gathering data. The [run_sphericalclustertensionwave.sh](run_sphericalclustertensionwave.sh) file provides the whole execution command to run all computations, plot the results and clean the folders. The quasi-acoustic model computation is done using parallelization, and takes around **30 minutes** to finish when running on 12 cores of an Intel 13th-Gen i7-13700K x 24 processor. The number of cores used can be changed in the header section of [run_sphericalclustertensionwave.sh](run_sphericalclustertensionwave.sh). \ No newline at end of file From 3a4cbc618de76e64bcac2f667e8a861b475d1fa5 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 23 Sep 2024 13:58:52 -0400 Subject: [PATCH 133/138] run_all ; adding the command lines to run the two new test cases imvolving interactions --- examples/run_all.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/run_all.sh b/examples/run_all.sh index 53aee26..7b5f1da 100755 --- a/examples/run_all.sh +++ b/examples/run_all.sh @@ -15,6 +15,7 @@ cd .. ./build/binaryinteraction_apecss -options run.apecss -freq 15.7e3 -amp -120e3 -tend 7.5e-4 python3 plot_result.py rm -r Bubble_0 Bubble_1 +./cavitationonset/run_cavitationonset.sh cd ../gastemperature/build ./compile.sh cd .. @@ -64,3 +65,4 @@ rm Gilmore_R1.000e-06_fa1.000e+06_pa1.000e+06.txt python3 plot_result_oldroydb.py rm RP_R1.000e-06_fa3.000e+06_pa4.000e+05.txt cd ../ +./sphericalclustertensionwave/run_sphericalclustertensionwave.sh From 23fbe550e3cb8b1bdc823d9a6835884bd2a19571 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 23 Sep 2024 15:49:01 -0400 Subject: [PATCH 134/138] run_all ; removing spherical cluster interactions test case due to its computation time --- examples/run_all.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/run_all.sh b/examples/run_all.sh index 7b5f1da..8d03f6b 100755 --- a/examples/run_all.sh +++ b/examples/run_all.sh @@ -65,4 +65,3 @@ rm Gilmore_R1.000e-06_fa1.000e+06_pa1.000e+06.txt python3 plot_result_oldroydb.py rm RP_R1.000e-06_fa3.000e+06_pa4.000e+05.txt cd ../ -./sphericalclustertensionwave/run_sphericalclustertensionwave.sh From fa33d61145da0db34ef06e2541d00adf0d389fd3 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 23 Sep 2024 15:55:31 -0400 Subject: [PATCH 135/138] run_all ; correct way to launch cavitationonset test case --- examples/run_all.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/run_all.sh b/examples/run_all.sh index 8d03f6b..94f0fa9 100755 --- a/examples/run_all.sh +++ b/examples/run_all.sh @@ -15,7 +15,8 @@ cd .. ./build/binaryinteraction_apecss -options run.apecss -freq 15.7e3 -amp -120e3 -tend 7.5e-4 python3 plot_result.py rm -r Bubble_0 Bubble_1 -./cavitationonset/run_cavitationonset.sh +cd ../cavitationonset +./run_cavitationonset.sh cd ../gastemperature/build ./compile.sh cd .. From 22922ff1d0a878afcee1f819ead23b64a3869e34 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Mon, 23 Sep 2024 16:05:50 -0400 Subject: [PATCH 136/138] binaryinteraction ; removal of unncessary comments and approximate computation of pressure derivative infinity, because it's an incompressible computation --- .../src/binaryinteraction_apecss.c | 33 +------------------ 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/examples/binaryinteraction/src/binaryinteraction_apecss.c b/examples/binaryinteraction/src/binaryinteraction_apecss.c index 074c9b0..c4c91a3 100644 --- a/examples/binaryinteraction/src/binaryinteraction_apecss.c +++ b/examples/binaryinteraction/src/binaryinteraction_apecss.c @@ -96,18 +96,6 @@ int main(int argc, char **args) for (register int i = 0; i < nBubbles; i++) apecss_bubble_setdefaultoptions(Bubbles[i]); for (register int i = 0; i < nBubbles; i++) apecss_bubble_readoptions(Bubbles[i], OptionsDir); - // // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // // Allocate and set bubble-associated variables for the interaction - // for (register int i = 0; i < nBubbles; i++) - // { - // struct Interaction *interaction_data = (struct Interaction *) malloc(sizeof(struct Interaction)); - // interaction_data->dp_neighbor = 0.0; // Pressure excerted by the neighbor bubbles - - // // Hook interaction-structure to the void data pointer - // Bubbles[i]->user_data = interaction_data; - // } - // // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - /* Allocate the structures for the fluid properties and ODE solver parameters */ struct APECSS_Gas *Gas = (struct APECSS_Gas *) malloc(sizeof(struct APECSS_Gas)); struct APECSS_Liquid *Liquid = (struct APECSS_Liquid *) malloc(sizeof(struct APECSS_Liquid)); @@ -234,21 +222,10 @@ int main(int argc, char **args) for (register int i = 0; i < nBubbles; i++) apecss_bubble_solver_run(tSim, Bubbles[i]); - // for (register int i = 0; i < nBubbles; i++) Bubbles[i]->Interaction->dp_neighbor = 0.0; - // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // Update the contribution of the neighbor bubble apecss_interactions_instantaneous(Bubbles); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - for (register int i = 0; i < nBubbles; i++) - { - Bubbles[i]->Interaction->last_t_2 = Bubbles[i]->Interaction->last_t_1; - Bubbles[i]->Interaction->last_p_2 = Bubbles[i]->Interaction->last_p_1; - - Bubbles[i]->Interaction->last_t_1 = tSim; - Bubbles[i]->Interaction->last_p_1 = Bubbles[i]->Interaction->dp_neighbor; - } } /* Finalize the simulation*/ @@ -286,14 +263,6 @@ APECSS_FLOAT interaction_bubble_pressure_infinity(APECSS_FLOAT t, struct APECSS_ APECSS_FLOAT interaction_bubble_pressurederivative_infinity(APECSS_FLOAT t, struct APECSS_Bubble *Bubble) { // Approximate numerical computation of p_infinity derivative - APECSS_FLOAT delta_t = Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2; APECSS_FLOAT derivative = -Bubble->Excitation->dp * 2.0 * APECSS_PI * Bubble->Excitation->f * APECSS_COS(2.0 * APECSS_PI * Bubble->Excitation->f * t); - if (delta_t > Bubble->dt) - { - return (derivative + ((Bubble->Interaction->last_p_1 - Bubble->Interaction->last_p_2) / (Bubble->Interaction->last_t_1 - Bubble->Interaction->last_t_2))); - } - else - { - return (derivative); - } + return (derivative); } \ No newline at end of file From 91033404eff00f6b4faded4946cc903343ec441f Mon Sep 17 00:00:00 2001 From: Pierre C Date: Wed, 25 Sep 2024 16:38:55 -0400 Subject: [PATCH 137/138] emissions ; removing deletenode function and restoring the initial pruning function + adding update in nNodes number when using pruning --- include/apecss.h | 1 - src/emissions.c | 90 +++++++++--------------------------------------- 2 files changed, 17 insertions(+), 74 deletions(-) diff --git a/include/apecss.h b/include/apecss.h index f4c55ec..d702fd0 100644 --- a/include/apecss.h +++ b/include/apecss.h @@ -535,7 +535,6 @@ int apecss_emissions_addnode(struct APECSS_Bubble *Bubble); int apecss_emissions_prunelist(struct APECSS_Bubble *Bubble); int apecss_emissions_prune_no_node(struct APECSS_EmissionNode *Node); int apecss_emissions_removenode(struct APECSS_Bubble *Bubble); -int apecss_emissions_deletenode(struct APECSS_Bubble *Bubble, struct APECSS_EmissionNode *Node); int apecss_emissions_advance_finitespeedincompressible(struct APECSS_Bubble *Bubble); int apecss_emissions_advance_quasiacoustic(struct APECSS_Bubble *Bubble); int apecss_emissions_advance_kirkwoodbethe_tait(struct APECSS_Bubble *Bubble); diff --git a/src/emissions.c b/src/emissions.c index e91b9ca..1ded191 100644 --- a/src/emissions.c +++ b/src/emissions.c @@ -135,40 +135,25 @@ int apecss_emissions_addnode(struct APECSS_Bubble *Bubble) int apecss_emissions_prunelist(struct APECSS_Bubble *Bubble) { - // if (Bubble->Emissions->nNodes > 2) // The list needs to consist of at least 3 nodes. - // { - // struct APECSS_EmissionNode *Current = Bubble->Emissions->LastNode->backward; - - // while (Current->backward != NULL) - // { - // if (Bubble->Emissions->prune_test(Current)) - // { - // struct APECSS_EmissionNode *Obsolete = Current; - // Current->backward->forward = Current->forward; - // Current->forward->backward = Current->backward; - // Current = Current->backward; - // free(Obsolete); - // } - // else - // { - // Current = Current->backward; // Move to the next node - // } - // } - // } - - struct APECSS_EmissionNode *Current = Bubble->Emissions->LastNode; - - while (Current != NULL) + if (Bubble->Emissions->nNodes > 2) // The list needs to consist of at least 3 nodes. { - if (Bubble->Emissions->prune_test(Current)) - { - // Delete the node if it satisfies the pruning condition - apecss_emissions_deletenode(Bubble, Current); - } - else + struct APECSS_EmissionNode *Current = Bubble->Emissions->LastNode->backward; + + while (Current->backward != NULL) { - // Move to the next node - Current = Current->backward; + if (Bubble->Emissions->prune_test(Current)) + { + struct APECSS_EmissionNode *Obsolete = Current; + Current->backward->forward = Current->forward; + Current->forward->backward = Current->backward; + Current = Current->backward; + Bubble->Emissions->nNodes -= 1; + free(Obsolete); + } + else + { + Current = Current->backward; // Move to the next node + } } } @@ -203,47 +188,6 @@ int apecss_emissions_removenode(struct APECSS_Bubble *Bubble) return (0); } -int apecss_emissions_deletenode(struct APECSS_Bubble *Bubble, struct APECSS_EmissionNode *Node) -{ - struct APECSS_EmissionNode *Obsolete = Node; - - if ((Node->backward != NULL) && (Node->forward != NULL)) - { - // The node has two neighbors - Node->backward->forward = Node->forward; - Node->forward->backward = Node->backward; - Node = Node->backward; - Bubble->Emissions->nNodes -= 1; - } - else if ((Node->backward != NULL) && (Node->forward == NULL)) - { - // The node is LastNode - Node->backward->forward = NULL; - Bubble->Emissions->LastNode = Node->backward; - Node = Node->backward; - Bubble->Emissions->nNodes -= 1; - } - else if ((Node->backward == NULL) && (Node->forward != NULL)) - { - // The node is FirstNode - Node->forward->backward = NULL; - Bubble->Emissions->FirstNode = Node->forward; - Node = NULL; - Bubble->Emissions->nNodes -= 1; - } - else - { - // There is only one node in the list - Bubble->Emissions->FirstNode = NULL; - Bubble->Emissions->LastNode = NULL; - Bubble->Emissions->nNodes = 0; - Node = NULL; - } - free(Obsolete); - - return (0); -} - // ------------------------------------------------------------------- // ADVANCE EMISSION NODES // ------------------------------------------------------------------- From d885999eeaa5dc7ac3d240c73edec503b14063f7 Mon Sep 17 00:00:00 2001 From: Pierre C Date: Wed, 25 Sep 2024 16:44:53 -0400 Subject: [PATCH 138/138] gitignore ; update by excluding .txt and .pdf files normally included in the base repo of APECSS (to ensure they're effectively taken into account and stored) --- .gitignore | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.gitignore b/.gitignore index 0d119a2..1b55076 100644 --- a/.gitignore +++ b/.gitignore @@ -83,5 +83,13 @@ Makefile # Results *.txt !CMakeLists.txt +!LICENSE.txt *.pdf +!APECSS_Documentation.pdf +!JOSS-Paper.pdf +!apecssbubble.pdf +!emissions_results.pdf +!LagrangianWaveTracking_withShock.pdf +!LagrangianWaveTracking.pdf +!ultrasound_lipdcoated_simple.pdf *.png \ No newline at end of file