2D case - Interactive plot#

Two-parameter 2D problem - Interactive widget with sliders

Libraries import#

import sys  
import torch
import torch.nn as nn
from neurom.HiDeNN_PDE import MeshNN, NeuROM, MeshNN_2D, MeshNN_1D
import neurom.src.Pre_processing as pre
from neurom.src.PDE_Library import Strain, Stress,VonMises_plain_strain
from neurom.src.Training import Training_NeuROM_multi_level
import neurom.Post.Plots as Pplot
import time
import os
import torch._dynamo as dynamo
from importlib import reload  
import tomllib
import numpy as np
import argparse

torch.manual_seed(0)
<torch._C.Generator at 0x1238e1610>

Load the config file#

    Configuration_file = 'Configurations/config_2D_ROM_interactive.toml'

    with open(Configuration_file, mode="rb") as file:
        config = tomllib.load(file)

Definition of the space domain and mechanical proprieties of the structure#

The initial Material parameters, the geometry, mesh and the boundary conditions are set.

# Material parameters definition

Mat = pre.Material(             flag_lame = False,                                  # If True should input lmbda and mu instead of E and nu
                                coef1     = config["material"]["E"],                # Young Modulus
                                coef2     = config["material"]["nu"]                # Poisson's ratio
                )


# Create mesh object
MaxElemSize = pre.ElementSize(
                                dimension     = config["interpolation"]["dimension"],
                                L             = config["geometry"]["L"],
                                order         = config["interpolation"]["order"],
                                np            = config["interpolation"]["np"],
                                MaxElemSize2D = config["interpolation"]["MaxElemSize2D"]
                            )
Excluded = []
Mesh_object = pre.Mesh( 
                                config["geometry"]["Name"],                         # Create the mesh object
                                MaxElemSize, 
                                config["interpolation"]["order"], 
                                config["interpolation"]["dimension"]
                        )

Mesh_object.AddBorders(config["Borders"]["Borders"])
Mesh_object.AddBCs(                                                                 # Include Boundary physical domains infos (BCs+volume)
                                config["geometry"]["Volume_element"],
                                Excluded,
                                config["DirichletDictionryList"]
                    )                   

Mesh_object.MeshGeo()                                                               # Mesh the .geo file if .msh does not exist
Mesh_object.ReadMesh()       
Mesh_object.ExportMeshVtk()
 
 
   _   _            ____   ___  __  __ 
  | \ | | ___ _   _|  _ \ / _ \|  \/  |
  |  \| |/ _ \ | | | |_) | | | | |\/| |
  | |\  |  __/ |_| |  _ <| |_| | |  | |
  |_| \_|\___|\__,_|_| \_\ ___/|_|  |_|

                  unknown version

************ MESH READING COMPLETE ************

 * Dimension of the problem: 2D
 * Elements type:            t3: 3-node triangle
 * Number of Dofs:           224
fatal: No names found, cannot describe anything.

Parametric study definition#

The hypercube describing the parametric domain used for the tensor decomposition is set-up here

ParameterHypercube = torch.tensor([ [   config["parameters"]["para_1_min"],
                                        config["parameters"]["para_1_max"],
                                        config["parameters"]["N_para_1"]],
                                    [   config["parameters"]["para_2_min"],
                                        config["parameters"]["para_2_max"],
                                        config["parameters"]["N_para_2"]]])

Initialisation of the surrogate model#

ROM_model = NeuROM(                                                                 # Build the surrogate (reduced-order) model
                    Mesh_object, 
                    ParameterHypercube, 
                    config,
                    config["solver"]["n_modes_ini"],
                    config["solver"]["n_modes_max"]
                    )

Plot initial parametric nodal values#

ROM_model.Para_modes[0][0].InterpoLayer.weight
Parameter containing:
tensor([[ 0.0359,  0.1644, -0.1118, -0.2690,  0.0633, -0.0255,  0.1551,  0.2669,
          0.2174,  0.1172]], requires_grad=True)

Training the model#

ROM_model.Freeze_Mesh()                                                             # Set space mesh coordinates as untrainable
ROM_model.Freeze_MeshPara()                                                         # Set parameters mesh coordinates as untrainable

ROM_model.TrainingParameters(   
                                loss_decrease_c = config["training"]["loss_decrease_c"], 
                                Max_epochs = config["training"]["n_epochs"], 
                                learning_rate = config["training"]["learning_rate"]
                            )

ROM_model.train()                                                                   # Put the model in training mode
ROM_model, Mesh_object = Training_NeuROM_multi_level(ROM_model,config, Mat)         
* Refinement level: 0

