2D case - Error pretrained#

Two-parameter 2D problem - Relative error with regard to the FEM solution

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)

Load the config file#

    Configuration_file = 'Configurations/config_2D_ROM.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
                )

MaxElemSize2D = config["interpolation"]["MaxElemSize2D"] = 0.125
# 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()

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"]
                    )

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)         

ROM_model.load_state_dict(torch.load('Pretrained_models/2D_ROM', weights_only=False))

Error computed at the nodes#

Compute the error of the displacement with regard to the reference solution. Error evaluated at the nodes

eval_coord_file = "GroundTruth/nodal_coordinates.npy"

E_vect = [0.0038, 0.0038, 0.00314, 0.00409, 0.00409, 0.00462, 0.00501, 0.00675]
theta_vect = [1.57, 4.21, 0, 3.7, 3.13, 0.82, 2.26, 5.45]
error_vect = []
for i in range(len(E_vect)):

    num_displ_file = "GroundTruth/nodal_num_displacement_E="+str(E_vect[i])+"_theta="+str(theta_vect[i])+".npy"


    eval_coord =  torch.tensor(np.load(eval_coord_file), dtype=torch.float64, requires_grad=True)
    num_displ = torch.tensor(np.load(num_displ_file))

    theta = torch.tensor([theta_vect[i]],dtype=torch.float64)
    theta = theta[:,None] 

    E = torch.tensor([E_vect[i]],dtype=torch.float64)
    E = E[:,None] 


    Para_coord_list = nn.ParameterList((E,theta))
    ROM_model.eval()                                                        # Put model in evaluation mode
    u_sol = ROM_model(eval_coord,Para_coord_list)                           # Evaluate model

    u_sol_x = u_sol[0,:,0,0]
    u_sol_y = u_sol[1,:,0,0]

    u_ref_x = num_displ[:,0]
    u_ref_y = num_displ[:,1]

    u_ref_tot = torch.hstack((u_ref_x,u_ref_y))
    u_sol_tot = torch.hstack((u_sol_x,u_sol_y))

    error_u_tot = (torch.linalg.vector_norm(u_sol_tot - u_ref_tot)/torch.linalg.vector_norm(u_ref_tot)).item()
    error_vect.append(error_u_tot)
error_vect
[0.0011179374774135927,
 0.0008721099977561525,
 0.0014990741132987406,
 0.008614060035762679,
 0.00931683192143615,
 0.0027197109293198856,
 0.005349891791602745,
 0.0012339046413615078]