Skip to content

Commit

Permalink
Merge pull request #79 from bsaakash/refactorUQ
Browse files Browse the repository at this point in the history
Updates for documentation
  • Loading branch information
fmckenna authored Apr 8, 2022
2 parents 82ebb96 + b5323a5 commit 9b64008
Show file tree
Hide file tree
Showing 42 changed files with 277 additions and 33 deletions.
1 change: 1 addition & 0 deletions Examples/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@
"qfem-0017/src/UQpySimpleExample.json",
"qfem-0017/figures/CUS_UQtab.png",
"qfem-0017/figures/CUS_UQtab2.png",
"qfem-0017/figures/CUS_UQtab3.png",
"qfem-0017/figures/CUS_FEMtab.png"
],
"entry_point": "qfem-0017/./input.json",
Expand Down
Binary file modified Examples/qfem-0007/figures/qfem-0007-FEM.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Examples/qfem-0007/figures/qfem-0007-QoI.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Examples/qfem-0007/figures/qfem-0007-RES1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Examples/qfem-0007/figures/qfem-0007-RES2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Examples/qfem-0007/figures/qfem-0007-RV.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Examples/qfem-0007/figures/qfem-0007-UQ.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions Examples/qfem-0014/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ For each variable, specify the prior probability distribution - from the **Distr

.. note::

For this particular problem setup in which the user is not using a postprocessing script, the user may specify any names for the QoI variables. They are only being used by Dakota to return information on the results.
For this particular problem setup in which the user is not using a postprocessing script, the user may specify any names for the QoI variables. They are only being used by the UCSD_UQ engine to return information on the results.


5. Next click on the **Run** button. This will cause the backend application to launch the **UCSD_UQ** engine, which performs Bayesian calibration using the TMCMC algorithm. When done, the **RES** tab will be selected and the results will be displayed as shown in the figure below. The results show the first four moments of the posterior marginal probability distribution of :math:`k_1` and :math:`k_2`. The true value of both :math:`k_1` and :math:`k_2` is **958.61 kips/in**.
Expand Down Expand Up @@ -227,7 +227,7 @@ Various views of the graphical display can be obtained by left and right clickin
:figclass: align-center
:width: 600

If a singular column of the tabular data is pressed with both right and left buttons a histogram and CDF will be displayed, as shown in the figures below.
If a single column of the tabular data is pressed with both right and left buttons a histogram and CDF will be displayed, as shown in the figures below.

.. figure:: figures/qfem-0014-RES4.png
:align: center
Expand Down
Binary file modified Examples/qfem-0014/figures/qfem-0014-FEM.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Examples/qfem-0014/figures/qfem-0014-QoI.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Examples/qfem-0014/figures/qfem-0014-RES1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Examples/qfem-0014/figures/qfem-0014-RES2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Examples/qfem-0014/figures/qfem-0014-RES3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Examples/qfem-0014/figures/qfem-0014-RES4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Examples/qfem-0014/figures/qfem-0014-RES5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Examples/qfem-0014/figures/qfem-0014-RES6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Examples/qfem-0014/figures/qfem-0014-RV.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Examples/qfem-0014/figures/qfem-0014-UQ.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 16 additions & 13 deletions Examples/qfem-0017/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Cross sectional area of the upper three bars, Au 400 600
Cross sectional area of the other six bars, Ao 200 300
================================================ ============ =========

The goal of the exercise is to implement UQpy as a **custom UQ engine** and estimate the mean and standard deviation of the vertical displacement at node2.
The goal of the exercise is to implement UQpy as a **custom UQ engine** and estimate the mean and standard deviation of the vertical displacement at node 3.

.. note::
The UQpy_ python package is required to be installed to run this example, e.g. pip install UQpy
Expand All @@ -35,36 +35,39 @@ The goal of the exercise is to implement UQpy as a **custom UQ engine** and esti
UQ Workflow
-------------

1. Start the application and the **UQ** Selection will be highlighted. In the panel for the UQ selection, change the UQ Engine to **CustomUQ**. In UQ Application Name, type **Other-UQ**.
1. Start the application and the **UQ** Selection will be highlighted. In the panel for the UQ selection, change the UQ Engine to **CustomUQ**.

.. figure:: figures/CUS_UQtab.png
:align: center
:figclass: align-center

Next, provide the configuration input file path. In the configuration file, users specify the interface for the parameters (type, name, values of each parameters) required for the custom UQ analysis. The provided script will generate 1 combo box to define sample types, 4 spin boxes to define number of samples, concurrent tasks, and notes, and 1 line edit field to specify the UQ Driver.
Next, provide the configuration input file path. In the configuration file, users specify the interface for the parameters (type, name, values of each parameters) required for the custom UQ analysis. The provided script will generate 1 combo box to define sample types, 2 line edit fields to define the number of samples and seed, 3 spin boxes to define number of concurrent tasks, nodes, and cores per task, and 1 line edit field to specify the UQ Driver.