**************** START TRAINING ***************
epoch 100 loss = -3.27861e-04 modes = 1
epoch 200 loss = -1.25096e-03 modes = 1
epoch 300 loss = -2.29776e-03 modes = 1
epoch 400 loss = -3.44243e-03 modes = 1
epoch 500 loss = -4.01850e-03 modes = 1
epoch 600 loss = -4.17413e-03 modes = 1
epoch 700 loss = -4.20585e-03 modes = 1
epoch 800 loss = -4.23706e-03 modes = 2
epoch 900 loss = -4.78608e-03 modes = 2
epoch 1000 loss = -5.07869e-03 modes = 2
epoch 1100 loss = -5.22825e-03 modes = 2
epoch 1200 loss = -5.33641e-03 modes = 2
epoch 1300 loss = -5.37339e-03 modes = 2
*************** END FIRST PHASE ***************

* Training time: 5.019593000411987s
* Saving time: 7.152557373046875e-07s
* Evaluation time: 2.730597734451294s
* Backward time: 2.04931902885437s
* Update time: 0.1777338981628418s
* Average epoch time: 0.003751564275345282s
************** START SECOND PAHSE *************

epoch 5 loss = -5.377e-03
*************** END OF TRAINING ***************

* Training time: 5.286859035491943s

************ MESH READING COMPLETE ************

 * Dimension of the problem: 2D
 * Elements type:            t3: 3-node triangle
 * Number of Dofs:           434

* Refinement level: 1

**************** START TRAINING ***************

epoch 100 loss = -5.71027e-03 modes = 2
*************** END FIRST PHASE ***************

* Training time: 6.105348110198975s
* Saving time: 0s
* Evaluation time: 0.4201951026916504s
* Backward time: 0.3636465072631836s
* Update time: 0.025295495986938477s
* Average epoch time: 0.00597437280808052s
************** START SECOND PAHSE *************

epoch 5 loss = -5.7137e-03
*************** END OF TRAINING ***************

* Training time: 6.436589241027832s

************ MESH READING COMPLETE ************

 * Dimension of the problem: 2D
 * Elements type:            t3: 3-node triangle
 * Number of Dofs:           1194

* Refinement level: 2

**************** START TRAINING ***************

*************** END FIRST PHASE ***************

* Training time: 7.43602728843689s
* Saving time: 0s
* Evaluation time: 0.4173312187194824s
* Backward time: 0.5454256534576416s
* Update time: 0.026410341262817383s
* Average epoch time: 0.010746645671065135s
************** START SECOND PAHSE *************

epoch 5 loss = -5.9394e-03
*************** END OF TRAINING ***************

* Training time: 7.599175453186035s

************ MESH READING COMPLETE ************

 * Dimension of the problem: 2D
 * Elements type:            t3: 3-node triangle
 * Number of Dofs:           4038

* Refinement level: 3

**************** START TRAINING ***************

*************** END FIRST PHASE ***************

* Training time: 9.333802461624146s
* Saving time: 0s
* Evaluation time: 0.6638827323913574s
* Backward time: 1.0338337421417236s
* Update time: 0.026207923889160156s
* Average epoch time: 0.02168283760547638s
************** START SECOND PAHSE *************

epoch 5 loss = -6.0577e-03
*************** END OF TRAINING ***************

* Training time: 9.775207281112671s

************ MESH READING COMPLETE ************

 * Dimension of the problem: 2D
 * Elements type:            t3: 3-node triangle
 * Number of Dofs:           14230

* Refinement level: 4

**************** START TRAINING ***************

*************** END FIRST PHASE ***************

* Training time: 15.05105209350586s
* Saving time: 0s
* Evaluation time: 1.7289412021636963s
* Backward time: 3.502650260925293s
* Update time: 0.033141136169433594s
* Average epoch time: 0.06356439533003841s
************** START SECOND PAHSE *************

epoch 5 loss = -6.1054e-03
epoch 10 loss = -6.1054e-03
*************** END OF TRAINING ***************

* Training time: 27.139592170715332s

Plotting area#

Reproducing figure 15

tikz = False

import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator
import pyvista as pv
pv.start_xvfb()
Pplot.Plot_2D_PyVista(ROM_model, 
                Mesh_object, 
                config, 
                E = config["postprocess"]["Default_E"], 
                theta = config["postprocess"]["Default_theta"], 
                scalar_field_name = config["postprocess"]["scalar_field_name"], 
                scaling_factor = config["postprocess"]["scaling_factor"], 
                Interactive_parameter = config["postprocess"]["Interactive_parameter"],
                Plot_mesh = config["postprocess"]["Plot_mesh"],
                color_map = config["postprocess"]["colormap"])
************** Available commands *************

* Take a screenshot : s

* Reset the camera  : r