.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples/00-fluent/DOE_ML.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end <sphx_glr_download_examples_00-fluent_DOE_ML.py>` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_examples_00-fluent_DOE_ML.py: .. _doe_ml: Design of Experiments and Machine Learning model building --------------------------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 30-45 Objective ===================================================================================== Water enters a Mixing Elbow from two Inlets; Hot (313 K) and Cold (293 K) and exits from Outlet. Using PyFluent in the background, this example runs Design of Experiments with Cold Inlet Velocity and Hot Inlet Velocity as Input Parameters and Outlet Temperature as an Output Parameter. Results can be visualized using a Response Surface. Finally, Supervised Machine Learning Regression Task is performed to build the ML Model. This example demonstrates: * Design of Experiment, Fluent setup and simulation using PyFluent. * Building of Supervised Machine Learning Model. .. GENERATED FROM PYTHON SOURCE LINES 47-49 Import required libraries/modules ================================= .. GENERATED FROM PYTHON SOURCE LINES 49-66 .. code-block:: Python # flake8: noqa: E402 from pathlib import Path import matplotlib.pyplot as plt import numpy as np import pandas as pd import plotly.express as px import plotly.graph_objects as go import seaborn as sns import tensorflow as tf from tensorflow import keras import ansys.fluent.core as pyfluent from ansys.fluent.core import examples .. GENERATED FROM PYTHON SOURCE LINES 67-72 Specifying save path ==================== * save_path can be specified as Path("E:/", "pyfluent-examples-tests") or * Path("E:/pyfluent-examples-tests") in a Windows machine for example, or * Path("~/pyfluent-examples-tests") in Linux. .. GENERATED FROM PYTHON SOURCE LINES 72-81 .. code-block:: Python save_path = Path(pyfluent.EXAMPLES_PATH) import_filename = examples.download_file( "elbow.cas.h5", "pyfluent/examples/DOE-ML-Mixing-Elbow", save_path=save_path, ) .. GENERATED FROM PYTHON SOURCE LINES 82-84 Fluent Solution Setup ===================== .. GENERATED FROM PYTHON SOURCE LINES 86-88 Launch Fluent session with solver mode and print Fluent version =============================================================== .. GENERATED FROM PYTHON SOURCE LINES 88-97 .. code-block:: Python solver = pyfluent.launch_fluent( precision="double", processor_count=2, version="3d", ) print(solver.get_fluent_version()) .. GENERATED FROM PYTHON SOURCE LINES 98-100 Read case ========= .. GENERATED FROM PYTHON SOURCE LINES 100-103 .. code-block:: Python solver.settings.file.read_case(file_name=import_filename) .. GENERATED FROM PYTHON SOURCE LINES 104-109 Design of Experiments ===================== * Define Manual DOE as numpy arrays * Run cases in sequence * Populate results (Mass Weighted Average of Temperature at Outlet) in resArr .. GENERATED FROM PYTHON SOURCE LINES 109-140 .. code-block:: Python coldVelArr = np.array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7]) hotVelArr = np.array([0.8, 1, 1.2, 1.4, 1.6, 1.8, 2.0]) resArr = np.zeros((coldVelArr.shape[0], hotVelArr.shape[0])) for idx1, coldVel in np.ndenumerate(coldVelArr): for idx2, hotVel in np.ndenumerate(hotVelArr): cold_inlet = solver.settings.setup.boundary_conditions.velocity_inlet[ "cold-inlet" ] cold_inlet.momentum.velocity.value = coldVel hot_inlet = solver.settings.setup.boundary_conditions.velocity_inlet[ "hot-inlet" ] hot_inlet.momentum.velocity.value = hotVel solver.settings.solution.initialization.initialization_type = "standard" solver.settings.solution.initialization.standard_initialize() solver.settings.solution.run_calculation.iterate(iter_count=200) res_tui = solver.scheme_eval.exec( ( "(ti-menu-load-string " '"/report/surface-integrals/mass-weighted-avg outlet () ' 'temperature no")', ) ) resArr[idx1][idx2] = eval(res_tui.split(" ")[-1]) .. GENERATED FROM PYTHON SOURCE LINES 141-143 Close the session ================= .. GENERATED FROM PYTHON SOURCE LINES 143-146 .. code-block:: Python solver.exit() .. GENERATED FROM PYTHON SOURCE LINES 147-149 Plot Response Surface using Plotly ================================== .. GENERATED FROM PYTHON SOURCE LINES 149-175 .. code-block:: Python fig = go.Figure(data=[go.Surface(z=resArr.T, x=coldVelArr, y=hotVelArr)]) fig.update_layout( title={ "text": "Mixing Elbow Response Surface", "y": 0.9, "x": 0.5, "xanchor": "center", "yanchor": "top", } ) fig.update_layout( scene=dict( xaxis_title="Cold Inlet Vel (m/s)", yaxis_title="Hot Inlet Vel (m/s)", zaxis_title="Outlet Temperature (K)", ), width=600, height=600, margin=dict(l=80, r=80, b=80, t=80), ) fig.show() .. GENERATED FROM PYTHON SOURCE LINES 176-178 Supervised ML for a Regression Task =================================== .. GENERATED FROM PYTHON SOURCE LINES 180-182 Create Pandas Dataframe for ML Model Input ========================================== .. GENERATED FROM PYTHON SOURCE LINES 182-201 .. code-block:: Python coldVelList = [] hotVelList = [] ResultList = [] for idx1, coldVel in np.ndenumerate(coldVelArr): for idx2, hotVel in np.ndenumerate(hotVelArr): coldVelList.append(coldVel) hotVelList.append(hotVel) ResultList.append(resArr[idx1][idx2]) tempDict = {"coldVel": coldVelList, "hotVel": hotVelList, "Result": ResultList} df = pd.DataFrame.from_dict(tempDict) from sklearn.compose import ColumnTransformer from sklearn.model_selection import train_test_split from sklearn.pipeline import Pipeline from sklearn.preprocessing import PolynomialFeatures, StandardScaler .. GENERATED FROM PYTHON SOURCE LINES 202-207 Using scikit-learn ================== * Prepare Features (X) and Label (y) using a Pre-Processing Pipeline * Train-Test (80-20) Split * Add Polynomial Features to improve ML Model .. GENERATED FROM PYTHON SOURCE LINES 207-236 .. code-block:: Python poly_features = PolynomialFeatures(degree=2, include_bias=False) transformer1 = Pipeline( [ ("poly_features", poly_features), ("std_scaler", StandardScaler()), ] ) x_ct = ColumnTransformer( [ ("transformer1", transformer1, ["coldVel", "hotVel"]), ], remainder="drop", ) train_set, test_set = train_test_split(df, test_size=0.2, random_state=42) X_train = x_ct.fit_transform(train_set) X_test = x_ct.fit_transform(test_set) y_train = train_set["Result"] y_test = test_set["Result"] y_train = np.ravel(y_train.T) y_test = np.ravel(y_test.T) .. GENERATED FROM PYTHON SOURCE LINES 237-242 * Define functions for: * Cross-Validation and Display Scores (scikit-learn) * Training the Model (scikit-learn) * Prediction on Unseen/Test Data (scikit-learn) * Parity Plot (Matplotlib and Seaborn) .. GENERATED FROM PYTHON SOURCE LINES 242-321 .. code-block:: Python # from pprint import pprint # from sklearn.ensemble import RandomForestRegressor # from sklearn.linear_model import LinearRegression from sklearn.metrics import r2_score from sklearn.model_selection import RepeatedKFold, cross_val_score from xgboost import XGBRegressor np.set_printoptions(precision=2) def display_scores(scores): """Display scores.""" print("\nCross-Validation Scores:", scores) print("Mean:%0.2f" % (scores.mean())) print("Std. Dev.:%0.2f" % (scores.std())) def fit_and_predict(model): """Fit abd predict.""" cv = RepeatedKFold(n_splits=5, n_repeats=3, random_state=42) cv_scores = cross_val_score( model, X_train, y_train, scoring="neg_mean_squared_error", cv=cv ) rmse_scores = np.sqrt(-cv_scores) display_scores(rmse_scores) model.fit(X_train, y_train) train_predictions = model.predict(X_train) test_predictions = model.predict(X_test) print(train_predictions.shape[0]) print("\n\nCoefficient Of Determination") print("Train Data R2 Score: %0.3f" % (r2_score(train_predictions, y_train))) print("Test Data R2 Score: %0.3f" % (r2_score(test_predictions, y_test))) print( "\n\nPredictions - Ground Truth (Kelvin): ", (test_predictions - y_test), "\n" ) # print("\n\nModel Parameters:") # pprint(model.get_params()) com_train_set = train_set com_test_set = test_set train_list = [] for i in range(train_predictions.shape[0]): train_list.append("Train") test_list = [] for i in range(test_predictions.shape[0]): test_list.append("Test") com_train_set["Result"] = train_predictions.tolist() com_train_set["Set"] = train_list com_test_set["Result"] = test_predictions.tolist() com_test_set["Set"] = test_list df_combined = pd.concat([com_train_set, com_test_set]) df_combined.to_csv("PyFluent_Output.csv", header=True, index=False) fig = plt.figure(figsize=(12, 5)) fig.add_subplot(121) sns.regplot(x=y_train, y=train_predictions, color="g") plt.title("Train Data", fontsize=16) plt.xlabel("Ground Truth", fontsize=12) plt.ylabel("Predictions", fontsize=12) fig.add_subplot(122) sns.regplot(x=y_test, y=test_predictions, color="g") plt.title("Unseen Data", fontsize=16) plt.xlabel("Ground Truth", fontsize=12) plt.ylabel("Predictions", fontsize=12) plt.tight_layout() plt.show() .. GENERATED FROM PYTHON SOURCE LINES 322-325 Select the Model from Linear, Random Forest or XGBoost ====================================================== * Call fit_and_predict .. GENERATED FROM PYTHON SOURCE LINES 325-334 .. code-block:: Python # model = LinearRegression() model = XGBRegressor( n_estimators=100, max_depth=10, eta=0.3, subsample=0.8, random_state=42 ) # model = RandomForestRegressor(random_state=42) fit_and_predict(model) .. GENERATED FROM PYTHON SOURCE LINES 335-337 Show graph ========== .. GENERATED FROM PYTHON SOURCE LINES 337-340 .. code-block:: Python plt.show() .. GENERATED FROM PYTHON SOURCE LINES 341-344 .. image:: ../../_static/doe_ml_predictions_regression.png :align: center :alt: Regression Model Predictions .. GENERATED FROM PYTHON SOURCE LINES 346-347 Regression Model Predictions .. GENERATED FROM PYTHON SOURCE LINES 349-351 3D Visualization of Model Predictions on Train & Test Set ========================================================= .. GENERATED FROM PYTHON SOURCE LINES 351-383 .. code-block:: Python df = pd.read_csv("PyFluent_Output.csv") fig = px.scatter_3d(df, x="coldVel", y="hotVel", z="Result", color="Set") fig.update_traces(marker=dict(size=4)) fig.update_layout(legend=dict(yanchor="top", y=1, xanchor="left", x=0.0)) fig.add_traces(go.Surface(z=resArr.T, x=coldVelArr, y=hotVelArr)) fig.update_layout( title={ "text": "Mixing Elbow Response Surface", "y": 0.9, "x": 0.5, "xanchor": "center", "yanchor": "top", } ) fig.update_layout( scene=dict( xaxis_title="Cold Inlet Vel (m/s)", yaxis_title="Hot Inlet Vel (m/s)", zaxis_title="Outlet Temperature (K)", ), width=500, height=500, margin=dict(l=80, r=80, b=80, t=80), ) fig.show() .. GENERATED FROM PYTHON SOURCE LINES 384-386 TensorFlow and Keras Neural Network Regression ============================================== .. GENERATED FROM PYTHON SOURCE LINES 386-465 .. code-block:: Python print("TensorFlow version is:", tf.__version__) keras.backend.clear_session() np.random.seed(42) tf.random.set_seed(42) model = keras.models.Sequential( [ keras.layers.Dense( 20, activation="relu", input_shape=X_train.shape[1:], kernel_initializer="lecun_normal", ), keras.layers.BatchNormalization(), keras.layers.Dense(20, activation="relu", kernel_initializer="lecun_normal"), keras.layers.BatchNormalization(), keras.layers.Dense(20, activation="relu", kernel_initializer="lecun_normal"), keras.layers.BatchNormalization(), keras.layers.Dense(1), ] ) optimizer = tf.keras.optimizers.Adam(learning_rate=0.1, beta_1=0.9, beta_2=0.999) model.compile(loss="mean_squared_error", optimizer=optimizer) checkpoint_cb = keras.callbacks.ModelCheckpoint( "my_keras_model.h5", save_best_only=True ) early_stopping_cb = keras.callbacks.EarlyStopping( patience=30, restore_best_weights=True ) model.summary() # keras.utils.plot_model(model, show_shapes=True,) # to_file='dot_img.png', ) history = model.fit( X_train, y_train, epochs=250, validation_split=0.2, callbacks=[checkpoint_cb, early_stopping_cb], ) model = keras.models.load_model("my_keras_model.h5") print(history.params) pd.DataFrame(history.history).plot(figsize=(8, 5)) plt.grid(True) plt.show() train_predictions = model.predict(X_train) test_predictions = model.predict(X_test) train_predictions = np.ravel(train_predictions.T) test_predictions = np.ravel(test_predictions.T) print(test_predictions.shape) print("\n\nTrain R2: %0.3f" % (r2_score(train_predictions, y_train))) print("Test R2: %0.3f" % (r2_score(test_predictions, y_test))) print("Predictions - Ground Truth (Kelvin): ", (test_predictions - y_test)) fig = plt.figure(figsize=(12, 5)) fig.add_subplot(121) sns.regplot(x=y_train, y=train_predictions, color="g") plt.title("Train Data", fontsize=16) plt.xlabel("Ground Truth", fontsize=12) plt.ylabel("Predictions", fontsize=12) fig.add_subplot(122) sns.regplot(x=y_test, y=test_predictions, color="g") plt.title("Test/Unseen Data", fontsize=16) plt.xlabel("Ground Truth", fontsize=12) plt.ylabel("Predictions", fontsize=12) plt.tight_layout() .. GENERATED FROM PYTHON SOURCE LINES 466-468 Show graph ========== .. GENERATED FROM PYTHON SOURCE LINES 468-471 .. code-block:: Python plt.show() .. GENERATED FROM PYTHON SOURCE LINES 472-475 .. image:: ../../_static/doe_ml_validation_loss.png :align: center :alt: Neural Network Validation Loss .. GENERATED FROM PYTHON SOURCE LINES 477-478 Neural Network Validation Loss .. GENERATED FROM PYTHON SOURCE LINES 480-483 .. image:: ../../_static/doe_ml_predictions_neural_network.png :align: center :alt: Neural Network Predictions .. GENERATED FROM PYTHON SOURCE LINES 485-486 Neural Network Predictions .. _sphx_glr_download_examples_00-fluent_DOE_ML.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: DOE_ML.ipynb <DOE_ML.ipynb>` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: DOE_ML.py <DOE_ML.py>` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: DOE_ML.zip <DOE_ML.zip>` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_