diff --git a/Examples/Examples.json b/Examples/Examples.json index 73749a1b..144e8f19 100644 --- a/Examples/Examples.json +++ b/Examples/Examples.json @@ -69,6 +69,11 @@ "name": "Material Model: Deterministic Calibration", "description": "In this example, non-linear least squares minimization is used to calibrate the parameters values of a material model subjected to cyclic strain history.", "inputFile": "qfem-0018/src/input.json" + }, + { + "name": "Two-Dimensional Truss: PLoM Modeling and Simulation", + "description": "In this example, the goal is to demonstrate the use of PLoM model method to predict the response of the example truss under the given load.", + "inputFile": "qfem-0022/src/input.json" } ] } diff --git a/Examples/Examples_all.json b/Examples/Examples_all.json index 6ae4d56b..4f252ac1 100644 --- a/Examples/Examples_all.json +++ b/Examples/Examples_all.json @@ -85,6 +85,10 @@ "description": "~", "InputFile": "qfem-0018/input.json" }, + { + "name": "Two-Dimensional Truss: PLoM Modeling and Simulation", + "description": "In this example, the goal is to demonstrate the use of PLoM model method to predict the response of the example truss under the given load.", + "inputFile": "qfem-0022/src/input.json"}, { "name": "Surrogate modeling with design of experiments", "description": "In this example illustrates different design of experiments strategies.", diff --git a/Examples/index.json b/Examples/index.json index 5c0ecc6e..c613a293 100644 --- a/Examples/index.json +++ b/Examples/index.json @@ -433,6 +433,35 @@ "Simulation": "OpenSees", "Difficulty": "0" } + }, + "qfem-0022": { + "id": "qfem-0022", + "title": "Two-Dimensional Truss: PLoM Modeling and Simulation", + "base": "qfem-0022", + "doc": [ + "qfem-0022/README.rst", + "qfem-0022/src/input.tcl", + "qfem-0022/src/TrussModel.tcl", + "qfem-0022/src/TrussPost.tcl", + "qfem-0022/src/TrussPost.py", + "qfem-0022/figures/truss.png", + "qfem-0022/figures/UQ.png", + "qfem-0022/figures/FEM.png", + "qfem-0022/figures/RV.png", + "qfem-0022/figures/EDP.png", + "qfem-0022/figures/RES1.png", + "qfem-0022/figures/RES2.png", + "qfem-0022/figures/RES3.png", + "qfem-0022/figures/RES4.png" + ], + "entry_point": "qfem-0022/./input.json", + "summary": "In this example, the goal is to demonstrate the use of PLoM model method \nto predict the response of the example truss under the given load.\n", + "logo": "figures/truss.png", + "published": "2022-04-01T21:26:53.946381-08:00", + "categories": { + "Simulation": "OpenSees", + "Difficulty": "0" + } } }, "categories": { diff --git a/Examples/qfem-0022/README.rst b/Examples/qfem-0022/README.rst new file mode 100644 index 00000000..29120cc1 --- /dev/null +++ b/Examples/qfem-0022/README.rst @@ -0,0 +1,99 @@ +.. _qfem-0022: + +Two-Dimensional Truss: PLoM Modeling and Simulation +===================================================== + ++----------------+------------------------------------------+ +| Problem files | :github:`Download ` | ++----------------+------------------------------------------+ + +Consider the problem simulating response of a two-dimensional truss structure with uncertain material properties shown in the following figure. +The goal of the exercise is to demonstrate the use of ``PLoM model`` method under ``SimCenterUQ``. + +.. figure:: figures/truss.png + :align: center + :width: 600 + +1. Elastic modulus(``E``): mean :math:`\mu_E=205 kN/{mm^2}` and standard deviation :math:`\sigma_E =15 kN/{mm^2}` (COV = 7.3%) +2. Load (``P``): mean :math:`\mu_P =25 kN` and a standard deviation of :math:`\sigma_P = 3 kN`, (COV = 12%). +3. Cross sectional area for the upper three bars (``Au``): mean :math:`\mu_{Au} = 500 mm^2`, and a standard deviation of :math:`\sigma_{Au} = 25mm^2` (COV = 5%) +4. Cross sectional area for the other six bars (``Ao``): mean :math:`\mu_{Ao} = 250mm^2`, and :math:`\sigma_{Ao} = 10mm^2` (COV = 4%) + +The exercise requires two files: + +1. :qfem-0022:`TrussTemplate.tcl ` + +.. literalinclude:: ./src/TrussModel.tcl + :language: tcl + +2. :qfem-0001:`TrussPost.tcl `. + +The ``TrussPost.tcl`` script shown below will accept as input any of the 6 nodes in the domain and for each of the two dof directions. + +.. literalinclude:: ./src/TrussPost.tcl + :language: tcl + +PLoM Modeling +^^^^^^^^^^^^^^^^^ + +1. Start the application and the UQ Selection will be highlighted. In the panel for the UQ selection, select ``SimCenterUQ`` as the UQ engine. + Select ``PLoM Model`` for the UQ method, and use ``Sampling and Simulation`` as the Training Dataset. + For sampling method, select ``LHS`` with 50 initial simulations for generating training data (with a random seed specified). + For the new sample number ratio, input 5 by which 250 new realizations will be created from the trained PLoM model. + +.. figure:: figures/UQ.png + :align: center + :figclass: align-center + +2. Next select the **FEM** panel from the input panel. This will default in the ``OpenSees`` engine. For the main script copy the path name to ``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. + +.. figure:: figures/FEM.png + :align: center + :figclass: align-center + +3. Next select the **RV** panel 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 from having a constant distribution to a normal one and then provide the means and standard deviations specified for the problem. + +.. figure:: figures/RV.png + :align: center + :figclass: align-center + +4. Next select the **EDP** tab. Here two response variables ``Node_2_Disp_2`` and ``Node_3_Disp_2`` are defined, which should be consistent with the post-process script. + +.. figure:: figures/EDP.png + :align: center + :figclass: align-center + +.. note:: + + The user can add extra EDP by selecting add and then providing additional names. As seen from the post-process script any of the 6 nodes may be specified and for any node either the 1 or 2 DOF direction. + +5. Next click on the **Run** button. This will cause the backend application to launch the job. When done the **RES** panel will be selected and the results will be displayed. + The landing page of **RES** will show summarize the training information including training sampling number along with two PLoM model trucation plots for PCA and KDE. + +.. figure:: figures/RES1.png + :align: center + :figclass: align-center + + PCA representation error versus the PCA eigenvalues overlapped by the truncating PCA eigenvalue used in training + +.. figure:: figures/RES2.png + :align: center + :figclass: align-center + + Diffusion map eigenvalue by components overlapped by the truncating eigenvalue used in training + + +If the user selects the **Data** tab in the results panel, they will be presented with both a graphical plot and a tabular listing of the data. +Various views of the graphical display can be obtained by left and right clicking in the columns of the tabular data. If a singular column of +the tabular data is pressed with both right and left buttons a frequency and CDF will be displayed, as shown in figure below. + +.. figure:: figures/RES3.png + :align: center + :figclass: align-center + +The PLoM model can be saved and be loaded back for future use. The ``Save PLoM Model`` button at the bottom of Summary +page would bring up a dialogue window for saving the model file to a user-defined directory. + +.. figure:: figures/RES4.png + :align: center + :figclass: align-center \ No newline at end of file diff --git a/Examples/qfem-0022/figures/EDP.png b/Examples/qfem-0022/figures/EDP.png new file mode 100644 index 00000000..9ee86b92 Binary files /dev/null and b/Examples/qfem-0022/figures/EDP.png differ diff --git a/Examples/qfem-0022/figures/FEM.png b/Examples/qfem-0022/figures/FEM.png new file mode 100644 index 00000000..366e512d Binary files /dev/null and b/Examples/qfem-0022/figures/FEM.png differ diff --git a/Examples/qfem-0022/figures/RES1.png b/Examples/qfem-0022/figures/RES1.png new file mode 100644 index 00000000..cf48d48a Binary files /dev/null and b/Examples/qfem-0022/figures/RES1.png differ diff --git a/Examples/qfem-0022/figures/RES2.png b/Examples/qfem-0022/figures/RES2.png new file mode 100644 index 00000000..cf162e80 Binary files /dev/null and b/Examples/qfem-0022/figures/RES2.png differ diff --git a/Examples/qfem-0022/figures/RES3.png b/Examples/qfem-0022/figures/RES3.png new file mode 100644 index 00000000..26054ce7 Binary files /dev/null and b/Examples/qfem-0022/figures/RES3.png differ diff --git a/Examples/qfem-0022/figures/RES4.png b/Examples/qfem-0022/figures/RES4.png new file mode 100644 index 00000000..093e8a95 Binary files /dev/null and b/Examples/qfem-0022/figures/RES4.png differ diff --git a/Examples/qfem-0022/figures/RV.png b/Examples/qfem-0022/figures/RV.png new file mode 100644 index 00000000..6d4f7b01 Binary files /dev/null and b/Examples/qfem-0022/figures/RV.png differ diff --git a/Examples/qfem-0022/figures/UQ.png b/Examples/qfem-0022/figures/UQ.png new file mode 100644 index 00000000..1bc5f57c Binary files /dev/null and b/Examples/qfem-0022/figures/UQ.png differ diff --git a/Examples/qfem-0022/figures/truss.png b/Examples/qfem-0022/figures/truss.png new file mode 100644 index 00000000..1291ed4b Binary files /dev/null and b/Examples/qfem-0022/figures/truss.png differ diff --git a/Examples/qfem-0022/meta.yaml b/Examples/qfem-0022/meta.yaml new file mode 100644 index 00000000..85628230 --- /dev/null +++ b/Examples/qfem-0022/meta.yaml @@ -0,0 +1,8 @@ +title: Two-Dimensional Truss - PLoM Modeling and Simulation +summary: | + Consider the problem simulating response of a two-dimensional truss structure with uncertain material properties. The goal of the exercise is to demonstrate the use of ``PLoM model`` method under ``SimCenterUQ`` to predict the response of the truss under the given load. +author: +- family: Zhong + given: Kuanshi +collection-title: Surrogate training - building +difficulty: 0 diff --git a/Examples/qfem-0022/src/TrussModel.tcl b/Examples/qfem-0022/src/TrussModel.tcl new file mode 100644 index 00000000..3c0191a1 --- /dev/null +++ b/Examples/qfem-0022/src/TrussModel.tcl @@ -0,0 +1,69 @@ + +# units kN & mm + +# +# set some parameters +# + +pset E 205 +pset P 25 +pset Au 500 +pset Ao 250 + +# +# build the model +# + +model Basic -ndm 2 -ndf 2 + +node 1 0 0 +node 2 4000 0 +node 3 8000 0 +node 4 12000 0 +node 5 4000 4000 +node 6 8000 4000 + +fix 1 1 1 +fix 4 0 1 + +uniaxialMaterial Elastic 1 $E + +element truss 1 1 2 $Ao 1 +element truss 2 2 3 $Ao 1 +element truss 3 3 4 $Ao 1 +element truss 4 1 5 $Au 1 +element truss 5 5 6 $Au 1 +element truss 6 6 4 $Au 1 +element truss 7 2 5 $Ao 1 +element truss 8 3 6 $Ao 1 +element truss 9 5 3 $Ao 1 +timeSeries Linear 1 +pattern Plain 1 1 { + load 2 0 [expr -$P] + load 3 0 [expr -$P] +} + +# +# create a recorder +# + +recorder Node -file node.out -scientific -precision 10 -node 1 2 3 4 5 6 -dof 1 2 disp + +# +# build and perform the analysis +# + +algorithm Linear +integrator LoadControl 1.0 +system ProfileSPD +numberer RCM +constraints Plain +analysis Static +analyze 1 + +# +# remove the recorders +# + +remove recorders + diff --git a/Examples/qfem-0022/src/TrussPost.py b/Examples/qfem-0022/src/TrussPost.py new file mode 100644 index 00000000..bc2d5396 --- /dev/null +++ b/Examples/qfem-0022/src/TrussPost.py @@ -0,0 +1,67 @@ +#!/usr/bin/python + +# written: fmk, adamzs 01/18 + +# import functions for Python 2.X support +from __future__ import division, print_function +import sys +if sys.version.startswith('2'): + range=xrange + string_types = basestring +else: + string_types = str + +import sys + +def process_results(inputArgs): + + # + # process output file "node.out" for nodal displacements + # + + with open ('node.out', 'rt') as inFile: + line = inFile.readline() + displ = line.split() + numNode = len(displ) + + inFile.close + + # now process the input args and write the results file + + outFile = open('results.out','w') + + # note for now assuming no ERROR in user data + for i in inputArgs: + + theList=i.split('_') + + if (len(theList) == 4): + dof = int(theList[3]) + else: + dof = 1 + + if (theList[0] == "Node"): + nodeTag = int(theList[1]) + + if (nodeTag > 0 and nodeTag <= numNode): + if (theList[2] == "Disp"): + nodeDisp = abs(float(displ[((nodeTag-1)*2)+dof-1])) + outFile.write(str(nodeDisp)) + outFile.write(' ') + else: + outFile.write('0. ') + else: + outFile.write('0. ') + else: + outFile.write('0. ') + + outFile.close + + +if __name__ == "__main__": + n = len(sys.argv) + responses = [] + for i in range(1,n): + responses.append(sys.argv[i]) + + process_results(responses) diff --git a/Examples/qfem-0022/src/TrussPost.tcl b/Examples/qfem-0022/src/TrussPost.tcl new file mode 100644 index 00000000..0c6069cc --- /dev/null +++ b/Examples/qfem-0022/src/TrussPost.tcl @@ -0,0 +1,31 @@ +# create file handler to write results to output & list into which we will put results +set resultFile [open results.out w] +set results [] + +# get list of valid nodeTags +set nodeTags [getNodeTags] + +# for each quanity in list of QoI passed +# - get nodeTag +# - get nodal displacement if valid node, output 0.0 if not +# - for valid node output displacement, note if dof not provided output 1'st dof + +foreach edp $listQoI { + set splitEDP [split $edp "_"] + set nodeTag [lindex $splitEDP 1] + if {$nodeTag in $nodeTags} { + set nodeDisp [nodeDisp $nodeTag] + if {[llength $splitEDP] == 3} { + set result [expr abs([lindex $nodeDisp 0])] + } else { + set result [expr abs([lindex $nodeDisp [expr [lindex $splitEDP 3]-1]])] + } + } else { + set result 0. + } + lappend results $result +} + +# send results to output file & close the file +puts $resultFile $results +close $resultFile diff --git a/Examples/qfem-0022/src/input.json b/Examples/qfem-0022/src/input.json new file mode 100644 index 00000000..9fbff059 --- /dev/null +++ b/Examples/qfem-0022/src/input.json @@ -0,0 +1,94 @@ +{ + "$schema": "https://raw.githubusercontent.com/claudioperez/SimCenterDocumentation/examples/docs/common/user_manual/schemas/quoFEM_Schema.json", + "Applications": { + "FEM": { + "Application": "OpenSees", + "ApplicationData": { + "MS_Path": "{Current_Dir}/", + "mainScript": "TrussModel.tcl", + "postprocessScript": "TrussPost.tcl", + "PS_Path": "{Current_Dir}/" + } + }, + "UQ": { + "Application": "SimCenter-UQ", + "ApplicationData": { + } + } + }, + "EDP": [ + { + "length": 1, + "name": "Node_3_Disp_2", + "type": "scalar" + }, + { + "length": 1, + "name": "Node_2_Disp_2", + "type": "scalar" + } + ], + "FEM": { + }, + "UQ_Method": { + "surrogateMethodInfo": { + "advancedOpt": false, + "inpFile": "PLoM_variables.csv", + "method": "Sampling and Simulation", + "newSampleRatio": 5, + "outFile": "PLoM_responses.csv", + "outputData": true, + "parallelExecution": false, + "preTrained": false, + "samplingMethod": { + "method": "LHS", + "samples": 50, + "seed": 150 + } + }, + "uqEngine": "SimCenterUQ", + "uqType": "PLoM Model" + }, + "randomVariables": [ + { + "distribution": "Lognormal", + "inputType": "Moments", + "mean": 205, + "name": "E", + "refCount": 1, + "stdDev": 15, + "value": "RV.E", + "variableClass": "Uncertain" + }, + { + "distribution": "Normal", + "inputType": "Parameters", + "mean": 25, + "name": "P", + "refCount": 1, + "stdDev": 3, + "value": "RV.P", + "variableClass": "Uncertain" + }, + { + "distribution": "Lognormal", + "inputType": "Moments", + "mean": 250, + "name": "Ao", + "refCount": 1, + "stdDev": 10, + "value": "RV.Ao", + "variableClass": "Uncertain" + }, + { + "distribution": "Normal", + "inputType": "Parameters", + "mean": 500, + "name": "Au", + "refCount": 1, + "stdDev": 25, + "value": "RV.Au", + "variableClass": "Uncertain" + } + ] +}