.. literalinclude:: src/UQpySimpleExample.json
:language: json
:caption: UQpySimpleExample.json

Note that configuration input file specifies the front-end interfaces while the back-end interface should be modified in the backend directory (See Section 2.1.4.1. Custom Uncertainty Quantification Engine Input). As an example, UQpy has been already implemented in the customized backend where users can find at ``{Backend Applications Directory}/applications/performUQ/other``, where the ``{Backend Applications Directory}`` is specified from the file-preference in the menu bar). Once the ``UQpySimpleExample.json`` is called, the following customized user interface will appear in UQ panel.
Note that configuration input file specifies the front-end interfaces while the back-end interface should be modified in the backend directory (Refer the :ref:`Configuring CustomUQ Engine <lblCustomUQ>` section for details). As an example, UQpy has been already implemented in the customized backend where users can find at ``{Backend Applications Directory}/applications/performUQ/other``, where the ``{Backend Applications Directory}`` is specified from the file-preference in the menu bar). Once the ``UQpySimpleExample.json`` is called, the following customized user interface will appear in UQ panel.

.. figure:: figures/CUS_UQtab2.png
:align: center
:figclass: align-center

Let us sample 50 samples by latine hypercube sampling (LHS).
Let us sample 50 samples by Latin hypercube sampling (LHS). The UQ Driver field must be filled in as **UQpy**, as shown in the following figure.

.. figure:: figures/CUS_UQtab3.png
:align: center
:figclass: align-center

2. Select the **FEM** tab from the input panel. For the main script copy the path to the ``TrussModel.tcl`` or select choose and navigate to the file. For the post-process script field, repeat the same procedure for the ``TrussPost.tcl script``. (See example 'q0001:Two-Dimensional Truss: Sampling, Reliability and Sensitivity' for the model details)
2. Select the **FEM** tab from the input panel. For the main script copy the path to the ``TrussModel.tcl`` or select choose and navigate to the file. For the post-process script field, repeat the same procedure for the ``TrussPost.tcl script``. (See example :ref:`Two-Dimensional Truss: Sampling, Reliability and Sensitivity <qfem-0001>` for the model details)


.. figure:: figures/CUS_FEMtab.png
:align: center
:figclass: align-center


3. Select the **RV** tab from the input panel. This should be pre-populated with four random variables with same names as those having ``pset`` in the tcl script. For each variable, from the drop down menu change them uniform one and then provide the lower and upper bounds specified for the problem.
3. Select the **RV** tab from the input panel. This should be pre-populated with four random variables with same names as those having ``pset`` in the tcl script. For each variable, from the drop down menu change them to uniform and provide the lower and upper bounds specified for the problem.

.. figure:: figures/CUS_RVtab.png
:align: center
Expand All @@ -73,23 +76,23 @@ Let us sample 50 samples by latine hypercube sampling (LHS).
.. note::
Only **uniform distribution** is supported in this preliminary example.

4. Next select the **QoI** tab. Here enter ``Node_2_Disp_2`` for the one variable.
4. Next select the **QoI** tab. Here enter ``Node_3_Disp_2`` for the one variable.

.. figure:: figures/CUS_QoItab.png
:align: center
:figclass: align-center

5. Next click on the **Run** button. This will cause the backend application to launch dakota.
5. Next click on the **Run** button. This will cause the backend application to launch the CustomUQ engine which will run UQpy.

6. When done the **RES** panel will be selected and the results will be displayed. The results show the values the mean and standard deviation.


Summary:

* Mean = 7.322
* Std = 4.29
* Skewness = 1.89
* Kurtosis = 7.13
* Mean = 5.77619
* Std = 2.4664
* Skewness = 0.456808
* Kurtosis = 2.7146


