Greedy training tutorial#
In this tutorial you will learn the basics of contructing a greedy training workflow using romtools
https://pressio.github.io/rom-tools-and-workflows/romtools/workflows/greedy/run_greedy.html
#First, let's import the relavant modules:
import romtools
import numpy as np
from matplotlib import pyplot as plt
import sys
import os
sys.path.append('adr_1d/')
from adr_1d import advectionDiffusionProblem
#First, we will import the FOM model.
#Here, we will just use the advection diffusion FOM we setup in the external model tutorial
from ipynb.fs.full.external_qoi_model import adrExternalRomToolsQoiModel
myFom = adrExternalRomToolsQoiModel()
# Now, let's setup our parameter space. We will use the parameter space we constructed in the parameter_space
from ipynb.fs.full.parameter_space import BasicParameterSpace
myParameterSpace = BasicParameterSpace()
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
Cell In[2], line 4
1 #First, we will import the FOM model.
2 #Here, we will just use the advection diffusion FOM we setup in the external model tutorial
----> 4 from ipynb.fs.full.external_qoi_model import adrExternalRomToolsQoiModel
5 myFom = adrExternalRomToolsQoiModel()
7 # Now, let's setup our parameter space. We will use the parameter space we constructed in the parameter_space
ModuleNotFoundError: No module named 'ipynb'
# Now, we need to setup our ROM. For greedy, we need a QoIModelWithErrorEstimate.
# we haven't make this type of model in our tutorial series, and will do so now.
#As a starting point, let's import the ROM model we made in the model_builder tutorial
from ipynb.fs.full.model_builder import adrRom
#We now need to add a compute_qoi method and a compute_error_estimate_method:
class adrQoiRomWithErrorEstimate(adrRom):
def compute_qoi(self, run_directory: str, parameter_sample: dict):
# Note that compute_qoi is always called after run_model
solution = np.load(run_directory + '/solution.npz')
u = solution['u']
x = solution['x']
dx = x[1] - x[0] #we use a uniform grid
ux_at_right_edge = (0. - u[-1])/dx
return ux_at_right_edge
# Now we will add a method for computing an error estimate.
# As an error estimate, we will use the norm of the FOM residual evaluated about the ROM solution
def compute_error_estimate(self, run_directory: str, parameter_sample: dict):
rom_data = np.load(self.offline_directory_ + '/rom_data.npz')
solution = np.load(run_directory + '/solution.npz')
u = solution['u']
residual = (parameter_sample['c']*rom_data['Ac'] - parameter_sample['nu']*rom_data['Ad'])@u - rom_data['f']
residual_norm = np.linalg.norm(residual)
return residual_norm
#Now we will construct a model_builder. We will use the one we initiated in the model_builder tutorial
from ipynb.fs.full.model_builder import AdrRomModelBuilder
myIntrusiveFom = advectionDiffusionProblem(nx=33)
myRomModelBuilder = AdrRomModelBuilder(myIntrusiveFom,adrQoiRomWithErrorEstimate)
#Now we can run the greedy workflow!
if __name__ == "__main__":
greedy_work_dir = os.getcwd() + '/greedy_example/'
tolerance = 1.e-6 #tolerance on greedy algorithm
testing_sample_size = 10 #sample size on which to evaluate greedy ROM
romtools.workflows.greedy.run_greedy(myFom,myRomModelBuilder,myParameterSpace,greedy_work_dir,
tolerance,testing_sample_size)
[0.09874884 0.19644988 0.29297092 0.38816313 0.48185886 0.57386933
0.66398197 0.75195735 0.83752586 0.92038389 1.0001895 1.07655765
1.1490547 1.21719231 1.28042056 1.33812013 1.38959358 1.43405551
1.47062142 1.49829524 1.51595524 1.52233821 1.51602155 1.49540322
1.45867911 1.40381748 1.32853032 1.23024098 1.10604776 0.95268294
0.76646655 0.54325444 0.27837963] [0. 0.03125 0.0625 0.09375 0.125 0.15625 0.1875 0.21875 0.25
0.28125 0.3125 0.34375 0.375 0.40625 0.4375 0.46875 0.5 0.53125
0.5625 0.59375 0.625 0.65625 0.6875 0.71875 0.75 0.78125 0.8125
0.84375 0.875 0.90625 0.9375 0.96875 1. ]
[0.06250604 0.12501153 0.18751619 0.25001959 0.31252111 0.3750198
0.43751422 0.50000222 0.56248055 0.62494432 0.68738621 0.74979513
0.81215444 0.87443909 0.93661136 0.99861449 1.06036304 1.12172844
1.18251715 1.24243788 1.30105222 1.3577003 1.41138898 1.46062344
1.50315389 1.5355941 1.5528475 1.54724323 1.50723587 1.41544843
1.24572676 0.95870628 0.49513932] [0. 0.03125 0.0625 0.09375 0.125 0.15625 0.1875 0.21875 0.25
0.28125 0.3125 0.34375 0.375 0.40625 0.4375 0.46875 0.5 0.53125
0.5625 0.59375 0.625 0.65625 0.6875 0.71875 0.75 0.78125 0.8125
0.84375 0.875 0.90625 0.9375 0.96875 1. ]
Greedy iteration # 0
[0.07322466 0.14644932 0.21967397 0.29289863 0.36612329 0.43934795
0.5125726 0.58579726 0.65902192 0.73224657 0.80547122 0.87869586
0.95192047 1.02514502 1.09836944 1.17159355 1.24481694 1.31803864
1.39125648 1.46446533 1.5376534 1.61079336 1.68382193 1.75659265
1.82876642 1.89955822 1.96715072 2.02733669 2.07037623 2.07372109
1.98517109 1.68388062 0.89008706] [0. 0.03125 0.0625 0.09375 0.125 0.15625 0.1875 0.21875 0.25
0.28125 0.3125 0.34375 0.375 0.40625 0.4375 0.46875 0.5 0.53125
0.5625 0.59375 0.625 0.65625 0.6875 0.71875 0.75 0.78125 0.8125
0.84375 0.875 0.90625 0.9375 0.96875 1. ]
Greedy iteration # 1
[0.13591109 0.26614355 0.39051337 0.5088306 0.62089912 0.72651646
0.82547358 0.91755469 1.00253699 1.08019045 1.15027762 1.21255333
1.26676447 1.31264973 1.34993934 1.37835479 1.39760852 1.40740369
1.40743382 1.3973825 1.37692307 1.34571829 1.30341999 1.24966871
1.18409336 1.10631081 1.01592552 0.91252915 0.7957001 0.66500313
0.5199889 0.36019348 0.18513795] [0. 0.03125 0.0625 0.09375 0.125 0.15625 0.1875 0.21875 0.25
0.28125 0.3125 0.34375 0.375 0.40625 0.4375 0.46875 0.5 0.53125
0.5625 0.59375 0.625 0.65625 0.6875 0.71875 0.75 0.78125 0.8125
0.84375 0.875 0.90625 0.9375 0.96875 1. ]
Greedy iteration # 2
#Let's check how some statistics for the workflow.
#Greedy will save out a file called greedy_stats.npz in the work directory with information on convergence
stats = np.load(greedy_work_dir + '/greedy_stats.npz')
print("Stored values are: ", list(stats.keys()))
#Let's look at a plot of the max_error_indicator vs iteration:
plt.plot(stats['max_error_indicators'])
plt.yscale('log')
plt.xlabel(r'Greedy iteration')
plt.ylabel(r'ROM residual norm')
plt.show()
#Now lets look at the "true QoI error" computed after each greedy iteration and compare it to our predicted QoI error
# Note that the predicted QoI error is not tabulated at the first iteration
iterations_for_predicted_errors = np.arange(1,stats['predicted_qoi_errors'].size+1)
plt.plot(stats['qoi_errors'],'-o',label='True error')
plt.plot(iterations_for_predicted_errors,stats['predicted_qoi_errors'],'-o',label='Predicted QoI error')
plt.yscale('log')
plt.xlabel(r'Greedy iteration')
plt.ylabel(r'QoI error')
plt.legend()
plt.show()