Data Table:
Expand Down
Binary file modified Examples/qfem-0017/figures/CUS_FEMtab.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Examples/qfem-0017/figures/CUS_QOItab.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Examples/qfem-0017/figures/CUS_REStab.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Examples/qfem-0017/figures/CUS_RVtab.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Examples/qfem-0017/figures/CUS_UQtab.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Examples/qfem-0017/figures/CUS_UQtab2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Examples/qfem-0017/figures/CUS_UQtab3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 13 additions & 13 deletions Examples/qfem-0017/src/UQpySimpleExample.json
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
{
"Parameters" : [
{
"type" : "ComboBox",
"name" : "Sampling Method",
"values" : ["LHS"]
"type" : "ComboBox",
"name" : "Sampling Method",
"values" : ["LHS"]
},
{
"type" : "LineEdit",
"name" : "Number of Samples"
"type" : "LineEdit",
"name" : "Number of Samples"
},
{
"type" : "LineEdit",
"name" : "Seed"
},
{
"type" : "SpinBox",
"name" : "Number of Concurrent Tasks"
"type" : "SpinBox",
"name" : "Number of Concurrent Tasks"
},
{
"type" : "SpinBox",
"name" : "Number of Nodes"
"type" : "SpinBox",
"name" : "Number of Nodes"
},
{
"type" : "SpinBox",
"name" : "Cores per Task"
"type" : "SpinBox",
"name" : "Cores per Task"
},
{
"type" : "LineEdit",
"name" : "UQ Driver"
"type" : "LineEdit",
"name" : "UQ Driver"
}
]
}
Binary file modified Examples/qfem-0019/figures/qf-0018-FEM.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Examples/qfem-0019/figures/qf-0018-QoI.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Examples/qfem-0019/figures/qf-0018-RES1.png
Binary file modified Examples/qfem-0019/figures/qf-0018-RV.png
Binary file modified Examples/qfem-0019/figures/qf-0018-UQ.png
Binary file modified Examples/qfem-0019/figures/qf-0019-FEM.png
Binary file modified Examples/qfem-0019/figures/qf-0019-QoI.png
Binary file modified Examples/qfem-0019/figures/qf-0019-RES1.png
Binary file modified Examples/qfem-0019/figures/qf-0019-RES2.png
Binary file modified Examples/qfem-0019/figures/qf-0019-RV.png
Binary file modified Examples/qfem-0019/figures/qf-0019-UQ.png
240 changes: 240 additions & 0 deletions Examples/qfem-0020/src/templatedir/HierBayesRunner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
# written: Aakash Bangalore Satish @ NHERI SimCenter, UC Berkeley

import json
import os
import sys
import time
import importlib

from uqRunner import UqRunner


class HierBayesRunner(UqRunner):
def __init__(self) -> None:
super().__init__()
self.n_samples = 0
self.n_burn_in = 0
self.tuning_interval = 0
self.seed = 0

def storeUQData(self, uqData):
for val in uqData["Parameters"]:
if val["name"] == "File To Run":
self.file_to_run = val["value"]
elif val["name"] == "# Samples":
self.n_samples = int(val["value"])
elif val["name"] == "# Burn-in":
self.n_burn_in = int(val["value"])
elif val["name"] == "Tuning Interval":
self.tuning_interval = int(val["value"])
elif val["name"] == "Seed":
self.seed = int(val["value"])

def performHierBayesSampling(self):
self.dir_name = os.path.dirname(self.file_to_run)
sys.path.append(self.dir_name)
module_name = os.path.basename(self.file_to_run)
module = importlib.import_module(module_name[:-3])
self.heir_code = module.HierBayesSampler()

self.trace, self.time_taken, self.inf_object = self.heir_code.perform_sampling(
n_samples=self.n_samples,
n_burn_in=self.n_burn_in,
tuning_interval=self.tuning_interval,
seed=self.seed
)

def saveResultsToPklFile(self):
self.saved_pickle_filename = self.heir_code.save_results(
self.trace, self.time_taken, self.inf_object, prefix="realdata_filtered"
)

def createHeadingStringsList(self):
self.params = ["fy", "E", "b", "cR1", "cR2", "a1", "a3"]
self.num_params = len(self.params)
self.num_coupons = 34

# self.heading_list = ["interface"]
self.heading_list = ["Sample#", "interface"]
for i in range(self.num_coupons):
for j in range(self.num_params):
self.heading_list.append(
"".join(["Coupon_", str(i + 1), "_", self.params[j]])
)

for row in range(self.num_params):
for col in range(row + 1):
self.heading_list.append("".join(["Cov_", str(row + 1), str(col + 1)]))

for par in self.params:
self.heading_list.append("".join(["Mean_", par]))

for sig in range(self.num_coupons):
self.heading_list.append("".join(["ErrorVariance_", str(sig + 1)]))

def makeHeadingRow(self, separator="\t"):
self.headingRow = separator.join([item for item in self.heading_list])

def makeOneRowString(self, sample_num, sample, separator="\t"):
initial_string = separator.join([str(sample_num), "1"])
coupon_string = separator.join(
[
str(sample[i][j])
for i in range(self.num_coupons)
for j in range(self.num_params)
]
)
cov_string = separator.join(
[
str(sample[self.num_coupons][row][col])
for row in range(self.num_params)
for col in range(row + 1)
]
)
mean_string = separator.join(
[
str(sample[self.num_coupons + 1][par_num])
for par_num in range(self.num_params)
]
)
error_string = separator.join(
[str(sample[-1][coupon_num]) for coupon_num in range(self.num_coupons)]
)
row_string = separator.join(
[initial_string, coupon_string, cov_string, mean_string, error_string]
)
return row_string

def makeTabularResultsFile(self, save_file_name="tabularResults.out", separator="\t"):
self.createHeadingStringsList()
self.makeHeadingRow(separator=separator)

cwd = os.getcwd()
save_file_dir = os.path.dirname(cwd)
save_file_full_path = os.path.join(save_file_dir, save_file_name)
with open(save_file_full_path, "w") as f:
f.write(self.headingRow)
f.write("\n")
for sample_num, sample in enumerate(self.trace):
row = self.makeOneRowString(
sample_num=sample_num, sample=sample, separator=separator
)
f.write(row)
f.write("\n")

# def makePlots(self):
# from temp_postprocess_real_data import make_plots

# make_plots(self.saved_pickle_filename)

def startTimer(self):
self.startingTime = time.time()

def computeTimeElapsed(self):
self.timeElapsed = time.time() - self.startingTime

def printTimeElapsed(self):
self.computeTimeElapsed()
print("Time elapsed: {:0.2f} minutes".format(self.timeElapsed / 60))

def startSectionTimer(self):
self.sectionStartingTime = time.time()

def resetSectionTimer(self):
self.startSectionTimer()

def computeSectionTimeElapsed(self):
self.sectionTimeElapsed = time.time() - self.sectionStartingTime

def printSectionTimeElapsed(self):
self.computeSectionTimeElapsed()
print("Time elapsed: {:0.2f} minutes".format(self.sectionTimeElapsed / 60))

@staticmethod
def printEndMessages():
print("Heirarchical Bayesian estimation done!")

def runUQ(
self,
uqData,
simulationData,
randomVarsData,
demandParams,
workingDir,
runType,
localAppDir,
remoteAppDir,
):
"""
This function configures and runs hierarchical Bayesian estimation based on the
input UQ configuration, simulation configuration, random variables,
and requested demand parameters
Input:
uqData: JsonObject that UQ options as input into the quoFEM GUI
simulationData: JsonObject that contains information on the analysis package to run and its
configuration as input in the quoFEM GUI
randomVarsData: JsonObject that specifies the input random variables, their distributions,
and associated parameters as input in the quoFEM GUI
demandParams: JsonObject that specifies the demand parameters as input in the quoFEM GUI
workingDir: Directory in which to run simulations and store temporary results
runType: Specifies whether computations are being run locally or on an HPC cluster
localAppDir: Directory containing apps for local run
remoteAppDir: Directory containing apps for remote run
"""
self.startTimer()
self.storeUQData(uqData=uqData)
os.chdir(workingDir)
self.performHierBayesSampling()
self.saveResultsToPklFile()
self.makeTabularResultsFile()
# self.makePlots()
self.printTimeElapsed()
self.printEndMessages()


class testRunUQ:
def __init__(self, json_file_path_string) -> None:
self.json_file_path_string = json_file_path_string
self.getUQData()
self.createRunner()
self.runTest()

def getUQData(self):
with open(os.path.abspath(self.json_file_path_string), "r") as f:
input_data = json.load(f)

self.ApplicationData = input_data["Applications"]
self.uqData = input_data["UQ_Method"]
self.simulationData = self.ApplicationData["FEM"]
self.randomVarsData = input_data["randomVariables"]
self.demandParams = input_data["EDP"]
self.localAppDir = input_data["localAppDir"]
self.remoteAppDir = input_data["remoteAppDir"]
self.workingDir = input_data["workingDir"]
self.workingDir = os.path.join(self.workingDir, "tmp.SimCenter", "templateDir")
self.runType = "runningLocal"

def createRunner(self):
self.runner = HierBayesRunner()

def runTest(self):
self.runner.runUQ(
uqData=self.uqData,
simulationData=self.simulationData,
randomVarsData=self.randomVarsData,
demandParams=self.demandParams,
workingDir=self.workingDir,
runType=self.runType,
localAppDir=self.localAppDir,
remoteAppDir=self.remoteAppDir,
)


def main():
filename = "/Users/aakash/Desktop/SimCenter/Joel/heirarchical-refactor/scInput.json"
testRunUQ(filename)


if __name__ == "__main__":
main()
Loading

0 comments on commit 9b64008

Please sign in to comment.