From 535e7719528212d6b1baa3e62a674e2b93c7b8c3 Mon Sep 17 00:00:00 2001 From: Francesco Rizzi Date: Fri, 15 Oct 2021 15:41:17 +0200 Subject: [PATCH 1/2] update version --- .../main.py | 3 +- .../main.py | 5 +- .../main.py | 5 +- .../main.py | 5 +- .../main.py | 3 +- .../main.py | 10 +- docs/conf.py | 4 +- docs/html/annotated.html | 2 +- docs/html/demo1_8md.html | 2 +- docs/html/demo2_8md.html | 2 +- docs/html/demo3_8md.html | 2 +- docs/html/demo4_8md.html | 2 +- docs/html/demo5_8md.html | 2 +- docs/html/demo6_8md.html | 2 +- .../dir_208d2690607c4e3d3fabfa1d18673d36.html | 2 +- .../dir_4af40c8677da60eb4c6f7c14f8103d72.html | 2 +- .../dir_e3e5033bce933e9613999c4991aa42b8.html | 2 +- docs/html/files.html | 2 +- docs/html/index.html | 6 +- docs/html/introduction_8md.html | 2 +- docs/html/logger_8md.html | 2 +- docs/html/main_8md.html | 2 +- docs/html/md_pages_components_logger.html | 2 +- ...ages_components_nonlinsolvers_general.html | 2 +- .../md_pages_components_nonlinsolvers_gn.html | 2 +- .../md_pages_components_nonlinsolvers_lm.html | 2 +- .../md_pages_components_nonlinsolvers_nr.html | 2 +- ...s_components_nonlinsolvers_system_api.html | 2 +- .../html/md_pages_components_ode_advance.html | 2 +- ...ages_components_ode_steppers_explicit.html | 2 +- ...ages_components_ode_steppers_implicit.html | 2 +- .../html/md_pages_components_rom_decoder.html | 2 +- .../md_pages_components_rom_fom_apis.html | 2 +- .../md_pages_components_rom_galerkin.html | 29 +- ...pages_components_rom_galerkin_default.html | 11 +- ..._pages_components_rom_galerkin_hypred.html | 6 +- ..._pages_components_rom_galerkin_masked.html | 8 +- ...ges_components_rom_galerkin_projector.html | 4 +- .../html/md_pages_components_rom_general.html | 2 +- .../md_pages_components_rom_lspg_default.html | 4 +- ...es_components_rom_lspg_default_steady.html | 8 +- .../md_pages_components_rom_lspg_hypred.html | 6 +- .../md_pages_components_rom_lspg_masked.html | 4 +- ...ges_components_rom_lspg_masked_steady.html | 8 +- .../md_pages_components_rom_lspg_steady.html | 6 +- ...md_pages_components_rom_lspg_unsteady.html | 22 +- docs/html/md_pages_components_rom_wls.html | 2 +- docs/html/md_pages_demos_demo1.html | 115 ++++---- docs/html/md_pages_demos_demo2.html | 76 +++--- docs/html/md_pages_demos_demo3.html | 58 ++-- docs/html/md_pages_demos_demo4.html | 109 ++++---- docs/html/md_pages_demos_demo5.html | 148 +++++------ docs/html/md_pages_demos_demo6.html | 58 ++-- docs/html/md_pages_introduction.html | 4 +- docs/html/md_pages_ml_role.html | 2 +- docs/html/ml__role_8md.html | 2 +- docs/html/modules.html | 2 +- docs/html/namespaces.html | 2 +- docs/html/nonlinsolvers__general_8md.html | 2 +- docs/html/nonlinsolvers__gn_8md.html | 2 +- docs/html/nonlinsolvers__lm_8md.html | 2 +- docs/html/nonlinsolvers__nr_8md.html | 2 +- docs/html/nonlinsolvers__system__api_8md.html | 2 +- docs/html/ode__advance_8md.html | 2 +- docs/html/ode__steppers__explicit_8md.html | 2 +- docs/html/ode__steppers__implicit_8md.html | 2 +- docs/html/pages.html | 2 +- docs/html/rom__decoder_8md.html | 2 +- docs/html/rom__fom__apis_8md.html | 2 +- docs/html/rom__galerkin_8md.html | 2 +- docs/html/rom__galerkin__default_8md.html | 2 +- docs/html/rom__galerkin__hypred_8md.html | 2 +- docs/html/rom__galerkin__masked_8md.html | 2 +- docs/html/rom__galerkin__projector_8md.html | 2 +- docs/html/rom__general_8md.html | 2 +- docs/html/rom__lspg__default_8md.html | 2 +- docs/html/rom__lspg__default__steady_8md.html | 2 +- docs/html/rom__lspg__hypred_8md.html | 2 +- docs/html/rom__lspg__masked_8md.html | 2 +- docs/html/rom__lspg__masked__steady_8md.html | 2 +- docs/html/rom__lspg__steady_8md.html | 2 +- docs/html/rom__lspg__unsteady_8md.html | 2 +- docs/html/rom__wls_8md.html | 2 +- docs/latex/index.tex | 13 +- .../md_pages_components_rom_galerkin.tex | 38 ++- ..._pages_components_rom_galerkin_default.tex | 13 +- ...d_pages_components_rom_galerkin_hypred.tex | 4 +- ...d_pages_components_rom_galerkin_masked.tex | 6 +- ...ages_components_rom_galerkin_projector.tex | 2 +- .../md_pages_components_rom_lspg_default.tex | 2 +- ...ges_components_rom_lspg_default_steady.tex | 6 +- .../md_pages_components_rom_lspg_hypred.tex | 6 +- .../md_pages_components_rom_lspg_masked.tex | 2 +- ...ages_components_rom_lspg_masked_steady.tex | 6 +- .../md_pages_components_rom_lspg_steady.tex | 4 +- .../md_pages_components_rom_lspg_unsteady.tex | 28 +- docs/latex/md_pages_demos_demo1.tex | 123 +++++---- docs/latex/md_pages_demos_demo2.tex | 82 +++--- docs/latex/md_pages_demos_demo3.tex | 64 +++-- docs/latex/md_pages_demos_demo4.tex | 131 +++++---- docs/latex/md_pages_demos_demo5.tex | 154 +++++------ docs/latex/md_pages_demos_demo6.tex | 64 +++-- docs/latex/md_pages_introduction.tex | 2 +- docs/pages/components/rom_galerkin.md | 60 +++-- docs/pages/components/rom_galerkin_default.md | 5 +- docs/pages/components/rom_lspg_unsteady.md | 36 +-- docs/pages/demos/demo1.md | 2 +- docs/pages/demos/demo5.md | 2 +- docs/pages/main.md | 8 +- docs/xml/indexpage.xml | 14 +- docs/xml/md_pages_components_rom_galerkin.xml | 45 +++- ..._pages_components_rom_galerkin_default.xml | 13 +- ...d_pages_components_rom_galerkin_hypred.xml | 4 +- ...d_pages_components_rom_galerkin_masked.xml | 6 +- ...ages_components_rom_galerkin_projector.xml | 2 +- .../md_pages_components_rom_lspg_default.xml | 2 +- ...ges_components_rom_lspg_default_steady.xml | 6 +- .../md_pages_components_rom_lspg_hypred.xml | 6 +- .../md_pages_components_rom_lspg_masked.xml | 2 +- ...ages_components_rom_lspg_masked_steady.xml | 6 +- .../md_pages_components_rom_lspg_steady.xml | 4 +- .../md_pages_components_rom_lspg_unsteady.xml | 28 +- docs/xml/md_pages_demos_demo1.xml | 123 +++++---- docs/xml/md_pages_demos_demo2.xml | 82 +++--- docs/xml/md_pages_demos_demo3.xml | 64 +++-- docs/xml/md_pages_demos_demo4.xml | 133 +++++----- docs/xml/md_pages_demos_demo5.xml | 156 +++++------ docs/xml/md_pages_demos_demo6.xml | 64 +++-- docs/xml/md_pages_introduction.xml | 2 +- pressio | 2 +- setup.py | 2 +- src/galerkin.hpp | 144 +++++----- src/lspg_unsteady.hpp | 250 +++++++++++------- src/main_binder.cc | 47 ++-- .../test_unsteady_galerkin_burgers1d.py | 7 +- ...dy_lspg_burgers1d_gn_neq_custom_mapping.py | 9 +- .../test_unsteady_lspg_burgers1d_gn_qr.py | 20 +- ...eady_lspg_burgers1d_levenberg_marquardt.py | 9 +- ...rivially_weighted_gn_neq_custom_mapping.py | 9 +- .../test_rom_galerkin_default_explicit.py | 9 +- .../test_rom_galerkin_default_implicit.py | 69 ++--- .../test_rom_galerkin_hypred_explicit.py | 4 +- .../test_rom_galerkin_masked_explicit.py | 4 +- .../test_rom_galerkin_masked_implicit_bdf1.py | 9 +- ...test_rom_lspg_unsteady_conttime_default.py | 5 +- ...cretetime_default_trivialapp_two_states.py | 5 +- ...g_unsteady_hyperreduced_trivialapp_bdf1.py | 9 +- ...g_unsteady_hyperreduced_trivialapp_bdf2.py | 9 +- ...om_lspg_unsteady_masked_trivialapp_bdf1.py | 11 +- 149 files changed, 1593 insertions(+), 1502 deletions(-) diff --git a/demos/unsteady_default_galerkin_advdiff1d_pod/main.py b/demos/unsteady_default_galerkin_advdiff1d_pod/main.py index d411a4a..6959f6c 100755 --- a/demos/unsteady_default_galerkin_advdiff1d_pod/main.py +++ b/demos/unsteady_default_galerkin_advdiff1d_pod/main.py @@ -43,12 +43,11 @@ def __call__(self, timeStep, time, state): pass # create problem scheme = ode.stepscheme.ForwardEuler problem = rom.galerkin.DefaultExplicitProblem(scheme, fomObj, linearDecoder, romState, fomReferenceState) - stepper = problem.stepper() # create object to monitor the romState at every iteration myObs = RomStateObserver() # solve problem - ode.advance_n_steps_and_observe(stepper, romState, 0., dt, nsteps, myObs) + ode.advance_n_steps_and_observe(problem, romState, 0., dt, nsteps, myObs) # after we are done, use the reconstructor object to reconstruct the fom state # get the reconstructor object: this allows to map romState to fomState diff --git a/demos/unsteady_default_lspg_advdiff1d_kpca/main.py b/demos/unsteady_default_lspg_advdiff1d_kpca/main.py index 361c17b..747e389 100755 --- a/demos/unsteady_default_lspg_advdiff1d_kpca/main.py +++ b/demos/unsteady_default_lspg_advdiff1d_kpca/main.py @@ -82,10 +82,9 @@ def solve(self, A,b,x): # create LSPG problem scheme = ode.stepscheme.BDF1 problem = rom.lspg.unsteady.DefaultProblem(scheme, fomObj, customDecoder, romState, fomReferenceState) - stepper = problem.stepper() # create the Gauss-Newton solver - nonLinSolver = solvers.create_gauss_newton(stepper, romState, MyLinSolver()) + nonLinSolver = solvers.create_gauss_newton(problem, romState, MyLinSolver()) # set tolerance and convergence criteria nlsTol, nlsMaxIt = 1e-7, 10 nonLinSolver.setMaxIterations(nlsMaxIt) @@ -94,7 +93,7 @@ def solve(self, A,b,x): # create object to monitor the romState at every iteration myObs = RomStateObserver() # solve problem - ode.advance_n_steps_and_observe(stepper, romState, 0., dt, nsteps, myObs, nonLinSolver) + ode.advance_n_steps_and_observe(problem, romState, 0., dt, nsteps, myObs, nonLinSolver) # after we are done, use the reconstructor object to reconstruct the fom state # get the reconstructor object: this allows to map romState to fomState diff --git a/demos/unsteady_default_lspg_advdiff1d_mlp/main.py b/demos/unsteady_default_lspg_advdiff1d_mlp/main.py index bd404a5..fa4fa3e 100644 --- a/demos/unsteady_default_lspg_advdiff1d_mlp/main.py +++ b/demos/unsteady_default_lspg_advdiff1d_mlp/main.py @@ -42,10 +42,9 @@ def solve(self, A,b,x): # create LSPG problem scheme = ode.stepscheme.BDF1 problem = rom.lspg.unsteady.DefaultProblem(scheme, fomObj, customDecoder, romState, fomReferenceState) - stepper = problem.stepper() # create the Gauss-Newton solver - nonLinSolver = solvers.create_gauss_newton(stepper, romState, MyLinSolver()) + nonLinSolver = solvers.create_gauss_newton(problem, romState, MyLinSolver()) # set tolerance and convergence criteria nlsTol, nlsMaxIt = 1e-7, 10 nonLinSolver.setMaxIterations(nlsMaxIt) @@ -54,7 +53,7 @@ def solve(self, A,b,x): # create object to monitor the romState at every iteration myObs = RomStateObserver() # solve problem - ode.advance_n_steps_and_observe(stepper, romState, 0., dt, nsteps, myObs, nonLinSolver) + ode.advance_n_steps_and_observe(problem, romState, 0., dt, nsteps, myObs, nonLinSolver) # after we are done, use the reconstructor object to reconstruct the fom state # get the reconstructor object: this allows to map romState to fomState diff --git a/demos/unsteady_default_lspg_advdiff1d_pod/main.py b/demos/unsteady_default_lspg_advdiff1d_pod/main.py index bd5125d..86cccdf 100755 --- a/demos/unsteady_default_lspg_advdiff1d_pod/main.py +++ b/demos/unsteady_default_lspg_advdiff1d_pod/main.py @@ -50,10 +50,9 @@ def solve(self, A,b,x): # create LSPG problem scheme = ode.stepscheme.BDF1 problem = rom.lspg.unsteady.DefaultProblem(scheme, fomObj, linearDecoder, romState, fomReferenceState) - stepper = problem.stepper() # create the Gauss-Newton solver - nonLinSolver = solvers.create_gauss_newton(stepper, romState, MyLinSolver()) + nonLinSolver = solvers.create_gauss_newton(problem, romState, MyLinSolver()) # set tolerance and convergence criteria nlsTol, nlsMaxIt = 1e-6, 5 nonLinSolver.setMaxIterations(nlsMaxIt) @@ -62,7 +61,7 @@ def solve(self, A,b,x): # create object to monitor the romState at every iteration myObs = RomStateObserver() # solve problem - ode.advance_n_steps_and_observe(stepper, romState, 0., dt, nsteps, myObs, nonLinSolver) + ode.advance_n_steps_and_observe(problem, romState, 0., dt, nsteps, myObs, nonLinSolver) # after we are done, use the reconstructor object to reconstruct the fom state # get the reconstructor object: this allows to map romState to fomState diff --git a/demos/unsteady_masked_galerkin_advdiff1d_pod/main.py b/demos/unsteady_masked_galerkin_advdiff1d_pod/main.py index 1d63e12..0a0bf75 100755 --- a/demos/unsteady_masked_galerkin_advdiff1d_pod/main.py +++ b/demos/unsteady_masked_galerkin_advdiff1d_pod/main.py @@ -80,10 +80,9 @@ def runMaskedGalerkin(fomObj, dt, nsteps, modes, sampleMeshIndices): problem = rom.galerkin.MaskedExplicitProblem(scheme, fomObj, linearDecoder, \ romState, fomReferenceState, \ projector, masker) - stepper = problem.stepper() # solve problem - ode.advance_n_steps(stepper, romState, 0., dt, nsteps) + ode.advance_n_steps(problem, romState, 0., dt, nsteps) # after we are done, use the reconstructor object to reconstruct the fom state # NOTE: even though the Galerkin problem was run on the "masked mesh points", diff --git a/demos/unsteady_masked_galerkin_vs_lspg_advdiff1d_pod/main.py b/demos/unsteady_masked_galerkin_vs_lspg_advdiff1d_pod/main.py index 186694c..dbb0d1c 100755 --- a/demos/unsteady_masked_galerkin_vs_lspg_advdiff1d_pod/main.py +++ b/demos/unsteady_masked_galerkin_vs_lspg_advdiff1d_pod/main.py @@ -93,15 +93,14 @@ def runMaskedGalerkin(fomObj, dt, nsteps, modes, sampleMeshIndices): problem = rom.galerkin.MaskedImplicitProblem(scheme, fomObj, linearDecoder, \ romState, fomReferenceState, \ projector, masker) - stepper = problem.stepper() # linear and non linear solver lsO = MyLinSolver() - nlsO = solvers.create_newton_raphson(stepper, romState, lsO) + nlsO = solvers.create_newton_raphson(problem, romState, lsO) nlsO.setMaxIterations(15) # solve the problem - ode.advance_n_steps(stepper, romState, 0., dt, nsteps, nlsO) + ode.advance_n_steps(problem, romState, 0., dt, nsteps, nlsO) # after we are done, use the reconstructor object to reconstruct the fom state # NOTE: even though the Galerkin problem was run on the "masked mesh points", @@ -140,15 +139,14 @@ def runMaskedLspg(fomObj, dt, nsteps, modes, sampleMeshIndices): problem = rom.lspg.unsteady.MaskedProblem(scheme, fomObj, linearDecoder,\ romState, fomReferenceState,\ masker) - stepper = problem.stepper() # linear and non linear solver lsO = MyLinSolver() - nlsO = solvers.create_gauss_newton(stepper, romState, lsO) + nlsO = solvers.create_gauss_newton(problem, romState, lsO) nlsO.setMaxIterations(10) # solve the problem - ode.advance_n_steps(stepper, romState, 0., dt, nsteps, nlsO) + ode.advance_n_steps(problem, romState, 0., dt, nsteps, nlsO) # after we are done, use the reconstructor object to reconstruct the fom state # NOTE: even though the Galerkin problem was run on the "masked mesh points", diff --git a/docs/conf.py b/docs/conf.py index 1a91431..384ad14 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -57,8 +57,6 @@ ("   - WLS",), ]), - ("Role of ML", []), - ("Full Demos", #("Demos", [ ("1D adv-diff: Galerkin with POD modes", ), @@ -69,6 +67,8 @@ ("1D adv-diff: LSPG with nonlinear manifold (MLP) ", ), ]), + ("Role of ML", []), + # # tutorials # ("Tutorials", #("Tutorials", # [ diff --git a/docs/html/annotated.html b/docs/html/annotated.html index 8b85953..388904a 100644 --- a/docs/html/annotated.html +++ b/docs/html/annotated.html @@ -55,7 +55,6 @@
  •   - WLS
  • -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/demo1_8md.html b/docs/html/demo1_8md.html index 9ee4ce9..0f34da3 100644 --- a/docs/html/demo1_8md.html +++ b/docs/html/demo1_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/demo2_8md.html b/docs/html/demo2_8md.html index b8f2427..d85735b 100644 --- a/docs/html/demo2_8md.html +++ b/docs/html/demo2_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/demo3_8md.html b/docs/html/demo3_8md.html index 1aca08b..473ac66 100644 --- a/docs/html/demo3_8md.html +++ b/docs/html/demo3_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/demo4_8md.html b/docs/html/demo4_8md.html index d1fab52..f48d3dd 100644 --- a/docs/html/demo4_8md.html +++ b/docs/html/demo4_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/demo5_8md.html b/docs/html/demo5_8md.html index 52c87d0..58afb67 100644 --- a/docs/html/demo5_8md.html +++ b/docs/html/demo5_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/demo6_8md.html b/docs/html/demo6_8md.html index bf45459..815f162 100644 --- a/docs/html/demo6_8md.html +++ b/docs/html/demo6_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/dir_208d2690607c4e3d3fabfa1d18673d36.html b/docs/html/dir_208d2690607c4e3d3fabfa1d18673d36.html index 1167cbf..cd2ac78 100644 --- a/docs/html/dir_208d2690607c4e3d3fabfa1d18673d36.html +++ b/docs/html/dir_208d2690607c4e3d3fabfa1d18673d36.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/dir_4af40c8677da60eb4c6f7c14f8103d72.html b/docs/html/dir_4af40c8677da60eb4c6f7c14f8103d72.html index d912322..251fcb3 100644 --- a/docs/html/dir_4af40c8677da60eb4c6f7c14f8103d72.html +++ b/docs/html/dir_4af40c8677da60eb4c6f7c14f8103d72.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/dir_e3e5033bce933e9613999c4991aa42b8.html b/docs/html/dir_e3e5033bce933e9613999c4991aa42b8.html index 4c57009..d1a646a 100644 --- a/docs/html/dir_e3e5033bce933e9613999c4991aa42b8.html +++ b/docs/html/dir_e3e5033bce933e9613999c4991aa42b8.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/files.html b/docs/html/files.html index d1a7e0b..1c5fe7d 100644 --- a/docs/html/files.html +++ b/docs/html/files.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/index.html b/docs/html/index.html index 5dd83d8..fc9778a 100644 --- a/docs/html/index.html +++ b/docs/html/index.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. @@ -86,7 +86,7 @@

      Python Bindings for Pressio

      -

      Advancing reduced order models (ROMs) for dynamical systems in science and engineering.

      This is the documentation of the Python library, one component of the Pressio ecosystem.

      Start with why

      Model reduction is a broad and very active field. Many methods exist, but there is no such thing as "one method to rule them all". We believe that evaluating the quality of a reduced model requires accounting for several factors, e.g., the reduction in degrees of freedom, training cost, evaluation cost, robustness, simplicity, predictive accuracy, etc. There is no single metric to rely on; it is always a tradeoff.

      We believe that there is a lot to explore in this field both in terms of new research directions as well as assessing robustness of current state-of-the-art methods. There is no better way than an agile Python framework to incentivize and foster work to impact this field. Working towards this goal, pressio4py is our open source contribution to research novel fundamental ideas on model reduction as well as test state-of-the-art methods on problems of arbitrary complexity and from arbitrary disciplines. Python is a great language to do so because it benefits from a large community of developers, a large choice of available packages, and has become the de-facto choice for machine learning. This makes it an ideal framework to explore and merge ideas from different fields.

      Components

      NameDescription/ContentLinksModule(s)
      logger
      (dis)enable pressio logging

      Doc Page
      pressio4py.logger
      solvers_nonlinear
      general info
      Newton-Raphson
      Gauss-Newton
      Levenberg-Marquardt

      Doc Page
      Doc Page
      Doc Page
      Doc Page
      pressio4py.solvers
      ode
      explicit steppers
      implicit steppers
      advancers

      Doc Page
      Doc Page
      Doc Page
      pressio4py.ode
      rom
      general info
      decoder
      Galerkin
      LSPG: steady
      LSPG: unsteady
      WLS

      Doc Page
      Doc Page
      Doc Page
      Doc Page
      Doc Page
      Doc Page
      pressio4py.rom

      Note that we intentionally keep pressio4py limited in scope for now. We don't provide bindings for all the functionalities in the pressio C++ library but only for the model reduction ones and those strictly auxiliary.

      Installation

      To avoid potential issues with mixed versions, make sure the version of pytest you use is compatible with the pip command you use to install. The Python commands must be from the same distribution.

      License and Citation

      The full license is available here.

      We are working on publishing this: you can find our arXiv preprint at: https://arxiv.org/abs/2003.07798

      Questions?

      Find us on Slack: https://pressioteam.slack.com or open an issue on github.

      diff --git a/docs/html/introduction_8md.html b/docs/html/introduction_8md.html index 238c519..d7ec319 100644 --- a/docs/html/introduction_8md.html +++ b/docs/html/introduction_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/logger_8md.html b/docs/html/logger_8md.html index bcf62c1..f14341f 100644 --- a/docs/html/logger_8md.html +++ b/docs/html/logger_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/main_8md.html b/docs/html/main_8md.html index f69544e..4b94219 100644 --- a/docs/html/main_8md.html +++ b/docs/html/main_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/md_pages_components_logger.html b/docs/html/md_pages_components_logger.html index 5bae619..37fc439 100644 --- a/docs/html/md_pages_components_logger.html +++ b/docs/html/md_pages_components_logger.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/md_pages_components_nonlinsolvers_general.html b/docs/html/md_pages_components_nonlinsolvers_general.html index 8712c36..06491e3 100644 --- a/docs/html/md_pages_components_nonlinsolvers_general.html +++ b/docs/html/md_pages_components_nonlinsolvers_general.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/md_pages_components_nonlinsolvers_gn.html b/docs/html/md_pages_components_nonlinsolvers_gn.html index bc38cc3..936d22b 100644 --- a/docs/html/md_pages_components_nonlinsolvers_gn.html +++ b/docs/html/md_pages_components_nonlinsolvers_gn.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/md_pages_components_nonlinsolvers_lm.html b/docs/html/md_pages_components_nonlinsolvers_lm.html index 5dfd3b3..286f842 100644 --- a/docs/html/md_pages_components_nonlinsolvers_lm.html +++ b/docs/html/md_pages_components_nonlinsolvers_lm.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/md_pages_components_nonlinsolvers_nr.html b/docs/html/md_pages_components_nonlinsolvers_nr.html index 1f7ed95..b34128e 100644 --- a/docs/html/md_pages_components_nonlinsolvers_nr.html +++ b/docs/html/md_pages_components_nonlinsolvers_nr.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/md_pages_components_nonlinsolvers_system_api.html b/docs/html/md_pages_components_nonlinsolvers_system_api.html index 82f09b7..4532502 100644 --- a/docs/html/md_pages_components_nonlinsolvers_system_api.html +++ b/docs/html/md_pages_components_nonlinsolvers_system_api.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/md_pages_components_ode_advance.html b/docs/html/md_pages_components_ode_advance.html index 9a9cb37..70568d7 100644 --- a/docs/html/md_pages_components_ode_advance.html +++ b/docs/html/md_pages_components_ode_advance.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/md_pages_components_ode_steppers_explicit.html b/docs/html/md_pages_components_ode_steppers_explicit.html index 675a4e4..8ab2539 100644 --- a/docs/html/md_pages_components_ode_steppers_explicit.html +++ b/docs/html/md_pages_components_ode_steppers_explicit.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/md_pages_components_ode_steppers_implicit.html b/docs/html/md_pages_components_ode_steppers_implicit.html index 5db295d..3b681bf 100644 --- a/docs/html/md_pages_components_ode_steppers_implicit.html +++ b/docs/html/md_pages_components_ode_steppers_implicit.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/md_pages_components_rom_decoder.html b/docs/html/md_pages_components_rom_decoder.html index 18af725..ffa7308 100644 --- a/docs/html/md_pages_components_rom_decoder.html +++ b/docs/html/md_pages_components_rom_decoder.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/md_pages_components_rom_fom_apis.html b/docs/html/md_pages_components_rom_fom_apis.html index 32108e4..a11c68e 100644 --- a/docs/html/md_pages_components_rom_fom_apis.html +++ b/docs/html/md_pages_components_rom_fom_apis.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/md_pages_components_rom_galerkin.html b/docs/html/md_pages_components_rom_galerkin.html index 780c12a..da53444 100644 --- a/docs/html/md_pages_components_rom_galerkin.html +++ b/docs/html/md_pages_components_rom_galerkin.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. @@ -86,13 +86,30 @@

      rom: Galerkin: General Info

      -

      todo: write more

      The pressio4py Galerkin ROMs are designed such that using them involves three main steps:

      1. Create

      You create an instance of a "Galerkin problem", e.g.:

      problem = pressio4py.rom.galerkin.DefaultExplicitProblem(args)

      We currently support three variants:

      All variants return a problem object that meets the following interface:

      class GalerkinProblem
      +

      todo: write more

      The pressio4py Galerkin ROMs are designed such that using them involves three main steps:

      1. Create

      You create an instance of a "Galerkin problem", e.g.:

      problem = pressio4py.rom.galerkin.DefaultExplicitProblem(args)

      We currently support three variants:

      The problem object behaves like a stepper. Therefore, you can use the problem like you would with any other stepper object (more on this below).

      Explicit Problem

      The problem meets the following API:

      class GalerkinProblem
      +
      +  def __call__(state, time, time_step_size, step_count);
      +
      +  def fomStateReconstructor();
      +};

      Implicit Problem

      The problem meets the following API:

      class GalerkinProblem
      +
      +  def __call__(state, time, time_step_size, step_count, solver);
      +
      +  def createResidual()
      +    return # a residual instance
      +
      +  def createJacobian()
      +    return # a Jacobian instance
      +
      +  def residual(state, R)
      +    # evaluates the residual for the given state
       
      -  def stepper()
      +  def jacobian(state, J)
      +    # evaluates the Jacobian for the given state
       
      -  def fomStateReconstructor()
      -};

      The stepper method returns a reference to an explicit stepper or implicit stepper, depending on what you pass when you create the Galerkin problem. The stepper method is, practically, what you would use to retrieve the underlying stepper and use it to solve the problem. Once you have the stepper, you can then use it as discussed on the explicit stepper page or implicit stepper page.

      What does a stepper have to do with a Galerkin ROM? The answer is that practically speaking, at the lowest-level, a Galerkin problem can be reduced to simply a "custom" stepper to advance in time. This is how pressio4py implements this and the reason why a Galerkin problem contains a stepper object inside: when you create the problem, pressio creates the appropriate custom stepper object that you can use. You don't need to know how this is done, or rely on the details, because these are problem- and implementation-dependent, and we reserve the right to change this in the future.

      2. Reference the stepper and solve in time

      Extract the underlying stepper object and solve in time:

      stepper = problme.stepper()
      -pressio4py.ode.advance_n_steps_and_observe(stepper, ...)
      + def fomStateReconstructor(); +};

      2. Solve in time

      What does a stepper have to do with a Galerkin ROM problme? The answer is that practically speaking, at the lowest-level, a Galerkin problem can be reduced to simply a "custom" stepper to advance in time. This is how pressio4py implements this and the reason why a Galerkin problem contains a stepper object inside: when you create the problem, pressio creates the appropriate custom stepper object that you can use. You don't need to know how this is done, or rely on the details, because these are problem- and implementation-dependent, and we reserve the right to change this in the future.

      problem = ...
      +pressio4py.ode.advance_n_steps_and_observe(problem, ...)
      diff --git a/docs/html/md_pages_components_rom_galerkin_default.html b/docs/html/md_pages_components_rom_galerkin_default.html index fb5cab8..8667d90 100644 --- a/docs/html/md_pages_components_rom_galerkin_default.html +++ b/docs/html/md_pages_components_rom_galerkin_default.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. @@ -86,21 +86,20 @@

      rom: Galerkin: default problem

      -

      Defined in module: pressio4py.rom.galerkin

      Import as:       from pressio4py.rom import galerkin

      API, Parameters and Requirements

      problem = galerkin.DefaultExplicitProblem(scheme, fom_adapter, decoder, \   (1)
      +

      Defined in module: pressio4py.rom.galerkin

      Import as:       from pressio4py.rom import galerkin

      API, Parameters and Requirements

      problem = galerkin.DefaultExplicitProblem(scheme, fom_adapter, decoder, \   (1)
                                                 rom_state, fom_ref_state)
       
       problem = galerkin.DefaultImplicitProblem(scheme, fom_adapter, decoder, \   (2)
      -                                          rom_state, fom_ref_state)
      • scheme:
      • fom_adapter:
        • instance of your adapter class specifying the FOM problem.
        • must satisfy one of the APIs suitable for Galerkin, see API list
      • decoder:
        • decoder object
        • must satify the requirements listed here
      • rom_state:
        • currently, must be a rank-1 numpy.array
      • fom_ref_state:
        • your FOM reference state that is used when reconstructing the FOM state
        • must be a rank-1 numpy.array


      Example usage

      Explicit Case

      An example usage for explicit stepper is as follows:

      # assuming: decoder, adapter, rom_state, fom_ref_state are defined
      +                                          rom_state, fom_ref_state)
      • scheme:
      • fom_adapter:
        • instance of your adapter class specifying the FOM problem.
        • must satisfy one of the APIs suitable for Galerkin, see API list
      • decoder:
        • decoder object
        • must satify the requirements listed here
      • rom_state:
        • currently, must be a rank-1 numpy.array
      • fom_ref_state:
        • your FOM reference state that is used when reconstructing the FOM state
        • must be a rank-1 numpy.array


      Example usage

      Explicit Case

      An example usage for explicit stepper is as follows:

      # assuming: decoder, adapter, rom_state, fom_ref_state are defined
       
       scheme = ode.stepscheme.ForwardEuler
       problem = rom.galerkin.DefaultExplicitProblem(scheme, adapter, decoder, rom_state, fom_ref_state)
      -stepper = problem.stepper()
       dt = 1.
       num_steps = 2
       observer = MyObserver()
      -ode.advance_n_steps_and_observe(stepper, rom_state, 0., dt, num_steps, observer)

      Implicit Case

      An example usage for implicit stepper is as follows:

      scheme = ode.stepscheme.BDF1
      +ode.advance_n_steps_and_observe(problem, rom_state, 0., dt, num_steps, observer)

      Implicit Case

      An example usage for implicit stepper is as follows:

      scheme = ode.stepscheme.BDF1
       problem = rom.galerkin.DefaultImplicitProblem(scheme, adapter, decoder, rom_state, fom_ref_state)
      -stepper = problem.stepper()
      +// todo add
      diff --git a/docs/html/md_pages_components_rom_galerkin_hypred.html b/docs/html/md_pages_components_rom_galerkin_hypred.html index 26e73fd..1d42932 100644 --- a/docs/html/md_pages_components_rom_galerkin_hypred.html +++ b/docs/html/md_pages_components_rom_galerkin_hypred.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. @@ -86,11 +86,11 @@

      rom: Galerkin: hyperreduced problem

      -

      Defined in module: pressio4py.rom.galerkin

      Import as:       from pressio4py.rom import galerkin

      API, Parameters and Requirements

      problem = galerkin.HyperreducedExplicitProblem(scheme, fom_adapter, decoder, \      (1)
      +

      Defined in module: pressio4py.rom.galerkin

      Import as:       from pressio4py.rom import galerkin

      API, Parameters and Requirements

      problem = galerkin.HyperreducedExplicitProblem(scheme, fom_adapter, decoder, \      (1)
                                                      rom_state, fom_ref_state, projector)
       
       problem = galerkin.HyperreducedImplicitProblem(scheme, fom_adapter, decoder, \      (2)
      -                                               rom_state, fom_ref_state, projector)
      • scheme:
      • fom_adapter:
        • instance of your adapter class specifying the FOM problem.
        • must satisfy one of the APIs suitable for Galerkin, see API list
      • decoder:
        • decoder object
        • must satify the requirements listed here
      • rom_state:
        • currently, must be a rank-1 numpy.array
      • fom_ref_state:
        • your FOM reference state that is used when reconstructing the FOM state
        • must be a rank-1 numpy.array
      • projector:
        • performs the projection of the FOM operators onto the reduced space
        • must meet this specific API


      Example usage

      todo link tutorials/demos

      + rom_state, fom_ref_state, projector)
      • scheme:
      • fom_adapter:
        • instance of your adapter class specifying the FOM problem.
        • must satisfy one of the APIs suitable for Galerkin, see API list
      • decoder:
        • decoder object
        • must satify the requirements listed here
      • rom_state:
        • currently, must be a rank-1 numpy.array
      • fom_ref_state:
        • your FOM reference state that is used when reconstructing the FOM state
        • must be a rank-1 numpy.array
      • projector:
        • performs the projection of the FOM operators onto the reduced space
        • must meet this specific API


      Example usage

      todo link tutorials/demos

      diff --git a/docs/html/md_pages_components_rom_galerkin_masked.html b/docs/html/md_pages_components_rom_galerkin_masked.html index c9caebe..acb3d83 100644 --- a/docs/html/md_pages_components_rom_galerkin_masked.html +++ b/docs/html/md_pages_components_rom_galerkin_masked.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. @@ -86,13 +86,13 @@

      rom: Galerkin: masked problem

      -

      Defined in module: pressio4py.rom.galerkin

      Import as:       from pressio4py.rom import galerkin

      API, Parameters and Requirements

      problem = galerkin.MaskedExplicitProblem(scheme, fom_adapter, decoder,
      +

      Defined in module: pressio4py.rom.galerkin

      Import as:       from pressio4py.rom import galerkin

      API, Parameters and Requirements

      problem = galerkin.MaskedExplicitProblem(scheme, fom_adapter, decoder,
                                                rom_state, fom_ref_state, \      (1)
                                                projector, masker)
       
       problem = galerkin.MaskedImplicitProblem(scheme, fom_adapter, decoder,
                                                rom_state, fom_ref_state, \      (2)
      -                                         projector, masker)
      • scheme:
      • fom_adapter:
        • instance of your adapter class specifying the FOM problem.
        • must satisfy one of the APIs suitable for Galerkin, see API list
      • decoder:
        • decoder object
        • must satify the requirements listed here
      • rom_state:
        • currently, must be a rank-1 numpy.array
      • fom_ref_state:
        • your FOM reference state that is used when reconstructing the FOM state
        • must be a rank-1 numpy.array
      • projector:
        • performs the projection of the FOM operators onto the reduced space
        • must meet this specific API
      • masker:
        • an functor responsible of "masking" the FOM operators
        • must be a functor with a specific API, see details below

      Masker

      todo: explain what it is

      The masker must meet the following API:

      class Masker:
      +                                         projector, masker)
      • scheme:
      • fom_adapter:
        • instance of your adapter class specifying the FOM problem.
        • must satisfy one of the APIs suitable for Galerkin, see API list
      • decoder:
        • decoder object
        • must satify the requirements listed here
      • rom_state:
        • currently, must be a rank-1 numpy.array
      • fom_ref_state:
        • your FOM reference state that is used when reconstructing the FOM state
        • must be a rank-1 numpy.array
      • projector:
        • performs the projection of the FOM operators onto the reduced space
        • must meet this specific API
      • masker:
        • an functor responsible of "masking" the FOM operators
        • must be a functor with a specific API, see details below

      Masker

      todo: explain what it is

      The masker must meet the following API:

      class Masker:
         def __init__(self, sample_indices):
           self.sample_indices = sample_indices
           self.N = len(self.sample_indices)
      @@ -105,7 +105,7 @@ 

      def __call__(self, operand, time, result): # time is not used, but you can potentially - result[:] = np.take(operand, self.sample_indices)

      where sample_indices is a numpy.array holding the set of the row indices to sample.

      Example usage

      todo link tutorials

      + result[:] = np.take(operand, self.sample_indices)

      where sample_indices is a numpy.array holding the set of the row indices to sample.

      Example usage

      todo link tutorials

      diff --git a/docs/html/md_pages_components_rom_galerkin_projector.html b/docs/html/md_pages_components_rom_galerkin_projector.html index a728489..a26c9f1 100644 --- a/docs/html/md_pages_components_rom_galerkin_projector.html +++ b/docs/html/md_pages_components_rom_galerkin_projector.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. @@ -86,7 +86,7 @@

      rom: Galerkin: projector

      -

      The projector is needed for Galerkin to perform the projection of the FOM operators onto the reduced space.

      It is explicitly required from the user when doing masked or hyper-reduced Galerkin.

      For a default problem, you don't need to pass it because the projector is constructed behind the scenes automatically using the decoder's jacobian.

      todo: explain more, talk about pressio-tools.

      API

      When provided by the user, the projector must be a functor as follows:

      class Projector:
      +

      The projector is needed for Galerkin to perform the projection of the FOM operators onto the reduced space.

      It is explicitly required from the user when doing masked or hyper-reduced Galerkin.

      For a default problem, you don't need to pass it because the projector is constructed behind the scenes automatically using the decoder's jacobian.

      todo: explain more, talk about pressio-tools.

      API

      When provided by the user, the projector must be a functor as follows:

      class Projector:
         def __init__(self, ...):
           # as needed
       
      diff --git a/docs/html/md_pages_components_rom_general.html b/docs/html/md_pages_components_rom_general.html
      index 4f49438..9db5ad0 100644
      --- a/docs/html/md_pages_components_rom_general.html
      +++ b/docs/html/md_pages_components_rom_general.html
      @@ -55,7 +55,6 @@
                       
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/md_pages_components_rom_lspg_default.html b/docs/html/md_pages_components_rom_lspg_default.html index fbbc76e..266e2c8 100644 --- a/docs/html/md_pages_components_rom_lspg_default.html +++ b/docs/html/md_pages_components_rom_lspg_default.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. @@ -86,7 +86,7 @@

      rom: LSPG: unsteady default problem

      -

      Defined in module: pressio4py.rom.lspg.unsteady

      Import as:       from pressio4py.rom import lspg

      API, Parameters and Requirements

      # continuous-time overloads
      +

      Defined in module: pressio4py.rom.lspg.unsteady

      Import as:       from pressio4py.rom import lspg

      API, Parameters and Requirements

      # continuous-time overloads
       problem = lspg.unsteady.DefaultProblem(scheme, fom_adapter, decoder, \            (1)
                                              rom_state, fom_ref_state)
       
      diff --git a/docs/html/md_pages_components_rom_lspg_default_steady.html b/docs/html/md_pages_components_rom_lspg_default_steady.html
      index 61acd70..d0ba712 100644
      --- a/docs/html/md_pages_components_rom_lspg_default_steady.html
      +++ b/docs/html/md_pages_components_rom_lspg_default_steady.html
      @@ -55,7 +55,6 @@
                       
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. @@ -86,18 +86,18 @@

      rom: LSPG: steady problem

      -

      Defined in module: pressio4py.rom.lspg.steady

      Import as:       from pressio4py.rom import lspg

      API

      problem = lspg.steady.Problem(fom_adapter, decoder, \               (1)
      +

      Defined in module: pressio4py.rom.lspg.steady

      Import as:       from pressio4py.rom import lspg

      API

      problem = lspg.steady.Problem(fom_adapter, decoder, \               (1)
                                     rom_state, fom_ref_state)
       
       problem = lspg.steady.PrecProblem(fom_adapter, decoder, rom_state,  (2)
      -                                  fom_ref_state, preconditioner)

      Parameters and Requirements

      • fom_adapter:
        • instance of your adapter class specifying the FOM problem.
        • must satisfy the steady API
      • decoder:
        • decoder object
        • must satify the requirements listed here
      • rom_state:
        • currently, must be a rank-1 numpy.array
      • fom_ref_state:
        • your FOM reference state that is used when reconstructing the FOM state
        • must be a rank-1 numpy.array
      • preconditioner:
        • an functor needed to precondition the ROM operators
        • must be a functor with a specific API:

          class Prec:
          +                                  fom_ref_state, preconditioner)

          Parameters and Requirements

          • fom_adapter:
            • instance of your adapter class specifying the FOM problem.
            • must satisfy the steady API
          • decoder:
            • decoder object
            • must satify the requirements listed here
          • rom_state:
            • currently, must be a rank-1 numpy.array
          • fom_ref_state:
            • your FOM reference state that is used when reconstructing the FOM state
            • must be a rank-1 numpy.array
          • preconditioner:
            • an functor needed to precondition the ROM operators
            • must be a functor with a specific API:

              class Prec:
                 def __call__(self, fom_state, operand):
                   # given the current FOM state,
                   # apply your preconditioner to the operand.
                   # Ensure that you overwrite the data in the operand.
                   # As an example, a trivial preconditioner that does nothing:
                   # operand[:] *= 1.



          -


      Example code

      import numpy as np
      + 


      Example code

      import numpy as np
       from scipy import linalg
       from pressio4py import logger, solvers, rom
       from pressio4py.rom import lspg
      diff --git a/docs/html/md_pages_components_rom_lspg_hypred.html b/docs/html/md_pages_components_rom_lspg_hypred.html
      index 2a82cf8..08ad826 100644
      --- a/docs/html/md_pages_components_rom_lspg_hypred.html
      +++ b/docs/html/md_pages_components_rom_lspg_hypred.html
      @@ -55,7 +55,6 @@
                       
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. @@ -86,7 +86,7 @@

      rom: LSPG: unsteady hyper-reduced problem

      -

      Defined in module: pressio4py.rom.lspg.unsteady

      Import as:       from pressio4py.rom import lspg

      API, Parameters and Requirements

      problem = lspg.unsteady.HypredProblem(scheme, fom_adapter, decoder, \
      +

      Defined in module: pressio4py.rom.lspg.unsteady

      Import as:       from pressio4py.rom import lspg

      API, Parameters and Requirements

      problem = lspg.unsteady.HypredProblem(scheme, fom_adapter, decoder, \
                                             rom_state, fom_ref_state, \
                                             sampleToStencilIndexing)
       
      @@ -98,7 +98,7 @@ 

      # apply your preconditioner to the operand. # Ensure that you overwrite the data in the operand. # As an example, a trivial preconditioner that does nothing: - # operand[:] *= 1.


      Stencil to sample indexing

      When working with a hyper-reduced problem, pressio4py has to manipulate objects that have different sizes/distributions. For such problem, in fact, some operators are naturally defined on the what we refer to as "sample mesh" while some are defined on what we call the "stencil mesh".

      As explained here, recall that:

      1. sample mesh: a disjoint collection of elements where the velocity (or residual) operator is computed.
      2. stencil mesh: the set of all nodes or elements needed to compute the velocity or residual on the sample mesh.
      3. Typically, the sample mesh is a subset of the stencil mesh.

      The sample to stencil indexing is a list of indices that you need to provide such that pressio4py knows how to properly combine operands defined on stencil and sample mesh.

      Explain it to me better!

      Suppose that your FOM problem involves a 2D problem and that your FOM numerical method needs at every cell information from the nearest neighbors. For the sake of explanation, it does not matter what problem we are solving, only what we just said. Now, suppose that you want to try hyper-reduced LSPG on it. You come up with a sample and stencil mesh for your problem (read this page for some information about how to select sample mesh cells), and let's say it looks like this:

      Image

      The stencil mesh is the set of all cells shown, while the sample mesh is the subset color-coded yellow. We have added an arbitrary enumeration scheme to uniquely assign a global index to each cell. The enumeration order does not matter, this is just for demonstration purposes. You have an adapter class for your problem that is able to compute the FOM right-hand-side + # operand[:] *= 1.


      Stencil to sample indexing

      When working with a hyper-reduced problem, pressio4py has to manipulate objects that have different sizes/distributions. For such problem, in fact, some operators are naturally defined on the what we refer to as "sample mesh" while some are defined on what we call the "stencil mesh".

      As explained here, recall that:

      1. sample mesh: a disjoint collection of elements where the velocity (or residual) operator is computed.
      2. stencil mesh: the set of all nodes or elements needed to compute the velocity or residual on the sample mesh.
      3. Typically, the sample mesh is a subset of the stencil mesh.

      The sample to stencil indexing is a list of indices that you need to provide such that pressio4py knows how to properly combine operands defined on stencil and sample mesh.

      Explain it to me better!

      Suppose that your FOM problem involves a 2D problem and that your FOM numerical method needs at every cell information from the nearest neighbors. For the sake of explanation, it does not matter what problem we are solving, only what we just said. Now, suppose that you want to try hyper-reduced LSPG on it. You come up with a sample and stencil mesh for your problem (read this page for some information about how to select sample mesh cells), and let's say it looks like this:

      Image

      The stencil mesh is the set of all cells shown, while the sample mesh is the subset color-coded yellow. We have added an arbitrary enumeration scheme to uniquely assign a global index to each cell. The enumeration order does not matter, this is just for demonstration purposes. You have an adapter class for your problem that is able to compute the FOM right-hand-side $f$ diff --git a/docs/html/md_pages_components_rom_lspg_masked.html b/docs/html/md_pages_components_rom_lspg_masked.html index 77bb00d..bf865da 100644 --- a/docs/html/md_pages_components_rom_lspg_masked.html +++ b/docs/html/md_pages_components_rom_lspg_masked.html @@ -55,7 +55,6 @@

    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. @@ -86,7 +86,7 @@

      rom: LSPG: unsteady masked problem

      -

      Defined in module: pressio4py.rom.lspg.unsteady

      Import as:       from pressio4py.rom import lspg

      API, Parameters and Requirements

      # continuous-time overloads
      +

      Defined in module: pressio4py.rom.lspg.unsteady

      Import as:       from pressio4py.rom import lspg

      API, Parameters and Requirements

      # continuous-time overloads
       problem = lspg.unsteady.MaskedProblem(scheme, fom_adapter, decoder, \              (1)
                                             rom_state, fom_ref_state, masker)
       
      diff --git a/docs/html/md_pages_components_rom_lspg_masked_steady.html b/docs/html/md_pages_components_rom_lspg_masked_steady.html
      index f895b01..fcca26f 100644
      --- a/docs/html/md_pages_components_rom_lspg_masked_steady.html
      +++ b/docs/html/md_pages_components_rom_lspg_masked_steady.html
      @@ -55,7 +55,6 @@
                       
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. @@ -86,11 +86,11 @@

      rom: LSPG: steady masked problem

      -

      Defined in module: pressio4py.rom.lspg.steady

      Import as:       from pressio4py.rom import lspg

      API

      problem = lspg.steady.MaskedProblem(fom_adapter, decoder, \
      +

      Defined in module: pressio4py.rom.lspg.steady

      Import as:       from pressio4py.rom import lspg

      API

      problem = lspg.steady.MaskedProblem(fom_adapter, decoder, \
                                           rom_state, fom_ref_state, masker)
       
       problem = lspg.steady.PrecMaskedProblem(fom_adapter, decoder, rom_state,
      -                                        fom_ref_state, masker, preconditioner)

      Parameters and Requirements

      • fom_adapter:
        • instance of your adapter class specifying the FOM problem.
        • must satisfy the steady API
      • decoder:
        • decoder object
        • must satify the requirements listed here
      • rom_state:
        • currently, must be a rank-1 numpy.array
      • fom_ref_state:
        • your FOM reference state that is used when reconstructing the FOM state
        • must be a rank-1 numpy.array
      • masker:
        • functor responsible of "masking" the FOM operators
        • must be a functor with a specific API:

          class Masker:
          +                                        fom_ref_state, masker, preconditioner)

          Parameters and Requirements

          • fom_adapter:
            • instance of your adapter class specifying the FOM problem.
            • must satisfy the steady API
          • decoder:
            • decoder object
            • must satify the requirements listed here
          • rom_state:
            • currently, must be a rank-1 numpy.array
          • fom_ref_state:
            • your FOM reference state that is used when reconstructing the FOM state
            • must be a rank-1 numpy.array
          • masker:
            • functor responsible of "masking" the FOM operators
            • must be a functor with a specific API:

              class Masker:
                 def __init__(self, sample_indices):
                   self.sample_indices = sample_indices
                   self.N = len(self.sample_indices)
              @@ -109,7 +109,7 @@ 

              # Ensure that you overwrite the data in the operand. # As an example, a trivial preconditioner that does nothing: # operand[:] *= 1.



          -


      Example code

      todo add

      +


      Example code

      todo add

      diff --git a/docs/html/md_pages_components_rom_lspg_steady.html b/docs/html/md_pages_components_rom_lspg_steady.html index d0c95bf..debdf52 100644 --- a/docs/html/md_pages_components_rom_lspg_steady.html +++ b/docs/html/md_pages_components_rom_lspg_steady.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. @@ -86,7 +86,7 @@

      rom: Steady LSPG

      -

      todo: write this better

      The pressio4py steady LSPG ROMs are designed to involve two main steps:

      1. Create

      You instantiate a "steady LSPG problem", e.g.:

      problem = pressio4py.rom.lspg.steady.Problem(...)

      We currently support two variants:

      Refer to each problem page for details on each specific variant.

      The returned problem object is an instantiation of a class exposing the following interface:

      class Problem
      +

      todo: write this better

      The pressio4py steady LSPG ROMs are designed to involve two main steps:

      1. Create

      You instantiate a "steady LSPG problem", e.g.:

      problem = pressio4py.rom.lspg.steady.Problem(...)

      We currently support two variants:

      Refer to each problem page for details on each specific variant.

      The returned problem object is an instantiation of a class exposing the following interface:

      class Problem
       
         def fomStateReconstructor()
           return # reference to object for reconstructing FOM state
      @@ -102,7 +102,7 @@ 

      def jacobian(state, J) # evaluates the Jacobian for the given state -};

      2. Solve

      • you use a nonlinear least-squares solvers to solve the problem

        solver = pressio4py.solvers.create_gauss_newton(problem, ...)
        +};

      2. Solve

      • you use a nonlinear least-squares solvers to solve the problem

        solver = pressio4py.solvers.create_gauss_newton(problem, ...)
         solver.solve(problem, ...)
      • note, in fact, that the problem's API conforms to the one required by the nonlinear solvers
      • for this solve stage, you don't have to use the pressio4py solvers. Once you have the problem object, you can also use your own nonlinear least-squares solver. As shown above, the problem exposes all the operators that you need to solve.




      diff --git a/docs/html/md_pages_components_rom_lspg_unsteady.html b/docs/html/md_pages_components_rom_lspg_unsteady.html index 14d886e..a5837e4 100644 --- a/docs/html/md_pages_components_rom_lspg_unsteady.html +++ b/docs/html/md_pages_components_rom_lspg_unsteady.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. @@ -86,13 +86,25 @@

      rom: Unsteady LSPG: General Info

      -

      todo: write more

      The pressio4py unsteady LSPG ROMs are designed such that using them involves these main steps:

      1. Create

      You create an instance of a "LSPG problem", e.g.:

      problem = pressio4py.rom.lspg.unsteady.DefaultProblem(args)

      We currently support three variants:

      All variants return a problem object that meets the following interface:

      class UnsteadyLSPGProblem
      +

      todo: write more

      The pressio4py unsteady LSPG ROMs are designed such that using them involves these main steps:

      1. Create

      You create an instance of a "LSPG problem", e.g.:

      problem = pressio4py.rom.lspg.unsteady.DefaultProblem(args)

      We currently support three variants:

      All variants return a problem object that meets the following interface:

      class UnsteadyLSPGProblem
      +
      +  def __call__(state, time, time_step_size, step_count, solver);
      +
      +  def createResidual()
      +    return # a residual instance
      +
      +  def createJacobian()
      +    return # a Jacobian instance
      +
      +  def residual(state, R)
      +    # evaluates the residual for the given state
       
      -  def stepper()
      +  def jacobian(state, J)
      +    # evaluates the Jacobian for the given state
       
         def fomStateReconstructor()
      -};

      The stepper method returns a reference to an implicit stepper object that the problem creates and owns. The stepper method is what you use to retrieve the underlying stepper and solve the problem in time. Once you have the stepper, you can then use it as discussed in implicit stepper page.

      What does a stepper have to do with a LSPG ROM? The answer is that practically speaking, at the lowest-level, an unsteady LSPG problem can be reduced to simply a "custom" stepper to advance in time. This is how pressio4py implements this and the reason why a LSPG problem contains a stepper object inside: when you create the problem, pressio creates the appropriate custom stepper object that you can use. You don't need to know how this is done, or rely on the details, because these are problem- and implementation-dependent, and we reserve the right to change this in the future.

      2. Reference the stepper and solve in time

      Extract the underlying stepper object and solve in time:

      stepper = problme.stepper()
      -pressio4py.ode.advance_n_steps_and_observe(stepper, ...)

      Remember that for LSPG, you are solving at each step a nonlinear least-squares problem. Therefore, the solver you need to use is a nonlinear least-squares solver, e.g, Gauss-Newton or Levernberg-Marquardt.

      +};

      2. Solve in time

      What does a stepper have to do with a LSPG ROM? The answer is that practically speaking, at the lowest-level, an unsteady LSPG problem can be reduced to simply a "custom" stepper to advance in time. This is how pressio4py implements this and the reason why a LSPG problem behaves like a stepper. You don't need to know how this is done, or rely on the details, because these are problem- and implementation-dependent, and we reserve the right to change this in the future.

      stepper = ...
      +pressio4py.ode.advance_n_steps_and_observe(problem, ...)

      Remember that for LSPG, you are solving at each step a nonlinear least-squares problem. Therefore, the solver you need to use is a nonlinear least-squares solver, e.g, Gauss-Newton or Levernberg-Marquardt.

      diff --git a/docs/html/md_pages_components_rom_wls.html b/docs/html/md_pages_components_rom_wls.html index 136006e..9eccb1d 100644 --- a/docs/html/md_pages_components_rom_wls.html +++ b/docs/html/md_pages_components_rom_wls.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/md_pages_demos_demo1.html b/docs/html/md_pages_demos_demo1.html index d3ec081..fabdd40 100644 --- a/docs/html/md_pages_demos_demo1.html +++ b/docs/html/md_pages_demos_demo1.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. @@ -86,7 +86,7 @@

      1D adv-diff: Galerkin with POD modes

      -

      Overview

      We cover these three typical steps needed for a ROM:

      1. generate of snapshots using the full-order model (FOM)
      2. compute the basis: here we demonstrate the use of POD modes
      3. execute the ROM: here we leverage the GALERKIN ROM to demonstrate a reproductive test, i.e., we run the ROM using the same physical coefficients, b.c., etc. A predictive run is demonstrated in a different demo.

      FOM Equations

      The governing equations for this problem are:

      +

      This page describes a demo for a reproductive Galerkin ROM applied to a 1D advection-diffusion problem using POD modes as basis. By the end, it should be clear how to setup the problem. This demo purposefully focuses on a simple test since the main goal is to demonstrate the steps and code. More complex cases will be shown in other demos. The full demo script is here.

      Overview

      We cover these three typical steps needed for a ROM:

      1. generate of snapshots using the full-order model (FOM)
      2. compute the basis: here we demonstrate the use of POD modes
      3. execute the ROM: here we leverage the GALERKIN ROM to demonstrate a reproductive test, i.e., we run the ROM using the same physical coefficients, b.c., etc. A predictive run is demonstrated in a different demo.

      FOM Equations

      The governing equations for this problem are:

      \[ \frac{\partial u}{\partial t} = \frac{\partial}{\partial x} (k(u,x) \frac{\partial u}{\partial x} ) - a*\frac{\partial u}{\partial x} \] @@ -224,41 +224,40 @@

      -. We use homogeneous BC. Note that a class approximating the FOM operators via finite-differences is implemented here.

      Main function

      The main function of the demo is the following:

      if __name__ == "__main__":
      -  logger.initialize(logger.logto.terminal)
      -  logger.setVerbosity([logger.loglevel.info])
      +. We use homogeneous BC. Note that a class approximating the FOM operators via finite-differences is implemented here.

      Main function

      The main function of the demo is the following:

      logger.initialize(logger.logto.terminal)
      +logger.setVerbosity([logger.loglevel.info])
       
      -  # create fom object
      -  fomObj = AdvDiff1d(nGrid=120, adv_coef=2.0)
      +# create fom object
      +fomObj = AdvDiff1d(nGrid=120, adv_coef=2.0)
       
      -  # the final time to integrate to
      -  finalTime = .05
      +# the final time to integrate to
      +finalTime = .05
       
      -  #--- 1. FOM ---#
      -  fomTimeStepSize  = 1e-5
      -  fomNumberOfSteps = int(finalTime/fomTimeStepSize)
      -  sampleEvery      = 200
      -  [fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)
      +#--- 1. FOM ---#
      +fomTimeStepSize  = 1e-5
      +fomNumberOfSteps = int(finalTime/fomTimeStepSize)
      +sampleEvery      = 200
      +[fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)
       
      -  #--- 2. POD ---#
      -  modes = computePodModes(snapshots)
      +#--- 2. POD ---#
      +modes = computePodModes(snapshots)
       
      -  #--- 3. GALERKIN ROM ---#
      -  romTimeStepSize  = 3e-4
      -  romNumberOfSteps = int(finalTime/romTimeStepSize)
      -  # run with various number of modes
      -  romSizes = [2,4,6]
      -  approximations = {}
      -  for romSize in romSizes:
      -    currentSolution = runGalerkin(fomObj, romTimeStepSize,
      -                                  romNumberOfSteps,
      -                                  modes[:,:romSize])
      -    approximations[romSize] = currentSolution
      +#--- 3. GALERKIN ROM ---#
      +romTimeStepSize  = 3e-4
      +romNumberOfSteps = int(finalTime/romTimeStepSize)
      +# run with various number of modes
      +romSizes = [2,4,6]
      +approximations = {}
      +for romSize in romSizes:
      +  currentSolution = runGalerkin(fomObj, romTimeStepSize,
      +                                romNumberOfSteps,
      +                                modes[:,:romSize])
      +  approximations[romSize] = currentSolution
       
      -    # compute l2-error between fom and approximate state
      -    fomNorm = linalg.norm(fomFinalState)
      -    err = linalg.norm(fomFinalState-currentSolution)
      -    print("With {} modes, final relative l2 error: {}".format(romSize, err/fomNorm))

      1. Run FOM and collect snapshots

      def doFom(fom, dt, nsteps, saveFreq):
      +  # compute l2-error between fom and approximate state
      +  fomNorm = linalg.norm(fomFinalState)
      +  err = linalg.norm(fomFinalState-currentSolution)
      +  print("With {} modes, final relative l2 error: {}".format(romSize, err/fomNorm))

      1. Run FOM and collect snapshots

      def doFom(fom, dt, nsteps, saveFreq):
         u = fom.u0.copy()
         U = [u]
         f = fom.createVelocity()
      @@ -270,41 +269,41 @@ 

      if i % saveFreq == 0: U.append(u) Usolns = np.array(U) - return [u, Usolns.T]

      2. Compute POD modes

      print("SVD on matrix: ", snapshots.shape)
      +  return [u, Usolns.T]

      2. Compute POD modes

      print("SVD on matrix: ", snapshots.shape)
       U,S,VT = np.linalg.svd(snapshots)
      -return U

      3. Construct and run ROM

      # auxiliary class to use in the solve below
      -# to monitor the rom state during time stepping
      -class RomStateObserver:
      -  def __call__(self, timeStep, time, state): pass
      +return U

      3. Construct and run ROM

      def runGalerkin(fomObj, dt, nsteps, modes):
      +  # auxiliary class to use in the solve below
      +  # to monitor the rom state during time stepping
      +  class RomStateObserver:
      +    def __call__(self, timeStep, time, state): pass
       
      -# find out number of modes wanted
      -romSize = modes.shape[1]
      +  # find out number of modes wanted
      +  romSize = modes.shape[1]
       
      -# create a linear decoder, passing only the desired number of modes
      -# this will make a deep copy of the modes
      -linearDecoder = rom.Decoder(modes)
      +  # create a linear decoder, passing only the desired number of modes
      +  # this will make a deep copy of the modes
      +  linearDecoder = rom.Decoder(modes)
       
      -# fom reference state: here it is zero
      -fomReferenceState = np.zeros(fomObj.nGrid)
      +  # fom reference state: here it is zero
      +  fomReferenceState = np.zeros(fomObj.nGrid)
       
      -# create ROM state by projecting the fom initial condition
      -fomInitialState = fomObj.u0.copy()
      -romState = np.dot(modes.T, fomInitialState)
      +  # create ROM state by projecting the fom initial condition
      +  fomInitialState = fomObj.u0.copy()
      +  romState = np.dot(modes.T, fomInitialState)
       
      -# create problem
      -scheme = ode.stepscheme.ForwardEuler
      -problem = rom.galerkin.DefaultExplicitProblem(scheme, fomObj, linearDecoder, romState, fomReferenceState)
      -stepper = problem.stepper()
      +  # create problem
      +  scheme = ode.stepscheme.ForwardEuler
      +  problem = rom.galerkin.DefaultExplicitProblem(scheme, fomObj, linearDecoder, romState, fomReferenceState)
       
      -# create object to monitor the romState at every iteration
      -myObs = RomStateObserver()
      -# solve problem
      -ode.advance_n_steps_and_observe(stepper, romState, 0., dt, nsteps, myObs)
      +  # create object to monitor the romState at every iteration
      +  myObs = RomStateObserver()
      +  # solve problem
      +  ode.advance_n_steps_and_observe(problem, romState, 0., dt, nsteps, myObs)
       
      -# after we are done, use the reconstructor object to reconstruct the fom state
      -# get the reconstructor object: this allows to map romState to fomState
      -fomRecon = problem.fomStateReconstructor()
      -return fomRecon(romState)

      Results

      If everything works fine, the following plot shows the result. We see that for this toy example, the full solution is recovered very well with Galerkin with just a few POD modes.

      Image
      + # after we are done, use the reconstructor object to reconstruct the fom state + # get the reconstructor object: this allows to map romState to fomState + fomRecon = problem.fomStateReconstructor() + return fomRecon(romState)

      Results

      If everything works fine, the following plot shows the result. We see that for this toy example, the full solution is recovered very well with Galerkin with just a few POD modes.

      Image
      diff --git a/docs/html/md_pages_demos_demo2.html b/docs/html/md_pages_demos_demo2.html index 00ce8d5..0851a8c 100644 --- a/docs/html/md_pages_demos_demo2.html +++ b/docs/html/md_pages_demos_demo2.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. @@ -86,38 +86,37 @@

      1D adv-diff: LSPG with POD modes

      -

      Overview

      We cover these three typical steps needed for a ROM:

      1. generate of snapshots using the full-order model (FOM)
      2. compute the basis: here we demonstrate the use of POD modes
      3. execute the ROM: here we leverage the LSPG ROM to demonstrate a reproductive test, i.e., we run the ROM using the same physical coefficients, b.c., etc. A predictive run is demonstrated in a different tutorial.

      The governing equations for this problem are the same as those in here,

      Main function

      The main function of the demo is the following:

      if __name__ == "__main__":
      -  logger.initialize(logger.logto.terminal)
      -  logger.setVerbosity([logger.loglevel.info])
      -
      -  # create fom object
      -  fomObj = AdvDiff1d(nGrid=120, adv_coef=2.0)
      -
      -  # the final time to integrate to
      -  finalTime = .05
      -
      -  #--- 1. FOM ---#
      -  fomTimeStepSize  = 1e-5
      -  fomNumberOfSteps = int(finalTime/fomTimeStepSize)
      -  sampleEvery      = 200
      -  [fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)
      -
      -  #--- 2. POD ---#
      -  modes = computePodModes(snapshots)
      -
      -  #--- 3. LSPG ROM ---#
      -  romSize = 4
      -  romTimeStepSize  = 3e-4
      -  romNumberOfSteps = int(finalTime/romTimeStepSize)
      -  # we pass only romSize modes
      -  approximatedState = runLspg(fomObj, romTimeStepSize, romNumberOfSteps, modes[:,:romSize])
      -
      -  # compute l2-error between fom and approximate state
      -  fomNorm = linalg.norm(fomFinalState)
      -  err = linalg.norm(fomFinalState-approximatedState)
      -  print("Final state relative l2 error: {}".format(err/fomNorm))
      -
      -  logger.finalize()

      1. Run FOM and collect snapshots

      def doFom(fom, dt, nsteps, saveFreq):
      +

      Overview

      We cover these three typical steps needed for a ROM:

      1. generate of snapshots using the full-order model (FOM)
      2. compute the basis: here we demonstrate the use of POD modes
      3. execute the ROM: here we leverage the LSPG ROM to demonstrate a reproductive test, i.e., we run the ROM using the same physical coefficients, b.c., etc. A predictive run is demonstrated in a different tutorial.

      The governing equations for this problem are the same as those in here,

      Main function

      The main function of the demo is the following:

      logger.initialize(logger.logto.terminal)
      +logger.setVerbosity([logger.loglevel.info])
      +
      +# create fom object
      +fomObj = AdvDiff1d(nGrid=120, adv_coef=2.0)
      +
      +# the final time to integrate to
      +finalTime = .05
      +
      +#--- 1. FOM ---#
      +fomTimeStepSize  = 1e-5
      +fomNumberOfSteps = int(finalTime/fomTimeStepSize)
      +sampleEvery      = 200
      +[fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)
      +
      +#--- 2. POD ---#
      +modes = computePodModes(snapshots)
      +
      +#--- 3. LSPG ROM ---#
      +romSize = 4
      +romTimeStepSize  = 3e-4
      +romNumberOfSteps = int(finalTime/romTimeStepSize)
      +# we pass only romSize modes
      +approximatedState = runLspg(fomObj, romTimeStepSize, romNumberOfSteps, modes[:,:romSize])
      +
      +# compute l2-error between fom and approximate state
      +fomNorm = linalg.norm(fomFinalState)
      +err = linalg.norm(fomFinalState-approximatedState)
      +print("Final state relative l2 error: {}".format(err/fomNorm))
      +
      +logger.finalize()

      1. Run FOM and collect snapshots

      def doFom(fom, dt, nsteps, saveFreq):
         u = fom.u0.copy()
         U = [u]
         f = fom.createVelocity()
      @@ -129,10 +128,10 @@ 

      if i % saveFreq == 0: U.append(u) Usolns = np.array(U) - return [u, Usolns.T]

      2. Compute POD modes

      def computePodModes(snapshots):
      +  return [u, Usolns.T]

      2. Compute POD modes

      def computePodModes(snapshots):
         print("SVD on matrix: ", snapshots.shape)
         U,S,VT = np.linalg.svd(snapshots)
      -  return U

      3. Construct and run ROM

      def runLspg(fomObj, dt, nsteps, modes):
      +  return U

      3. Construct and run ROM

      def runLspg(fomObj, dt, nsteps, modes):
         # this is an auxiliary class that can be passed to solve
         # LSPG to monitor the rom state.
         class RomStateObserver:
      @@ -162,10 +161,9 @@ 

      # create LSPG problem scheme = ode.stepscheme.BDF1 problem = rom.lspg.unsteady.DefaultProblem(scheme, fomObj, linearDecoder, romState, fomReferenceState) - stepper = problem.stepper() # create the Gauss-Newton solver - nonLinSolver = solvers.create_gauss_newton(stepper, romState, MyLinSolver()) + nonLinSolver = solvers.create_gauss_newton(problem, romState, MyLinSolver()) # set tolerance and convergence criteria nlsTol, nlsMaxIt = 1e-6, 5 nonLinSolver.setMaxIterations(nlsMaxIt) @@ -174,12 +172,12 @@

      # create object to monitor the romState at every iteration myObs = RomStateObserver() # solve problem - ode.advance_n_steps_and_observe(stepper, romState, 0., dt, nsteps, myObs, nonLinSolver) + ode.advance_n_steps_and_observe(problem, romState, 0., dt, nsteps, myObs, nonLinSolver) # after we are done, use the reconstructor object to reconstruct the fom state # get the reconstructor object: this allows to map romState to fomState fomRecon = problem.fomStateReconstructor() - return fomRecon(romState)

      Results

      If everything works fine, the following plot shows the result.

      Image
      + return fomRecon(romState)

      Results

      If everything works fine, the following plot shows the result.

      Image
      diff --git a/docs/html/md_pages_demos_demo3.html b/docs/html/md_pages_demos_demo3.html index a3eb81a..7971ff0 100644 --- a/docs/html/md_pages_demos_demo3.html +++ b/docs/html/md_pages_demos_demo3.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. @@ -86,37 +86,36 @@

      1D adv-diff: LSPG with nonlinear manifold projection via kPCA

      -

      Overview

      This demo solves the same problem as the one here, but instead of using POD modes, we show here how to use a nonlinear manifold computed via kernel PCA.

      Main function

      The main function of the demo is the following:

      if __name__ == "__main__":
      -  logger.initialize(logger.logto.terminal)
      -  logger.setVerbosity([logger.loglevel.info])
      +

      Overview

      This demo solves the same problem as the one here, but instead of using POD modes, we show here how to use a nonlinear manifold computed via kernel PCA.

      Main function

      The main function of the demo is the following:

      logger.initialize(logger.logto.terminal)
      +logger.setVerbosity([logger.loglevel.info])
       
      -  # create fom object
      -  fomObj = AdvDiff1d(nGrid=120, adv_coef=2.0)
      +# create fom object
      +fomObj = AdvDiff1d(nGrid=120, adv_coef=2.0)
       
      -  # the final time to integrate to
      -  finalTime = .05
      +# the final time to integrate to
      +finalTime = .05
       
      -  #--- 1. FOM ---#
      -  fomTimeStepSize  = 1e-5
      -  fomNumberOfSteps = int(finalTime/fomTimeStepSize)
      -  sampleEvery      = 200
      -  [fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)
      +#--- 1. FOM ---#
      +fomTimeStepSize  = 1e-5
      +fomNumberOfSteps = int(finalTime/fomTimeStepSize)
      +sampleEvery      = 200
      +[fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)
       
      -  #--- 2. train a nonlinear mapping using kPCA ---#
      -  # here we use 3 modes, change this to try different modes
      -  myNonLinearMapper = MyMapperKPCA(snapshots.T, numModes=3)
      +#--- 2. train a nonlinear mapping using kPCA ---#
      +# here we use 3 modes, change this to try different modes
      +myNonLinearMapper = MyMapperKPCA(snapshots.T, numModes=3)
       
      -  #--- 3. LSPG ROM ---#
      -  romTimeStepSize  = 3e-4
      -  romNumberOfSteps = int(finalTime/romTimeStepSize)
      -  approximatedState = runLspg(fomObj, romTimeStepSize, romNumberOfSteps, myNonLinearMapper)
      +#--- 3. LSPG ROM ---#
      +romTimeStepSize  = 3e-4
      +romNumberOfSteps = int(finalTime/romTimeStepSize)
      +approximatedState = runLspg(fomObj, romTimeStepSize, romNumberOfSteps, myNonLinearMapper)
       
      -  # compute l2-error between fom and approximate state
      -  fomNorm = linalg.norm(fomFinalState)
      -  err = linalg.norm(fomFinalState-approximatedState)
      -  print("Final state relative l2 error: {}".format(err/fomNorm))
      +# compute l2-error between fom and approximate state
      +fomNorm = linalg.norm(fomFinalState)
      +err = linalg.norm(fomFinalState-approximatedState)
      +print("Final state relative l2 error: {}".format(err/fomNorm))
       
      -  logger.finalize()

      1. Run FOM and collect snapshots

      This step is the same as described here,

      2. Setup and train the nonlinear kPCA mapper

      It is important to note that while the mapper class below has the API required by pressio4py, it can encapsulate any arbitrary mapping function. In this case we show how to create a kPCA-based representation, but one can use, e.g., autoencoder, and any other types of mapping. This is how we enable support for testing various methods.

      class MyMapperKPCA:
      +logger.finalize()

      1. Run FOM and collect snapshots

      This step is the same as described here,

      2. Setup and train the nonlinear kPCA mapper

      It is important to note that while the mapper class below has the API required by pressio4py, it can encapsulate any arbitrary mapping function. In this case we show how to create a kPCA-based representation, but one can use, e.g., autoencoder, and any other types of mapping. This is how we enable support for testing various methods.

      class MyMapperKPCA:
         def __init__(self, snapshots, numModes):
           self.transformer_ = skd.KernelPCA(n_components=numModes,\
                                             kernel='poly',
      @@ -154,7 +153,7 @@ 

      romStateLocal[i] += eps self.applyMapping(romStateLocal, self.fomState1) self.jacobian_[:,i] = (self.fomState1 - self.fomState0) / eps - romStateLocal[i] -= eps

      3. Construct and run LSPG

      def runLspg(fomObj, dt, nsteps, customMapper):
      +        romStateLocal[i] -= eps

      3. Construct and run LSPG

      def runLspg(fomObj, dt, nsteps, customMapper):
         # this is an auxiliary class that can be passed to solve
         # LSPG to monitor the rom state.
         class RomStateObserver:
      @@ -181,10 +180,9 @@ 

      # create LSPG problem scheme = ode.stepscheme.BDF1 problem = rom.lspg.unsteady.DefaultProblem(scheme, fomObj, customDecoder, romState, fomReferenceState) - stepper = problem.stepper() # create the Gauss-Newton solver - nonLinSolver = solvers.create_gauss_newton(stepper, romState, MyLinSolver()) + nonLinSolver = solvers.create_gauss_newton(problem, romState, MyLinSolver()) # set tolerance and convergence criteria nlsTol, nlsMaxIt = 1e-7, 10 nonLinSolver.setMaxIterations(nlsMaxIt) @@ -193,12 +191,12 @@

      # create object to monitor the romState at every iteration myObs = RomStateObserver() # solve problem - ode.advance_n_steps_and_observe(stepper, romState, 0., dt, nsteps, myObs, nonLinSolver) + ode.advance_n_steps_and_observe(problem, romState, 0., dt, nsteps, myObs, nonLinSolver) # after we are done, use the reconstructor object to reconstruct the fom state # get the reconstructor object: this allows to map romState to fomState fomRecon = problem.fomStateReconstructor() - return fomRecon(romState)

      Results

      If everything works fine, the following plot shows the result.

      Image
      + return fomRecon(romState)

      Results

      If everything works fine, the following plot shows the result.

      Image
      diff --git a/docs/html/md_pages_demos_demo4.html b/docs/html/md_pages_demos_demo4.html index 2f23df8..c2b219f 100644 --- a/docs/html/md_pages_demos_demo4.html +++ b/docs/html/md_pages_demos_demo4.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. @@ -86,7 +86,7 @@

      1D adv-diff: POD Galerkin with collocation masking

      -

      Overview

      We cover these steps:

      1. generate of snapshots using the full-order model (FOM)
      2. compute the POD basis
      3. create the masking operator
      4. execute the ROM: here we leverage the GALERKIN ROM to demonstrate a reproductive test, i.e., we run the ROM using the same physical coefficients, b.c., etc.

      The key item introduced here is the "masking" operator. In simple words, masking allows us to mimic the effect of the hyper-reduction without changing the application code. Hyper-reduction is a fundamental part of ROMs needed to approximate the FOM operators, thus contributing significantly to the computational cost savings. However, the main difficulty of hyper-reduction is that it generally is quite intrusive to be done properly.

      To briefly explain what hyper-reduction, let's look at the most basic form of hyper-reduction, namely "collocation". Consider the following system of N ODEs:

      +

      This page describes a demo for a reproductive "masked" Galerkin ROM applied to a 1D advection-diffusion problem using POD modes as basis. The term "mask" refers to using a "trick" to mimic hyper-reduction without actually needing to change the origian application. By the end, it should be clear how to setup the problem. The full demo script is here.

      Overview

      We cover these steps:

      1. generate of snapshots using the full-order model (FOM)
      2. compute the POD basis
      3. create the masking operator
      4. execute the ROM: here we leverage the GALERKIN ROM to demonstrate a reproductive test, i.e., we run the ROM using the same physical coefficients, b.c., etc.

      The key item introduced here is the "masking" operator. In simple words, masking allows us to mimic the effect of the hyper-reduction without changing the application code. Hyper-reduction is a fundamental part of ROMs needed to approximate the FOM operators, thus contributing significantly to the computational cost savings. However, the main difficulty of hyper-reduction is that it generally is quite intrusive to be done properly.

      To briefly explain what hyper-reduction, let's look at the most basic form of hyper-reduction, namely "collocation". Consider the following system of N ODEs:

      \[ \frac{du}{dt} = f(u,x,t) \] @@ -131,7 +131,7 @@

      - only at a subset of grid points. Obviously, the way we compute the locations to select is critical and there are several techniques available to do so. Here, we show a simple example just for demonstration purposes of performing collocation with randomly selected points

      FOM Equations

      The governing equations for this problem are:

      + only at a subset of grid points. Obviously, the way we compute the locations to select is critical and there are several techniques available to do so. Here, we show a simple example just for demonstration purposes of performing collocation with randomly selected points

      FOM Equations

      The governing equations for this problem are:

      \[ \frac{\partial u}{\partial t} = \frac{\partial}{\partial x} (k(u,x) \frac{\partial u}{\partial x} ) - a*\frac{\partial u}{\partial x} \] @@ -269,61 +269,60 @@

      -. We use homogeneous BC. Note that a class approximating the FOM operators via finite-differences is implemented here.

      Main function

      The main function of the demo is the following:

      if __name__ == "__main__":
      -  logger.initialize(logger.logto.terminal)
      -  logger.setVerbosity([logger.loglevel.info])
      +. We use homogeneous BC. Note that a class approximating the FOM operators via finite-differences is implemented here.

      Main function

      The main function of the demo is the following:

      logger.initialize(logger.logto.terminal)
      +logger.setVerbosity([logger.loglevel.info])
       
      -  # total number of grid points
      -  meshSize = 200
      +# total number of grid points
      +meshSize = 200
       
      -  # create fom object
      -  fomObj = AdvDiff1d(nGrid=meshSize, adv_coef=1.0)
      +# create fom object
      +fomObj = AdvDiff1d(nGrid=meshSize, adv_coef=1.0)
       
      -  # the final time to integrate to
      -  finalTime = .05
      +# the final time to integrate to
      +finalTime = .05
       
      -  #--- 1. FOM ---#
      -  fomTimeStepSize  = 1e-5
      -  fomNumberOfSteps = int(finalTime/fomTimeStepSize)
      -  sampleEvery      = 100
      -  [fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)
      +#--- 1. FOM ---#
      +fomTimeStepSize  = 1e-5
      +fomNumberOfSteps = int(finalTime/fomTimeStepSize)
      +sampleEvery      = 100
      +[fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)
       
      -  #--- 2. POD ---#
      -  modes = computePodModes(snapshots)
      +#--- 2. POD ---#
      +modes = computePodModes(snapshots)
       
      -  #--- 3. MASKED GALERKIN ROM ---#
      -  romSize = 10  # number of modes to use
      -  romTimeStepSize  = 1e-4
      -  romNumberOfSteps = int(finalTime/romTimeStepSize)
      +#--- 3. MASKED GALERKIN ROM ---#
      +romSize = 10  # number of modes to use
      +romTimeStepSize  = 1e-4
      +romNumberOfSteps = int(finalTime/romTimeStepSize)
       
      -  # a masked galerkin is supposed to make it easier to emulate the
      -  # effect of hyper-reduction. To create a mask ROM problem,
      -  # we need to select and provide to pressio a set of indices
      -  # identifying a subset of the grid points in the full mesh.
      -  # This is a simple way to mimic hyper-reduction
      -  # without changing the FOM problem. In fact, the fom still
      -  # computes the full operators but we have an additional step
      -  # to "mask" the operators to compute the sample mesh version.
      -  # In this test, the meshSize = 200. Our sample mesh includes
      -  # the two end points since those contain the boundary conditions,
      -  # and 150 randomly selected grid points inside the domain.
      -  # So effectively we use 25% less of the full mesh.
      -  random.seed(312367)
      -  sampleMeshSize = 150
      -  sampleMeshIndices = random.sample(range(1, 199), sampleMeshSize)
      -  sampleMeshIndices = np.append(sampleMeshIndices, [0, 199])
      +# a masked galerkin is supposed to make it easier to emulate the
      +# effect of hyper-reduction. To create a mask ROM problem,
      +# we need to select and provide to pressio a set of indices
      +# identifying a subset of the grid points in the full mesh.
      +# This is a simple way to mimic hyper-reduction
      +# without changing the FOM problem. In fact, the fom still
      +# computes the full operators but we have an additional step
      +# to "mask" the operators to compute the sample mesh version.
      +# In this test, the meshSize = 200. Our sample mesh includes
      +# the two end points since those contain the boundary conditions,
      +# and 150 randomly selected grid points inside the domain.
      +# So effectively we use 25% less of the full mesh.
      +random.seed(312367)
      +sampleMeshSize = 150
      +sampleMeshIndices = random.sample(range(1, 199), sampleMeshSize)
      +sampleMeshIndices = np.append(sampleMeshIndices, [0, 199])
       
      -  # run the masked galerkin problem
      -  approximatedState = runMaskedGalerkin(fomObj, romTimeStepSize,
      -                                        romNumberOfSteps, modes[:,:romSize],
      -                                        sampleMeshIndices)
      +# run the masked galerkin problem
      +approximatedState = runMaskedGalerkin(fomObj, romTimeStepSize,
      +                                      romNumberOfSteps, modes[:,:romSize],
      +                                      sampleMeshIndices)
       
      -  # compute l2-error between fom and approximate state
      -  fomNorm = linalg.norm(fomFinalState)
      -  err = linalg.norm(fomFinalState-approximatedState)
      -  print("Final state relative l2 error: {}".format(err/fomNorm))
      +# compute l2-error between fom and approximate state
      +fomNorm = linalg.norm(fomFinalState)
      +err = linalg.norm(fomFinalState-approximatedState)
      +print("Final state relative l2 error: {}".format(err/fomNorm))
       
      -  logger.finalize()

      1. Run FOM and collect snapshots

      def doFom(fom, dt, nsteps, saveFreq):
      +logger.finalize()

      1. Run FOM and collect snapshots

      def doFom(fom, dt, nsteps, saveFreq):
         u = fom.u0.copy()
         U = [u]
         f = fom.createVelocity()
      @@ -335,11 +334,10 @@ 

      if i % saveFreq == 0: U.append(u) Usolns = np.array(U) - return [u, Usolns.T]

      2. Compute POD modes

      def computePodModes(snapshots):
      +  return [u, Usolns.T]

      2. Compute POD modes

      def computePodModes(snapshots):
         print("SVD on matrix: ", snapshots.shape)
         U,S,VT = np.linalg.svd(snapshots)
      -  return U

      3. Create the sampling indices

      # a masked galerkin is supposed to make it easier to emulate the
      -# effect of hyper-reduction. To create a mask ROM problem,
      +  return U

      3. Create the sampling indices

      # effect of hyper-reduction. To create a mask ROM problem,
       # we need to select and provide to pressio a set of indices
       # identifying a subset of the grid points in the full mesh.
       # This is a simple way to mimic hyper-reduction
      @@ -353,7 +351,7 @@ 

      random.seed(312367) sampleMeshSize = 150 sampleMeshIndices = random.sample(range(1, 199), sampleMeshSize) -sampleMeshIndices = np.append(sampleMeshIndices, [0, 199])

      4. The masker class

      class MyMasker:
      +sampleMeshIndices = np.append(sampleMeshIndices, [0, 199])

      4. The masker class

      class MyMasker:
         def __init__(self, indices):
           self.rows_ = indices
           self.sampleMeshSize_ = len(indices)
      @@ -362,7 +360,7 @@ 

      return np.zeros(self.sampleMeshSize_) def __call__(self, operand, time, result): - result[:] = np.take(operand, self.rows_)

      5. Construct and run the masked ROM

      def runMaskedGalerkin(fomObj, dt, nsteps, modes, sampleMeshIndices):
      +    result[:] = np.take(operand, self.rows_)

      5. Construct and run the masked ROM

      def runMaskedGalerkin(fomObj, dt, nsteps, modes, sampleMeshIndices):
         # find out number of modes wanted
         romSize = modes.shape[1]
       
      @@ -401,17 +399,16 @@ 

      problem = rom.galerkin.MaskedExplicitProblem(scheme, fomObj, linearDecoder, \ romState, fomReferenceState, \ projector, masker) - stepper = problem.stepper() # solve problem - ode.advance_n_steps(stepper, romState, 0., dt, nsteps) + ode.advance_n_steps(problem, romState, 0., dt, nsteps) # after we are done, use the reconstructor object to reconstruct the fom state # NOTE: even though the Galerkin problem was run on the "masked mesh points", # this reconstruction uses the POD modes on the full mesh stored in the decoder # so we can effectively obtain an approximation of the full solution fomRecon = problem.fomStateReconstructor() - return fomRecon(romState)

      Results

      If everything works fine, the following plot shows the result. We see that for this toy example, the full solution is recovered very well with Galerkin with just a few POD modes.

      Image
      + return fomRecon(romState)

      Results

      If everything works fine, the following plot shows the result. We see that for this toy example, the full solution is recovered very well with Galerkin with just a few POD modes.

      Image
      diff --git a/docs/html/md_pages_demos_demo5.html b/docs/html/md_pages_demos_demo5.html index 3be46b3..19dbe48 100644 --- a/docs/html/md_pages_demos_demo5.html +++ b/docs/html/md_pages_demos_demo5.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. @@ -86,71 +86,71 @@

      1D adv-diff: Comparing Masked POD Galerkin against masked POD LSPG

      -

      Overview

      This is a follow up to the previous demo here We compare here maskdd Galerkin and masked LSPG.

      Main function

      The main function of the demo is the following:

      if __name__ == "__main__":
      -  logger.initialize(logger.logto.terminal)
      -  logger.setVerbosity([logger.loglevel.info])
      -
      -  # total number of grid points
      -  meshSize = 200
      -
      -  # create fom object
      -  fomObj = AdvDiff1d(nGrid=meshSize, adv_coef=1.0)
      -
      -  # the final time to integrate to
      -  finalTime = .05
      -
      -  #--- 1. FOM ---#
      -  fomTimeStepSize  = 1e-5
      -  fomNumberOfSteps = int(finalTime/fomTimeStepSize)
      -  sampleEvery      = 100
      -  [fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)
      -
      -  #--- 2. POD ---#
      -  modes = computePodModes(snapshots)
      -
      -  #--- 3. MASKED GALERKIN and LSPG ROM ---#
      -  # a masked problem is supposed to make it easier to emulate the
      -  # effect of hyper-reduction. To create a mask ROM problem,
      -  # we need to select and provide to pressio a set of indices
      -  # identifying a subset of the grid points in the full mesh.
      -  # This is a simple way to mimic hyper-reduction
      -  # without changing the FOM problem. In fact, the fom still
      -  # computes the full operators but we have an additional step
      -  # to "mask" the operators to compute the sample mesh version.
      -  # In this test, the meshSize = 200. Our sample mesh includes
      -  # the two end points since those contain the boundary conditions,
      -  # and 20 randomly selected grid points inside the domain.
      -  # So effectively we use 1/10 of the full mesh.
      -  random.seed(22123)
      -  sampleMeshSize = 20
      -  sampleMeshIndices = random.sample(range(1, 199), sampleMeshSize)
      -  sampleMeshIndices = np.append(sampleMeshIndices, [0, 199])
      -  # sort for convenience, not necessarily needed
      -  sampleMeshIndices = np.sort(sampleMeshIndices)
      -
      -  romSize = 5  # number of modes to use
      -  romTimeStepSize  = 1e-4
      -  romNumberOfSteps = int(finalTime/romTimeStepSize)
      -
      -  # run the masked galerkin problem
      -  [approximatedStateGal, romGal] = runMaskedGalerkin(fomObj, romTimeStepSize,
      -                                                     romNumberOfSteps,
      -                                                     modes[:,:romSize],
      -                                                     sampleMeshIndices)
      -  # run the masked galerkin problem
      -  [approximatedStateLspg, romLspg] = runMaskedLspg(fomObj, romTimeStepSize,
      +

      Overview

      This is a follow up to the previous demo here We compare here maskdd Galerkin and masked LSPG.

      Main function

      The main function of the demo is the following:

      logger.setVerbosity([logger.loglevel.info])
      +
      +# total number of grid points
      +meshSize = 200
      +
      +# create fom object
      +fomObj = AdvDiff1d(nGrid=meshSize, adv_coef=1.0)
      +
      +# the final time to integrate to
      +finalTime = .05
      +
      +#--- 1. FOM ---#
      +fomTimeStepSize  = 1e-5
      +fomNumberOfSteps = int(finalTime/fomTimeStepSize)
      +sampleEvery      = 100
      +[fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)
      +
      +#--- 2. POD ---#
      +modes = computePodModes(snapshots)
      +
      +#--- 3. MASKED GALERKIN and LSPG ROM ---#
      +# a masked problem is supposed to make it easier to emulate the
      +# effect of hyper-reduction. To create a mask ROM problem,
      +# we need to select and provide to pressio a set of indices
      +# identifying a subset of the grid points in the full mesh.
      +# This is a simple way to mimic hyper-reduction
      +# without changing the FOM problem. In fact, the fom still
      +# computes the full operators but we have an additional step
      +# to "mask" the operators to compute the sample mesh version.
      +# In this test, the meshSize = 200. Our sample mesh includes
      +# the two end points since those contain the boundary conditions,
      +# and 20 randomly selected grid points inside the domain.
      +# So effectively we use 1/10 of the full mesh.
      +random.seed(22123)
      +sampleMeshSize = 20
      +sampleMeshIndices = random.sample(range(1, 199), sampleMeshSize)
      +sampleMeshIndices = np.append(sampleMeshIndices, [0, 199])
      +# sort for convenience, not necessarily needed
      +sampleMeshIndices = np.sort(sampleMeshIndices)
      +
      +romSize = 5  # number of modes to use
      +romTimeStepSize  = 1e-4
      +romNumberOfSteps = int(finalTime/romTimeStepSize)
      +
      +# run the masked galerkin problem
      +[approximatedStateGal, romGal] = runMaskedGalerkin(fomObj, romTimeStepSize,
                                                          romNumberOfSteps,
                                                          modes[:,:romSize],
                                                          sampleMeshIndices)
      +# run the masked galerkin problem
      +[approximatedStateLspg, romLspg] = runMaskedLspg(fomObj, romTimeStepSize,
      +                                                 romNumberOfSteps,
      +                                                 modes[:,:romSize],
      +                                                 sampleMeshIndices)
      +
      +# compute l2-error between fom and approximate state
      +fomNorm = linalg.norm(fomFinalState)
      +err1 = linalg.norm(fomFinalState-approximatedStateGal)
      +print("Galerkin: final state relative l2 error: {}".format(err1/fomNorm))
      +err2 = linalg.norm(fomFinalState-approximatedStateLspg)
      +print("LSPG: final state relative l2 error: {}".format(err2/fomNorm))
       
      -  # compute l2-error between fom and approximate state
      -  fomNorm = linalg.norm(fomFinalState)
      -  err1 = linalg.norm(fomFinalState-approximatedStateGal)
      -  print("Galerkin: final state relative l2 error: {}".format(err1/fomNorm))
      -  err2 = linalg.norm(fomFinalState-approximatedStateLspg)
      -  print("LSPG: final state relative l2 error: {}".format(err2/fomNorm))
      +logger.finalize()
       
      -  logger.finalize()

      1. Run FOM and collect snapshots

      def doFom(fom, dt, nsteps, saveFreq):
      +#----------------------------------------------#

      1. Run FOM and collect snapshots

      def doFom(fom, dt, nsteps, saveFreq):
         u = fom.u0.copy()
         U = [u]
         f = fom.createVelocity()
      @@ -162,12 +162,10 @@ 

      if i % saveFreq == 0: U.append(u) Usolns = np.array(U) - return [u, Usolns.T]

      2. Compute POD modes

      def computePodModes(snapshots):
      +  return [u, Usolns.T]

      2. Compute POD modes

      def computePodModes(snapshots):
         print("SVD on matrix: ", snapshots.shape)
         U,S,VT = np.linalg.svd(snapshots)
      -  return U

      3. Create the sampling indices

      # a masked problem is supposed to make it easier to emulate the
      -# effect of hyper-reduction. To create a mask ROM problem,
      -# we need to select and provide to pressio a set of indices
      +  return U

      3. Create the sampling indices

      # we need to select and provide to pressio a set of indices
       # identifying a subset of the grid points in the full mesh.
       # This is a simple way to mimic hyper-reduction
       # without changing the FOM problem. In fact, the fom still
      @@ -182,7 +180,9 @@ 

      sampleMeshIndices = random.sample(range(1, 199), sampleMeshSize) sampleMeshIndices = np.append(sampleMeshIndices, [0, 199]) # sort for convenience, not necessarily needed -sampleMeshIndices = np.sort(sampleMeshIndices)

      4. The masker class

      class MyMasker:
      +sampleMeshIndices = np.sort(sampleMeshIndices)
      +
      +romSize = 5  # number of modes to use

      4. The masker class

      class MyMasker:
         def __init__(self, indices):
           self.rows_ = indices
           self.sampleMeshSize_ = len(indices)
      @@ -197,7 +197,7 @@ 

      if (operand.ndim == 1): result[:] = np.take(operand, self.rows_) else: - result[:] = np.take(operand, self.rows_, axis=0)

      5. Masked Galerkin ROM

      def runMaskedGalerkin(fomObj, dt, nsteps, modes, sampleMeshIndices):
      +      result[:] = np.take(operand, self.rows_, axis=0)

      5. Masked Galerkin ROM

      def runMaskedGalerkin(fomObj, dt, nsteps, modes, sampleMeshIndices):
         # find out number of modes wanted
         romSize = modes.shape[1]
       
      @@ -236,22 +236,21 @@ 

      problem = rom.galerkin.MaskedImplicitProblem(scheme, fomObj, linearDecoder, \ romState, fomReferenceState, \ projector, masker) - stepper = problem.stepper() # linear and non linear solver lsO = MyLinSolver() - nlsO = solvers.create_newton_raphson(stepper, romState, lsO) + nlsO = solvers.create_newton_raphson(problem, romState, lsO) nlsO.setMaxIterations(15) # solve the problem - ode.advance_n_steps(stepper, romState, 0., dt, nsteps, nlsO) + ode.advance_n_steps(problem, romState, 0., dt, nsteps, nlsO) # after we are done, use the reconstructor object to reconstruct the fom state # NOTE: even though the Galerkin problem was run on the "masked mesh points", # this reconstruction uses the POD modes on the full mesh stored in the decoder # so we can effectively obtain an approximation of the full solution fomRecon = problem.fomStateReconstructor() - return [fomRecon(romState), romState]

      6. Masked LSPG ROM

      def runMaskedLspg(fomObj, dt, nsteps, modes, sampleMeshIndices):
      +  return [fomRecon(romState), romState]

      6. Masked LSPG ROM

      def runMaskedLspg(fomObj, dt, nsteps, modes, sampleMeshIndices):
         # find out number of modes wanted
         romSize = modes.shape[1]
       
      @@ -280,22 +279,21 @@ 

      problem = rom.lspg.unsteady.MaskedProblem(scheme, fomObj, linearDecoder,\ romState, fomReferenceState,\ masker) - stepper = problem.stepper() # linear and non linear solver lsO = MyLinSolver() - nlsO = solvers.create_gauss_newton(stepper, romState, lsO) + nlsO = solvers.create_gauss_newton(problem, romState, lsO) nlsO.setMaxIterations(10) # solve the problem - ode.advance_n_steps(stepper, romState, 0., dt, nsteps, nlsO) + ode.advance_n_steps(problem, romState, 0., dt, nsteps, nlsO) # after we are done, use the reconstructor object to reconstruct the fom state # NOTE: even though the Galerkin problem was run on the "masked mesh points", # this reconstruction uses the POD modes on the full mesh stored in the decoder # so we can effectively obtain an approximation of the full solution fomRecon = problem.fomStateReconstructor() - return [fomRecon(romState), romState]

      Results

      If everything works fine, the following plots shows the result. We first plot the result reconstructed only on the sample mesh. This can easily be done using the bases collocated on the sample mesh indices.

      Image

      We then plot the fom solution reconstructed using the bases on the full mesh. Note that all we need to change is just using the full bases. We see that for this toy example, even with just 10% of the grid, LSPG with 5 modes accuractely reproduces the FOM solution. While for Galerkin the solution is less accurate.

      Image
      + return [fomRecon(romState), romState]

      Results

      If everything works fine, the following plots shows the result. We first plot the result reconstructed only on the sample mesh. This can easily be done using the bases collocated on the sample mesh indices.

      Image

      We then plot the fom solution reconstructed using the bases on the full mesh. Note that all we need to change is just using the full bases. We see that for this toy example, even with just 10% of the grid, LSPG with 5 modes accuractely reproduces the FOM solution. While for Galerkin the solution is less accurate.

      Image
      diff --git a/docs/html/md_pages_demos_demo6.html b/docs/html/md_pages_demos_demo6.html index 2534fbc..c3da9e2 100644 --- a/docs/html/md_pages_demos_demo6.html +++ b/docs/html/md_pages_demos_demo6.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. @@ -86,37 +86,36 @@

      1D adv-diff: LSPG with nonlinear manifold projection via MLP

      -

      Overview

      This demo solves the same problem as the one here, but instead of using POD modes, we show here how to use a nonlinear manifold computed approximated by a neural network. Specifically, we use a MLP with 2 hidden layers of sizes 64 and 200.

      Main function

      The main function of the demo is the following:

      if __name__ == "__main__":
      -  logger.initialize(logger.logto.terminal)
      -  logger.setVerbosity([logger.loglevel.info])
      +

      Overview

      This demo solves the same problem as the one here, but instead of using POD modes, we show here how to use a nonlinear manifold computed approximated by a neural network. Specifically, we use a MLP with 2 hidden layers of sizes 64 and 200.

      Main function

      The main function of the demo is the following:

      logger.initialize(logger.logto.terminal)
      +logger.setVerbosity([logger.loglevel.info])
       
      -  # create fom object
      -  fomObj = AdvDiff1d(nGrid=120, adv_coef=2.0)
      +# create fom object
      +fomObj = AdvDiff1d(nGrid=120, adv_coef=2.0)
       
      -  # the final time to integrate to
      -  finalTime = .05
      +# the final time to integrate to
      +finalTime = .05
       
      -  #--- 1. FOM ---#
      -  fomTimeStepSize  = 1e-5
      -  fomNumberOfSteps = int(finalTime/fomTimeStepSize)
      -  sampleEvery      = 200
      -  [fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)
      +#--- 1. FOM ---#
      +fomTimeStepSize  = 1e-5
      +fomNumberOfSteps = int(finalTime/fomTimeStepSize)
      +sampleEvery      = 200
      +[fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)
       
      -  #--- 2. train a nonlinear mapping using PyTorch ---#
      -  # here we use 3 modes, change this to try different modes
      -  myNonLinearMapper = trainMapping(snapshots, romSize=3, epochs=500)
      +#--- 2. train a nonlinear mapping using PyTorch ---#
      +# here we use 3 modes, change this to try different modes
      +myNonLinearMapper = trainMapping(snapshots, romSize=3, epochs=500)
       
      -  #--- 3. LSPG ROM ---#
      -  romTimeStepSize  = 3e-4
      -  romNumberOfSteps = int(finalTime/romTimeStepSize)
      -  approximatedState = runLspg(fomObj, romTimeStepSize, romNumberOfSteps, myNonLinearMapper)
      +#--- 3. LSPG ROM ---#
      +romTimeStepSize  = 3e-4
      +romNumberOfSteps = int(finalTime/romTimeStepSize)
      +approximatedState = runLspg(fomObj, romTimeStepSize, romNumberOfSteps, myNonLinearMapper)
       
      -  # compute l2-error between fom and approximate state
      -  fomNorm = linalg.norm(fomFinalState)
      -  err = linalg.norm(fomFinalState-approximatedState)
      -  print("Final state relative l2 error: {}".format(err/fomNorm))
      +# compute l2-error between fom and approximate state
      +fomNorm = linalg.norm(fomFinalState)
      +err = linalg.norm(fomFinalState-approximatedState)
      +print("Final state relative l2 error: {}".format(err/fomNorm))
       
      -  logger.finalize()

      1. Run FOM and collect snapshots

      This step is the same as described here,

      2. Setup and train the nonlinear mapper

      It is important to note that while the mapper class below has the API required by pressio4py, it can encapsulate any arbitrary mapping function. In this case we show how to create a MLP-based representation in PyTorch, but one can use any other types of mapping and any other library (e.g., Tensorflow, keras). All of the PyTorch-specific code is encapsulated here. If you prefer Tensorflow/keras, an equivalent implementation is here.

      The autoencoder is defined by

      class myAutoencoder(torch.nn.Module):
      +logger.finalize()

      1. Run FOM and collect snapshots

      This step is the same as described here,

      2. Setup and train the nonlinear mapper

      It is important to note that while the mapper class below has the API required by pressio4py, it can encapsulate any arbitrary mapping function. In this case we show how to create a MLP-based representation in PyTorch, but one can use any other types of mapping and any other library (e.g., Tensorflow, keras). All of the PyTorch-specific code is encapsulated here. If you prefer Tensorflow/keras, an equivalent implementation is here.

      The autoencoder is defined by

      class myAutoencoder(torch.nn.Module):
         def __init__(self, fomSize, romSize=10):
           super(myAutoencoder, self).__init__()
           self.encoder = myEncoder(fomSize, romSize)
      @@ -237,7 +236,7 @@ 

      # use pytorch autodifferentiation to compute jacobian of the mapping # slower than finite difference currently J = torch.autograd.functional.jacobian(self.decoder_, torch.Tensor(romState)) - self.jacobian_[:,:] = J.detach()[:,:]

      3. Construct and run LSPG

      def runLspg(fomObj, dt, nsteps, customMapper):
      +    self.jacobian_[:,:] = J.detach()[:,:]

      3. Construct and run LSPG

      def runLspg(fomObj, dt, nsteps, customMapper):
         # this is an auxiliary class that can be passed to solve
         # LSPG to monitor the rom state.
         class RomStateObserver:
      @@ -263,10 +262,9 @@ 

      # create LSPG problem scheme = ode.stepscheme.BDF1 problem = rom.lspg.unsteady.DefaultProblem(scheme, fomObj, customDecoder, romState, fomReferenceState) - stepper = problem.stepper() # create the Gauss-Newton solver - nonLinSolver = solvers.create_gauss_newton(stepper, romState, MyLinSolver()) + nonLinSolver = solvers.create_gauss_newton(problem, romState, MyLinSolver()) # set tolerance and convergence criteria nlsTol, nlsMaxIt = 1e-7, 10 nonLinSolver.setMaxIterations(nlsMaxIt) @@ -275,12 +273,12 @@

      # create object to monitor the romState at every iteration myObs = RomStateObserver() # solve problem - ode.advance_n_steps_and_observe(stepper, romState, 0., dt, nsteps, myObs, nonLinSolver) + ode.advance_n_steps_and_observe(problem, romState, 0., dt, nsteps, myObs, nonLinSolver) # after we are done, use the reconstructor object to reconstruct the fom state # get the reconstructor object: this allows to map romState to fomState fomRecon = problem.fomStateReconstructor() - return fomRecon(romState)

      Results

      If everything works fine, the following plot shows the result.

      Image
      + return fomRecon(romState)

      Results

      If everything works fine, the following plot shows the result.

      Image
      diff --git a/docs/html/md_pages_introduction.html b/docs/html/md_pages_introduction.html index 83dcf2a..5065265 100644 --- a/docs/html/md_pages_introduction.html +++ b/docs/html/md_pages_introduction.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. @@ -86,7 +86,7 @@

      Introduction

      -

      todo Finish

      In a nutshell

      Pressio can be applied to any dynamical system expressible in a continuous-time form as

      +

      todo Finish

      In a nutshell

      Pressio can be applied to any dynamical system expressible in a continuous-time form as

      \[ \frac{d \boldsymbol{y}}{dt} = \boldsymbol{f}(\boldsymbol{y},t; ...) \] diff --git a/docs/html/md_pages_ml_role.html b/docs/html/md_pages_ml_role.html index e2a20ca..82ec5a6 100644 --- a/docs/html/md_pages_ml_role.html +++ b/docs/html/md_pages_ml_role.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/ml__role_8md.html b/docs/html/ml__role_8md.html index b3ce45b..04bab4a 100644 --- a/docs/html/ml__role_8md.html +++ b/docs/html/ml__role_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/modules.html b/docs/html/modules.html index 76e6878..1b53e1f 100644 --- a/docs/html/modules.html +++ b/docs/html/modules.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/namespaces.html b/docs/html/namespaces.html index 3c95434..a302e93 100644 --- a/docs/html/namespaces.html +++ b/docs/html/namespaces.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/nonlinsolvers__general_8md.html b/docs/html/nonlinsolvers__general_8md.html index 5dcd842..83e768d 100644 --- a/docs/html/nonlinsolvers__general_8md.html +++ b/docs/html/nonlinsolvers__general_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/nonlinsolvers__gn_8md.html b/docs/html/nonlinsolvers__gn_8md.html index 0827e28..26197df 100644 --- a/docs/html/nonlinsolvers__gn_8md.html +++ b/docs/html/nonlinsolvers__gn_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/nonlinsolvers__lm_8md.html b/docs/html/nonlinsolvers__lm_8md.html index b9b4181..64808e8 100644 --- a/docs/html/nonlinsolvers__lm_8md.html +++ b/docs/html/nonlinsolvers__lm_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/nonlinsolvers__nr_8md.html b/docs/html/nonlinsolvers__nr_8md.html index 7ebd46e..e7d716c 100644 --- a/docs/html/nonlinsolvers__nr_8md.html +++ b/docs/html/nonlinsolvers__nr_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/nonlinsolvers__system__api_8md.html b/docs/html/nonlinsolvers__system__api_8md.html index 5fd58e0..4154cf5 100644 --- a/docs/html/nonlinsolvers__system__api_8md.html +++ b/docs/html/nonlinsolvers__system__api_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/ode__advance_8md.html b/docs/html/ode__advance_8md.html index b090d6a..e217857 100644 --- a/docs/html/ode__advance_8md.html +++ b/docs/html/ode__advance_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/ode__steppers__explicit_8md.html b/docs/html/ode__steppers__explicit_8md.html index 9007f20..3f4c1f8 100644 --- a/docs/html/ode__steppers__explicit_8md.html +++ b/docs/html/ode__steppers__explicit_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/ode__steppers__implicit_8md.html b/docs/html/ode__steppers__implicit_8md.html index 3e4d6a3..a00bdd8 100644 --- a/docs/html/ode__steppers__implicit_8md.html +++ b/docs/html/ode__steppers__implicit_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/pages.html b/docs/html/pages.html index b9b5856..27e90ac 100644 --- a/docs/html/pages.html +++ b/docs/html/pages.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/rom__decoder_8md.html b/docs/html/rom__decoder_8md.html index c1df4e2..fcf3f3d 100644 --- a/docs/html/rom__decoder_8md.html +++ b/docs/html/rom__decoder_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/rom__fom__apis_8md.html b/docs/html/rom__fom__apis_8md.html index 9e8accf..e5c65e2 100644 --- a/docs/html/rom__fom__apis_8md.html +++ b/docs/html/rom__fom__apis_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/rom__galerkin_8md.html b/docs/html/rom__galerkin_8md.html index 671f9c8..94a300e 100644 --- a/docs/html/rom__galerkin_8md.html +++ b/docs/html/rom__galerkin_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/rom__galerkin__default_8md.html b/docs/html/rom__galerkin__default_8md.html index 43b8a96..d25d862 100644 --- a/docs/html/rom__galerkin__default_8md.html +++ b/docs/html/rom__galerkin__default_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/rom__galerkin__hypred_8md.html b/docs/html/rom__galerkin__hypred_8md.html index 55dcbfa..ce93ef4 100644 --- a/docs/html/rom__galerkin__hypred_8md.html +++ b/docs/html/rom__galerkin__hypred_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/rom__galerkin__masked_8md.html b/docs/html/rom__galerkin__masked_8md.html index 833c2bd..7ece560 100644 --- a/docs/html/rom__galerkin__masked_8md.html +++ b/docs/html/rom__galerkin__masked_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/rom__galerkin__projector_8md.html b/docs/html/rom__galerkin__projector_8md.html index bff61f1..87a3cf0 100644 --- a/docs/html/rom__galerkin__projector_8md.html +++ b/docs/html/rom__galerkin__projector_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/rom__general_8md.html b/docs/html/rom__general_8md.html index 2299a47..4e2477b 100644 --- a/docs/html/rom__general_8md.html +++ b/docs/html/rom__general_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/rom__lspg__default_8md.html b/docs/html/rom__lspg__default_8md.html index 247d09a..7065be9 100644 --- a/docs/html/rom__lspg__default_8md.html +++ b/docs/html/rom__lspg__default_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/rom__lspg__default__steady_8md.html b/docs/html/rom__lspg__default__steady_8md.html index fc53273..ab64543 100644 --- a/docs/html/rom__lspg__default__steady_8md.html +++ b/docs/html/rom__lspg__default__steady_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/rom__lspg__hypred_8md.html b/docs/html/rom__lspg__hypred_8md.html index 02488c3..e323dcd 100644 --- a/docs/html/rom__lspg__hypred_8md.html +++ b/docs/html/rom__lspg__hypred_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/rom__lspg__masked_8md.html b/docs/html/rom__lspg__masked_8md.html index 7c3b919..1b55066 100644 --- a/docs/html/rom__lspg__masked_8md.html +++ b/docs/html/rom__lspg__masked_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/rom__lspg__masked__steady_8md.html b/docs/html/rom__lspg__masked__steady_8md.html index 78657d9..e0da2e8 100644 --- a/docs/html/rom__lspg__masked__steady_8md.html +++ b/docs/html/rom__lspg__masked__steady_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/rom__lspg__steady_8md.html b/docs/html/rom__lspg__steady_8md.html index f1b28dc..6718436 100644 --- a/docs/html/rom__lspg__steady_8md.html +++ b/docs/html/rom__lspg__steady_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/rom__lspg__unsteady_8md.html b/docs/html/rom__lspg__unsteady_8md.html index 8cf13d3..fb84bfd 100644 --- a/docs/html/rom__lspg__unsteady_8md.html +++ b/docs/html/rom__lspg__unsteady_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/html/rom__wls_8md.html b/docs/html/rom__wls_8md.html index 33d6893..a92fb90 100644 --- a/docs/html/rom__wls_8md.html +++ b/docs/html/rom__wls_8md.html @@ -55,7 +55,6 @@
    2.   - WLS
    -
  • Role of ML
  • Full Demos
      @@ -67,6 +66,7 @@
    1. 1D adv-diff: LSPG with nonlinear manifold (MLP)
  • +
  • Role of ML
  • Github Page
    1. diff --git a/docs/latex/index.tex b/docs/latex/index.tex index f5cc89f..1a81887 100644 --- a/docs/latex/index.tex +++ b/docs/latex/index.tex @@ -6,10 +6,10 @@ {\itshape Advancing reduced order models (ROMs) for dynamical systems in science and engineering.} -This is the documentation of the \href{https://github.com/Pressio/pressio4py}{\texttt{ Python library}}, one component of the \href{https://pressio.github.io/}{\texttt{ Pressio ecosystem}}. \hypertarget{index_autotoc_md154}{}\doxysection{Start with why}\label{index_autotoc_md154} +This is the documentation of the \href{https://github.com/Pressio/pressio4py}{\texttt{ Python library}}, one component of the \href{https://pressio.github.io/}{\texttt{ Pressio ecosystem}}. \hypertarget{index_autotoc_md156}{}\doxysection{Start with why}\label{index_autotoc_md156} Model reduction is a broad and very active field. Many methods exist, but there is no such thing as \char`\"{}one method to rule them all\char`\"{}. We believe that evaluating the quality of a reduced model requires accounting for several factors, e.\+g., the reduction in degrees of freedom, training cost, evaluation cost, robustness, simplicity, predictive accuracy, etc. There is no single metric to rely on; it is always a tradeoff. -We believe that there is a lot to explore in this field both in terms of new research directions as well as assessing robustness of current state-\/of-\/the-\/art methods. There is no better way than an agile Python framework to incentivize and foster work to impact this field. Working towards this goal, pressio4py is our open source contribution to research novel fundamental ideas on model reduction as well as test state-\/of-\/the-\/art methods on problems of arbitrary complexity and from arbitrary disciplines. Python is a great language to do so because it benefits from a large community of developers, a large choice of available packages, and has become the de-\/facto choice for machine learning. This makes it an ideal framework to explore and merge ideas from different fields.\hypertarget{index_autotoc_md155}{}\doxysection{Components}\label{index_autotoc_md155} +We believe that there is a lot to explore in this field both in terms of new research directions as well as assessing robustness of current state-\/of-\/the-\/art methods. There is no better way than an agile Python framework to incentivize and foster work to impact this field. Working towards this goal, pressio4py is our open source contribution to research novel fundamental ideas on model reduction as well as test state-\/of-\/the-\/art methods on problems of arbitrary complexity and from arbitrary disciplines. Python is a great language to do so because it benefits from a large community of developers, a large choice of available packages, and has become the de-\/facto choice for machine learning. This makes it an ideal framework to explore and merge ideas from different fields.\hypertarget{index_autotoc_md157}{}\doxysection{Components}\label{index_autotoc_md157} \tabulinesep=1mm \begin{longtabu}spread 0pt [c]{*{4}{|X[-1]}|} \hline @@ -59,7 +59,7 @@ \end{longtabu} -Note that we intentionally keep pressio4py limited in scope for now. We don\textquotesingle{}t provide bindings for all the functionalities in the \href{https://pressio.github.io/pressio/html/index.html}{\texttt{ pressio C++ library}} but only for the model reduction ones and those strictly auxiliary.\hypertarget{index_autotoc_md156}{}\doxysection{Installation}\label{index_autotoc_md156} +Note that we intentionally keep pressio4py limited in scope for now. We don\textquotesingle{}t provide bindings for all the functionalities in the \href{https://pressio.github.io/pressio/html/index.html}{\texttt{ pressio C++ library}} but only for the model reduction ones and those strictly auxiliary.\hypertarget{index_autotoc_md158}{}\doxysection{Installation}\label{index_autotoc_md158} \begin{DoxyParagraph}{} @@ -84,11 +84,8 @@ -If you get an import error, make sure the version of {\ttfamily pytest} you are using is compatible with the {\ttfamily pip} command you used to install. For compatibility, the Python commands must be from the {\bfseries{same}} distribution. - -~\newline -\hypertarget{index_autotoc_md157}{}\doxysection{License and Citation}\label{index_autotoc_md157} +To avoid potential issues with mixed versions, make sure the version of {\ttfamily pytest} you use is compatible with the {\ttfamily pip} command you use to install. The Python commands must be from the {\bfseries{same}} distribution. \hypertarget{index_autotoc_md159}{}\doxysection{License and Citation}\label{index_autotoc_md159} The full license is available \href{https://pressio.github.io/various/license/}{\texttt{ here}}. -We are working on publishing this\+: you can find our ar\+Xiv preprint at\+: \href{https://arxiv.org/abs/2003.07798}{\texttt{ https\+://arxiv.\+org/abs/2003.\+07798}}\hypertarget{index_autotoc_md158}{}\doxysection{Questions?}\label{index_autotoc_md158} +We are working on publishing this\+: you can find our ar\+Xiv preprint at\+: \href{https://arxiv.org/abs/2003.07798}{\texttt{ https\+://arxiv.\+org/abs/2003.\+07798}}\hypertarget{index_autotoc_md160}{}\doxysection{Questions?}\label{index_autotoc_md160} Find us on Slack\+: \href{https://pressioteam.slack.com}{\texttt{ https\+://pressioteam.\+slack.\+com}} or open an issue on \href{https://github.com/Pressio/pressio4py}{\texttt{ github}}. \ No newline at end of file diff --git a/docs/latex/md_pages_components_rom_galerkin.tex b/docs/latex/md_pages_components_rom_galerkin.tex index 508bb5a..97872bd 100644 --- a/docs/latex/md_pages_components_rom_galerkin.tex +++ b/docs/latex/md_pages_components_rom_galerkin.tex @@ -20,29 +20,51 @@ \item Masked\+: \href{md_pages_components_rom_galerkin_masked.html}{\texttt{ link}} \end{DoxyItemize} -All variants return a problem object that meets the following interface\+: +The {\ttfamily problem} object behaves like a stepper. Therefore, you can use the problem like you would with any other stepper object (more on this below).\hypertarget{md_pages_components_rom_galerkin_autotoc_md63}{}\doxysubsection{Explicit Problem}\label{md_pages_components_rom_galerkin_autotoc_md63} +The problem meets the following API\+: \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{class }GalerkinProblem} \DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{keyword}{def }stepper()} +\DoxyCodeLine{ \textcolor{keyword}{def }\_\_call\_\_(state, time, time\_step\_size, step\_count);} \DoxyCodeLine{} -\DoxyCodeLine{ def fomStateReconstructor()} +\DoxyCodeLine{ def fomStateReconstructor();} \DoxyCodeLine{\};} \end{DoxyCode} +\hypertarget{md_pages_components_rom_galerkin_autotoc_md64}{}\doxysubsection{Implicit Problem}\label{md_pages_components_rom_galerkin_autotoc_md64} +The problem meets the following API\+: -The stepper method returns a reference to an \href{md_pages_components_ode_steppers_explicit.html}{\texttt{ explicit stepper}} or \href{md_pages_components_ode_steppers_implicit.html}{\texttt{ implicit stepper}}, depending on what you pass when you create the Galerkin problem. The {\ttfamily stepper} method is, practically, what you would use to retrieve the underlying stepper and use it to solve the problem. Once you have the stepper, you can then use it as discussed on the \href{md_pages_components_ode_steppers_explicit.html}{\texttt{ explicit stepper page}} or \href{md_pages_components_ode_steppers_implicit.html}{\texttt{ implicit stepper page}}. +\begin{DoxyCode}{0} +\DoxyCodeLine{\textcolor{keyword}{class }GalerkinProblem} +\DoxyCodeLine{} +\DoxyCodeLine{ \textcolor{keyword}{def }\_\_call\_\_(state, time, time\_step\_size, step\_count, solver);} +\DoxyCodeLine{} +\DoxyCodeLine{ def createResidual()} +\DoxyCodeLine{ \textcolor{keywordflow}{return} \textcolor{comment}{\# a residual instance}} +\DoxyCodeLine{} +\DoxyCodeLine{ \textcolor{keyword}{def }createJacobian()} +\DoxyCodeLine{ return \textcolor{comment}{\# a Jacobian instance}} +\DoxyCodeLine{} +\DoxyCodeLine{ def residual(state, R)} +\DoxyCodeLine{ \textcolor{comment}{\# evaluates the residual for the given state}} +\DoxyCodeLine{} +\DoxyCodeLine{ \textcolor{keyword}{def }jacobian(state, J)} +\DoxyCodeLine{ \textcolor{comment}{\# evaluates the Jacobian for the given state}} +\DoxyCodeLine{} +\DoxyCodeLine{ def fomStateReconstructor();} +\DoxyCodeLine{\};} -What does a stepper have to do with a Galerkin ROM? The answer is that practically speaking, at the lowest-\/level, a Galerkin problem can be reduced to simply a \char`\"{}custom\char`\"{} stepper to advance in time. This is how pressio4py implements this and the reason why a Galerkin problem contains a stepper object inside\+: when you create the problem, pressio creates the appropriate custom stepper object that you can use. You don\textquotesingle{}t need to know how this is done, or rely on the details, because these are problem-\/ and implementation-\/dependent, and we reserve the right to change this in the future.\hypertarget{md_pages_components_rom_galerkin_autotoc_md63}{}\doxysection{2. Reference the stepper and solve in time}\label{md_pages_components_rom_galerkin_autotoc_md63} -Extract the underlying stepper object and solve in time\+: +\end{DoxyCode} +\hypertarget{md_pages_components_rom_galerkin_autotoc_md65}{}\doxysection{2. Solve in time}\label{md_pages_components_rom_galerkin_autotoc_md65} +What does a stepper have to do with a Galerkin ROM problme? The answer is that practically speaking, at the lowest-\/level, a Galerkin problem can be reduced to simply a \char`\"{}custom\char`\"{} stepper to advance in time. This is how pressio4py implements this and the reason why a Galerkin problem contains a stepper object inside\+: when you create the problem, pressio creates the appropriate custom stepper object that you can use. You don\textquotesingle{}t need to know how this is done, or rely on the details, because these are problem-\/ and implementation-\/dependent, and we reserve the right to change this in the future. \begin{DoxyCode}{0} -\DoxyCodeLine{stepper = problme.stepper()} -\DoxyCodeLine{pressio4py.ode.advance\_n\_steps\_and\_observe(stepper, ...)} +\DoxyCodeLine{problem = ...} +\DoxyCodeLine{pressio4py.ode.advance\_n\_steps\_and\_observe(problem, ...)} \end{DoxyCode} \ No newline at end of file diff --git a/docs/latex/md_pages_components_rom_galerkin_default.tex b/docs/latex/md_pages_components_rom_galerkin_default.tex index a49c894..be300c5 100644 --- a/docs/latex/md_pages_components_rom_galerkin_default.tex +++ b/docs/latex/md_pages_components_rom_galerkin_default.tex @@ -2,7 +2,7 @@ Defined in module\+: {\ttfamily pressio4py.\+rom.\+galerkin} -Import as\+: \quad{} \quad{} \quad{} {\ttfamily from pressio4py.\+rom import galerkin} \hypertarget{md_pages_components_rom_galerkin_default_autotoc_md65}{}\doxysection{API, Parameters and Requirements}\label{md_pages_components_rom_galerkin_default_autotoc_md65} +Import as\+: \quad{} \quad{} \quad{} {\ttfamily from pressio4py.\+rom import galerkin} \hypertarget{md_pages_components_rom_galerkin_default_autotoc_md67}{}\doxysection{API, Parameters and Requirements}\label{md_pages_components_rom_galerkin_default_autotoc_md67} \begin{DoxyCode}{0} \DoxyCodeLine{problem = galerkin.DefaultExplicitProblem(scheme, fom\_adapter, decoder, \(\backslash\) (1)} @@ -45,8 +45,8 @@ \end{DoxyItemize} ~\newline -\hypertarget{md_pages_components_rom_galerkin_default_autotoc_md66}{}\doxysection{Example usage}\label{md_pages_components_rom_galerkin_default_autotoc_md66} -\hypertarget{md_pages_components_rom_galerkin_default_autotoc_md67}{}\doxysubsection{Explicit Case}\label{md_pages_components_rom_galerkin_default_autotoc_md67} +\hypertarget{md_pages_components_rom_galerkin_default_autotoc_md68}{}\doxysection{Example usage}\label{md_pages_components_rom_galerkin_default_autotoc_md68} +\hypertarget{md_pages_components_rom_galerkin_default_autotoc_md69}{}\doxysubsection{Explicit Case}\label{md_pages_components_rom_galerkin_default_autotoc_md69} An example usage for explicit stepper is as follows\+: @@ -55,21 +55,20 @@ \DoxyCodeLine{} \DoxyCodeLine{scheme = ode.stepscheme.ForwardEuler} \DoxyCodeLine{problem = rom.galerkin.DefaultExplicitProblem(scheme, adapter, decoder, rom\_state, fom\_ref\_state)} -\DoxyCodeLine{stepper = problem.stepper()} \DoxyCodeLine{dt = 1.} \DoxyCodeLine{num\_steps = 2} \DoxyCodeLine{observer = MyObserver()} -\DoxyCodeLine{ode.advance\_n\_steps\_and\_observe(stepper, rom\_state, 0., dt, num\_steps, observer)} +\DoxyCodeLine{ode.advance\_n\_steps\_and\_observe(problem, rom\_state, 0., dt, num\_steps, observer)} \end{DoxyCode} -\hypertarget{md_pages_components_rom_galerkin_default_autotoc_md68}{}\doxysubsection{Implicit Case}\label{md_pages_components_rom_galerkin_default_autotoc_md68} +\hypertarget{md_pages_components_rom_galerkin_default_autotoc_md70}{}\doxysubsection{Implicit Case}\label{md_pages_components_rom_galerkin_default_autotoc_md70} An example usage for implicit stepper is as follows\+: \begin{DoxyCode}{0} \DoxyCodeLine{scheme = ode.stepscheme.BDF1} \DoxyCodeLine{problem = rom.galerkin.DefaultImplicitProblem(scheme, adapter, decoder, rom\_state, fom\_ref\_state)} -\DoxyCodeLine{stepper = problem.stepper()} +\DoxyCodeLine{// todo add} \end{DoxyCode} \ No newline at end of file diff --git a/docs/latex/md_pages_components_rom_galerkin_hypred.tex b/docs/latex/md_pages_components_rom_galerkin_hypred.tex index 1e3daa7..d85eb4a 100644 --- a/docs/latex/md_pages_components_rom_galerkin_hypred.tex +++ b/docs/latex/md_pages_components_rom_galerkin_hypred.tex @@ -2,7 +2,7 @@ Defined in module\+: {\ttfamily pressio4py.\+rom.\+galerkin} -Import as\+: \quad{} \quad{} \quad{} {\ttfamily from pressio4py.\+rom import galerkin} \hypertarget{md_pages_components_rom_galerkin_hypred_autotoc_md70}{}\doxysection{API, Parameters and Requirements}\label{md_pages_components_rom_galerkin_hypred_autotoc_md70} +Import as\+: \quad{} \quad{} \quad{} {\ttfamily from pressio4py.\+rom import galerkin} \hypertarget{md_pages_components_rom_galerkin_hypred_autotoc_md72}{}\doxysection{API, Parameters and Requirements}\label{md_pages_components_rom_galerkin_hypred_autotoc_md72} \begin{DoxyCode}{0} \DoxyCodeLine{problem = galerkin.HyperreducedExplicitProblem(scheme, fom\_adapter, decoder, \(\backslash\) (1)} @@ -50,5 +50,5 @@ \end{DoxyItemize} ~\newline -\hypertarget{md_pages_components_rom_galerkin_hypred_autotoc_md71}{}\doxysection{Example usage}\label{md_pages_components_rom_galerkin_hypred_autotoc_md71} +\hypertarget{md_pages_components_rom_galerkin_hypred_autotoc_md73}{}\doxysection{Example usage}\label{md_pages_components_rom_galerkin_hypred_autotoc_md73} todo link tutorials/demos \ No newline at end of file diff --git a/docs/latex/md_pages_components_rom_galerkin_masked.tex b/docs/latex/md_pages_components_rom_galerkin_masked.tex index 96a8061..4aeaef1 100644 --- a/docs/latex/md_pages_components_rom_galerkin_masked.tex +++ b/docs/latex/md_pages_components_rom_galerkin_masked.tex @@ -2,7 +2,7 @@ Defined in module\+: {\ttfamily pressio4py.\+rom.\+galerkin} -Import as\+: \quad{} \quad{} \quad{} {\ttfamily from pressio4py.\+rom import galerkin} \hypertarget{md_pages_components_rom_galerkin_masked_autotoc_md73}{}\doxysection{API, Parameters and Requirements}\label{md_pages_components_rom_galerkin_masked_autotoc_md73} +Import as\+: \quad{} \quad{} \quad{} {\ttfamily from pressio4py.\+rom import galerkin} \hypertarget{md_pages_components_rom_galerkin_masked_autotoc_md75}{}\doxysection{API, Parameters and Requirements}\label{md_pages_components_rom_galerkin_masked_autotoc_md75} \begin{DoxyCode}{0} \DoxyCodeLine{problem = galerkin.MaskedExplicitProblem(scheme, fom\_adapter, decoder,} @@ -54,7 +54,7 @@ \item an functor responsible of \char`\"{}masking\char`\"{} the FOM operators \item must be a functor with a specific API, see details below \end{DoxyItemize} -\end{DoxyItemize}\hypertarget{md_pages_components_rom_galerkin_masked_autotoc_md74}{}\doxysubsection{Masker}\label{md_pages_components_rom_galerkin_masked_autotoc_md74} +\end{DoxyItemize}\hypertarget{md_pages_components_rom_galerkin_masked_autotoc_md76}{}\doxysubsection{Masker}\label{md_pages_components_rom_galerkin_masked_autotoc_md76} todo\+: explain what it is The masker must meet the following API\+: @@ -79,5 +79,5 @@ \end{DoxyCode} -where {\ttfamily sample\+\_\+indices} is a {\ttfamily numpy.\+array} holding the set of the row indices to sample.\hypertarget{md_pages_components_rom_galerkin_masked_autotoc_md75}{}\doxysection{Example usage}\label{md_pages_components_rom_galerkin_masked_autotoc_md75} +where {\ttfamily sample\+\_\+indices} is a {\ttfamily numpy.\+array} holding the set of the row indices to sample.\hypertarget{md_pages_components_rom_galerkin_masked_autotoc_md77}{}\doxysection{Example usage}\label{md_pages_components_rom_galerkin_masked_autotoc_md77} todo link tutorials \ No newline at end of file diff --git a/docs/latex/md_pages_components_rom_galerkin_projector.tex b/docs/latex/md_pages_components_rom_galerkin_projector.tex index 87e3626..f3c5a4b 100644 --- a/docs/latex/md_pages_components_rom_galerkin_projector.tex +++ b/docs/latex/md_pages_components_rom_galerkin_projector.tex @@ -6,7 +6,7 @@ For a \href{md_pages_components_rom_galerkin_default.html}{\texttt{ default}} problem, you don\textquotesingle{}t need to pass it because the projector is constructed behind the scenes automatically using the decoder\textquotesingle{}s jacobian. -todo\+: explain more, talk about pressio-\/tools.\hypertarget{md_pages_components_rom_galerkin_projector_autotoc_md77}{}\doxysection{API}\label{md_pages_components_rom_galerkin_projector_autotoc_md77} +todo\+: explain more, talk about pressio-\/tools.\hypertarget{md_pages_components_rom_galerkin_projector_autotoc_md79}{}\doxysection{API}\label{md_pages_components_rom_galerkin_projector_autotoc_md79} When provided by the user, the projector must be a functor as follows\+: diff --git a/docs/latex/md_pages_components_rom_lspg_default.tex b/docs/latex/md_pages_components_rom_lspg_default.tex index 67d0f99..730d3bc 100644 --- a/docs/latex/md_pages_components_rom_lspg_default.tex +++ b/docs/latex/md_pages_components_rom_lspg_default.tex @@ -2,7 +2,7 @@ Defined in module\+: {\ttfamily pressio4py.\+rom.\+lspg.\+unsteady} -Import as\+: \quad{} \quad{} \quad{} {\ttfamily from pressio4py.\+rom import lspg} \hypertarget{md_pages_components_rom_lspg_default_autotoc_md80}{}\doxysection{API, Parameters and Requirements}\label{md_pages_components_rom_lspg_default_autotoc_md80} +Import as\+: \quad{} \quad{} \quad{} {\ttfamily from pressio4py.\+rom import lspg} \hypertarget{md_pages_components_rom_lspg_default_autotoc_md82}{}\doxysection{API, Parameters and Requirements}\label{md_pages_components_rom_lspg_default_autotoc_md82} \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{comment}{\# continuous-\/time overloads}} diff --git a/docs/latex/md_pages_components_rom_lspg_default_steady.tex b/docs/latex/md_pages_components_rom_lspg_default_steady.tex index 0f96b59..cdc0f07 100644 --- a/docs/latex/md_pages_components_rom_lspg_default_steady.tex +++ b/docs/latex/md_pages_components_rom_lspg_default_steady.tex @@ -2,7 +2,7 @@ Defined in module\+: {\ttfamily pressio4py.\+rom.\+lspg.\+steady} -Import as\+: \quad{} \quad{} \quad{} {\ttfamily from pressio4py.\+rom import lspg} \hypertarget{md_pages_components_rom_lspg_default_steady_autotoc_md82}{}\doxysection{API}\label{md_pages_components_rom_lspg_default_steady_autotoc_md82} +Import as\+: \quad{} \quad{} \quad{} {\ttfamily from pressio4py.\+rom import lspg} \hypertarget{md_pages_components_rom_lspg_default_steady_autotoc_md84}{}\doxysection{API}\label{md_pages_components_rom_lspg_default_steady_autotoc_md84} \begin{DoxyCode}{0} \DoxyCodeLine{problem = lspg.steady.Problem(fom\_adapter, decoder, \(\backslash\) (1)} @@ -12,7 +12,7 @@ \DoxyCodeLine{ fom\_ref\_state, preconditioner)} \end{DoxyCode} -\hypertarget{md_pages_components_rom_lspg_default_steady_autotoc_md83}{}\doxysubsection{Parameters and Requirements}\label{md_pages_components_rom_lspg_default_steady_autotoc_md83} +\hypertarget{md_pages_components_rom_lspg_default_steady_autotoc_md85}{}\doxysubsection{Parameters and Requirements}\label{md_pages_components_rom_lspg_default_steady_autotoc_md85} \begin{DoxyItemize} \item {\ttfamily fom\+\_\+adapter}\+: @@ -56,7 +56,7 @@ ~\newline \DoxyHorRuler{0} ~\newline -\hypertarget{md_pages_components_rom_lspg_default_steady_autotoc_md84}{}\doxysection{Example code}\label{md_pages_components_rom_lspg_default_steady_autotoc_md84} +\hypertarget{md_pages_components_rom_lspg_default_steady_autotoc_md86}{}\doxysection{Example code}\label{md_pages_components_rom_lspg_default_steady_autotoc_md86} \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{import} numpy \textcolor{keyword}{as} np} diff --git a/docs/latex/md_pages_components_rom_lspg_hypred.tex b/docs/latex/md_pages_components_rom_lspg_hypred.tex index 9a2a481..56e7224 100644 --- a/docs/latex/md_pages_components_rom_lspg_hypred.tex +++ b/docs/latex/md_pages_components_rom_lspg_hypred.tex @@ -2,7 +2,7 @@ Defined in module\+: {\ttfamily pressio4py.\+rom.\+lspg.\+unsteady} -Import as\+: \quad{} \quad{} \quad{} {\ttfamily from pressio4py.\+rom import lspg} \hypertarget{md_pages_components_rom_lspg_hypred_autotoc_md86}{}\doxysection{API, Parameters and Requirements}\label{md_pages_components_rom_lspg_hypred_autotoc_md86} +Import as\+: \quad{} \quad{} \quad{} {\ttfamily from pressio4py.\+rom import lspg} \hypertarget{md_pages_components_rom_lspg_hypred_autotoc_md88}{}\doxysection{API, Parameters and Requirements}\label{md_pages_components_rom_lspg_hypred_autotoc_md88} \begin{DoxyCode}{0} \DoxyCodeLine{problem = lspg.unsteady.HypredProblem(scheme, fom\_adapter, decoder, \(\backslash\)} @@ -72,7 +72,7 @@ ~\newline \end{DoxyItemize} -\end{DoxyItemize}\hypertarget{md_pages_components_rom_lspg_hypred_autotoc_md87}{}\doxysection{Stencil to sample indexing}\label{md_pages_components_rom_lspg_hypred_autotoc_md87} +\end{DoxyItemize}\hypertarget{md_pages_components_rom_lspg_hypred_autotoc_md89}{}\doxysection{Stencil to sample indexing}\label{md_pages_components_rom_lspg_hypred_autotoc_md89} When working with a hyper-\/reduced problem, pressio4py has to manipulate objects that have different sizes/distributions. For such problem, in fact, some operators are naturally defined on the what we refer to as \char`\"{}sample mesh\char`\"{} while some are defined on what we call the \char`\"{}stencil mesh\char`\"{}. As explained \href{https://pressio.github.io/algos/hyper/}{\texttt{ here}}, recall that\+: @@ -86,7 +86,7 @@ -The sample to stencil indexing is a list of indices that you need to provide such that pressio4py knows how to properly combine operands defined on stencil and sample mesh. \hypertarget{md_pages_components_rom_lspg_hypred_autotoc_md88}{}\doxysubsection{Explain it to me better!}\label{md_pages_components_rom_lspg_hypred_autotoc_md88} +The sample to stencil indexing is a list of indices that you need to provide such that pressio4py knows how to properly combine operands defined on stencil and sample mesh. \hypertarget{md_pages_components_rom_lspg_hypred_autotoc_md90}{}\doxysubsection{Explain it to me better!}\label{md_pages_components_rom_lspg_hypred_autotoc_md90} Suppose that your FOM problem involves a 2D problem and that your FOM numerical method needs at every cell information from the nearest neighbors. For the sake of explanation, {\itshape it does not matter what problem we are solving}, only what we just said. Now, suppose that you want to try hyper-\/reduced LSPG on it. You come up with a sample and stencil mesh for your problem (read \href{https://pressio.github.io/algos/hyper/}{\texttt{ this page}} for some information about how to select sample mesh cells), and let\textquotesingle{}s say it looks like this\+: The stencil mesh is the set of {\itshape all} cells shown, while the sample mesh is the {\itshape subset} color-\/coded yellow. We have added an arbitrary enumeration scheme to uniquely assign a global index to each cell. The enumeration order does not matter, this is just for demonstration purposes. You have an adapter class for your problem that is able to compute the FOM right-\/hand-\/side $f$ on the yellow cells, for a given FOM state $y$ on the stencil mesh. diff --git a/docs/latex/md_pages_components_rom_lspg_masked.tex b/docs/latex/md_pages_components_rom_lspg_masked.tex index 91150df..fd18f74 100644 --- a/docs/latex/md_pages_components_rom_lspg_masked.tex +++ b/docs/latex/md_pages_components_rom_lspg_masked.tex @@ -2,7 +2,7 @@ Defined in module\+: {\ttfamily pressio4py.\+rom.\+lspg.\+unsteady} -Import as\+: \quad{} \quad{} \quad{} {\ttfamily from pressio4py.\+rom import lspg} \hypertarget{md_pages_components_rom_lspg_masked_autotoc_md90}{}\doxysection{API, Parameters and Requirements}\label{md_pages_components_rom_lspg_masked_autotoc_md90} +Import as\+: \quad{} \quad{} \quad{} {\ttfamily from pressio4py.\+rom import lspg} \hypertarget{md_pages_components_rom_lspg_masked_autotoc_md92}{}\doxysection{API, Parameters and Requirements}\label{md_pages_components_rom_lspg_masked_autotoc_md92} \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{comment}{\# continuous-\/time overloads}} diff --git a/docs/latex/md_pages_components_rom_lspg_masked_steady.tex b/docs/latex/md_pages_components_rom_lspg_masked_steady.tex index aacb327..18090d4 100644 --- a/docs/latex/md_pages_components_rom_lspg_masked_steady.tex +++ b/docs/latex/md_pages_components_rom_lspg_masked_steady.tex @@ -2,7 +2,7 @@ Defined in module\+: {\ttfamily pressio4py.\+rom.\+lspg.\+steady} -Import as\+: \quad{} \quad{} \quad{} {\ttfamily from pressio4py.\+rom import lspg} \hypertarget{md_pages_components_rom_lspg_masked_steady_autotoc_md92}{}\doxysection{API}\label{md_pages_components_rom_lspg_masked_steady_autotoc_md92} +Import as\+: \quad{} \quad{} \quad{} {\ttfamily from pressio4py.\+rom import lspg} \hypertarget{md_pages_components_rom_lspg_masked_steady_autotoc_md94}{}\doxysection{API}\label{md_pages_components_rom_lspg_masked_steady_autotoc_md94} \begin{DoxyCode}{0} \DoxyCodeLine{problem = lspg.steady.MaskedProblem(fom\_adapter, decoder, \(\backslash\)} @@ -12,7 +12,7 @@ \DoxyCodeLine{ fom\_ref\_state, masker, preconditioner)} \end{DoxyCode} -\hypertarget{md_pages_components_rom_lspg_masked_steady_autotoc_md93}{}\doxysubsection{Parameters and Requirements}\label{md_pages_components_rom_lspg_masked_steady_autotoc_md93} +\hypertarget{md_pages_components_rom_lspg_masked_steady_autotoc_md95}{}\doxysubsection{Parameters and Requirements}\label{md_pages_components_rom_lspg_masked_steady_autotoc_md95} \begin{DoxyItemize} \item {\ttfamily fom\+\_\+adapter}\+: @@ -78,5 +78,5 @@ ~\newline \DoxyHorRuler{0} ~\newline -\hypertarget{md_pages_components_rom_lspg_masked_steady_autotoc_md94}{}\doxysection{Example code}\label{md_pages_components_rom_lspg_masked_steady_autotoc_md94} +\hypertarget{md_pages_components_rom_lspg_masked_steady_autotoc_md96}{}\doxysection{Example code}\label{md_pages_components_rom_lspg_masked_steady_autotoc_md96} todo add \ No newline at end of file diff --git a/docs/latex/md_pages_components_rom_lspg_steady.tex b/docs/latex/md_pages_components_rom_lspg_steady.tex index 3d3e803..3aa5601 100644 --- a/docs/latex/md_pages_components_rom_lspg_steady.tex +++ b/docs/latex/md_pages_components_rom_lspg_steady.tex @@ -1,6 +1,6 @@ todo\+: write this better -The pressio4py steady LSPG ROMs are designed to involve two main steps\+:\hypertarget{md_pages_components_rom_lspg_steady_autotoc_md96}{}\doxysection{1. Create}\label{md_pages_components_rom_lspg_steady_autotoc_md96} +The pressio4py steady LSPG ROMs are designed to involve two main steps\+:\hypertarget{md_pages_components_rom_lspg_steady_autotoc_md98}{}\doxysection{1. Create}\label{md_pages_components_rom_lspg_steady_autotoc_md98} You instantiate a \char`\"{}steady LSPG problem\char`\"{}, e.\+g.\+:~\newline @@ -42,7 +42,7 @@ \DoxyCodeLine{\};} \end{DoxyCode} -\hypertarget{md_pages_components_rom_lspg_steady_autotoc_md97}{}\doxysection{2. Solve}\label{md_pages_components_rom_lspg_steady_autotoc_md97} +\hypertarget{md_pages_components_rom_lspg_steady_autotoc_md99}{}\doxysection{2. Solve}\label{md_pages_components_rom_lspg_steady_autotoc_md99} \begin{DoxyItemize} \item you use a nonlinear least-\/squares solvers to solve the problem diff --git a/docs/latex/md_pages_components_rom_lspg_unsteady.tex b/docs/latex/md_pages_components_rom_lspg_unsteady.tex index 45c26e7..2fcc1d6 100644 --- a/docs/latex/md_pages_components_rom_lspg_unsteady.tex +++ b/docs/latex/md_pages_components_rom_lspg_unsteady.tex @@ -1,6 +1,6 @@ todo\+: write more -The pressio4py unsteady LSPG ROMs are designed such that using them involves these main steps\+:\hypertarget{md_pages_components_rom_lspg_unsteady_autotoc_md99}{}\doxysection{1. Create}\label{md_pages_components_rom_lspg_unsteady_autotoc_md99} +The pressio4py unsteady LSPG ROMs are designed such that using them involves these main steps\+:\hypertarget{md_pages_components_rom_lspg_unsteady_autotoc_md101}{}\doxysection{1. Create}\label{md_pages_components_rom_lspg_unsteady_autotoc_md101} You create an instance of a \char`\"{}\+LSPG problem\char`\"{}, e.\+g.\+: ~\newline @@ -26,23 +26,31 @@ \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{class }UnsteadyLSPGProblem} \DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{keyword}{def }stepper()} +\DoxyCodeLine{ \textcolor{keyword}{def }\_\_call\_\_(state, time, time\_step\_size, step\_count, solver);} +\DoxyCodeLine{} +\DoxyCodeLine{ def createResidual()} +\DoxyCodeLine{ \textcolor{keywordflow}{return} \textcolor{comment}{\# a residual instance}} +\DoxyCodeLine{} +\DoxyCodeLine{ \textcolor{keyword}{def }createJacobian()} +\DoxyCodeLine{ return \textcolor{comment}{\# a Jacobian instance}} +\DoxyCodeLine{} +\DoxyCodeLine{ def residual(state, R)} +\DoxyCodeLine{ \textcolor{comment}{\# evaluates the residual for the given state}} +\DoxyCodeLine{} +\DoxyCodeLine{ \textcolor{keyword}{def }jacobian(state, J)} +\DoxyCodeLine{ \textcolor{comment}{\# evaluates the Jacobian for the given state}} \DoxyCodeLine{} \DoxyCodeLine{ def fomStateReconstructor()} \DoxyCodeLine{\};} \end{DoxyCode} - - -The stepper method returns a reference to an \href{md_pages_components_ode_steppers_implicit.html}{\texttt{ implicit stepper}} object that the problem creates and owns. The {\ttfamily stepper} method is what you use to retrieve the underlying stepper and solve the problem in time. Once you have the stepper, you can then use it as discussed in \href{md_pages_components_ode_steppers_implicit.html}{\texttt{ implicit stepper page}}. - -What does a stepper have to do with a LSPG ROM? The answer is that practically speaking, at the lowest-\/level, an unsteady LSPG problem can be reduced to simply a \char`\"{}custom\char`\"{} stepper to advance in time. This is how pressio4py implements this and the reason why a LSPG problem contains a stepper object inside\+: when you create the problem, pressio creates the appropriate custom stepper object that you can use. You don\textquotesingle{}t need to know how this is done, or rely on the details, because these are problem-\/ and implementation-\/dependent, and we reserve the right to change this in the future.\hypertarget{md_pages_components_rom_lspg_unsteady_autotoc_md100}{}\doxysection{2. Reference the stepper and solve in time}\label{md_pages_components_rom_lspg_unsteady_autotoc_md100} -Extract the underlying stepper object and solve in time\+: +\hypertarget{md_pages_components_rom_lspg_unsteady_autotoc_md102}{}\doxysection{2. Solve in time}\label{md_pages_components_rom_lspg_unsteady_autotoc_md102} +What does a stepper have to do with a LSPG ROM? The answer is that practically speaking, at the lowest-\/level, an unsteady LSPG problem can be reduced to simply a \char`\"{}custom\char`\"{} stepper to advance in time. This is how pressio4py implements this and the reason why a LSPG problem behaves like a stepper. You don\textquotesingle{}t need to know how this is done, or rely on the details, because these are problem-\/ and implementation-\/dependent, and we reserve the right to change this in the future. \begin{DoxyCode}{0} -\DoxyCodeLine{stepper = problme.stepper()} -\DoxyCodeLine{pressio4py.ode.advance\_n\_steps\_and\_observe(stepper, ...)} +\DoxyCodeLine{stepper = ...} +\DoxyCodeLine{pressio4py.ode.advance\_n\_steps\_and\_observe(problem, ...)} \end{DoxyCode} diff --git a/docs/latex/md_pages_demos_demo1.tex b/docs/latex/md_pages_demos_demo1.tex index 69fa6c6..8ac2326 100644 --- a/docs/latex/md_pages_demos_demo1.tex +++ b/docs/latex/md_pages_demos_demo1.tex @@ -3,56 +3,55 @@ \begin{DoxyParagraph}{} This page describes a demo for a reproductive Galerkin ROM applied to a 1D advection-\/diffusion problem using POD modes as basis. By the end, it should be clear how to setup the problem. This demo purposefully focuses on a simple test since the main goal is to demonstrate the steps and code. More complex cases will be shown in other demos. The full demo script is \href{https://github.com/Pressio/pressio4py/blob/master/demos/unsteady_default_galerkin_advdiff1d_pod/main.py}{\texttt{ here.}} \end{DoxyParagraph} -\hypertarget{md_pages_demos_demo1_autotoc_md103}{}\doxysection{Overview}\label{md_pages_demos_demo1_autotoc_md103} +\hypertarget{md_pages_demos_demo1_autotoc_md105}{}\doxysection{Overview}\label{md_pages_demos_demo1_autotoc_md105} We cover these three typical steps needed for a ROM\+: \begin{DoxyEnumerate} \item generate of snapshots using the full-\/order model (FOM) \item compute the basis\+: here we demonstrate the use of POD modes \item execute the ROM\+: here we leverage the GALERKIN ROM to demonstrate a {\itshape reproductive} test, i.\+e., we run the ROM using the same physical coefficients, b.\+c., etc. A predictive run is demonstrated in a different demo. -\end{DoxyEnumerate}\hypertarget{md_pages_demos_demo1_autotoc_md104}{}\doxysection{FOM Equations}\label{md_pages_demos_demo1_autotoc_md104} +\end{DoxyEnumerate}\hypertarget{md_pages_demos_demo1_autotoc_md106}{}\doxysection{FOM Equations}\label{md_pages_demos_demo1_autotoc_md106} The governing equations for this problem are\+: -\[ \frac{\partial u}{\partial t} = \frac{\partial}{\partial x} (k(u,x) \frac{\partial u}{\partial x} ) - a*\frac{\partial u}{\partial x} \] where $k(u,x)=x^4$, the field is $u(x;t)$, the advection velocity is fixed at $a=2$, the spatial coordinate is $x$ and the domain is $(0,1)$. We use homogeneous BC. Note that a class approximating the FOM operators via finite-\/differences is implemented \href{https://github.com/Pressio/pressio4py/blob/master/apps/adv_diff1d.py}{\texttt{ here}}.\hypertarget{md_pages_demos_demo1_autotoc_md105}{}\doxysection{Main function}\label{md_pages_demos_demo1_autotoc_md105} +\[ \frac{\partial u}{\partial t} = \frac{\partial}{\partial x} (k(u,x) \frac{\partial u}{\partial x} ) - a*\frac{\partial u}{\partial x} \] where $k(u,x)=x^4$, the field is $u(x;t)$, the advection velocity is fixed at $a=2$, the spatial coordinate is $x$ and the domain is $(0,1)$. We use homogeneous BC. Note that a class approximating the FOM operators via finite-\/differences is implemented \href{https://github.com/Pressio/pressio4py/blob/master/apps/adv_diff1d.py}{\texttt{ here}}.\hypertarget{md_pages_demos_demo1_autotoc_md107}{}\doxysection{Main function}\label{md_pages_demos_demo1_autotoc_md107} The main function of the demo is the following\+: \begin{DoxyCode}{0} -\DoxyCodeLine{\textcolor{keywordflow}{if} \_\_name\_\_ == \textcolor{stringliteral}{"{}\_\_main\_\_"{}}:} -\DoxyCodeLine{ logger.initialize(logger.logto.terminal)} -\DoxyCodeLine{ logger.setVerbosity([logger.loglevel.info])} +\DoxyCodeLine{logger.initialize(logger.logto.terminal)} +\DoxyCodeLine{logger.setVerbosity([logger.loglevel.info])} \DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\# create fom object}} -\DoxyCodeLine{ fomObj = AdvDiff1d(nGrid=120, adv\_coef=2.0)} +\DoxyCodeLine{\textcolor{comment}{\# create fom object}} +\DoxyCodeLine{fomObj = AdvDiff1d(nGrid=120, adv\_coef=2.0)} \DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\# the final time to integrate to}} -\DoxyCodeLine{ finalTime = .05} +\DoxyCodeLine{\textcolor{comment}{\# the final time to integrate to}} +\DoxyCodeLine{finalTime = .05} \DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\#-\/-\/-\/ 1. FOM -\/-\/-\/\#}} -\DoxyCodeLine{ fomTimeStepSize = 1e-\/5} -\DoxyCodeLine{ fomNumberOfSteps = int(finalTime/fomTimeStepSize)} -\DoxyCodeLine{ sampleEvery = 200} -\DoxyCodeLine{ [fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)} +\DoxyCodeLine{\textcolor{comment}{\#-\/-\/-\/ 1. FOM -\/-\/-\/\#}} +\DoxyCodeLine{fomTimeStepSize = 1e-\/5} +\DoxyCodeLine{fomNumberOfSteps = int(finalTime/fomTimeStepSize)} +\DoxyCodeLine{sampleEvery = 200} +\DoxyCodeLine{[fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)} \DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\#-\/-\/-\/ 2. POD -\/-\/-\/\#}} -\DoxyCodeLine{ modes = computePodModes(snapshots)} +\DoxyCodeLine{\textcolor{comment}{\#-\/-\/-\/ 2. POD -\/-\/-\/\#}} +\DoxyCodeLine{modes = computePodModes(snapshots)} \DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\#-\/-\/-\/ 3. GALERKIN ROM -\/-\/-\/\#}} -\DoxyCodeLine{ romTimeStepSize = 3e-\/4} -\DoxyCodeLine{ romNumberOfSteps = int(finalTime/romTimeStepSize)} -\DoxyCodeLine{ \textcolor{comment}{\# run with various number of modes}} -\DoxyCodeLine{ romSizes = [2,4,6]} -\DoxyCodeLine{ approximations = \{\}} -\DoxyCodeLine{ \textcolor{keywordflow}{for} romSize \textcolor{keywordflow}{in} romSizes:} -\DoxyCodeLine{ currentSolution = runGalerkin(fomObj, romTimeStepSize,} -\DoxyCodeLine{ romNumberOfSteps,} -\DoxyCodeLine{ modes[:,:romSize])} -\DoxyCodeLine{ approximations[romSize] = currentSolution} +\DoxyCodeLine{\textcolor{comment}{\#-\/-\/-\/ 3. GALERKIN ROM -\/-\/-\/\#}} +\DoxyCodeLine{romTimeStepSize = 3e-\/4} +\DoxyCodeLine{romNumberOfSteps = int(finalTime/romTimeStepSize)} +\DoxyCodeLine{\textcolor{comment}{\# run with various number of modes}} +\DoxyCodeLine{romSizes = [2,4,6]} +\DoxyCodeLine{approximations = \{\}} +\DoxyCodeLine{\textcolor{keywordflow}{for} romSize \textcolor{keywordflow}{in} romSizes:} +\DoxyCodeLine{ currentSolution = runGalerkin(fomObj, romTimeStepSize,} +\DoxyCodeLine{ romNumberOfSteps,} +\DoxyCodeLine{ modes[:,:romSize])} +\DoxyCodeLine{ approximations[romSize] = currentSolution} \DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\# compute l2-\/error between fom and approximate state}} -\DoxyCodeLine{ fomNorm = linalg.norm(fomFinalState)} -\DoxyCodeLine{ err = linalg.norm(fomFinalState-\/currentSolution)} -\DoxyCodeLine{ print(\textcolor{stringliteral}{"{}With \{\} modes, final relative l2 error: \{\}"{}}.format(romSize, err/fomNorm))} +\DoxyCodeLine{ \textcolor{comment}{\# compute l2-\/error between fom and approximate state}} +\DoxyCodeLine{ fomNorm = linalg.norm(fomFinalState)} +\DoxyCodeLine{ err = linalg.norm(fomFinalState-\/currentSolution)} +\DoxyCodeLine{ print(\textcolor{stringliteral}{"{}With \{\} modes, final relative l2 error: \{\}"{}}.format(romSize, err/fomNorm))} \end{DoxyCode} -\hypertarget{md_pages_demos_demo1_autotoc_md106}{}\doxysubsection{1. Run FOM and collect snapshots}\label{md_pages_demos_demo1_autotoc_md106} +\hypertarget{md_pages_demos_demo1_autotoc_md108}{}\doxysubsection{1. Run FOM and collect snapshots}\label{md_pages_demos_demo1_autotoc_md108} \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{def }doFom(fom, dt, nsteps, saveFreq):} @@ -70,7 +69,7 @@ \DoxyCodeLine{ \textcolor{keywordflow}{return} [u, Usolns.T]} \end{DoxyCode} -\hypertarget{md_pages_demos_demo1_autotoc_md107}{}\doxysubsection{2. Compute POD modes}\label{md_pages_demos_demo1_autotoc_md107} +\hypertarget{md_pages_demos_demo1_autotoc_md109}{}\doxysubsection{2. Compute POD modes}\label{md_pages_demos_demo1_autotoc_md109} \begin{DoxyCode}{0} \DoxyCodeLine{print(\textcolor{stringliteral}{"{}SVD on matrix: "{}}, snapshots.shape)} @@ -78,43 +77,43 @@ \DoxyCodeLine{\textcolor{keywordflow}{return} U} \end{DoxyCode} -\hypertarget{md_pages_demos_demo1_autotoc_md108}{}\doxysubsection{3. Construct and run ROM}\label{md_pages_demos_demo1_autotoc_md108} +\hypertarget{md_pages_demos_demo1_autotoc_md110}{}\doxysubsection{3. Construct and run ROM}\label{md_pages_demos_demo1_autotoc_md110} \begin{DoxyCode}{0} -\DoxyCodeLine{\textcolor{comment}{\# auxiliary class to use in the solve below}} -\DoxyCodeLine{\textcolor{comment}{\# to monitor the rom state during time stepping}} -\DoxyCodeLine{\textcolor{keyword}{class }RomStateObserver:} -\DoxyCodeLine{ \textcolor{keyword}{def }\_\_call\_\_(self, timeStep, time, state): \textcolor{keyword}{pass}} +\DoxyCodeLine{\textcolor{keyword}{def }runGalerkin(fomObj, dt, nsteps, modes):} +\DoxyCodeLine{ \textcolor{comment}{\# auxiliary class to use in the solve below}} +\DoxyCodeLine{ \textcolor{comment}{\# to monitor the rom state during time stepping}} +\DoxyCodeLine{ \textcolor{keyword}{class }RomStateObserver:} +\DoxyCodeLine{ \textcolor{keyword}{def }\_\_call\_\_(self, timeStep, time, state): \textcolor{keyword}{pass}} \DoxyCodeLine{} -\DoxyCodeLine{\textcolor{comment}{\# find out number of modes wanted}} -\DoxyCodeLine{romSize = modes.shape[1]} +\DoxyCodeLine{ \textcolor{comment}{\# find out number of modes wanted}} +\DoxyCodeLine{ romSize = modes.shape[1]} \DoxyCodeLine{} -\DoxyCodeLine{\textcolor{comment}{\# create a linear decoder, passing only the desired number of modes}} -\DoxyCodeLine{\textcolor{comment}{\# this will make a deep copy of the modes}} -\DoxyCodeLine{linearDecoder = rom.Decoder(modes)} +\DoxyCodeLine{ \textcolor{comment}{\# create a linear decoder, passing only the desired number of modes}} +\DoxyCodeLine{ \textcolor{comment}{\# this will make a deep copy of the modes}} +\DoxyCodeLine{ linearDecoder = rom.Decoder(modes)} \DoxyCodeLine{} -\DoxyCodeLine{\textcolor{comment}{\# fom reference state: here it is zero}} -\DoxyCodeLine{fomReferenceState = np.zeros(fomObj.nGrid)} +\DoxyCodeLine{ \textcolor{comment}{\# fom reference state: here it is zero}} +\DoxyCodeLine{ fomReferenceState = np.zeros(fomObj.nGrid)} \DoxyCodeLine{} -\DoxyCodeLine{\textcolor{comment}{\# create ROM state by projecting the fom initial condition}} -\DoxyCodeLine{fomInitialState = fomObj.u0.copy()} -\DoxyCodeLine{romState = np.dot(modes.T, fomInitialState)} +\DoxyCodeLine{ \textcolor{comment}{\# create ROM state by projecting the fom initial condition}} +\DoxyCodeLine{ fomInitialState = fomObj.u0.copy()} +\DoxyCodeLine{ romState = np.dot(modes.T, fomInitialState)} \DoxyCodeLine{} -\DoxyCodeLine{\textcolor{comment}{\# create problem}} -\DoxyCodeLine{scheme = ode.stepscheme.ForwardEuler} -\DoxyCodeLine{problem = rom.galerkin.DefaultExplicitProblem(scheme, fomObj, linearDecoder, romState, fomReferenceState)} -\DoxyCodeLine{stepper = problem.stepper()} +\DoxyCodeLine{ \textcolor{comment}{\# create problem}} +\DoxyCodeLine{ scheme = ode.stepscheme.ForwardEuler} +\DoxyCodeLine{ problem = rom.galerkin.DefaultExplicitProblem(scheme, fomObj, linearDecoder, romState, fomReferenceState)} \DoxyCodeLine{} -\DoxyCodeLine{\textcolor{comment}{\# create object to monitor the romState at every iteration}} -\DoxyCodeLine{myObs = RomStateObserver()} -\DoxyCodeLine{\textcolor{comment}{\# solve problem}} -\DoxyCodeLine{ode.advance\_n\_steps\_and\_observe(stepper, romState, 0., dt, nsteps, myObs)} +\DoxyCodeLine{ \textcolor{comment}{\# create object to monitor the romState at every iteration}} +\DoxyCodeLine{ myObs = RomStateObserver()} +\DoxyCodeLine{ \textcolor{comment}{\# solve problem}} +\DoxyCodeLine{ ode.advance\_n\_steps\_and\_observe(problem, romState, 0., dt, nsteps, myObs)} \DoxyCodeLine{} -\DoxyCodeLine{\textcolor{comment}{\# after we are done, use the reconstructor object to reconstruct the fom state}} -\DoxyCodeLine{\textcolor{comment}{\# get the reconstructor object: this allows to map romState to fomState}} -\DoxyCodeLine{fomRecon = problem.fomStateReconstructor()} -\DoxyCodeLine{\textcolor{keywordflow}{return} fomRecon(romState)} +\DoxyCodeLine{ \textcolor{comment}{\# after we are done, use the reconstructor object to reconstruct the fom state}} +\DoxyCodeLine{ \textcolor{comment}{\# get the reconstructor object: this allows to map romState to fomState}} +\DoxyCodeLine{ fomRecon = problem.fomStateReconstructor()} +\DoxyCodeLine{ \textcolor{keywordflow}{return} fomRecon(romState)} \end{DoxyCode} -\hypertarget{md_pages_demos_demo1_autotoc_md109}{}\doxysection{Results}\label{md_pages_demos_demo1_autotoc_md109} +\hypertarget{md_pages_demos_demo1_autotoc_md111}{}\doxysection{Results}\label{md_pages_demos_demo1_autotoc_md111} If everything works fine, the following plot shows the result. We see that for this toy example, the full solution is recovered very well with Galerkin with just a few POD modes. \ No newline at end of file diff --git a/docs/latex/md_pages_demos_demo2.tex b/docs/latex/md_pages_demos_demo2.tex index 00a1814..f064a5c 100644 --- a/docs/latex/md_pages_demos_demo2.tex +++ b/docs/latex/md_pages_demos_demo2.tex @@ -3,7 +3,7 @@ \begin{DoxyParagraph}{} This page describes a demo for a reproductive LSPG ROM applied to a 1D advection-\/diffusion problem using POD modes as basis. By the end, it should be clear how to setup the problem. This demo purposefully focuses on a simple test since the main goal is to demonstrate the steps and the code. The full demo script is \href{https://github.com/Pressio/pressio4py/blob/master/demos/unsteady_default_lspg_advdiff1d_pod/main.py}{\texttt{ here.}} \end{DoxyParagraph} -\hypertarget{md_pages_demos_demo2_autotoc_md111}{}\doxysection{Overview}\label{md_pages_demos_demo2_autotoc_md111} +\hypertarget{md_pages_demos_demo2_autotoc_md113}{}\doxysection{Overview}\label{md_pages_demos_demo2_autotoc_md113} We cover these three typical steps needed for a ROM\+: \begin{DoxyEnumerate} \item generate of snapshots using the full-\/order model (FOM) @@ -11,44 +11,43 @@ \item execute the ROM\+: here we leverage the LSPG ROM to demonstrate a {\itshape reproductive} test, i.\+e., we run the ROM using the same physical coefficients, b.\+c., etc. A predictive run is demonstrated in a different tutorial. \end{DoxyEnumerate} -The governing equations for this problem are the same as those in \href{https://pressio.github.io/pressio4py/html/md_pages_demos_demo2.html}{\texttt{ here}},\hypertarget{md_pages_demos_demo2_autotoc_md112}{}\doxysection{Main function}\label{md_pages_demos_demo2_autotoc_md112} +The governing equations for this problem are the same as those in \href{https://pressio.github.io/pressio4py/html/md_pages_demos_demo2.html}{\texttt{ here}},\hypertarget{md_pages_demos_demo2_autotoc_md114}{}\doxysection{Main function}\label{md_pages_demos_demo2_autotoc_md114} The main function of the demo is the following\+: \begin{DoxyCode}{0} -\DoxyCodeLine{\textcolor{keywordflow}{if} \_\_name\_\_ == \textcolor{stringliteral}{"{}\_\_main\_\_"{}}:} -\DoxyCodeLine{ logger.initialize(logger.logto.terminal)} -\DoxyCodeLine{ logger.setVerbosity([logger.loglevel.info])} -\DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\# create fom object}} -\DoxyCodeLine{ fomObj = AdvDiff1d(nGrid=120, adv\_coef=2.0)} -\DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\# the final time to integrate to}} -\DoxyCodeLine{ finalTime = .05} -\DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\#-\/-\/-\/ 1. FOM -\/-\/-\/\#}} -\DoxyCodeLine{ fomTimeStepSize = 1e-\/5} -\DoxyCodeLine{ fomNumberOfSteps = int(finalTime/fomTimeStepSize)} -\DoxyCodeLine{ sampleEvery = 200} -\DoxyCodeLine{ [fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)} -\DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\#-\/-\/-\/ 2. POD -\/-\/-\/\#}} -\DoxyCodeLine{ modes = computePodModes(snapshots)} -\DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\#-\/-\/-\/ 3. LSPG ROM -\/-\/-\/\#}} -\DoxyCodeLine{ romSize = 4} -\DoxyCodeLine{ romTimeStepSize = 3e-\/4} -\DoxyCodeLine{ romNumberOfSteps = int(finalTime/romTimeStepSize)} -\DoxyCodeLine{ \textcolor{comment}{\# we pass only romSize modes}} -\DoxyCodeLine{ approximatedState = runLspg(fomObj, romTimeStepSize, romNumberOfSteps, modes[:,:romSize])} -\DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\# compute l2-\/error between fom and approximate state}} -\DoxyCodeLine{ fomNorm = linalg.norm(fomFinalState)} -\DoxyCodeLine{ err = linalg.norm(fomFinalState-\/approximatedState)} -\DoxyCodeLine{ print(\textcolor{stringliteral}{"{}Final state relative l2 error: \{\}"{}}.format(err/fomNorm))} -\DoxyCodeLine{} -\DoxyCodeLine{ logger.finalize()} +\DoxyCodeLine{logger.initialize(logger.logto.terminal)} +\DoxyCodeLine{logger.setVerbosity([logger.loglevel.info])} +\DoxyCodeLine{} +\DoxyCodeLine{\textcolor{comment}{\# create fom object}} +\DoxyCodeLine{fomObj = AdvDiff1d(nGrid=120, adv\_coef=2.0)} +\DoxyCodeLine{} +\DoxyCodeLine{\textcolor{comment}{\# the final time to integrate to}} +\DoxyCodeLine{finalTime = .05} +\DoxyCodeLine{} +\DoxyCodeLine{\textcolor{comment}{\#-\/-\/-\/ 1. FOM -\/-\/-\/\#}} +\DoxyCodeLine{fomTimeStepSize = 1e-\/5} +\DoxyCodeLine{fomNumberOfSteps = int(finalTime/fomTimeStepSize)} +\DoxyCodeLine{sampleEvery = 200} +\DoxyCodeLine{[fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)} +\DoxyCodeLine{} +\DoxyCodeLine{\textcolor{comment}{\#-\/-\/-\/ 2. POD -\/-\/-\/\#}} +\DoxyCodeLine{modes = computePodModes(snapshots)} +\DoxyCodeLine{} +\DoxyCodeLine{\textcolor{comment}{\#-\/-\/-\/ 3. LSPG ROM -\/-\/-\/\#}} +\DoxyCodeLine{romSize = 4} +\DoxyCodeLine{romTimeStepSize = 3e-\/4} +\DoxyCodeLine{romNumberOfSteps = int(finalTime/romTimeStepSize)} +\DoxyCodeLine{\textcolor{comment}{\# we pass only romSize modes}} +\DoxyCodeLine{approximatedState = runLspg(fomObj, romTimeStepSize, romNumberOfSteps, modes[:,:romSize])} +\DoxyCodeLine{} +\DoxyCodeLine{\textcolor{comment}{\# compute l2-\/error between fom and approximate state}} +\DoxyCodeLine{fomNorm = linalg.norm(fomFinalState)} +\DoxyCodeLine{err = linalg.norm(fomFinalState-\/approximatedState)} +\DoxyCodeLine{print(\textcolor{stringliteral}{"{}Final state relative l2 error: \{\}"{}}.format(err/fomNorm))} +\DoxyCodeLine{} +\DoxyCodeLine{logger.finalize()} \end{DoxyCode} -\hypertarget{md_pages_demos_demo2_autotoc_md113}{}\doxysubsection{1. Run FOM and collect snapshots}\label{md_pages_demos_demo2_autotoc_md113} +\hypertarget{md_pages_demos_demo2_autotoc_md115}{}\doxysubsection{1. Run FOM and collect snapshots}\label{md_pages_demos_demo2_autotoc_md115} \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{def }doFom(fom, dt, nsteps, saveFreq):} @@ -66,7 +65,7 @@ \DoxyCodeLine{ \textcolor{keywordflow}{return} [u, Usolns.T]} \end{DoxyCode} -\hypertarget{md_pages_demos_demo2_autotoc_md114}{}\doxysubsection{2. Compute POD modes}\label{md_pages_demos_demo2_autotoc_md114} +\hypertarget{md_pages_demos_demo2_autotoc_md116}{}\doxysubsection{2. Compute POD modes}\label{md_pages_demos_demo2_autotoc_md116} \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{def }computePodModes(snapshots):} @@ -75,7 +74,7 @@ \DoxyCodeLine{ \textcolor{keywordflow}{return} U} \end{DoxyCode} -\hypertarget{md_pages_demos_demo2_autotoc_md115}{}\doxysubsection{3. Construct and run ROM}\label{md_pages_demos_demo2_autotoc_md115} +\hypertarget{md_pages_demos_demo2_autotoc_md117}{}\doxysubsection{3. Construct and run ROM}\label{md_pages_demos_demo2_autotoc_md117} \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{def }runLspg(fomObj, dt, nsteps, modes):} @@ -108,10 +107,9 @@ \DoxyCodeLine{ \textcolor{comment}{\# create LSPG problem}} \DoxyCodeLine{ scheme = ode.stepscheme.BDF1} \DoxyCodeLine{ problem = rom.lspg.unsteady.DefaultProblem(scheme, fomObj, linearDecoder, romState, fomReferenceState)} -\DoxyCodeLine{ stepper = problem.stepper()} \DoxyCodeLine{} \DoxyCodeLine{ \textcolor{comment}{\# create the Gauss-\/Newton solver}} -\DoxyCodeLine{ nonLinSolver = solvers.create\_gauss\_newton(stepper, romState, MyLinSolver())} +\DoxyCodeLine{ nonLinSolver = solvers.create\_gauss\_newton(problem, romState, MyLinSolver())} \DoxyCodeLine{ \textcolor{comment}{\# set tolerance and convergence criteria}} \DoxyCodeLine{ nlsTol, nlsMaxIt = 1e-\/6, 5} \DoxyCodeLine{ nonLinSolver.setMaxIterations(nlsMaxIt)} @@ -120,13 +118,15 @@ \DoxyCodeLine{ \textcolor{comment}{\# create object to monitor the romState at every iteration}} \DoxyCodeLine{ myObs = RomStateObserver()} \DoxyCodeLine{ \textcolor{comment}{\# solve problem}} -\DoxyCodeLine{ ode.advance\_n\_steps\_and\_observe(stepper, romState, 0., dt, nsteps, myObs, nonLinSolver)} +\DoxyCodeLine{ ode.advance\_n\_steps\_and\_observe(problem, romState, 0., dt, nsteps, myObs, nonLinSolver)} \DoxyCodeLine{} \DoxyCodeLine{ \textcolor{comment}{\# after we are done, use the reconstructor object to reconstruct the fom state}} \DoxyCodeLine{ \textcolor{comment}{\# get the reconstructor object: this allows to map romState to fomState}} \DoxyCodeLine{ fomRecon = problem.fomStateReconstructor()} \DoxyCodeLine{ \textcolor{keywordflow}{return} fomRecon(romState)} +\DoxyCodeLine{} +\DoxyCodeLine{} \end{DoxyCode} -\hypertarget{md_pages_demos_demo2_autotoc_md116}{}\doxysection{Results}\label{md_pages_demos_demo2_autotoc_md116} +\hypertarget{md_pages_demos_demo2_autotoc_md118}{}\doxysection{Results}\label{md_pages_demos_demo2_autotoc_md118} If everything works fine, the following plot shows the result. \ No newline at end of file diff --git a/docs/latex/md_pages_demos_demo3.tex b/docs/latex/md_pages_demos_demo3.tex index 097f9c0..3b93a50 100644 --- a/docs/latex/md_pages_demos_demo3.tex +++ b/docs/latex/md_pages_demos_demo3.tex @@ -3,45 +3,44 @@ \begin{DoxyParagraph}{} This page describes a demo for a reproductive LSPG ROM applied to a 1D advection-\/diffusion problem using a nonlinear manifold via kernel PCA. This demo purposefully focuses on a simple test since the main goal is to demonstrate the steps and the code. The full demo script is \href{https://github.com/Pressio/pressio4py/blob/master/demos/unsteady_default_lspg_advdiff1d_kpca/main.py}{\texttt{ here.}} \end{DoxyParagraph} -\hypertarget{md_pages_demos_demo3_autotoc_md118}{}\doxysection{Overview}\label{md_pages_demos_demo3_autotoc_md118} -This demo solves the same problem as the one \href{https://pressio.github.io/pressio4py/html/md_pages_demos_demo1.html}{\texttt{ here}}, but instead of using POD modes, we show here how to use a nonlinear manifold computed via kernel PCA.\hypertarget{md_pages_demos_demo3_autotoc_md119}{}\doxysection{Main function}\label{md_pages_demos_demo3_autotoc_md119} +\hypertarget{md_pages_demos_demo3_autotoc_md120}{}\doxysection{Overview}\label{md_pages_demos_demo3_autotoc_md120} +This demo solves the same problem as the one \href{https://pressio.github.io/pressio4py/html/md_pages_demos_demo1.html}{\texttt{ here}}, but instead of using POD modes, we show here how to use a nonlinear manifold computed via kernel PCA.\hypertarget{md_pages_demos_demo3_autotoc_md121}{}\doxysection{Main function}\label{md_pages_demos_demo3_autotoc_md121} The main function of the demo is the following\+: \begin{DoxyCode}{0} -\DoxyCodeLine{\textcolor{keywordflow}{if} \_\_name\_\_ == \textcolor{stringliteral}{"{}\_\_main\_\_"{}}:} -\DoxyCodeLine{ logger.initialize(logger.logto.terminal)} -\DoxyCodeLine{ logger.setVerbosity([logger.loglevel.info])} +\DoxyCodeLine{logger.initialize(logger.logto.terminal)} +\DoxyCodeLine{logger.setVerbosity([logger.loglevel.info])} \DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\# create fom object}} -\DoxyCodeLine{ fomObj = AdvDiff1d(nGrid=120, adv\_coef=2.0)} +\DoxyCodeLine{\textcolor{comment}{\# create fom object}} +\DoxyCodeLine{fomObj = AdvDiff1d(nGrid=120, adv\_coef=2.0)} \DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\# the final time to integrate to}} -\DoxyCodeLine{ finalTime = .05} +\DoxyCodeLine{\textcolor{comment}{\# the final time to integrate to}} +\DoxyCodeLine{finalTime = .05} \DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\#-\/-\/-\/ 1. FOM -\/-\/-\/\#}} -\DoxyCodeLine{ fomTimeStepSize = 1e-\/5} -\DoxyCodeLine{ fomNumberOfSteps = int(finalTime/fomTimeStepSize)} -\DoxyCodeLine{ sampleEvery = 200} -\DoxyCodeLine{ [fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)} +\DoxyCodeLine{\textcolor{comment}{\#-\/-\/-\/ 1. FOM -\/-\/-\/\#}} +\DoxyCodeLine{fomTimeStepSize = 1e-\/5} +\DoxyCodeLine{fomNumberOfSteps = int(finalTime/fomTimeStepSize)} +\DoxyCodeLine{sampleEvery = 200} +\DoxyCodeLine{[fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)} \DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\#-\/-\/-\/ 2. train a nonlinear mapping using kPCA -\/-\/-\/\#}} -\DoxyCodeLine{ \textcolor{comment}{\# here we use 3 modes, change this to try different modes}} -\DoxyCodeLine{ myNonLinearMapper = MyMapperKPCA(snapshots.T, numModes=3)} +\DoxyCodeLine{\textcolor{comment}{\#-\/-\/-\/ 2. train a nonlinear mapping using kPCA -\/-\/-\/\#}} +\DoxyCodeLine{\textcolor{comment}{\# here we use 3 modes, change this to try different modes}} +\DoxyCodeLine{myNonLinearMapper = MyMapperKPCA(snapshots.T, numModes=3)} \DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\#-\/-\/-\/ 3. LSPG ROM -\/-\/-\/\#}} -\DoxyCodeLine{ romTimeStepSize = 3e-\/4} -\DoxyCodeLine{ romNumberOfSteps = int(finalTime/romTimeStepSize)} -\DoxyCodeLine{ approximatedState = runLspg(fomObj, romTimeStepSize, romNumberOfSteps, myNonLinearMapper)} +\DoxyCodeLine{\textcolor{comment}{\#-\/-\/-\/ 3. LSPG ROM -\/-\/-\/\#}} +\DoxyCodeLine{romTimeStepSize = 3e-\/4} +\DoxyCodeLine{romNumberOfSteps = int(finalTime/romTimeStepSize)} +\DoxyCodeLine{approximatedState = runLspg(fomObj, romTimeStepSize, romNumberOfSteps, myNonLinearMapper)} \DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\# compute l2-\/error between fom and approximate state}} -\DoxyCodeLine{ fomNorm = linalg.norm(fomFinalState)} -\DoxyCodeLine{ err = linalg.norm(fomFinalState-\/approximatedState)} -\DoxyCodeLine{ print(\textcolor{stringliteral}{"{}Final state relative l2 error: \{\}"{}}.format(err/fomNorm))} +\DoxyCodeLine{\textcolor{comment}{\# compute l2-\/error between fom and approximate state}} +\DoxyCodeLine{fomNorm = linalg.norm(fomFinalState)} +\DoxyCodeLine{err = linalg.norm(fomFinalState-\/approximatedState)} +\DoxyCodeLine{print(\textcolor{stringliteral}{"{}Final state relative l2 error: \{\}"{}}.format(err/fomNorm))} \DoxyCodeLine{} -\DoxyCodeLine{ logger.finalize()} +\DoxyCodeLine{logger.finalize()} \end{DoxyCode} -\hypertarget{md_pages_demos_demo3_autotoc_md120}{}\doxysubsection{1. Run FOM and collect snapshots}\label{md_pages_demos_demo3_autotoc_md120} -This step is the same as described \href{https://pressio.github.io/pressio4py/html/md_pages_demos_demo1.html}{\texttt{ here}},\hypertarget{md_pages_demos_demo3_autotoc_md121}{}\doxysubsection{2. Setup and train the nonlinear k\+PCA mapper}\label{md_pages_demos_demo3_autotoc_md121} +\hypertarget{md_pages_demos_demo3_autotoc_md122}{}\doxysubsection{1. Run FOM and collect snapshots}\label{md_pages_demos_demo3_autotoc_md122} +This step is the same as described \href{https://pressio.github.io/pressio4py/html/md_pages_demos_demo1.html}{\texttt{ here}},\hypertarget{md_pages_demos_demo3_autotoc_md123}{}\doxysubsection{2. Setup and train the nonlinear k\+PCA mapper}\label{md_pages_demos_demo3_autotoc_md123} It is important to note that while the mapper class below has the API required by pressio4py, it can encapsulate any arbitrary mapping function. In this case we show how to create a k\+PCA-\/based representation, but one can use, e.\+g., autoencoder, and any other types of mapping. This is how we enable support for testing various methods. \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{class }MyMapperKPCA:} @@ -92,7 +91,7 @@ \begin{DoxyParagraph}{Important\+:} when creating an arbitrary mapping (as in the class above), the jacobian matrix {\bfseries{must}} be column-\/major oder so that pressio can reference it without deep copying it. This not only reduced the memory footprint since it allows to keep only one jacobian object around but also it is fundamental for the update method below correctly. \end{DoxyParagraph} -\hypertarget{md_pages_demos_demo3_autotoc_md122}{}\doxysubsection{3. Construct and run LSPG}\label{md_pages_demos_demo3_autotoc_md122} +\hypertarget{md_pages_demos_demo3_autotoc_md124}{}\doxysubsection{3. Construct and run LSPG}\label{md_pages_demos_demo3_autotoc_md124} \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{def }runLspg(fomObj, dt, nsteps, customMapper):} @@ -122,10 +121,9 @@ \DoxyCodeLine{ \textcolor{comment}{\# create LSPG problem}} \DoxyCodeLine{ scheme = ode.stepscheme.BDF1} \DoxyCodeLine{ problem = rom.lspg.unsteady.DefaultProblem(scheme, fomObj, customDecoder, romState, fomReferenceState)} -\DoxyCodeLine{ stepper = problem.stepper()} \DoxyCodeLine{} \DoxyCodeLine{ \textcolor{comment}{\# create the Gauss-\/Newton solver}} -\DoxyCodeLine{ nonLinSolver = solvers.create\_gauss\_newton(stepper, romState, MyLinSolver())} +\DoxyCodeLine{ nonLinSolver = solvers.create\_gauss\_newton(problem, romState, MyLinSolver())} \DoxyCodeLine{ \textcolor{comment}{\# set tolerance and convergence criteria}} \DoxyCodeLine{ nlsTol, nlsMaxIt = 1e-\/7, 10} \DoxyCodeLine{ nonLinSolver.setMaxIterations(nlsMaxIt)} @@ -134,7 +132,7 @@ \DoxyCodeLine{ \textcolor{comment}{\# create object to monitor the romState at every iteration}} \DoxyCodeLine{ myObs = RomStateObserver()} \DoxyCodeLine{ \textcolor{comment}{\# solve problem}} -\DoxyCodeLine{ ode.advance\_n\_steps\_and\_observe(stepper, romState, 0., dt, nsteps, myObs, nonLinSolver)} +\DoxyCodeLine{ ode.advance\_n\_steps\_and\_observe(problem, romState, 0., dt, nsteps, myObs, nonLinSolver)} \DoxyCodeLine{} \DoxyCodeLine{ \textcolor{comment}{\# after we are done, use the reconstructor object to reconstruct the fom state}} \DoxyCodeLine{ \textcolor{comment}{\# get the reconstructor object: this allows to map romState to fomState}} @@ -142,5 +140,5 @@ \DoxyCodeLine{ \textcolor{keywordflow}{return} fomRecon(romState)} \end{DoxyCode} -\hypertarget{md_pages_demos_demo3_autotoc_md123}{}\doxysection{Results}\label{md_pages_demos_demo3_autotoc_md123} +\hypertarget{md_pages_demos_demo3_autotoc_md125}{}\doxysection{Results}\label{md_pages_demos_demo3_autotoc_md125} If everything works fine, the following plot shows the result. \ No newline at end of file diff --git a/docs/latex/md_pages_demos_demo4.tex b/docs/latex/md_pages_demos_demo4.tex index 97e44a1..d27269c 100644 --- a/docs/latex/md_pages_demos_demo4.tex +++ b/docs/latex/md_pages_demos_demo4.tex @@ -8,7 +8,7 @@ \begin{DoxyParagraph}{We are currently working on this page, it will be updated with more explanations.} \end{DoxyParagraph} -\hypertarget{md_pages_demos_demo4_autotoc_md125}{}\doxysection{Overview}\label{md_pages_demos_demo4_autotoc_md125} +\hypertarget{md_pages_demos_demo4_autotoc_md127}{}\doxysection{Overview}\label{md_pages_demos_demo4_autotoc_md127} We cover these steps\+: \begin{DoxyEnumerate} \item generate of snapshots using the full-\/order model (FOM) @@ -19,70 +19,69 @@ The key item introduced here is the \char`\"{}masking\char`\"{} operator. In simple words, masking allows us to mimic the effect of the hyper-\/reduction without changing the application code. Hyper-\/reduction is a fundamental part of ROMs needed to approximate the FOM operators, thus contributing significantly to the computational cost savings. However, the main difficulty of hyper-\/reduction is that it generally is quite intrusive to be done properly. -To briefly explain what hyper-\/reduction, let\textquotesingle{}s look at the most basic form of hyper-\/reduction, namely \char`\"{}collocation\char`\"{}. Consider the following system of N ODEs\+: \[ \frac{du}{dt} = f(u,x,t) \] A collocation-\/based hyper-\/reduction involves {\itshape approximating} the right-\/hand side by computing $f()$ only at a subset of grid points. Obviously, the way we compute the locations to select is critical and there are several techniques available to do so. Here, we show a simple example just for demonstration purposes of performing collocation with randomly selected points\hypertarget{md_pages_demos_demo4_autotoc_md126}{}\doxysection{FOM Equations}\label{md_pages_demos_demo4_autotoc_md126} +To briefly explain what hyper-\/reduction, let\textquotesingle{}s look at the most basic form of hyper-\/reduction, namely \char`\"{}collocation\char`\"{}. Consider the following system of N ODEs\+: \[ \frac{du}{dt} = f(u,x,t) \] A collocation-\/based hyper-\/reduction involves {\itshape approximating} the right-\/hand side by computing $f()$ only at a subset of grid points. Obviously, the way we compute the locations to select is critical and there are several techniques available to do so. Here, we show a simple example just for demonstration purposes of performing collocation with randomly selected points\hypertarget{md_pages_demos_demo4_autotoc_md128}{}\doxysection{FOM Equations}\label{md_pages_demos_demo4_autotoc_md128} The governing equations for this problem are\+: -\[ \frac{\partial u}{\partial t} = \frac{\partial}{\partial x} (k(u,x) \frac{\partial u}{\partial x} ) - a*\frac{\partial u}{\partial x} \] where $k(u,x)=x^4$, the field is $u(x;t)$, the advection velocity is fixed at $a=2$, the spatial coordinate is $x$ and the domain is $(0,1)$. We use homogeneous BC. Note that a class approximating the FOM operators via finite-\/differences is implemented \href{https://github.com/Pressio/pressio4py/blob/master/apps/adv_diff1d.py}{\texttt{ here}}.\hypertarget{md_pages_demos_demo4_autotoc_md127}{}\doxysection{Main function}\label{md_pages_demos_demo4_autotoc_md127} +\[ \frac{\partial u}{\partial t} = \frac{\partial}{\partial x} (k(u,x) \frac{\partial u}{\partial x} ) - a*\frac{\partial u}{\partial x} \] where $k(u,x)=x^4$, the field is $u(x;t)$, the advection velocity is fixed at $a=2$, the spatial coordinate is $x$ and the domain is $(0,1)$. We use homogeneous BC. Note that a class approximating the FOM operators via finite-\/differences is implemented \href{https://github.com/Pressio/pressio4py/blob/master/apps/adv_diff1d.py}{\texttt{ here}}.\hypertarget{md_pages_demos_demo4_autotoc_md129}{}\doxysection{Main function}\label{md_pages_demos_demo4_autotoc_md129} The main function of the demo is the following\+: \begin{DoxyCode}{0} -\DoxyCodeLine{\textcolor{keywordflow}{if} \_\_name\_\_ == \textcolor{stringliteral}{"{}\_\_main\_\_"{}}:} -\DoxyCodeLine{ logger.initialize(logger.logto.terminal)} -\DoxyCodeLine{ logger.setVerbosity([logger.loglevel.info])} -\DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\# total number of grid points}} -\DoxyCodeLine{ meshSize = 200} -\DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\# create fom object}} -\DoxyCodeLine{ fomObj = AdvDiff1d(nGrid=meshSize, adv\_coef=1.0)} -\DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\# the final time to integrate to}} -\DoxyCodeLine{ finalTime = .05} -\DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\#-\/-\/-\/ 1. FOM -\/-\/-\/\#}} -\DoxyCodeLine{ fomTimeStepSize = 1e-\/5} -\DoxyCodeLine{ fomNumberOfSteps = int(finalTime/fomTimeStepSize)} -\DoxyCodeLine{ sampleEvery = 100} -\DoxyCodeLine{ [fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)} -\DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\#-\/-\/-\/ 2. POD -\/-\/-\/\#}} -\DoxyCodeLine{ modes = computePodModes(snapshots)} -\DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\#-\/-\/-\/ 3. MASKED GALERKIN ROM -\/-\/-\/\#}} -\DoxyCodeLine{ romSize = 10 \textcolor{comment}{\# number of modes to use}} -\DoxyCodeLine{ romTimeStepSize = 1e-\/4} -\DoxyCodeLine{ romNumberOfSteps = int(finalTime/romTimeStepSize)} -\DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\# a masked galerkin is supposed to make it easier to emulate the}} -\DoxyCodeLine{ \textcolor{comment}{\# effect of hyper-\/reduction. To create a mask ROM problem,}} -\DoxyCodeLine{ \textcolor{comment}{\# we need to select and provide to pressio a set of indices}} -\DoxyCodeLine{ \textcolor{comment}{\# identifying a subset of the grid points in the full mesh.}} -\DoxyCodeLine{ \textcolor{comment}{\# This is a simple way to mimic hyper-\/reduction}} -\DoxyCodeLine{ \textcolor{comment}{\# without changing the FOM problem. In fact, the fom still}} -\DoxyCodeLine{ \textcolor{comment}{\# computes the full operators but we have an additional step}} -\DoxyCodeLine{ \textcolor{comment}{\# to "{}mask"{} the operators to compute the sample mesh version.}} -\DoxyCodeLine{ \textcolor{comment}{\# In this test, the meshSize = 200. Our sample mesh includes}} -\DoxyCodeLine{ \textcolor{comment}{\# the two end points since those contain the boundary conditions,}} -\DoxyCodeLine{ \textcolor{comment}{\# and 150 randomly selected grid points inside the domain.}} -\DoxyCodeLine{ \textcolor{comment}{\# So effectively we use 25\% less of the full mesh.}} -\DoxyCodeLine{ random.seed(312367)} -\DoxyCodeLine{ sampleMeshSize = 150} -\DoxyCodeLine{ sampleMeshIndices = random.sample(range(1, 199), sampleMeshSize)} -\DoxyCodeLine{ sampleMeshIndices = np.append(sampleMeshIndices, [0, 199])} -\DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\# run the masked galerkin problem}} -\DoxyCodeLine{ approximatedState = runMaskedGalerkin(fomObj, romTimeStepSize,} -\DoxyCodeLine{ romNumberOfSteps, modes[:,:romSize],} -\DoxyCodeLine{ sampleMeshIndices)} -\DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\# compute l2-\/error between fom and approximate state}} -\DoxyCodeLine{ fomNorm = linalg.norm(fomFinalState)} -\DoxyCodeLine{ err = linalg.norm(fomFinalState-\/approximatedState)} -\DoxyCodeLine{ print(\textcolor{stringliteral}{"{}Final state relative l2 error: \{\}"{}}.format(err/fomNorm))} -\DoxyCodeLine{} -\DoxyCodeLine{ logger.finalize()} +\DoxyCodeLine{logger.initialize(logger.logto.terminal)} +\DoxyCodeLine{logger.setVerbosity([logger.loglevel.info])} +\DoxyCodeLine{} +\DoxyCodeLine{\textcolor{comment}{\# total number of grid points}} +\DoxyCodeLine{meshSize = 200} +\DoxyCodeLine{} +\DoxyCodeLine{\textcolor{comment}{\# create fom object}} +\DoxyCodeLine{fomObj = AdvDiff1d(nGrid=meshSize, adv\_coef=1.0)} +\DoxyCodeLine{} +\DoxyCodeLine{\textcolor{comment}{\# the final time to integrate to}} +\DoxyCodeLine{finalTime = .05} +\DoxyCodeLine{} +\DoxyCodeLine{\textcolor{comment}{\#-\/-\/-\/ 1. FOM -\/-\/-\/\#}} +\DoxyCodeLine{fomTimeStepSize = 1e-\/5} +\DoxyCodeLine{fomNumberOfSteps = int(finalTime/fomTimeStepSize)} +\DoxyCodeLine{sampleEvery = 100} +\DoxyCodeLine{[fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)} +\DoxyCodeLine{} +\DoxyCodeLine{\textcolor{comment}{\#-\/-\/-\/ 2. POD -\/-\/-\/\#}} +\DoxyCodeLine{modes = computePodModes(snapshots)} +\DoxyCodeLine{} +\DoxyCodeLine{\textcolor{comment}{\#-\/-\/-\/ 3. MASKED GALERKIN ROM -\/-\/-\/\#}} +\DoxyCodeLine{romSize = 10 \textcolor{comment}{\# number of modes to use}} +\DoxyCodeLine{romTimeStepSize = 1e-\/4} +\DoxyCodeLine{romNumberOfSteps = int(finalTime/romTimeStepSize)} +\DoxyCodeLine{} +\DoxyCodeLine{\textcolor{comment}{\# a masked galerkin is supposed to make it easier to emulate the}} +\DoxyCodeLine{\textcolor{comment}{\# effect of hyper-\/reduction. To create a mask ROM problem,}} +\DoxyCodeLine{\textcolor{comment}{\# we need to select and provide to pressio a set of indices}} +\DoxyCodeLine{\textcolor{comment}{\# identifying a subset of the grid points in the full mesh.}} +\DoxyCodeLine{\textcolor{comment}{\# This is a simple way to mimic hyper-\/reduction}} +\DoxyCodeLine{\textcolor{comment}{\# without changing the FOM problem. In fact, the fom still}} +\DoxyCodeLine{\textcolor{comment}{\# computes the full operators but we have an additional step}} +\DoxyCodeLine{\textcolor{comment}{\# to "{}mask"{} the operators to compute the sample mesh version.}} +\DoxyCodeLine{\textcolor{comment}{\# In this test, the meshSize = 200. Our sample mesh includes}} +\DoxyCodeLine{\textcolor{comment}{\# the two end points since those contain the boundary conditions,}} +\DoxyCodeLine{\textcolor{comment}{\# and 150 randomly selected grid points inside the domain.}} +\DoxyCodeLine{\textcolor{comment}{\# So effectively we use 25\% less of the full mesh.}} +\DoxyCodeLine{random.seed(312367)} +\DoxyCodeLine{sampleMeshSize = 150} +\DoxyCodeLine{sampleMeshIndices = random.sample(range(1, 199), sampleMeshSize)} +\DoxyCodeLine{sampleMeshIndices = np.append(sampleMeshIndices, [0, 199])} +\DoxyCodeLine{} +\DoxyCodeLine{\textcolor{comment}{\# run the masked galerkin problem}} +\DoxyCodeLine{approximatedState = runMaskedGalerkin(fomObj, romTimeStepSize,} +\DoxyCodeLine{ romNumberOfSteps, modes[:,:romSize],} +\DoxyCodeLine{ sampleMeshIndices)} +\DoxyCodeLine{} +\DoxyCodeLine{\textcolor{comment}{\# compute l2-\/error between fom and approximate state}} +\DoxyCodeLine{fomNorm = linalg.norm(fomFinalState)} +\DoxyCodeLine{err = linalg.norm(fomFinalState-\/approximatedState)} +\DoxyCodeLine{print(\textcolor{stringliteral}{"{}Final state relative l2 error: \{\}"{}}.format(err/fomNorm))} +\DoxyCodeLine{} +\DoxyCodeLine{logger.finalize()} \end{DoxyCode} -\hypertarget{md_pages_demos_demo4_autotoc_md128}{}\doxysubsection{1. Run FOM and collect snapshots}\label{md_pages_demos_demo4_autotoc_md128} +\hypertarget{md_pages_demos_demo4_autotoc_md130}{}\doxysubsection{1. Run FOM and collect snapshots}\label{md_pages_demos_demo4_autotoc_md130} \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{def }doFom(fom, dt, nsteps, saveFreq):} @@ -100,7 +99,7 @@ \DoxyCodeLine{ \textcolor{keywordflow}{return} [u, Usolns.T]} \end{DoxyCode} -\hypertarget{md_pages_demos_demo4_autotoc_md129}{}\doxysubsection{2. Compute POD modes}\label{md_pages_demos_demo4_autotoc_md129} +\hypertarget{md_pages_demos_demo4_autotoc_md131}{}\doxysubsection{2. Compute POD modes}\label{md_pages_demos_demo4_autotoc_md131} \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{def }computePodModes(snapshots):} @@ -109,10 +108,9 @@ \DoxyCodeLine{ \textcolor{keywordflow}{return} U} \end{DoxyCode} -\hypertarget{md_pages_demos_demo4_autotoc_md130}{}\doxysubsection{3. Create the sampling indices}\label{md_pages_demos_demo4_autotoc_md130} +\hypertarget{md_pages_demos_demo4_autotoc_md132}{}\doxysubsection{3. Create the sampling indices}\label{md_pages_demos_demo4_autotoc_md132} \begin{DoxyCode}{0} -\DoxyCodeLine{\textcolor{comment}{\# a masked galerkin is supposed to make it easier to emulate the}} \DoxyCodeLine{\textcolor{comment}{\# effect of hyper-\/reduction. To create a mask ROM problem,}} \DoxyCodeLine{\textcolor{comment}{\# we need to select and provide to pressio a set of indices}} \DoxyCodeLine{\textcolor{comment}{\# identifying a subset of the grid points in the full mesh.}} @@ -130,7 +128,7 @@ \DoxyCodeLine{sampleMeshIndices = np.append(sampleMeshIndices, [0, 199])} \end{DoxyCode} -\hypertarget{md_pages_demos_demo4_autotoc_md131}{}\doxysubsection{4. The masker class}\label{md_pages_demos_demo4_autotoc_md131} +\hypertarget{md_pages_demos_demo4_autotoc_md133}{}\doxysubsection{4. The masker class}\label{md_pages_demos_demo4_autotoc_md133} \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{class }MyMasker:} @@ -145,7 +143,7 @@ \DoxyCodeLine{ result[:] = np.take(operand, self.rows\_)} \end{DoxyCode} -\hypertarget{md_pages_demos_demo4_autotoc_md132}{}\doxysubsection{5. Construct and run the masked ROM}\label{md_pages_demos_demo4_autotoc_md132} +\hypertarget{md_pages_demos_demo4_autotoc_md134}{}\doxysubsection{5. Construct and run the masked ROM}\label{md_pages_demos_demo4_autotoc_md134} \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{def }runMaskedGalerkin(fomObj, dt, nsteps, modes, sampleMeshIndices):} @@ -187,10 +185,9 @@ \DoxyCodeLine{ problem = rom.galerkin.MaskedExplicitProblem(scheme, fomObj, linearDecoder, \(\backslash\)} \DoxyCodeLine{ romState, fomReferenceState, \(\backslash\)} \DoxyCodeLine{ projector, masker)} -\DoxyCodeLine{ stepper = problem.stepper()} \DoxyCodeLine{} \DoxyCodeLine{ \textcolor{comment}{\# solve problem}} -\DoxyCodeLine{ ode.advance\_n\_steps(stepper, romState, 0., dt, nsteps)} +\DoxyCodeLine{ ode.advance\_n\_steps(problem, romState, 0., dt, nsteps)} \DoxyCodeLine{} \DoxyCodeLine{ \textcolor{comment}{\# after we are done, use the reconstructor object to reconstruct the fom state}} \DoxyCodeLine{ \textcolor{comment}{\# NOTE: even though the Galerkin problem was run on the "{}masked mesh points"{},}} @@ -200,7 +197,7 @@ \DoxyCodeLine{ \textcolor{keywordflow}{return} fomRecon(romState)} \end{DoxyCode} -\hypertarget{md_pages_demos_demo4_autotoc_md133}{}\doxysection{Results}\label{md_pages_demos_demo4_autotoc_md133} +\hypertarget{md_pages_demos_demo4_autotoc_md135}{}\doxysection{Results}\label{md_pages_demos_demo4_autotoc_md135} If everything works fine, the following plot shows the result. We see that for this toy example, the full solution is recovered very well with Galerkin with just a few POD modes. diff --git a/docs/latex/md_pages_demos_demo5.tex b/docs/latex/md_pages_demos_demo5.tex index 4f27eae..c4693b9 100644 --- a/docs/latex/md_pages_demos_demo5.tex +++ b/docs/latex/md_pages_demos_demo5.tex @@ -8,78 +8,78 @@ \begin{DoxyParagraph}{We are currently working on this page, it will be updated with more explanations.} \end{DoxyParagraph} -\hypertarget{md_pages_demos_demo5_autotoc_md135}{}\doxysection{Overview}\label{md_pages_demos_demo5_autotoc_md135} -This is a follow up to the previous demo \href{./md_pages_demos_demo4.html}{\texttt{ here}} We compare here maskdd Galerkin and masked LSPG.\hypertarget{md_pages_demos_demo5_autotoc_md136}{}\doxysection{Main function}\label{md_pages_demos_demo5_autotoc_md136} +\hypertarget{md_pages_demos_demo5_autotoc_md137}{}\doxysection{Overview}\label{md_pages_demos_demo5_autotoc_md137} +This is a follow up to the previous demo \href{./md_pages_demos_demo4.html}{\texttt{ here}} We compare here maskdd Galerkin and masked LSPG.\hypertarget{md_pages_demos_demo5_autotoc_md138}{}\doxysection{Main function}\label{md_pages_demos_demo5_autotoc_md138} The main function of the demo is the following\+: \begin{DoxyCode}{0} -\DoxyCodeLine{\textcolor{keywordflow}{if} \_\_name\_\_ == \textcolor{stringliteral}{"{}\_\_main\_\_"{}}:} -\DoxyCodeLine{ logger.initialize(logger.logto.terminal)} -\DoxyCodeLine{ logger.setVerbosity([logger.loglevel.info])} -\DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\# total number of grid points}} -\DoxyCodeLine{ meshSize = 200} -\DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\# create fom object}} -\DoxyCodeLine{ fomObj = AdvDiff1d(nGrid=meshSize, adv\_coef=1.0)} -\DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\# the final time to integrate to}} -\DoxyCodeLine{ finalTime = .05} -\DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\#-\/-\/-\/ 1. FOM -\/-\/-\/\#}} -\DoxyCodeLine{ fomTimeStepSize = 1e-\/5} -\DoxyCodeLine{ fomNumberOfSteps = int(finalTime/fomTimeStepSize)} -\DoxyCodeLine{ sampleEvery = 100} -\DoxyCodeLine{ [fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)} -\DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\#-\/-\/-\/ 2. POD -\/-\/-\/\#}} -\DoxyCodeLine{ modes = computePodModes(snapshots)} -\DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\#-\/-\/-\/ 3. MASKED GALERKIN and LSPG ROM -\/-\/-\/\#}} -\DoxyCodeLine{ \textcolor{comment}{\# a masked problem is supposed to make it easier to emulate the}} -\DoxyCodeLine{ \textcolor{comment}{\# effect of hyper-\/reduction. To create a mask ROM problem,}} -\DoxyCodeLine{ \textcolor{comment}{\# we need to select and provide to pressio a set of indices}} -\DoxyCodeLine{ \textcolor{comment}{\# identifying a subset of the grid points in the full mesh.}} -\DoxyCodeLine{ \textcolor{comment}{\# This is a simple way to mimic hyper-\/reduction}} -\DoxyCodeLine{ \textcolor{comment}{\# without changing the FOM problem. In fact, the fom still}} -\DoxyCodeLine{ \textcolor{comment}{\# computes the full operators but we have an additional step}} -\DoxyCodeLine{ \textcolor{comment}{\# to "{}mask"{} the operators to compute the sample mesh version.}} -\DoxyCodeLine{ \textcolor{comment}{\# In this test, the meshSize = 200. Our sample mesh includes}} -\DoxyCodeLine{ \textcolor{comment}{\# the two end points since those contain the boundary conditions,}} -\DoxyCodeLine{ \textcolor{comment}{\# and 20 randomly selected grid points inside the domain.}} -\DoxyCodeLine{ \textcolor{comment}{\# So effectively we use 1/10 of the full mesh.}} -\DoxyCodeLine{ random.seed(22123)} -\DoxyCodeLine{ sampleMeshSize = 20} -\DoxyCodeLine{ sampleMeshIndices = random.sample(range(1, 199), sampleMeshSize)} -\DoxyCodeLine{ sampleMeshIndices = np.append(sampleMeshIndices, [0, 199])} -\DoxyCodeLine{ \textcolor{comment}{\# sort for convenience, not necessarily needed}} -\DoxyCodeLine{ sampleMeshIndices = np.sort(sampleMeshIndices)} -\DoxyCodeLine{} -\DoxyCodeLine{ romSize = 5 \textcolor{comment}{\# number of modes to use}} -\DoxyCodeLine{ romTimeStepSize = 1e-\/4} -\DoxyCodeLine{ romNumberOfSteps = int(finalTime/romTimeStepSize)} -\DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\# run the masked galerkin problem}} -\DoxyCodeLine{ [approximatedStateGal, romGal] = runMaskedGalerkin(fomObj, romTimeStepSize,} -\DoxyCodeLine{ romNumberOfSteps,} -\DoxyCodeLine{ modes[:,:romSize],} -\DoxyCodeLine{ sampleMeshIndices)} -\DoxyCodeLine{ \textcolor{comment}{\# run the masked galerkin problem}} -\DoxyCodeLine{ [approximatedStateLspg, romLspg] = runMaskedLspg(fomObj, romTimeStepSize,} +\DoxyCodeLine{logger.setVerbosity([logger.loglevel.info])} +\DoxyCodeLine{} +\DoxyCodeLine{\textcolor{comment}{\# total number of grid points}} +\DoxyCodeLine{meshSize = 200} +\DoxyCodeLine{} +\DoxyCodeLine{\textcolor{comment}{\# create fom object}} +\DoxyCodeLine{fomObj = AdvDiff1d(nGrid=meshSize, adv\_coef=1.0)} +\DoxyCodeLine{} +\DoxyCodeLine{\textcolor{comment}{\# the final time to integrate to}} +\DoxyCodeLine{finalTime = .05} +\DoxyCodeLine{} +\DoxyCodeLine{\textcolor{comment}{\#-\/-\/-\/ 1. FOM -\/-\/-\/\#}} +\DoxyCodeLine{fomTimeStepSize = 1e-\/5} +\DoxyCodeLine{fomNumberOfSteps = int(finalTime/fomTimeStepSize)} +\DoxyCodeLine{sampleEvery = 100} +\DoxyCodeLine{[fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)} +\DoxyCodeLine{} +\DoxyCodeLine{\textcolor{comment}{\#-\/-\/-\/ 2. POD -\/-\/-\/\#}} +\DoxyCodeLine{modes = computePodModes(snapshots)} +\DoxyCodeLine{} +\DoxyCodeLine{\textcolor{comment}{\#-\/-\/-\/ 3. MASKED GALERKIN and LSPG ROM -\/-\/-\/\#}} +\DoxyCodeLine{\textcolor{comment}{\# a masked problem is supposed to make it easier to emulate the}} +\DoxyCodeLine{\textcolor{comment}{\# effect of hyper-\/reduction. To create a mask ROM problem,}} +\DoxyCodeLine{\textcolor{comment}{\# we need to select and provide to pressio a set of indices}} +\DoxyCodeLine{\textcolor{comment}{\# identifying a subset of the grid points in the full mesh.}} +\DoxyCodeLine{\textcolor{comment}{\# This is a simple way to mimic hyper-\/reduction}} +\DoxyCodeLine{\textcolor{comment}{\# without changing the FOM problem. In fact, the fom still}} +\DoxyCodeLine{\textcolor{comment}{\# computes the full operators but we have an additional step}} +\DoxyCodeLine{\textcolor{comment}{\# to "{}mask"{} the operators to compute the sample mesh version.}} +\DoxyCodeLine{\textcolor{comment}{\# In this test, the meshSize = 200. Our sample mesh includes}} +\DoxyCodeLine{\textcolor{comment}{\# the two end points since those contain the boundary conditions,}} +\DoxyCodeLine{\textcolor{comment}{\# and 20 randomly selected grid points inside the domain.}} +\DoxyCodeLine{\textcolor{comment}{\# So effectively we use 1/10 of the full mesh.}} +\DoxyCodeLine{random.seed(22123)} +\DoxyCodeLine{sampleMeshSize = 20} +\DoxyCodeLine{sampleMeshIndices = random.sample(range(1, 199), sampleMeshSize)} +\DoxyCodeLine{sampleMeshIndices = np.append(sampleMeshIndices, [0, 199])} +\DoxyCodeLine{\textcolor{comment}{\# sort for convenience, not necessarily needed}} +\DoxyCodeLine{sampleMeshIndices = np.sort(sampleMeshIndices)} +\DoxyCodeLine{} +\DoxyCodeLine{romSize = 5 \textcolor{comment}{\# number of modes to use}} +\DoxyCodeLine{romTimeStepSize = 1e-\/4} +\DoxyCodeLine{romNumberOfSteps = int(finalTime/romTimeStepSize)} +\DoxyCodeLine{} +\DoxyCodeLine{\textcolor{comment}{\# run the masked galerkin problem}} +\DoxyCodeLine{[approximatedStateGal, romGal] = runMaskedGalerkin(fomObj, romTimeStepSize,} \DoxyCodeLine{ romNumberOfSteps,} \DoxyCodeLine{ modes[:,:romSize],} \DoxyCodeLine{ sampleMeshIndices)} +\DoxyCodeLine{\textcolor{comment}{\# run the masked galerkin problem}} +\DoxyCodeLine{[approximatedStateLspg, romLspg] = runMaskedLspg(fomObj, romTimeStepSize,} +\DoxyCodeLine{ romNumberOfSteps,} +\DoxyCodeLine{ modes[:,:romSize],} +\DoxyCodeLine{ sampleMeshIndices)} \DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\# compute l2-\/error between fom and approximate state}} -\DoxyCodeLine{ fomNorm = linalg.norm(fomFinalState)} -\DoxyCodeLine{ err1 = linalg.norm(fomFinalState-\/approximatedStateGal)} -\DoxyCodeLine{ print(\textcolor{stringliteral}{"{}Galerkin: final state relative l2 error: \{\}"{}}.format(err1/fomNorm))} -\DoxyCodeLine{ err2 = linalg.norm(fomFinalState-\/approximatedStateLspg)} -\DoxyCodeLine{ print(\textcolor{stringliteral}{"{}LSPG: final state relative l2 error: \{\}"{}}.format(err2/fomNorm))} +\DoxyCodeLine{\textcolor{comment}{\# compute l2-\/error between fom and approximate state}} +\DoxyCodeLine{fomNorm = linalg.norm(fomFinalState)} +\DoxyCodeLine{err1 = linalg.norm(fomFinalState-\/approximatedStateGal)} +\DoxyCodeLine{print(\textcolor{stringliteral}{"{}Galerkin: final state relative l2 error: \{\}"{}}.format(err1/fomNorm))} +\DoxyCodeLine{err2 = linalg.norm(fomFinalState-\/approximatedStateLspg)} +\DoxyCodeLine{print(\textcolor{stringliteral}{"{}LSPG: final state relative l2 error: \{\}"{}}.format(err2/fomNorm))} \DoxyCodeLine{} -\DoxyCodeLine{ logger.finalize()} +\DoxyCodeLine{logger.finalize()} +\DoxyCodeLine{} +\DoxyCodeLine{\textcolor{comment}{\#-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/\#}} \end{DoxyCode} -\hypertarget{md_pages_demos_demo5_autotoc_md137}{}\doxysubsection{1. Run FOM and collect snapshots}\label{md_pages_demos_demo5_autotoc_md137} +\hypertarget{md_pages_demos_demo5_autotoc_md139}{}\doxysubsection{1. Run FOM and collect snapshots}\label{md_pages_demos_demo5_autotoc_md139} \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{def }doFom(fom, dt, nsteps, saveFreq):} @@ -97,7 +97,7 @@ \DoxyCodeLine{ \textcolor{keywordflow}{return} [u, Usolns.T]} \end{DoxyCode} -\hypertarget{md_pages_demos_demo5_autotoc_md138}{}\doxysubsection{2. Compute POD modes}\label{md_pages_demos_demo5_autotoc_md138} +\hypertarget{md_pages_demos_demo5_autotoc_md140}{}\doxysubsection{2. Compute POD modes}\label{md_pages_demos_demo5_autotoc_md140} \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{def }computePodModes(snapshots):} @@ -106,11 +106,9 @@ \DoxyCodeLine{ \textcolor{keywordflow}{return} U} \end{DoxyCode} -\hypertarget{md_pages_demos_demo5_autotoc_md139}{}\doxysubsection{3. Create the sampling indices}\label{md_pages_demos_demo5_autotoc_md139} +\hypertarget{md_pages_demos_demo5_autotoc_md141}{}\doxysubsection{3. Create the sampling indices}\label{md_pages_demos_demo5_autotoc_md141} \begin{DoxyCode}{0} -\DoxyCodeLine{\textcolor{comment}{\# a masked problem is supposed to make it easier to emulate the}} -\DoxyCodeLine{\textcolor{comment}{\# effect of hyper-\/reduction. To create a mask ROM problem,}} \DoxyCodeLine{\textcolor{comment}{\# we need to select and provide to pressio a set of indices}} \DoxyCodeLine{\textcolor{comment}{\# identifying a subset of the grid points in the full mesh.}} \DoxyCodeLine{\textcolor{comment}{\# This is a simple way to mimic hyper-\/reduction}} @@ -127,9 +125,11 @@ \DoxyCodeLine{sampleMeshIndices = np.append(sampleMeshIndices, [0, 199])} \DoxyCodeLine{\textcolor{comment}{\# sort for convenience, not necessarily needed}} \DoxyCodeLine{sampleMeshIndices = np.sort(sampleMeshIndices)} +\DoxyCodeLine{} +\DoxyCodeLine{romSize = 5 \textcolor{comment}{\# number of modes to use}} \end{DoxyCode} -\hypertarget{md_pages_demos_demo5_autotoc_md140}{}\doxysubsection{4. The masker class}\label{md_pages_demos_demo5_autotoc_md140} +\hypertarget{md_pages_demos_demo5_autotoc_md142}{}\doxysubsection{4. The masker class}\label{md_pages_demos_demo5_autotoc_md142} \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{class }MyMasker:} @@ -150,7 +150,7 @@ \DoxyCodeLine{ result[:] = np.take(operand, self.rows\_, axis=0)} \end{DoxyCode} -\hypertarget{md_pages_demos_demo5_autotoc_md141}{}\doxysubsection{5. Masked Galerkin ROM}\label{md_pages_demos_demo5_autotoc_md141} +\hypertarget{md_pages_demos_demo5_autotoc_md143}{}\doxysubsection{5. Masked Galerkin ROM}\label{md_pages_demos_demo5_autotoc_md143} \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{def }runMaskedGalerkin(fomObj, dt, nsteps, modes, sampleMeshIndices):} @@ -192,15 +192,14 @@ \DoxyCodeLine{ problem = rom.galerkin.MaskedImplicitProblem(scheme, fomObj, linearDecoder, \(\backslash\)} \DoxyCodeLine{ romState, fomReferenceState, \(\backslash\)} \DoxyCodeLine{ projector, masker)} -\DoxyCodeLine{ stepper = problem.stepper()} \DoxyCodeLine{} \DoxyCodeLine{ \textcolor{comment}{\# linear and non linear solver}} \DoxyCodeLine{ lsO = MyLinSolver()} -\DoxyCodeLine{ nlsO = solvers.create\_newton\_raphson(stepper, romState, lsO)} +\DoxyCodeLine{ nlsO = solvers.create\_newton\_raphson(problem, romState, lsO)} \DoxyCodeLine{ nlsO.setMaxIterations(15)} \DoxyCodeLine{} \DoxyCodeLine{ \textcolor{comment}{\# solve the problem}} -\DoxyCodeLine{ ode.advance\_n\_steps(stepper, romState, 0., dt, nsteps, nlsO)} +\DoxyCodeLine{ ode.advance\_n\_steps(problem, romState, 0., dt, nsteps, nlsO)} \DoxyCodeLine{} \DoxyCodeLine{ \textcolor{comment}{\# after we are done, use the reconstructor object to reconstruct the fom state}} \DoxyCodeLine{ \textcolor{comment}{\# NOTE: even though the Galerkin problem was run on the "{}masked mesh points"{},}} @@ -210,7 +209,7 @@ \DoxyCodeLine{ \textcolor{keywordflow}{return} [fomRecon(romState), romState]} \end{DoxyCode} -\hypertarget{md_pages_demos_demo5_autotoc_md142}{}\doxysubsection{6. Masked LSPG ROM}\label{md_pages_demos_demo5_autotoc_md142} +\hypertarget{md_pages_demos_demo5_autotoc_md144}{}\doxysubsection{6. Masked LSPG ROM}\label{md_pages_demos_demo5_autotoc_md144} \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{def }runMaskedLspg(fomObj, dt, nsteps, modes, sampleMeshIndices):} @@ -242,15 +241,14 @@ \DoxyCodeLine{ problem = rom.lspg.unsteady.MaskedProblem(scheme, fomObj, linearDecoder,\(\backslash\)} \DoxyCodeLine{ romState, fomReferenceState,\(\backslash\)} \DoxyCodeLine{ masker)} -\DoxyCodeLine{ stepper = problem.stepper()} \DoxyCodeLine{} \DoxyCodeLine{ \textcolor{comment}{\# linear and non linear solver}} \DoxyCodeLine{ lsO = MyLinSolver()} -\DoxyCodeLine{ nlsO = solvers.create\_gauss\_newton(stepper, romState, lsO)} +\DoxyCodeLine{ nlsO = solvers.create\_gauss\_newton(problem, romState, lsO)} \DoxyCodeLine{ nlsO.setMaxIterations(10)} \DoxyCodeLine{} \DoxyCodeLine{ \textcolor{comment}{\# solve the problem}} -\DoxyCodeLine{ ode.advance\_n\_steps(stepper, romState, 0., dt, nsteps, nlsO)} +\DoxyCodeLine{ ode.advance\_n\_steps(problem, romState, 0., dt, nsteps, nlsO)} \DoxyCodeLine{} \DoxyCodeLine{ \textcolor{comment}{\# after we are done, use the reconstructor object to reconstruct the fom state}} \DoxyCodeLine{ \textcolor{comment}{\# NOTE: even though the Galerkin problem was run on the "{}masked mesh points"{},}} @@ -258,9 +256,11 @@ \DoxyCodeLine{ \textcolor{comment}{\# so we can effectively obtain an approximation of the full solution}} \DoxyCodeLine{ fomRecon = problem.fomStateReconstructor()} \DoxyCodeLine{ \textcolor{keywordflow}{return} [fomRecon(romState), romState]} +\DoxyCodeLine{} +\DoxyCodeLine{} \end{DoxyCode} -\hypertarget{md_pages_demos_demo5_autotoc_md143}{}\doxysection{Results}\label{md_pages_demos_demo5_autotoc_md143} +\hypertarget{md_pages_demos_demo5_autotoc_md145}{}\doxysection{Results}\label{md_pages_demos_demo5_autotoc_md145} If everything works fine, the following plots shows the result. We first plot the result reconstructed {\itshape only on the sample mesh}. This can easily be done using the bases collocated on the sample mesh indices. We then plot the fom solution reconstructed using the bases on the full mesh. Note that all we need to change is just using the full bases. We see that for this toy example, even with just 10\% of the grid, LSPG with 5 modes accuractely reproduces the FOM solution. While for Galerkin the solution is less accurate. diff --git a/docs/latex/md_pages_demos_demo6.tex b/docs/latex/md_pages_demos_demo6.tex index acb16b1..103d127 100644 --- a/docs/latex/md_pages_demos_demo6.tex +++ b/docs/latex/md_pages_demos_demo6.tex @@ -3,7 +3,7 @@ \begin{DoxyParagraph}{} This page describes a demo for a reproductive LSPG ROM applied to a 1D advection-\/diffusion problem using a nonlinear manifold via a multilayer perceptron (MLP). This demo purposefully focuses on a simple test since the main goal is to demonstrate the steps and the code. The full demo script is \href{https://github.com/Pressio/pressio4py/blob/master/demos/unsteady_default_lspg_advdiff1d_mlp/main.py}{\texttt{ here}}. \end{DoxyParagraph} -\hypertarget{md_pages_demos_demo6_autotoc_md145}{}\doxysection{Overview}\label{md_pages_demos_demo6_autotoc_md145} +\hypertarget{md_pages_demos_demo6_autotoc_md147}{}\doxysection{Overview}\label{md_pages_demos_demo6_autotoc_md147} This demo solves the same problem as the one \href{https://pressio.github.io/pressio4py/html/md_pages_demos_demo1.html}{\texttt{ here}}, but instead of using POD modes, we show here how to use a nonlinear manifold computed approximated by a neural network. Specifically, we use a MLP with 2 hidden layers of sizes 64 and 200. @@ -11,44 +11,43 @@ \begin{DoxyParagraph}{Important\+:} The MLP used in this demo is implemented in Py\+Torch, thus Py\+Torch must be installed prior to executing this demo. Look \href{https://pytorch.org/get-started/locally/}{\texttt{ here}} for information on how to install Py\+Torch on your system. \end{DoxyParagraph} -\hypertarget{md_pages_demos_demo6_autotoc_md146}{}\doxysection{Main function}\label{md_pages_demos_demo6_autotoc_md146} +\hypertarget{md_pages_demos_demo6_autotoc_md148}{}\doxysection{Main function}\label{md_pages_demos_demo6_autotoc_md148} The main function of the demo is the following\+: \begin{DoxyCode}{0} -\DoxyCodeLine{\textcolor{keywordflow}{if} \_\_name\_\_ == \textcolor{stringliteral}{"{}\_\_main\_\_"{}}:} -\DoxyCodeLine{ logger.initialize(logger.logto.terminal)} -\DoxyCodeLine{ logger.setVerbosity([logger.loglevel.info])} +\DoxyCodeLine{logger.initialize(logger.logto.terminal)} +\DoxyCodeLine{logger.setVerbosity([logger.loglevel.info])} \DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\# create fom object}} -\DoxyCodeLine{ fomObj = AdvDiff1d(nGrid=120, adv\_coef=2.0)} +\DoxyCodeLine{\textcolor{comment}{\# create fom object}} +\DoxyCodeLine{fomObj = AdvDiff1d(nGrid=120, adv\_coef=2.0)} \DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\# the final time to integrate to}} -\DoxyCodeLine{ finalTime = .05} +\DoxyCodeLine{\textcolor{comment}{\# the final time to integrate to}} +\DoxyCodeLine{finalTime = .05} \DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\#-\/-\/-\/ 1. FOM -\/-\/-\/\#}} -\DoxyCodeLine{ fomTimeStepSize = 1e-\/5} -\DoxyCodeLine{ fomNumberOfSteps = int(finalTime/fomTimeStepSize)} -\DoxyCodeLine{ sampleEvery = 200} -\DoxyCodeLine{ [fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)} +\DoxyCodeLine{\textcolor{comment}{\#-\/-\/-\/ 1. FOM -\/-\/-\/\#}} +\DoxyCodeLine{fomTimeStepSize = 1e-\/5} +\DoxyCodeLine{fomNumberOfSteps = int(finalTime/fomTimeStepSize)} +\DoxyCodeLine{sampleEvery = 200} +\DoxyCodeLine{[fomFinalState, snapshots] = doFom(fomObj, fomTimeStepSize, fomNumberOfSteps, sampleEvery)} \DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\#-\/-\/-\/ 2. train a nonlinear mapping using PyTorch -\/-\/-\/\#}} -\DoxyCodeLine{ \textcolor{comment}{\# here we use 3 modes, change this to try different modes}} -\DoxyCodeLine{ myNonLinearMapper = trainMapping(snapshots, romSize=3, epochs=500)} +\DoxyCodeLine{\textcolor{comment}{\#-\/-\/-\/ 2. train a nonlinear mapping using PyTorch -\/-\/-\/\#}} +\DoxyCodeLine{\textcolor{comment}{\# here we use 3 modes, change this to try different modes}} +\DoxyCodeLine{myNonLinearMapper = trainMapping(snapshots, romSize=3, epochs=500)} \DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\#-\/-\/-\/ 3. LSPG ROM -\/-\/-\/\#}} -\DoxyCodeLine{ romTimeStepSize = 3e-\/4} -\DoxyCodeLine{ romNumberOfSteps = int(finalTime/romTimeStepSize)} -\DoxyCodeLine{ approximatedState = runLspg(fomObj, romTimeStepSize, romNumberOfSteps, myNonLinearMapper)} +\DoxyCodeLine{\textcolor{comment}{\#-\/-\/-\/ 3. LSPG ROM -\/-\/-\/\#}} +\DoxyCodeLine{romTimeStepSize = 3e-\/4} +\DoxyCodeLine{romNumberOfSteps = int(finalTime/romTimeStepSize)} +\DoxyCodeLine{approximatedState = runLspg(fomObj, romTimeStepSize, romNumberOfSteps, myNonLinearMapper)} \DoxyCodeLine{} -\DoxyCodeLine{ \textcolor{comment}{\# compute l2-\/error between fom and approximate state}} -\DoxyCodeLine{ fomNorm = linalg.norm(fomFinalState)} -\DoxyCodeLine{ err = linalg.norm(fomFinalState-\/approximatedState)} -\DoxyCodeLine{ print(\textcolor{stringliteral}{"{}Final state relative l2 error: \{\}"{}}.format(err/fomNorm))} +\DoxyCodeLine{\textcolor{comment}{\# compute l2-\/error between fom and approximate state}} +\DoxyCodeLine{fomNorm = linalg.norm(fomFinalState)} +\DoxyCodeLine{err = linalg.norm(fomFinalState-\/approximatedState)} +\DoxyCodeLine{print(\textcolor{stringliteral}{"{}Final state relative l2 error: \{\}"{}}.format(err/fomNorm))} \DoxyCodeLine{} -\DoxyCodeLine{ logger.finalize()} +\DoxyCodeLine{logger.finalize()} \end{DoxyCode} -\hypertarget{md_pages_demos_demo6_autotoc_md147}{}\doxysubsection{1. Run FOM and collect snapshots}\label{md_pages_demos_demo6_autotoc_md147} -This step is the same as described \href{https://pressio.github.io/pressio4py/html/md_pages_demos_demo1.html}{\texttt{ here}},\hypertarget{md_pages_demos_demo6_autotoc_md148}{}\doxysubsection{2. Setup and train the nonlinear mapper}\label{md_pages_demos_demo6_autotoc_md148} +\hypertarget{md_pages_demos_demo6_autotoc_md149}{}\doxysubsection{1. Run FOM and collect snapshots}\label{md_pages_demos_demo6_autotoc_md149} +This step is the same as described \href{https://pressio.github.io/pressio4py/html/md_pages_demos_demo1.html}{\texttt{ here}},\hypertarget{md_pages_demos_demo6_autotoc_md150}{}\doxysubsection{2. Setup and train the nonlinear mapper}\label{md_pages_demos_demo6_autotoc_md150} It is important to note that while the mapper class below has the API required by pressio4py, it can encapsulate any arbitrary mapping function. In this case we show how to create a MLP-\/based representation in Py\+Torch, but one can use any other types of mapping and any other library (e.\+g., Tensorflow, keras). All of the Py\+Torch-\/specific code is encapsulated \href{https://github.com/Pressio/pressio4py/blob/master/demos/unsteady_default_lspg_advdiff1d_mlp/autoencoder_PyTorch.py}{\texttt{ here}}. If you prefer Tensorflow/keras, an equivalent implementation is \href{https://github.com/Pressio/pressio4py/blob/master/demos/unsteady_default_lspg_advdiff1d_mlp/autoencoder_keras.py}{\texttt{ here}}. The autoencoder is defined by @@ -198,7 +197,7 @@ \begin{DoxyParagraph}{Important\+:} when creating an arbitrary mapping (as in the class above), the jacobian matrix {\bfseries{must}} be column-\/major oder so that pressio can reference it without deep copying it. This not only reduces the memory footprint since it allows to keep only one jacobian object around but also it is fundamental for the update method below correctly. \end{DoxyParagraph} -\hypertarget{md_pages_demos_demo6_autotoc_md149}{}\doxysubsection{3. Construct and run LSPG}\label{md_pages_demos_demo6_autotoc_md149} +\hypertarget{md_pages_demos_demo6_autotoc_md151}{}\doxysubsection{3. Construct and run LSPG}\label{md_pages_demos_demo6_autotoc_md151} \begin{DoxyCode}{0} \DoxyCodeLine{\textcolor{keyword}{def }runLspg(fomObj, dt, nsteps, customMapper):} @@ -227,10 +226,9 @@ \DoxyCodeLine{ \textcolor{comment}{\# create LSPG problem}} \DoxyCodeLine{ scheme = ode.stepscheme.BDF1} \DoxyCodeLine{ problem = rom.lspg.unsteady.DefaultProblem(scheme, fomObj, customDecoder, romState, fomReferenceState)} -\DoxyCodeLine{ stepper = problem.stepper()} \DoxyCodeLine{} \DoxyCodeLine{ \textcolor{comment}{\# create the Gauss-\/Newton solver}} -\DoxyCodeLine{ nonLinSolver = solvers.create\_gauss\_newton(stepper, romState, MyLinSolver())} +\DoxyCodeLine{ nonLinSolver = solvers.create\_gauss\_newton(problem, romState, MyLinSolver())} \DoxyCodeLine{ \textcolor{comment}{\# set tolerance and convergence criteria}} \DoxyCodeLine{ nlsTol, nlsMaxIt = 1e-\/7, 10} \DoxyCodeLine{ nonLinSolver.setMaxIterations(nlsMaxIt)} @@ -239,7 +237,7 @@ \DoxyCodeLine{ \textcolor{comment}{\# create object to monitor the romState at every iteration}} \DoxyCodeLine{ myObs = RomStateObserver()} \DoxyCodeLine{ \textcolor{comment}{\# solve problem}} -\DoxyCodeLine{ ode.advance\_n\_steps\_and\_observe(stepper, romState, 0., dt, nsteps, myObs, nonLinSolver)} +\DoxyCodeLine{ ode.advance\_n\_steps\_and\_observe(problem, romState, 0., dt, nsteps, myObs, nonLinSolver)} \DoxyCodeLine{} \DoxyCodeLine{ \textcolor{comment}{\# after we are done, use the reconstructor object to reconstruct the fom state}} \DoxyCodeLine{ \textcolor{comment}{\# get the reconstructor object: this allows to map romState to fomState}} @@ -247,5 +245,5 @@ \DoxyCodeLine{ \textcolor{keywordflow}{return} fomRecon(romState)} \end{DoxyCode} -\hypertarget{md_pages_demos_demo6_autotoc_md150}{}\doxysection{Results}\label{md_pages_demos_demo6_autotoc_md150} +\hypertarget{md_pages_demos_demo6_autotoc_md152}{}\doxysection{Results}\label{md_pages_demos_demo6_autotoc_md152} If everything works fine, the following plot shows the result. \ No newline at end of file diff --git a/docs/latex/md_pages_introduction.tex b/docs/latex/md_pages_introduction.tex index 52c68cf..136b821 100644 --- a/docs/latex/md_pages_introduction.tex +++ b/docs/latex/md_pages_introduction.tex @@ -1,4 +1,4 @@ -todo Finish\hypertarget{md_pages_introduction_autotoc_md152}{}\doxysection{In a nutshell}\label{md_pages_introduction_autotoc_md152} +todo Finish\hypertarget{md_pages_introduction_autotoc_md154}{}\doxysection{In a nutshell}\label{md_pages_introduction_autotoc_md154} Pressio can be applied to any dynamical system expressible in a {\itshape continuous-\/time} form as \[ \frac{d \boldsymbol{y}}{dt} = \boldsymbol{f}(\boldsymbol{y},t; ...) \] and/or in a {\itshape discrete-\/time} form \[ \boldsymbol{R}(\boldsymbol{y}, \boldsymbol{y_{n-1}}, ..., t_n, dt_n; ...) = \boldsymbol{0} \] Here, $y$ is the full-\/order model (FOM) state, $f$ the FOM velocity, $t$ is time, and $R$ is the residual. diff --git a/docs/pages/components/rom_galerkin.md b/docs/pages/components/rom_galerkin.md index 2f86058..bedf6c4 100644 --- a/docs/pages/components/rom_galerkin.md +++ b/docs/pages/components/rom_galerkin.md @@ -21,28 +21,51 @@ We currently support three variants: - Masked: [link](md_pages_components_rom_galerkin_masked.html) -All variants return a problem object that meets the following interface: +The `problem` object behaves like a stepper. +Therefore, you can use the problem like +you would with any other stepper object (more on this below). + +### Explicit Problem + +The problem meets the following API: ```py class GalerkinProblem - def stepper() + def __call__(state, time, time_step_size, step_count); - def fomStateReconstructor() + def fomStateReconstructor(); }; ``` -The stepper method returns a reference to an -[explicit stepper](md_pages_components_ode_steppers_explicit.html) or -[implicit stepper](md_pages_components_ode_steppers_implicit.html), -depending on what you pass when you create the Galerkin problem. -The `stepper` method is, practically, what you would use -to retrieve the underlying stepper and use it to solve the problem. -Once you have the stepper, you can then use it as discussed -on the [explicit stepper page](md_pages_components_ode_steppers_explicit.html) -or [implicit stepper page](md_pages_components_ode_steppers_implicit.html). - -What does a stepper have to do with a Galerkin ROM? +### Implicit Problem + +The problem meets the following API: + +```py +class GalerkinProblem + + def __call__(state, time, time_step_size, step_count, solver); + + def createResidual() + return # a residual instance + + def createJacobian() + return # a Jacobian instance + + def residual(state, R) + # evaluates the residual for the given state + + def jacobian(state, J) + # evaluates the Jacobian for the given state + + def fomStateReconstructor(); +}; +``` + +## 2. Solve in time + +What does a stepper have to do with a Galerkin ROM problme? The answer is that practically speaking, at the lowest-level, a Galerkin problem can be reduced to simply a "custom" stepper to advance in time. This is how pressio4py implements this and the reason why a Galerkin @@ -52,12 +75,7 @@ object that you can use. You don't need to know how this is done, or rely on the details, because these are problem- and implementation-dependent, and we reserve the right to change this in the future. - -## 2. Reference the stepper and solve in time - -Extract the underlying stepper object and solve in time: - ```py -stepper = problme.stepper() -pressio4py.ode.advance_n_steps_and_observe(stepper, ...) +problem = ... +pressio4py.ode.advance_n_steps_and_observe(problem, ...) ``` diff --git a/docs/pages/components/rom_galerkin_default.md b/docs/pages/components/rom_galerkin_default.md index 6f91b30..d036c28 100644 --- a/docs/pages/components/rom_galerkin_default.md +++ b/docs/pages/components/rom_galerkin_default.md @@ -55,11 +55,10 @@ An example usage for explicit stepper is as follows: scheme = ode.stepscheme.ForwardEuler problem = rom.galerkin.DefaultExplicitProblem(scheme, adapter, decoder, rom_state, fom_ref_state) -stepper = problem.stepper() dt = 1. num_steps = 2 observer = MyObserver() -ode.advance_n_steps_and_observe(stepper, rom_state, 0., dt, num_steps, observer) +ode.advance_n_steps_and_observe(problem, rom_state, 0., dt, num_steps, observer) ``` ### Implicit Case @@ -68,5 +67,5 @@ An example usage for implicit stepper is as follows: ```py scheme = ode.stepscheme.BDF1 problem = rom.galerkin.DefaultImplicitProblem(scheme, adapter, decoder, rom_state, fom_ref_state) -stepper = problem.stepper() +// todo add ``` diff --git a/docs/pages/components/rom_lspg_unsteady.md b/docs/pages/components/rom_lspg_unsteady.md index 39125f6..05b56dc 100644 --- a/docs/pages/components/rom_lspg_unsteady.md +++ b/docs/pages/components/rom_lspg_unsteady.md @@ -26,38 +26,40 @@ All variants return a problem object that meets the following interface: ```py class UnsteadyLSPGProblem - def stepper() + def __call__(state, time, time_step_size, step_count, solver); + + def createResidual() + return # a residual instance + + def createJacobian() + return # a Jacobian instance + + def residual(state, R) + # evaluates the residual for the given state + + def jacobian(state, J) + # evaluates the Jacobian for the given state def fomStateReconstructor() }; ``` -The stepper method returns a reference -to an [implicit stepper](md_pages_components_ode_steppers_implicit.html) object -that the problem creates and owns. -The `stepper` method is what you use to retrieve the underlying -stepper and solve the problem in time. -Once you have the stepper, you can then use it as discussed -in [implicit stepper page](md_pages_components_ode_steppers_implicit.html). + +## 2. Solve in time What does a stepper have to do with a LSPG ROM? The answer is that practically speaking, at the lowest-level, an unsteady LSPG problem can be reduced to simply a "custom" stepper to advance in time. This is how pressio4py implements this and the reason why a LSPG -problem contains a stepper object inside: when you create the -problem, pressio creates the appropriate custom stepper -object that you can use. You don't need to know how this is done, +problem behaves like a stepper. +You don't need to know how this is done, or rely on the details, because these are problem- and implementation-dependent, and we reserve the right to change this in the future. -## 2. Reference the stepper and solve in time - -Extract the underlying stepper object and solve in time: - ```py -stepper = problme.stepper() -pressio4py.ode.advance_n_steps_and_observe(stepper, ...) +stepper = ... +pressio4py.ode.advance_n_steps_and_observe(problem, ...) ``` @m_class{m-note m-warning} diff --git a/docs/pages/demos/demo1.md b/docs/pages/demos/demo1.md index 85b479e..75bf9f5 100644 --- a/docs/pages/demos/demo1.md +++ b/docs/pages/demos/demo1.md @@ -60,7 +60,7 @@ The main function of the demo is the following: ```py @codesnippet ../../../demos/unsteady_default_galerkin_advdiff1d_pod/main.py -24:56 +23:56 ``` ## Results diff --git a/docs/pages/demos/demo5.md b/docs/pages/demos/demo5.md index 2090100..aee58ad 100644 --- a/docs/pages/demos/demo5.md +++ b/docs/pages/demos/demo5.md @@ -66,7 +66,7 @@ The main function of the demo is the following: ```py @codesnippet ../../../demos/unsteady_masked_galerkin_vs_lspg_advdiff1d_pod/main.py -114:158 +113:158 ``` ## Results diff --git a/docs/pages/main.md b/docs/pages/main.md index 08805f4..11a9cfe 100644 --- a/docs/pages/main.md +++ b/docs/pages/main.md @@ -72,9 +72,9 @@ pytest -s @m_class{m-note m-info} @parblock -If you get an import error, make sure the version of `pytest` you are -using is compatible with the `pip` command you used to install. -For compatibility, the Python commands must be from the **same** distribution. +To avoid potential issues with mixed versions, make sure the version of `pytest` +you use is compatible with the `pip` command you use to install. +The Python commands must be from the **same** distribution. @endparblock @@ -89,8 +89,6 @@ For compatibility, the Python commands must be from the **same** distribution. -
      - ## License and Citation The full license is available [here](https://pressio.github.io/various/license/). diff --git a/docs/xml/indexpage.xml b/docs/xml/indexpage.xml index d99eaeb..cfa4923 100644 --- a/docs/xml/indexpage.xml +++ b/docs/xml/indexpage.xml @@ -11,12 +11,12 @@ Advancing reduced order models (ROMs) for dynamical systems in science and engineering. This is the documentation of the Python library, one component of the Pressio ecosystem. - + Start with why Model reduction is a broad and very active field. Many methods exist, but there is no such thing as "one method to rule them all". We believe that evaluating the quality of a reduced model requires accounting for several factors, e.g., the reduction in degrees of freedom, training cost, evaluation cost, robustness, simplicity, predictive accuracy, etc. There is no single metric to rely on; it is always a tradeoff. We believe that there is a lot to explore in this field both in terms of new research directions as well as assessing robustness of current state-of-the-art methods. There is no better way than an agile Python framework to incentivize and foster work to impact this field. Working towards this goal, pressio4py is our open source contribution to research novel fundamental ideas on model reduction as well as test state-of-the-art methods on problems of arbitrary complexity and from arbitrary disciplines. Python is a great language to do so because it benefits from a large community of developers, a large choice of available packages, and has become the de-facto choice for machine learning. This makes it an ideal framework to explore and merge ideas from different fields. - + Components Name @@ -84,7 +84,7 @@ general info Note that we intentionally keep pressio4py limited in scope for now. We don't provide bindings for all the functionalities in the pressio C++ library but only for the model reduction ones and those strictly auxiliary. - + Installation #theC++compilermustsupportC++14 @@ -102,17 +102,15 @@ general info -If you get an import error, make sure the version of pytest you are using is compatible with the pip command you used to install. For compatibility, the Python commands must be from the same distribution. +To avoid potential issues with mixed versions, make sure the version of pytest you use is compatible with the pip command you use to install. The Python commands must be from the same distribution. - - - + License and Citation The full license is available here. We are working on publishing this: you can find our arXiv preprint at: https://arxiv.org/abs/2003.07798 - + Questions? Find us on Slack: https://pressioteam.slack.com or open an issue on github. diff --git a/docs/xml/md_pages_components_rom_galerkin.xml b/docs/xml/md_pages_components_rom_galerkin.xml index 6b26484..3b4372b 100644 --- a/docs/xml/md_pages_components_rom_galerkin.xml +++ b/docs/xml/md_pages_components_rom_galerkin.xml @@ -21,22 +21,47 @@ Masked: link -All variants return a problem object that meets the following interface: +The problem object behaves like a stepper. Therefore, you can use the problem like you would with any other stepper object (more on this below). + +Explicit Problem +The problem meets the following API: classGalerkinProblem -defstepper() +def__call__(state,time,time_step_size,step_count); -deffomStateReconstructor() +deffomStateReconstructor(); }; -The stepper method returns a reference to an explicit stepper or implicit stepper, depending on what you pass when you create the Galerkin problem. The stepper method is, practically, what you would use to retrieve the underlying stepper and use it to solve the problem. Once you have the stepper, you can then use it as discussed on the explicit stepper page or implicit stepper page. -What does a stepper have to do with a Galerkin ROM? The answer is that practically speaking, at the lowest-level, a Galerkin problem can be reduced to simply a "custom" stepper to advance in time. This is how pressio4py implements this and the reason why a Galerkin problem contains a stepper object inside: when you create the problem, pressio creates the appropriate custom stepper object that you can use. You don't need to know how this is done, or rely on the details, because these are problem- and implementation-dependent, and we reserve the right to change this in the future. + + +Implicit Problem +The problem meets the following API: +classGalerkinProblem + +def__call__(state,time,time_step_size,step_count,solver); + +defcreateResidual() +return#aresidualinstance + +defcreateJacobian() +return#aJacobianinstance + +defresidual(state,R) +#evaluatestheresidualforthegivenstate + +defjacobian(state,J) +#evaluatestheJacobianforthegivenstate + +deffomStateReconstructor(); +}; + + - -2. Reference the stepper and solve in time -Extract the underlying stepper object and solve in time: -stepper=problme.stepper() -pressio4py.ode.advance_n_steps_and_observe(stepper,...) + +2. Solve in time +What does a stepper have to do with a Galerkin ROM problme? The answer is that practically speaking, at the lowest-level, a Galerkin problem can be reduced to simply a "custom" stepper to advance in time. This is how pressio4py implements this and the reason why a Galerkin problem contains a stepper object inside: when you create the problem, pressio creates the appropriate custom stepper object that you can use. You don't need to know how this is done, or rely on the details, because these are problem- and implementation-dependent, and we reserve the right to change this in the future. +problem=... +pressio4py.ode.advance_n_steps_and_observe(problem,...) diff --git a/docs/xml/md_pages_components_rom_galerkin_default.xml b/docs/xml/md_pages_components_rom_galerkin_default.xml index ae03e5e..3a26a06 100644 --- a/docs/xml/md_pages_components_rom_galerkin_default.xml +++ b/docs/xml/md_pages_components_rom_galerkin_default.xml @@ -10,7 +10,7 @@ Defined in module: pressio4py.rom.galerkin Import as: from pressio4py.rom import galerkin - + API, Parameters and Requirements problem=galerkin.DefaultExplicitProblem(scheme,fom_adapter,decoder,\(1) rom_state,fom_ref_state) @@ -50,28 +50,27 @@ - + Example usage - + Explicit Case An example usage for explicit stepper is as follows: #assuming:decoder,adapter,rom_state,fom_ref_statearedefined scheme=ode.stepscheme.ForwardEuler problem=rom.galerkin.DefaultExplicitProblem(scheme,adapter,decoder,rom_state,fom_ref_state) -stepper=problem.stepper() dt=1. num_steps=2 observer=MyObserver() -ode.advance_n_steps_and_observe(stepper,rom_state,0.,dt,num_steps,observer) +ode.advance_n_steps_and_observe(problem,rom_state,0.,dt,num_steps,observer) - + Implicit Case An example usage for implicit stepper is as follows: scheme=ode.stepscheme.BDF1 problem=rom.galerkin.DefaultImplicitProblem(scheme,adapter,decoder,rom_state,fom_ref_state) -stepper=problem.stepper() +//todoadd diff --git a/docs/xml/md_pages_components_rom_galerkin_hypred.xml b/docs/xml/md_pages_components_rom_galerkin_hypred.xml index d1c0fe3..41ae836 100644 --- a/docs/xml/md_pages_components_rom_galerkin_hypred.xml +++ b/docs/xml/md_pages_components_rom_galerkin_hypred.xml @@ -10,7 +10,7 @@ Defined in module: pressio4py.rom.galerkin Import as: from pressio4py.rom import galerkin - + API, Parameters and Requirements problem=galerkin.HyperreducedExplicitProblem(scheme,fom_adapter,decoder,\(1) rom_state,fom_ref_state,projector) @@ -55,7 +55,7 @@ - + Example usage todo link tutorials/demos diff --git a/docs/xml/md_pages_components_rom_galerkin_masked.xml b/docs/xml/md_pages_components_rom_galerkin_masked.xml index c83d13b..c903fb9 100644 --- a/docs/xml/md_pages_components_rom_galerkin_masked.xml +++ b/docs/xml/md_pages_components_rom_galerkin_masked.xml @@ -10,7 +10,7 @@ Defined in module: pressio4py.rom.galerkin Import as: from pressio4py.rom import galerkin - + API, Parameters and Requirements problem=galerkin.MaskedExplicitProblem(scheme,fom_adapter,decoder, rom_state,fom_ref_state,\(1) @@ -59,7 +59,7 @@ - + Masker todo: explain what it is The masker must meet the following API: @@ -81,7 +81,7 @@ where sample_indices is a numpy.array holding the set of the row indices to sample. - + Example usage todo link tutorials diff --git a/docs/xml/md_pages_components_rom_galerkin_projector.xml b/docs/xml/md_pages_components_rom_galerkin_projector.xml index 6412ec8..d718e00 100644 --- a/docs/xml/md_pages_components_rom_galerkin_projector.xml +++ b/docs/xml/md_pages_components_rom_galerkin_projector.xml @@ -12,7 +12,7 @@ For a default problem, you don't need to pass it because the projector is constructed behind the scenes automatically using the decoder's jacobian. todo: explain more, talk about pressio-tools. - + API When provided by the user, the projector must be a functor as follows: classProjector: diff --git a/docs/xml/md_pages_components_rom_lspg_default.xml b/docs/xml/md_pages_components_rom_lspg_default.xml index ed39de5..0fd2c57 100644 --- a/docs/xml/md_pages_components_rom_lspg_default.xml +++ b/docs/xml/md_pages_components_rom_lspg_default.xml @@ -10,7 +10,7 @@ Defined in module: pressio4py.rom.lspg.unsteady Import as: from pressio4py.rom import lspg - + API, Parameters and Requirements #continuous-timeoverloads problem=lspg.unsteady.DefaultProblem(scheme,fom_adapter,decoder,\(1) diff --git a/docs/xml/md_pages_components_rom_lspg_default_steady.xml b/docs/xml/md_pages_components_rom_lspg_default_steady.xml index 0946df4..338b1fd 100644 --- a/docs/xml/md_pages_components_rom_lspg_default_steady.xml +++ b/docs/xml/md_pages_components_rom_lspg_default_steady.xml @@ -10,7 +10,7 @@ Defined in module: pressio4py.rom.lspg.steady Import as: from pressio4py.rom import lspg - + API problem=lspg.steady.Problem(fom_adapter,decoder,\(1) rom_state,fom_ref_state) @@ -18,7 +18,7 @@ problem=lspg.steady.PrecProblem(fom_adapter,decoder,rom_state,(2) fom_ref_state,preconditioner) - + Parameters and Requirements fom_adapter: @@ -61,7 +61,7 @@ - + Example code importnumpyasnp fromscipyimportlinalg diff --git a/docs/xml/md_pages_components_rom_lspg_hypred.xml b/docs/xml/md_pages_components_rom_lspg_hypred.xml index b63ee36..9e58b1d 100644 --- a/docs/xml/md_pages_components_rom_lspg_hypred.xml +++ b/docs/xml/md_pages_components_rom_lspg_hypred.xml @@ -10,7 +10,7 @@ Defined in module: pressio4py.rom.lspg.unsteady Import as: from pressio4py.rom import lspg - + API, Parameters and Requirements problem=lspg.unsteady.HypredProblem(scheme,fom_adapter,decoder,\ rom_state,fom_ref_state,\ @@ -70,7 +70,7 @@ - + Stencil to sample indexing When working with a hyper-reduced problem, pressio4py has to manipulate objects that have different sizes/distributions. For such problem, in fact, some operators are naturally defined on the what we refer to as "sample mesh" while some are defined on what we call the "stencil mesh". As explained here, recall that: @@ -83,7 +83,7 @@ The sample to stencil indexing is a list of indices that you need to provide such that pressio4py knows how to properly combine operands defined on stencil and sample mesh. - + Explain it to me better! Suppose that your FOM problem involves a 2D problem and that your FOM numerical method needs at every cell information from the nearest neighbors. For the sake of explanation, it does not matter what problem we are solving, only what we just said. Now, suppose that you want to try hyper-reduced LSPG on it. You come up with a sample and stencil mesh for your problem (read this page for some information about how to select sample mesh cells), and let's say it looks like this: diff --git a/docs/xml/md_pages_components_rom_lspg_masked.xml b/docs/xml/md_pages_components_rom_lspg_masked.xml index 2df164e..e3a1066 100644 --- a/docs/xml/md_pages_components_rom_lspg_masked.xml +++ b/docs/xml/md_pages_components_rom_lspg_masked.xml @@ -10,7 +10,7 @@ Defined in module: pressio4py.rom.lspg.unsteady Import as: from pressio4py.rom import lspg - + API, Parameters and Requirements #continuous-timeoverloads problem=lspg.unsteady.MaskedProblem(scheme,fom_adapter,decoder,\(1) diff --git a/docs/xml/md_pages_components_rom_lspg_masked_steady.xml b/docs/xml/md_pages_components_rom_lspg_masked_steady.xml index 5790b16..b9991e7 100644 --- a/docs/xml/md_pages_components_rom_lspg_masked_steady.xml +++ b/docs/xml/md_pages_components_rom_lspg_masked_steady.xml @@ -10,7 +10,7 @@ Defined in module: pressio4py.rom.lspg.steady Import as: from pressio4py.rom import lspg - + API problem=lspg.steady.MaskedProblem(fom_adapter,decoder,\ rom_state,fom_ref_state,masker) @@ -18,7 +18,7 @@ problem=lspg.steady.PrecMaskedProblem(fom_adapter,decoder,rom_state, fom_ref_state,masker,preconditioner) - + Parameters and Requirements fom_adapter: @@ -79,7 +79,7 @@ - + Example code todo add diff --git a/docs/xml/md_pages_components_rom_lspg_steady.xml b/docs/xml/md_pages_components_rom_lspg_steady.xml index 762937f..39182fc 100644 --- a/docs/xml/md_pages_components_rom_lspg_steady.xml +++ b/docs/xml/md_pages_components_rom_lspg_steady.xml @@ -8,7 +8,7 @@ todo: write this better The pressio4py steady LSPG ROMs are designed to involve two main steps: - + 1. Create You instantiate a "steady LSPG problem", e.g.: @@ -40,7 +40,7 @@ }; - + 2. Solve you use a nonlinear least-squares solvers to solve the problem solver=pressio4py.solvers.create_gauss_newton(problem,...) diff --git a/docs/xml/md_pages_components_rom_lspg_unsteady.xml b/docs/xml/md_pages_components_rom_lspg_unsteady.xml index e01df7b..08e391e 100644 --- a/docs/xml/md_pages_components_rom_lspg_unsteady.xml +++ b/docs/xml/md_pages_components_rom_lspg_unsteady.xml @@ -8,7 +8,7 @@ todo: write more The pressio4py unsteady LSPG ROMs are designed such that using them involves these main steps: - + 1. Create You create an instance of a "LSPG problem", e.g.: @@ -24,19 +24,29 @@ All variants return a problem object that meets the following interface: classUnsteadyLSPGProblem -defstepper() +def__call__(state,time,time_step_size,step_count,solver); + +defcreateResidual() +return#aresidualinstance + +defcreateJacobian() +return#aJacobianinstance + +defresidual(state,R) +#evaluatestheresidualforthegivenstate + +defjacobian(state,J) +#evaluatestheJacobianforthegivenstate deffomStateReconstructor() }; -The stepper method returns a reference to an implicit stepper object that the problem creates and owns. The stepper method is what you use to retrieve the underlying stepper and solve the problem in time. Once you have the stepper, you can then use it as discussed in implicit stepper page. -What does a stepper have to do with a LSPG ROM? The answer is that practically speaking, at the lowest-level, an unsteady LSPG problem can be reduced to simply a "custom" stepper to advance in time. This is how pressio4py implements this and the reason why a LSPG problem contains a stepper object inside: when you create the problem, pressio creates the appropriate custom stepper object that you can use. You don't need to know how this is done, or rely on the details, because these are problem- and implementation-dependent, and we reserve the right to change this in the future. - -2. Reference the stepper and solve in time -Extract the underlying stepper object and solve in time: -stepper=problme.stepper() -pressio4py.ode.advance_n_steps_and_observe(stepper,...) + +2. Solve in time +What does a stepper have to do with a LSPG ROM? The answer is that practically speaking, at the lowest-level, an unsteady LSPG problem can be reduced to simply a "custom" stepper to advance in time. This is how pressio4py implements this and the reason why a LSPG problem behaves like a stepper. You don't need to know how this is done, or rely on the details, because these are problem- and implementation-dependent, and we reserve the right to change this in the future. +stepper=... +pressio4py.ode.advance_n_steps_and_observe(problem,...) Remember that for LSPG, you are solving at each step a nonlinear least-squares problem. Therefore, the solver you need to use is a nonlinear least-squares solver, e.g, Gauss-Newton or Levernberg-Marquardt. diff --git a/docs/xml/md_pages_demos_demo1.xml b/docs/xml/md_pages_demos_demo1.xml index 66af334..2d71e99 100644 --- a/docs/xml/md_pages_demos_demo1.xml +++ b/docs/xml/md_pages_demos_demo1.xml @@ -10,7 +10,7 @@ This page describes a demo for a reproductive Galerkin ROM applied to a 1D advection-diffusion problem using POD modes as basis. By the end, it should be clear how to setup the problem. This demo purposefully focuses on a simple test since the main goal is to demonstrate the steps and code. More complex cases will be shown in other demos. The full demo script is here. - + Overview We cover these three typical steps needed for a ROM: generate of snapshots using the full-order model (FOM) @@ -19,50 +19,49 @@ - + FOM Equations The governing equations for this problem are: \[ \frac{\partial u}{\partial t} = \frac{\partial}{\partial x} (k(u,x) \frac{\partial u}{\partial x} ) - a*\frac{\partial u}{\partial x} \] where $k(u,x)=x^4$, the field is $u(x;t)$, the advection velocity is fixed at $a=2$, the spatial coordinate is $x$ and the domain is $(0,1)$. We use homogeneous BC. Note that a class approximating the FOM operators via finite-differences is implemented here. - + Main function -The main function of the demo is the following: if__name__=="__main__": -logger.initialize(logger.logto.terminal) -logger.setVerbosity([logger.loglevel.info]) +The main function of the demo is the following: logger.initialize(logger.logto.terminal) +logger.setVerbosity([logger.loglevel.info]) -#createfomobject -fomObj=AdvDiff1d(nGrid=120,adv_coef=2.0) +#createfomobject +fomObj=AdvDiff1d(nGrid=120,adv_coef=2.0) -#thefinaltimetointegrateto -finalTime=.05 +#thefinaltimetointegrateto +finalTime=.05 -#---1.FOM---# -fomTimeStepSize=1e-5 -fomNumberOfSteps=int(finalTime/fomTimeStepSize) -sampleEvery=200 -[fomFinalState,snapshots]=doFom(fomObj,fomTimeStepSize,fomNumberOfSteps,sampleEvery) +#---1.FOM---# +fomTimeStepSize=1e-5 +fomNumberOfSteps=int(finalTime/fomTimeStepSize) +sampleEvery=200 +[fomFinalState,snapshots]=doFom(fomObj,fomTimeStepSize,fomNumberOfSteps,sampleEvery) -#---2.POD---# -modes=computePodModes(snapshots) +#---2.POD---# +modes=computePodModes(snapshots) -#---3.GALERKINROM---# -romTimeStepSize=3e-4 -romNumberOfSteps=int(finalTime/romTimeStepSize) -#runwithvariousnumberofmodes -romSizes=[2,4,6] -approximations={} -forromSizeinromSizes: -currentSolution=runGalerkin(fomObj,romTimeStepSize, -romNumberOfSteps, -modes[:,:romSize]) -approximations[romSize]=currentSolution +#---3.GALERKINROM---# +romTimeStepSize=3e-4 +romNumberOfSteps=int(finalTime/romTimeStepSize) +#runwithvariousnumberofmodes +romSizes=[2,4,6] +approximations={} +forromSizeinromSizes: +currentSolution=runGalerkin(fomObj,romTimeStepSize, +romNumberOfSteps, +modes[:,:romSize]) +approximations[romSize]=currentSolution -#computel2-errorbetweenfomandapproximatestate -fomNorm=linalg.norm(fomFinalState) -err=linalg.norm(fomFinalState-currentSolution) -print("With{}modes,finalrelativel2error:{}".format(romSize,err/fomNorm)) +#computel2-errorbetweenfomandapproximatestate +fomNorm=linalg.norm(fomFinalState) +err=linalg.norm(fomFinalState-currentSolution) +print("With{}modes,finalrelativel2error:{}".format(romSize,err/fomNorm)) - + 1. Run FOM and collect snapshots defdoFom(fom,dt,nsteps,saveFreq): u=fom.u0.copy() @@ -79,52 +78,52 @@ return[u,Usolns.T] - + 2. Compute POD modes print("SVDonmatrix:",snapshots.shape) U,S,VT=np.linalg.svd(snapshots) returnU - + 3. Construct and run ROM -#auxiliaryclasstouseinthesolvebelow -#tomonitortheromstateduringtimestepping -classRomStateObserver: -def__call__(self,timeStep,time,state):pass +defrunGalerkin(fomObj,dt,nsteps,modes): +#auxiliaryclasstouseinthesolvebelow +#tomonitortheromstateduringtimestepping +classRomStateObserver: +def__call__(self,timeStep,time,state):pass -#findoutnumberofmodeswanted -romSize=modes.shape[1] +#findoutnumberofmodeswanted +romSize=modes.shape[1] -#createalineardecoder,passingonlythedesirednumberofmodes -#thiswillmakeadeepcopyofthemodes -linearDecoder=rom.Decoder(modes) +#createalineardecoder,passingonlythedesirednumberofmodes +#thiswillmakeadeepcopyofthemodes +linearDecoder=rom.Decoder(modes) -#fomreferencestate:hereitiszero -fomReferenceState=np.zeros(fomObj.nGrid) +#fomreferencestate:hereitiszero +fomReferenceState=np.zeros(fomObj.nGrid) -#createROMstatebyprojectingthefominitialcondition -fomInitialState=fomObj.u0.copy() -romState=np.dot(modes.T,fomInitialState) +#createROMstatebyprojectingthefominitialcondition +fomInitialState=fomObj.u0.copy() +romState=np.dot(modes.T,fomInitialState) -#createproblem -scheme=ode.stepscheme.ForwardEuler -problem=rom.galerkin.DefaultExplicitProblem(scheme,fomObj,linearDecoder,romState,fomReferenceState) -stepper=problem.stepper() +#createproblem +scheme=ode.stepscheme.ForwardEuler +problem=rom.galerkin.DefaultExplicitProblem(scheme,fomObj,linearDecoder,romState,fomReferenceState) -#createobjecttomonitortheromStateateveryiteration -myObs=RomStateObserver() -#solveproblem -ode.advance_n_steps_and_observe(stepper,romState,0.,dt,nsteps,myObs) +#createobjecttomonitortheromStateateveryiteration +myObs=RomStateObserver() +#solveproblem +ode.advance_n_steps_and_observe(problem,romState,0.,dt,nsteps,myObs) -#afterwearedone,usethereconstructorobjecttoreconstructthefomstate -#getthereconstructorobject:thisallowstomapromStatetofomState -fomRecon=problem.fomStateReconstructor() -returnfomRecon(romState) +#afterwearedone,usethereconstructorobjecttoreconstructthefomstate +#getthereconstructorobject:thisallowstomapromStatetofomState +fomRecon=problem.fomStateReconstructor() +returnfomRecon(romState) - + Results If everything works fine, the following plot shows the result. We see that for this toy example, the full solution is recovered very well with Galerkin with just a few POD modes. diff --git a/docs/xml/md_pages_demos_demo2.xml b/docs/xml/md_pages_demos_demo2.xml index e80b2d2..b4a70e9 100644 --- a/docs/xml/md_pages_demos_demo2.xml +++ b/docs/xml/md_pages_demos_demo2.xml @@ -10,7 +10,7 @@ This page describes a demo for a reproductive LSPG ROM applied to a 1D advection-diffusion problem using POD modes as basis. By the end, it should be clear how to setup the problem. This demo purposefully focuses on a simple test since the main goal is to demonstrate the steps and the code. The full demo script is here. - + Overview We cover these three typical steps needed for a ROM: generate of snapshots using the full-order model (FOM) @@ -20,42 +20,41 @@ The governing equations for this problem are the same as those in here, - + Main function -The main function of the demo is the following: if__name__=="__main__": -logger.initialize(logger.logto.terminal) -logger.setVerbosity([logger.loglevel.info]) - -#createfomobject -fomObj=AdvDiff1d(nGrid=120,adv_coef=2.0) - -#thefinaltimetointegrateto -finalTime=.05 - -#---1.FOM---# -fomTimeStepSize=1e-5 -fomNumberOfSteps=int(finalTime/fomTimeStepSize) -sampleEvery=200 -[fomFinalState,snapshots]=doFom(fomObj,fomTimeStepSize,fomNumberOfSteps,sampleEvery) - -#---2.POD---# -modes=computePodModes(snapshots) - -#---3.LSPGROM---# -romSize=4 -romTimeStepSize=3e-4 -romNumberOfSteps=int(finalTime/romTimeStepSize) -#wepassonlyromSizemodes -approximatedState=runLspg(fomObj,romTimeStepSize,romNumberOfSteps,modes[:,:romSize]) - -#computel2-errorbetweenfomandapproximatestate -fomNorm=linalg.norm(fomFinalState) -err=linalg.norm(fomFinalState-approximatedState) -print("Finalstaterelativel2error:{}".format(err/fomNorm)) - -logger.finalize() +The main function of the demo is the following: logger.initialize(logger.logto.terminal) +logger.setVerbosity([logger.loglevel.info]) + +#createfomobject +fomObj=AdvDiff1d(nGrid=120,adv_coef=2.0) + +#thefinaltimetointegrateto +finalTime=.05 + +#---1.FOM---# +fomTimeStepSize=1e-5 +fomNumberOfSteps=int(finalTime/fomTimeStepSize) +sampleEvery=200 +[fomFinalState,snapshots]=doFom(fomObj,fomTimeStepSize,fomNumberOfSteps,sampleEvery) + +#---2.POD---# +modes=computePodModes(snapshots) + +#---3.LSPGROM---# +romSize=4 +romTimeStepSize=3e-4 +romNumberOfSteps=int(finalTime/romTimeStepSize) +#wepassonlyromSizemodes +approximatedState=runLspg(fomObj,romTimeStepSize,romNumberOfSteps,modes[:,:romSize]) + +#computel2-errorbetweenfomandapproximatestate +fomNorm=linalg.norm(fomFinalState) +err=linalg.norm(fomFinalState-approximatedState) +print("Finalstaterelativel2error:{}".format(err/fomNorm)) + +logger.finalize() - + 1. Run FOM and collect snapshots defdoFom(fom,dt,nsteps,saveFreq): u=fom.u0.copy() @@ -72,7 +71,7 @@ return[u,Usolns.T] - + 2. Compute POD modes defcomputePodModes(snapshots): print("SVDonmatrix:",snapshots.shape) @@ -80,7 +79,7 @@ returnU - + 3. Construct and run ROM defrunLspg(fomObj,dt,nsteps,modes): #thisisanauxiliaryclassthatcanbepassedtosolve @@ -112,10 +111,9 @@ #createLSPGproblem scheme=ode.stepscheme.BDF1 problem=rom.lspg.unsteady.DefaultProblem(scheme,fomObj,linearDecoder,romState,fomReferenceState) -stepper=problem.stepper() #createtheGauss-Newtonsolver -nonLinSolver=solvers.create_gauss_newton(stepper,romState,MyLinSolver()) +nonLinSolver=solvers.create_gauss_newton(problem,romState,MyLinSolver()) #settoleranceandconvergencecriteria nlsTol,nlsMaxIt=1e-6,5 nonLinSolver.setMaxIterations(nlsMaxIt) @@ -124,16 +122,18 @@ #createobjecttomonitortheromStateateveryiteration myObs=RomStateObserver() #solveproblem -ode.advance_n_steps_and_observe(stepper,romState,0.,dt,nsteps,myObs,nonLinSolver) +ode.advance_n_steps_and_observe(problem,romState,0.,dt,nsteps,myObs,nonLinSolver) #afterwearedone,usethereconstructorobjecttoreconstructthefomstate #getthereconstructorobject:thisallowstomapromStatetofomState fomRecon=problem.fomStateReconstructor() returnfomRecon(romState) + + - + Results If everything works fine, the following plot shows the result. diff --git a/docs/xml/md_pages_demos_demo3.xml b/docs/xml/md_pages_demos_demo3.xml index ffc9bca..dd36fd1 100644 --- a/docs/xml/md_pages_demos_demo3.xml +++ b/docs/xml/md_pages_demos_demo3.xml @@ -10,49 +10,48 @@ This page describes a demo for a reproductive LSPG ROM applied to a 1D advection-diffusion problem using a nonlinear manifold via kernel PCA. This demo purposefully focuses on a simple test since the main goal is to demonstrate the steps and the code. The full demo script is here. - + Overview This demo solves the same problem as the one here, but instead of using POD modes, we show here how to use a nonlinear manifold computed via kernel PCA. - + Main function -The main function of the demo is the following: if__name__=="__main__": -logger.initialize(logger.logto.terminal) -logger.setVerbosity([logger.loglevel.info]) +The main function of the demo is the following: logger.initialize(logger.logto.terminal) +logger.setVerbosity([logger.loglevel.info]) -#createfomobject -fomObj=AdvDiff1d(nGrid=120,adv_coef=2.0) +#createfomobject +fomObj=AdvDiff1d(nGrid=120,adv_coef=2.0) -#thefinaltimetointegrateto -finalTime=.05 +#thefinaltimetointegrateto +finalTime=.05 -#---1.FOM---# -fomTimeStepSize=1e-5 -fomNumberOfSteps=int(finalTime/fomTimeStepSize) -sampleEvery=200 -[fomFinalState,snapshots]=doFom(fomObj,fomTimeStepSize,fomNumberOfSteps,sampleEvery) +#---1.FOM---# +fomTimeStepSize=1e-5 +fomNumberOfSteps=int(finalTime/fomTimeStepSize) +sampleEvery=200 +[fomFinalState,snapshots]=doFom(fomObj,fomTimeStepSize,fomNumberOfSteps,sampleEvery) -#---2.trainanonlinearmappingusingkPCA---# -#hereweuse3modes,changethistotrydifferentmodes -myNonLinearMapper=MyMapperKPCA(snapshots.T,numModes=3) +#---2.trainanonlinearmappingusingkPCA---# +#hereweuse3modes,changethistotrydifferentmodes +myNonLinearMapper=MyMapperKPCA(snapshots.T,numModes=3) -#---3.LSPGROM---# -romTimeStepSize=3e-4 -romNumberOfSteps=int(finalTime/romTimeStepSize) -approximatedState=runLspg(fomObj,romTimeStepSize,romNumberOfSteps,myNonLinearMapper) +#---3.LSPGROM---# +romTimeStepSize=3e-4 +romNumberOfSteps=int(finalTime/romTimeStepSize) +approximatedState=runLspg(fomObj,romTimeStepSize,romNumberOfSteps,myNonLinearMapper) -#computel2-errorbetweenfomandapproximatestate -fomNorm=linalg.norm(fomFinalState) -err=linalg.norm(fomFinalState-approximatedState) -print("Finalstaterelativel2error:{}".format(err/fomNorm)) +#computel2-errorbetweenfomandapproximatestate +fomNorm=linalg.norm(fomFinalState) +err=linalg.norm(fomFinalState-approximatedState) +print("Finalstaterelativel2error:{}".format(err/fomNorm)) -logger.finalize() +logger.finalize() - + 1. Run FOM and collect snapshots This step is the same as described here, - + 2. Setup and train the nonlinear kPCA mapper It is important to note that while the mapper class below has the API required by pressio4py, it can encapsulate any arbitrary mapping function. In this case we show how to create a kPCA-based representation, but one can use, e.g., autoencoder, and any other types of mapping. This is how we enable support for testing various methods. classMyMapperKPCA: def__init__(self,snapshots,numModes): @@ -99,7 +98,7 @@ - + 3. Construct and run LSPG defrunLspg(fomObj,dt,nsteps,customMapper): #thisisanauxiliaryclassthatcanbepassedtosolve @@ -128,10 +127,9 @@ #createLSPGproblem scheme=ode.stepscheme.BDF1 problem=rom.lspg.unsteady.DefaultProblem(scheme,fomObj,customDecoder,romState,fomReferenceState) -stepper=problem.stepper() #createtheGauss-Newtonsolver -nonLinSolver=solvers.create_gauss_newton(stepper,romState,MyLinSolver()) +nonLinSolver=solvers.create_gauss_newton(problem,romState,MyLinSolver()) #settoleranceandconvergencecriteria nlsTol,nlsMaxIt=1e-7,10 nonLinSolver.setMaxIterations(nlsMaxIt) @@ -140,7 +138,7 @@ #createobjecttomonitortheromStateateveryiteration myObs=RomStateObserver() #solveproblem -ode.advance_n_steps_and_observe(stepper,romState,0.,dt,nsteps,myObs,nonLinSolver) +ode.advance_n_steps_and_observe(problem,romState,0.,dt,nsteps,myObs,nonLinSolver) #afterwearedone,usethereconstructorobjecttoreconstructthefomstate #getthereconstructorobject:thisallowstomapromStatetofomState @@ -149,7 +147,7 @@ - + Results If everything works fine, the following plot shows the result. diff --git a/docs/xml/md_pages_demos_demo4.xml b/docs/xml/md_pages_demos_demo4.xml index 936670a..3ed517a 100644 --- a/docs/xml/md_pages_demos_demo4.xml +++ b/docs/xml/md_pages_demos_demo4.xml @@ -13,7 +13,7 @@ We are currently working on this page, it will be updated with more explanations. - + Overview We cover these steps: generate of snapshots using the full-order model (FOM) @@ -25,70 +25,69 @@ The key item introduced here is the "masking" operator. In simple words, masking allows us to mimic the effect of the hyper-reduction without changing the application code. Hyper-reduction is a fundamental part of ROMs needed to approximate the FOM operators, thus contributing significantly to the computational cost savings. However, the main difficulty of hyper-reduction is that it generally is quite intrusive to be done properly. To briefly explain what hyper-reduction, let's look at the most basic form of hyper-reduction, namely "collocation". Consider the following system of N ODEs: \[ \frac{du}{dt} = f(u,x,t) \] A collocation-based hyper-reduction involves approximating the right-hand side by computing $f()$ only at a subset of grid points. Obviously, the way we compute the locations to select is critical and there are several techniques available to do so. Here, we show a simple example just for demonstration purposes of performing collocation with randomly selected points - + FOM Equations The governing equations for this problem are: \[ \frac{\partial u}{\partial t} = \frac{\partial}{\partial x} (k(u,x) \frac{\partial u}{\partial x} ) - a*\frac{\partial u}{\partial x} \] where $k(u,x)=x^4$, the field is $u(x;t)$, the advection velocity is fixed at $a=2$, the spatial coordinate is $x$ and the domain is $(0,1)$. We use homogeneous BC. Note that a class approximating the FOM operators via finite-differences is implemented here. - + Main function -The main function of the demo is the following: if__name__=="__main__": -logger.initialize(logger.logto.terminal) -logger.setVerbosity([logger.loglevel.info]) - -#totalnumberofgridpoints -meshSize=200 - -#createfomobject -fomObj=AdvDiff1d(nGrid=meshSize,adv_coef=1.0) - -#thefinaltimetointegrateto -finalTime=.05 - -#---1.FOM---# -fomTimeStepSize=1e-5 -fomNumberOfSteps=int(finalTime/fomTimeStepSize) -sampleEvery=100 -[fomFinalState,snapshots]=doFom(fomObj,fomTimeStepSize,fomNumberOfSteps,sampleEvery) - -#---2.POD---# -modes=computePodModes(snapshots) - -#---3.MASKEDGALERKINROM---# -romSize=10#numberofmodestouse -romTimeStepSize=1e-4 -romNumberOfSteps=int(finalTime/romTimeStepSize) - -#amaskedgalerkinissupposedtomakeiteasiertoemulatethe -#effectofhyper-reduction.TocreateamaskROMproblem, -#weneedtoselectandprovidetopressioasetofindices -#identifyingasubsetofthegridpointsinthefullmesh. -#Thisisasimplewaytomimichyper-reduction -#withoutchangingtheFOMproblem.Infact,thefomstill -#computesthefulloperatorsbutwehaveanadditionalstep -#to"mask"theoperatorstocomputethesamplemeshversion. -#Inthistest,themeshSize=200.Oursamplemeshincludes -#thetwoendpointssincethosecontaintheboundaryconditions, -#and150randomlyselectedgridpointsinsidethedomain. -#Soeffectivelyweuse25%lessofthefullmesh. -random.seed(312367) -sampleMeshSize=150 -sampleMeshIndices=random.sample(range(1,199),sampleMeshSize) -sampleMeshIndices=np.append(sampleMeshIndices,[0,199]) - -#runthemaskedgalerkinproblem -approximatedState=runMaskedGalerkin(fomObj,romTimeStepSize, -romNumberOfSteps,modes[:,:romSize], -sampleMeshIndices) - -#computel2-errorbetweenfomandapproximatestate -fomNorm=linalg.norm(fomFinalState) -err=linalg.norm(fomFinalState-approximatedState) -print("Finalstaterelativel2error:{}".format(err/fomNorm)) - -logger.finalize() +The main function of the demo is the following: logger.initialize(logger.logto.terminal) +logger.setVerbosity([logger.loglevel.info]) + +#totalnumberofgridpoints +meshSize=200 + +#createfomobject +fomObj=AdvDiff1d(nGrid=meshSize,adv_coef=1.0) + +#thefinaltimetointegrateto +finalTime=.05 + +#---1.FOM---# +fomTimeStepSize=1e-5 +fomNumberOfSteps=int(finalTime/fomTimeStepSize) +sampleEvery=100 +[fomFinalState,snapshots]=doFom(fomObj,fomTimeStepSize,fomNumberOfSteps,sampleEvery) + +#---2.POD---# +modes=computePodModes(snapshots) + +#---3.MASKEDGALERKINROM---# +romSize=10#numberofmodestouse +romTimeStepSize=1e-4 +romNumberOfSteps=int(finalTime/romTimeStepSize) + +#amaskedgalerkinissupposedtomakeiteasiertoemulatethe +#effectofhyper-reduction.TocreateamaskROMproblem, +#weneedtoselectandprovidetopressioasetofindices +#identifyingasubsetofthegridpointsinthefullmesh. +#Thisisasimplewaytomimichyper-reduction +#withoutchangingtheFOMproblem.Infact,thefomstill +#computesthefulloperatorsbutwehaveanadditionalstep +#to"mask"theoperatorstocomputethesamplemeshversion. +#Inthistest,themeshSize=200.Oursamplemeshincludes +#thetwoendpointssincethosecontaintheboundaryconditions, +#and150randomlyselectedgridpointsinsidethedomain. +#Soeffectivelyweuse25%lessofthefullmesh. +random.seed(312367) +sampleMeshSize=150 +sampleMeshIndices=random.sample(range(1,199),sampleMeshSize) +sampleMeshIndices=np.append(sampleMeshIndices,[0,199]) + +#runthemaskedgalerkinproblem +approximatedState=runMaskedGalerkin(fomObj,romTimeStepSize, +romNumberOfSteps,modes[:,:romSize], +sampleMeshIndices) + +#computel2-errorbetweenfomandapproximatestate +fomNorm=linalg.norm(fomFinalState) +err=linalg.norm(fomFinalState-approximatedState) +print("Finalstaterelativel2error:{}".format(err/fomNorm)) + +logger.finalize() - + 1. Run FOM and collect snapshots defdoFom(fom,dt,nsteps,saveFreq): u=fom.u0.copy() @@ -105,7 +104,7 @@ return[u,Usolns.T] - + 2. Compute POD modes defcomputePodModes(snapshots): print("SVDonmatrix:",snapshots.shape) @@ -113,10 +112,9 @@ returnU - + 3. Create the sampling indices -#amaskedgalerkinissupposedtomakeiteasiertoemulatethe -#effectofhyper-reduction.TocreateamaskROMproblem, +#effectofhyper-reduction.TocreateamaskROMproblem, #weneedtoselectandprovidetopressioasetofindices #identifyingasubsetofthegridpointsinthefullmesh. #Thisisasimplewaytomimichyper-reduction @@ -133,7 +131,7 @@ sampleMeshIndices=np.append(sampleMeshIndices,[0,199]) - + 4. The masker class classMyMasker: def__init__(self,indices): @@ -147,7 +145,7 @@ result[:]=np.take(operand,self.rows_) - + 5. Construct and run the masked ROM defrunMaskedGalerkin(fomObj,dt,nsteps,modes,sampleMeshIndices): #findoutnumberofmodeswanted @@ -188,10 +186,9 @@ problem=rom.galerkin.MaskedExplicitProblem(scheme,fomObj,linearDecoder,\ romState,fomReferenceState,\ projector,masker) -stepper=problem.stepper() #solveproblem -ode.advance_n_steps(stepper,romState,0.,dt,nsteps) +ode.advance_n_steps(problem,romState,0.,dt,nsteps) #afterwearedone,usethereconstructorobjecttoreconstructthefomstate #NOTE:eventhoughtheGalerkinproblemwasrunonthe"maskedmeshpoints", @@ -202,7 +199,7 @@ - + Results If everything works fine, the following plot shows the result. We see that for this toy example, the full solution is recovered very well with Galerkin with just a few POD modes. diff --git a/docs/xml/md_pages_demos_demo5.xml b/docs/xml/md_pages_demos_demo5.xml index 58518e3..e2d8bb5 100644 --- a/docs/xml/md_pages_demos_demo5.xml +++ b/docs/xml/md_pages_demos_demo5.xml @@ -13,79 +13,79 @@ We are currently working on this page, it will be updated with more explanations. - + Overview This is a follow up to the previous demo here We compare here maskdd Galerkin and masked LSPG. - + Main function -The main function of the demo is the following: if__name__=="__main__": -logger.initialize(logger.logto.terminal) -logger.setVerbosity([logger.loglevel.info]) - -#totalnumberofgridpoints -meshSize=200 - -#createfomobject -fomObj=AdvDiff1d(nGrid=meshSize,adv_coef=1.0) - -#thefinaltimetointegrateto -finalTime=.05 - -#---1.FOM---# -fomTimeStepSize=1e-5 -fomNumberOfSteps=int(finalTime/fomTimeStepSize) -sampleEvery=100 -[fomFinalState,snapshots]=doFom(fomObj,fomTimeStepSize,fomNumberOfSteps,sampleEvery) - -#---2.POD---# -modes=computePodModes(snapshots) - -#---3.MASKEDGALERKINandLSPGROM---# -#amaskedproblemissupposedtomakeiteasiertoemulatethe -#effectofhyper-reduction.TocreateamaskROMproblem, -#weneedtoselectandprovidetopressioasetofindices -#identifyingasubsetofthegridpointsinthefullmesh. -#Thisisasimplewaytomimichyper-reduction -#withoutchangingtheFOMproblem.Infact,thefomstill -#computesthefulloperatorsbutwehaveanadditionalstep -#to"mask"theoperatorstocomputethesamplemeshversion. -#Inthistest,themeshSize=200.Oursamplemeshincludes -#thetwoendpointssincethosecontaintheboundaryconditions, -#and20randomlyselectedgridpointsinsidethedomain. -#Soeffectivelyweuse1/10ofthefullmesh. -random.seed(22123) -sampleMeshSize=20 -sampleMeshIndices=random.sample(range(1,199),sampleMeshSize) -sampleMeshIndices=np.append(sampleMeshIndices,[0,199]) -#sortforconvenience,notnecessarilyneeded -sampleMeshIndices=np.sort(sampleMeshIndices) - -romSize=5#numberofmodestouse -romTimeStepSize=1e-4 -romNumberOfSteps=int(finalTime/romTimeStepSize) - -#runthemaskedgalerkinproblem -[approximatedStateGal,romGal]=runMaskedGalerkin(fomObj,romTimeStepSize, -romNumberOfSteps, -modes[:,:romSize], -sampleMeshIndices) -#runthemaskedgalerkinproblem -[approximatedStateLspg,romLspg]=runMaskedLspg(fomObj,romTimeStepSize, +The main function of the demo is the following: logger.setVerbosity([logger.loglevel.info]) + +#totalnumberofgridpoints +meshSize=200 + +#createfomobject +fomObj=AdvDiff1d(nGrid=meshSize,adv_coef=1.0) + +#thefinaltimetointegrateto +finalTime=.05 + +#---1.FOM---# +fomTimeStepSize=1e-5 +fomNumberOfSteps=int(finalTime/fomTimeStepSize) +sampleEvery=100 +[fomFinalState,snapshots]=doFom(fomObj,fomTimeStepSize,fomNumberOfSteps,sampleEvery) + +#---2.POD---# +modes=computePodModes(snapshots) + +#---3.MASKEDGALERKINandLSPGROM---# +#amaskedproblemissupposedtomakeiteasiertoemulatethe +#effectofhyper-reduction.TocreateamaskROMproblem, +#weneedtoselectandprovidetopressioasetofindices +#identifyingasubsetofthegridpointsinthefullmesh. +#Thisisasimplewaytomimichyper-reduction +#withoutchangingtheFOMproblem.Infact,thefomstill +#computesthefulloperatorsbutwehaveanadditionalstep +#to"mask"theoperatorstocomputethesamplemeshversion. +#Inthistest,themeshSize=200.Oursamplemeshincludes +#thetwoendpointssincethosecontaintheboundaryconditions, +#and20randomlyselectedgridpointsinsidethedomain. +#Soeffectivelyweuse1/10ofthefullmesh. +random.seed(22123) +sampleMeshSize=20 +sampleMeshIndices=random.sample(range(1,199),sampleMeshSize) +sampleMeshIndices=np.append(sampleMeshIndices,[0,199]) +#sortforconvenience,notnecessarilyneeded +sampleMeshIndices=np.sort(sampleMeshIndices) + +romSize=5#numberofmodestouse +romTimeStepSize=1e-4 +romNumberOfSteps=int(finalTime/romTimeStepSize) + +#runthemaskedgalerkinproblem +[approximatedStateGal,romGal]=runMaskedGalerkin(fomObj,romTimeStepSize, romNumberOfSteps, modes[:,:romSize], sampleMeshIndices) +#runthemaskedgalerkinproblem +[approximatedStateLspg,romLspg]=runMaskedLspg(fomObj,romTimeStepSize, +romNumberOfSteps, +modes[:,:romSize], +sampleMeshIndices) -#computel2-errorbetweenfomandapproximatestate -fomNorm=linalg.norm(fomFinalState) -err1=linalg.norm(fomFinalState-approximatedStateGal) -print("Galerkin:finalstaterelativel2error:{}".format(err1/fomNorm)) -err2=linalg.norm(fomFinalState-approximatedStateLspg) -print("LSPG:finalstaterelativel2error:{}".format(err2/fomNorm)) +#computel2-errorbetweenfomandapproximatestate +fomNorm=linalg.norm(fomFinalState) +err1=linalg.norm(fomFinalState-approximatedStateGal) +print("Galerkin:finalstaterelativel2error:{}".format(err1/fomNorm)) +err2=linalg.norm(fomFinalState-approximatedStateLspg) +print("LSPG:finalstaterelativel2error:{}".format(err2/fomNorm)) -logger.finalize() +logger.finalize() + +#----------------------------------------------# - + 1. Run FOM and collect snapshots defdoFom(fom,dt,nsteps,saveFreq): u=fom.u0.copy() @@ -102,7 +102,7 @@ return[u,Usolns.T] - + 2. Compute POD modes defcomputePodModes(snapshots): print("SVDonmatrix:",snapshots.shape) @@ -110,11 +110,9 @@ returnU - + 3. Create the sampling indices -#amaskedproblemissupposedtomakeiteasiertoemulatethe -#effectofhyper-reduction.TocreateamaskROMproblem, -#weneedtoselectandprovidetopressioasetofindices +#weneedtoselectandprovidetopressioasetofindices #identifyingasubsetofthegridpointsinthefullmesh. #Thisisasimplewaytomimichyper-reduction #withoutchangingtheFOMproblem.Infact,thefomstill @@ -130,9 +128,11 @@ sampleMeshIndices=np.append(sampleMeshIndices,[0,199]) #sortforconvenience,notnecessarilyneeded sampleMeshIndices=np.sort(sampleMeshIndices) + +romSize=5#numberofmodestouse - + 4. The masker class classMyMasker: def__init__(self,indices): @@ -152,7 +152,7 @@ result[:]=np.take(operand,self.rows_,axis=0) - + 5. Masked Galerkin ROM defrunMaskedGalerkin(fomObj,dt,nsteps,modes,sampleMeshIndices): #findoutnumberofmodeswanted @@ -193,15 +193,14 @@ problem=rom.galerkin.MaskedImplicitProblem(scheme,fomObj,linearDecoder,\ romState,fomReferenceState,\ projector,masker) -stepper=problem.stepper() #linearandnonlinearsolver lsO=MyLinSolver() -nlsO=solvers.create_newton_raphson(stepper,romState,lsO) +nlsO=solvers.create_newton_raphson(problem,romState,lsO) nlsO.setMaxIterations(15) #solvetheproblem -ode.advance_n_steps(stepper,romState,0.,dt,nsteps,nlsO) +ode.advance_n_steps(problem,romState,0.,dt,nsteps,nlsO) #afterwearedone,usethereconstructorobjecttoreconstructthefomstate #NOTE:eventhoughtheGalerkinproblemwasrunonthe"maskedmeshpoints", @@ -211,7 +210,7 @@ return[fomRecon(romState),romState] - + 6. Masked LSPG ROM defrunMaskedLspg(fomObj,dt,nsteps,modes,sampleMeshIndices): #findoutnumberofmodeswanted @@ -242,15 +241,14 @@ problem=rom.lspg.unsteady.MaskedProblem(scheme,fomObj,linearDecoder,\ romState,fomReferenceState,\ masker) -stepper=problem.stepper() #linearandnonlinearsolver lsO=MyLinSolver() -nlsO=solvers.create_gauss_newton(stepper,romState,lsO) +nlsO=solvers.create_gauss_newton(problem,romState,lsO) nlsO.setMaxIterations(10) #solvetheproblem -ode.advance_n_steps(stepper,romState,0.,dt,nsteps,nlsO) +ode.advance_n_steps(problem,romState,0.,dt,nsteps,nlsO) #afterwearedone,usethereconstructorobjecttoreconstructthefomstate #NOTE:eventhoughtheGalerkinproblemwasrunonthe"maskedmeshpoints", @@ -258,10 +256,12 @@ #sowecaneffectivelyobtainanapproximationofthefullsolution fomRecon=problem.fomStateReconstructor() return[fomRecon(romState),romState] + + - + Results If everything works fine, the following plots shows the result. We first plot the result reconstructed only on the sample mesh. This can easily be done using the bases collocated on the sample mesh indices. diff --git a/docs/xml/md_pages_demos_demo6.xml b/docs/xml/md_pages_demos_demo6.xml index f85c55d..c7f508c 100644 --- a/docs/xml/md_pages_demos_demo6.xml +++ b/docs/xml/md_pages_demos_demo6.xml @@ -10,7 +10,7 @@ This page describes a demo for a reproductive LSPG ROM applied to a 1D advection-diffusion problem using a nonlinear manifold via a multilayer perceptron (MLP). This demo purposefully focuses on a simple test since the main goal is to demonstrate the steps and the code. The full demo script is here. - + Overview This demo solves the same problem as the one here, but instead of using POD modes, we show here how to use a nonlinear manifold computed approximated by a neural network. Specifically, we use a MLP with 2 hidden layers of sizes 64 and 200. @@ -18,45 +18,44 @@ - + Main function -The main function of the demo is the following: if__name__=="__main__": -logger.initialize(logger.logto.terminal) -logger.setVerbosity([logger.loglevel.info]) +The main function of the demo is the following: logger.initialize(logger.logto.terminal) +logger.setVerbosity([logger.loglevel.info]) -#createfomobject -fomObj=AdvDiff1d(nGrid=120,adv_coef=2.0) +#createfomobject +fomObj=AdvDiff1d(nGrid=120,adv_coef=2.0) -#thefinaltimetointegrateto -finalTime=.05 +#thefinaltimetointegrateto +finalTime=.05 -#---1.FOM---# -fomTimeStepSize=1e-5 -fomNumberOfSteps=int(finalTime/fomTimeStepSize) -sampleEvery=200 -[fomFinalState,snapshots]=doFom(fomObj,fomTimeStepSize,fomNumberOfSteps,sampleEvery) +#---1.FOM---# +fomTimeStepSize=1e-5 +fomNumberOfSteps=int(finalTime/fomTimeStepSize) +sampleEvery=200 +[fomFinalState,snapshots]=doFom(fomObj,fomTimeStepSize,fomNumberOfSteps,sampleEvery) -#---2.trainanonlinearmappingusingPyTorch---# -#hereweuse3modes,changethistotrydifferentmodes -myNonLinearMapper=trainMapping(snapshots,romSize=3,epochs=500) +#---2.trainanonlinearmappingusingPyTorch---# +#hereweuse3modes,changethistotrydifferentmodes +myNonLinearMapper=trainMapping(snapshots,romSize=3,epochs=500) -#---3.LSPGROM---# -romTimeStepSize=3e-4 -romNumberOfSteps=int(finalTime/romTimeStepSize) -approximatedState=runLspg(fomObj,romTimeStepSize,romNumberOfSteps,myNonLinearMapper) +#---3.LSPGROM---# +romTimeStepSize=3e-4 +romNumberOfSteps=int(finalTime/romTimeStepSize) +approximatedState=runLspg(fomObj,romTimeStepSize,romNumberOfSteps,myNonLinearMapper) -#computel2-errorbetweenfomandapproximatestate -fomNorm=linalg.norm(fomFinalState) -err=linalg.norm(fomFinalState-approximatedState) -print("Finalstaterelativel2error:{}".format(err/fomNorm)) +#computel2-errorbetweenfomandapproximatestate +fomNorm=linalg.norm(fomFinalState) +err=linalg.norm(fomFinalState-approximatedState) +print("Finalstaterelativel2error:{}".format(err/fomNorm)) -logger.finalize() +logger.finalize() - + 1. Run FOM and collect snapshots This step is the same as described here, - + 2. Setup and train the nonlinear mapper It is important to note that while the mapper class below has the API required by pressio4py, it can encapsulate any arbitrary mapping function. In this case we show how to create a MLP-based representation in PyTorch, but one can use any other types of mapping and any other library (e.g., Tensorflow, keras). All of the PyTorch-specific code is encapsulated here. If you prefer Tensorflow/keras, an equivalent implementation is here. The autoencoder is defined by classmyAutoencoder(torch.nn.Module): @@ -191,7 +190,7 @@ - + 3. Construct and run LSPG defrunLspg(fomObj,dt,nsteps,customMapper): #thisisanauxiliaryclassthatcanbepassedtosolve @@ -219,10 +218,9 @@ #createLSPGproblem scheme=ode.stepscheme.BDF1 problem=rom.lspg.unsteady.DefaultProblem(scheme,fomObj,customDecoder,romState,fomReferenceState) -stepper=problem.stepper() #createtheGauss-Newtonsolver -nonLinSolver=solvers.create_gauss_newton(stepper,romState,MyLinSolver()) +nonLinSolver=solvers.create_gauss_newton(problem,romState,MyLinSolver()) #settoleranceandconvergencecriteria nlsTol,nlsMaxIt=1e-7,10 nonLinSolver.setMaxIterations(nlsMaxIt) @@ -231,7 +229,7 @@ #createobjecttomonitortheromStateateveryiteration myObs=RomStateObserver() #solveproblem -ode.advance_n_steps_and_observe(stepper,romState,0.,dt,nsteps,myObs,nonLinSolver) +ode.advance_n_steps_and_observe(problem,romState,0.,dt,nsteps,myObs,nonLinSolver) #afterwearedone,usethereconstructorobjecttoreconstructthefomstate #getthereconstructorobject:thisallowstomapromStatetofomState @@ -240,7 +238,7 @@ - + Results If everything works fine, the following plot shows the result. diff --git a/docs/xml/md_pages_introduction.xml b/docs/xml/md_pages_introduction.xml index 22ecd48..980f686 100644 --- a/docs/xml/md_pages_introduction.xml +++ b/docs/xml/md_pages_introduction.xml @@ -7,7 +7,7 @@ todo Finish - + In a nutshell Pressio can be applied to any dynamical system expressible in a continuous-time form as \[ \frac{d \boldsymbol{y}}{dt} = \boldsymbol{f}(\boldsymbol{y},t; ...) \] and/or in a discrete-time form \[ \boldsymbol{R}(\boldsymbol{y}, \boldsymbol{y_{n-1}}, ..., t_n, dt_n; ...) = \boldsymbol{0} \] Here, $y$ is the full-order model (FOM) state, $f$ the FOM velocity, $t$ is time, and $R$ is the residual. diff --git a/pressio b/pressio index 049b7be..5903636 160000 --- a/pressio +++ b/pressio @@ -1 +1 @@ -Subproject commit 049b7bec173d635f8d35ad40ae56e1d7559263e0 +Subproject commit 5903636992346ceab852332f7050ed7f7e79ba43 diff --git a/setup.py b/setup.py index 494de99..b51a79d 100644 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ def myname(): return "pressio4py" def myversion(): - return "0.11.0rc1" + return "0.12.0rc1" def description(): with open(os.path.join(topdir, 'DESCRIPTION.rst')) as f: diff --git a/src/galerkin.hpp b/src/galerkin.hpp index 67e1253..de630d3 100644 --- a/src/galerkin.hpp +++ b/src/galerkin.hpp @@ -158,11 +158,11 @@ struct GalerkinBinder using implicit_problem_types = std::tuple< implicit_default_problem_t, implicit_masked_problem_t, implicit_hypred_problem_t>; - // collect all stepper types in tuples - using explicit_stepper_types = std::tuple< - explicit_default_stepper_t, explicit_masked_stepper_t, explicit_hypred_stepper_t>; - using implicit_stepper_types = std::tuple< - implicit_default_stepper_t, implicit_masked_stepper_t, implicit_hypred_stepper_t>; + // // collect all stepper types in tuples + // using explicit_stepper_types = std::tuple< + // explicit_default_stepper_t, explicit_masked_stepper_t, explicit_hypred_stepper_t>; + // using implicit_stepper_types = std::tuple< + // implicit_default_stepper_t, implicit_masked_stepper_t, implicit_hypred_stepper_t>; template static void bindConstructorDefault(pybind11::class_ & problem) @@ -204,55 +204,28 @@ struct GalerkinBinder } template - static void bindMethods(pybind11::class_ & problem) + static void bindCommonMethods(pybind11::class_ & object) { - problem.def("stepper", - &T::stepper, - pybind11::return_value_policy::reference); + // object.def("stepper", + // &T::stepper, + // pybind11::return_value_policy::reference); - problem.def("fomStateReconstructor", + object.def("fomStateReconstructor", &T::fomStateReconstructor, pybind11::return_value_policy::reference); } - static void bindProblems(pybind11::module & m) - { - pybind11::class_ DefProbClass(m, "DefaultExplicitProblem"); - bindConstructorDefault(DefProbClass); - bindMethods(DefProbClass); - - pybind11::class_ MaskedProbClass(m, "MaskedExplicitProblem"); - bindConstructorMasked(MaskedProbClass); - bindMethods(MaskedProbClass); - - pybind11::class_ HypredProbClass(m, "HyperreducedExplicitProblem"); - bindConstructorHypRed(HypredProbClass); - bindMethods(HypredProbClass); - - pybind11::class_ ImpDefProbClass(m, "DefaultImplicitProblem"); - bindConstructorDefault(ImpDefProbClass); - bindMethods(ImpDefProbClass); - - pybind11::class_ ImpMaskedProbClass(m, "MaskedImplicitProblem"); - bindConstructorMasked(ImpMaskedProbClass); - bindMethods(ImpMaskedProbClass); - - pybind11::class_ ImpHypredProbClass(m, "HyperreducedImplicitProblem"); - bindConstructorHypRed(ImpHypredProbClass); - bindMethods(ImpHypredProbClass); - } - template - static void bindExplicitStepperCallOperator(pybind11::class_ & stepper) + static void bindExplicitStepperCallOperator(pybind11::class_ & object) { - stepper.def("__call__", - [](T & stepper, + object.def("__call__", + [](T & object, ::pressio4py::py_f_arr & state, ::pressio4py::scalar_t time, ::pressio4py::scalar_t dt, int32_t step) { - stepper(state, time, dt, step); + object(state, time, dt, step); }, pybind11::is_operator()); } @@ -260,10 +233,10 @@ struct GalerkinBinder class SolverType, class T, pressio::mpl::enable_if_t::value, int> = 0 > - static void bindImplicitStepperCallOperator(pybind11::class_ & stepper) + static void bindImplicitStepperCallOperator(pybind11::class_ & object) { - stepper.def("__call__", - [](T & stepper, + object.def("__call__", + [](T & object, ::pressio4py::py_f_arr & state, ::pressio4py::scalar_t time, ::pressio4py::scalar_t dt, @@ -271,7 +244,7 @@ struct GalerkinBinder SolverType & solver ) { - stepper(state, time, dt, step, solver); + object(state, time, dt, step, solver); }, pybind11::is_operator()); } @@ -279,10 +252,10 @@ struct GalerkinBinder class SolverType, class T, pressio::mpl::enable_if_t<::pressio4py::is_solver_wrapper::value, int> = 0 > - static void bindImplicitStepperCallOperator(pybind11::class_ & stepper) + static void bindImplicitStepperCallOperator(pybind11::class_ & object) { - stepper.def("__call__", - [](T & stepper, + object.def("__call__", + [](T & object, ::pressio4py::py_f_arr & state, ::pressio4py::scalar_t time, ::pressio4py::scalar_t dt, @@ -291,56 +264,87 @@ struct GalerkinBinder ) { UserDefinedNonLinSolverWrapper nlsw(pysolver); - stepper(state, time, dt, step, nlsw); + object(state, time, dt, step, nlsw); }, pybind11::is_operator()); } - template - static void bindImplicitStepperCallOperatorVar(pybind11::class_ & stepper) - { - bindImplicitStepperCallOperator(stepper); - bindImplicitStepperCallOperator(stepper); + template + static void bindImplicitStepperCallOperatorVar(pybind11::class_ & object){ + bindImplicitStepperCallOperator(object); + bindImplicitStepperCallOperator(object); } template - static void bindImplicitStepperOperatorMethods(pybind11::class_ & stepper) + static void bindImplicitStepperOperatorMethods(pybind11::class_ & object) { - stepper.def("createResidual", + object.def("createResidual", &T::createResidual, pybind11::return_value_policy::take_ownership); - stepper.def("createJacobian", + object.def("createJacobian", &T::createJacobian, pybind11::return_value_policy::take_ownership); - stepper.def("residual", &T::residual); - stepper.def("jacobian", &T::jacobian); + object.def("residual", &T::residual); + object.def("jacobian", &T::jacobian); } - static void bindExplicitSteppers(pybind11::module & m) + static void bindExplicitProblems(pybind11::module & m) { - pybind11::class_ ExpDefStepperClass(m, "DefaultExplicitStepper"); - bindExplicitStepperCallOperator(ExpDefStepperClass); + pybind11::class_ DefProbClass(m, "DefaultExplicitProblem"); + bindConstructorDefault(DefProbClass); + bindCommonMethods(DefProbClass); + bindExplicitStepperCallOperator(DefProbClass); - pybind11::class_ ExpMaskedStepperClass(m, "MaskedExplicitStepper"); - bindExplicitStepperCallOperator(ExpMaskedStepperClass); + pybind11::class_ MaskedProbClass(m, "MaskedExplicitProblem"); + bindConstructorMasked(MaskedProbClass); + bindCommonMethods(MaskedProbClass); + bindExplicitStepperCallOperator(MaskedProbClass); - pybind11::class_ ExpHypredStepperClass(m, "HyperreducedExplicitStepper"); - bindExplicitStepperCallOperator(ExpHypredStepperClass); + pybind11::class_ HypredProbClass(m, "HyperreducedExplicitProblem"); + bindConstructorHypRed(HypredProbClass); + bindCommonMethods(HypredProbClass); + bindExplicitStepperCallOperator(HypredProbClass); } template - static void bindImplicitSteppers(pybind11::module & m) + static void bindImplicitProblems(pybind11::module & m) { + // note that below we need to bind both problem and underlying steppers + // becauase of how the operator() is implemented: remember that it calls *this + // otherwise we get a python error that a stepper cannnot be converted to python object + + pybind11::class_ DefProbClass(m, "DefaultImplicitProblem"); + bindConstructorDefault(DefProbClass); + bindCommonMethods(DefProbClass); + bindImplicitStepperOperatorMethods(DefProbClass); + bindImplicitStepperCallOperatorVar(DefProbClass); pybind11::class_ ImpDefStepperClass(m, "DefaultImplicitStepper"); - bindImplicitStepperCallOperatorVar(ImpDefStepperClass); bindImplicitStepperOperatorMethods(ImpDefStepperClass); + bindImplicitStepperCallOperatorVar(ImpDefStepperClass); + pybind11::class_ MaskedProbClass(m, "MaskedImplicitProblem"); + bindConstructorMasked(MaskedProbClass); + bindCommonMethods(MaskedProbClass); + bindImplicitStepperOperatorMethods(MaskedProbClass); + bindImplicitStepperCallOperatorVar(MaskedProbClass); pybind11::class_ ImpMaskedStepperClass(m, "MaskedImplicitStepper"); - bindImplicitStepperCallOperatorVar(ImpMaskedStepperClass); bindImplicitStepperOperatorMethods(ImpMaskedStepperClass); + bindImplicitStepperCallOperatorVar(ImpMaskedStepperClass); + pybind11::class_ HypredProbClass(m, "HyperreducedImplicitProblem"); + bindConstructorHypRed(HypredProbClass); + bindCommonMethods(HypredProbClass); + bindImplicitStepperOperatorMethods(HypredProbClass); + bindImplicitStepperCallOperatorVar(HypredProbClass); pybind11::class_ ImpHypredStepperClass(m, "HyperreducedImplicitStepper"); - bindImplicitStepperCallOperatorVar(ImpHypredStepperClass); bindImplicitStepperOperatorMethods(ImpHypredStepperClass); + bindImplicitStepperCallOperatorVar(ImpHypredStepperClass); + } + + static void bindSteppers(pybind11::module & m) + { + pybind11::class_ ExpDefStepperClass(m, "DefaultExplicitStepper"); + pybind11::class_ ExpMaskedStepperClass(m, "MaskedExplicitStepper"); + pybind11::class_ ExpHypredStepperClass(m, "HyperreducedExplicitStepper"); } }; diff --git a/src/lspg_unsteady.hpp b/src/lspg_unsteady.hpp index ff2b623..9bc27fa 100644 --- a/src/lspg_unsteady.hpp +++ b/src/lspg_unsteady.hpp @@ -233,13 +233,13 @@ struct UnsteadyLSPGBinder default_dt_n2_problem_t, masked_dt_n2_problem_t, default_dt_n3_problem_t, masked_dt_n3_problem_t>; - // collect all stepper types in tuples - using stepper_types = std::tuple< - default_stepper_t, prec_default_stepper_t, - masked_stepper_t, prec_masked_stepper_t, - hypred_stepper_t, prec_hypred_stepper_t, - default_dt_n2_stepper_t, masked_dt_n2_stepper_t, - default_dt_n3_stepper_t, masked_dt_n3_stepper_t>; + // // collect all stepper types in tuples + // using stepper_types = std::tuple< + // default_stepper_t, prec_default_stepper_t, + // masked_stepper_t, prec_masked_stepper_t, + // hypred_stepper_t, prec_hypred_stepper_t, + // default_dt_n2_stepper_t, masked_dt_n2_stepper_t, + // default_dt_n3_stepper_t, masked_dt_n3_stepper_t>; // ====================================================== // functions @@ -350,74 +350,25 @@ struct UnsteadyLSPGBinder } template - static void bindMethods(pybind11::class_ & problem) + static void bindMethods(pybind11::class_ & object) { - problem.def("stepper", - &T::stepper, - pybind11::return_value_policy::reference); + // object.def("stepper", + // &T::stepper, + // pybind11::return_value_policy::reference); - problem.def("fomStateReconstructor", + object.def("fomStateReconstructor", &T::fomStateReconstructor, pybind11::return_value_policy::reference); } - static void bindProblems(pybind11::module & m) - { - pybind11::class_ HypredUpdaterClass(m, "StencilToSampleIndexing"); - HypredUpdaterClass.def(pybind11::init &>()); - - // ---- discrete-time 2 states ---- - pybind11::class_ DefProbClassDTN2(m, "DiscreteTimeProblemTwoStates"); - bindConstructorDefaultDT(DefProbClassDTN2); - bindMethods(DefProbClassDTN2); - - pybind11::class_ MaskedProbClassDTN2(m, "DiscreteTimeMaskedProblemTwoStates"); - bindConstructorMaskedDT(MaskedProbClassDTN2); - bindMethods(MaskedProbClassDTN2); - - // ---- discrete-time 3 states ---- - pybind11::class_ DefProbClassDTN3(m, "DiscreteTimeProblemThreeStates"); - bindConstructorDefaultDT(DefProbClassDTN3); - bindMethods(DefProbClassDTN3); - - pybind11::class_ MaskedProbClassDTN3(m, "DiscreteTimeMaskedProblemThreeStates"); - bindConstructorMaskedDT(MaskedProbClassDTN3); - bindMethods(MaskedProbClassDTN3); - - // ----- cont-time ---- - pybind11::class_ DefProbClass(m, "DefaultProblem"); - bindConstructorDefault(DefProbClass); - bindMethods(DefProbClass); - - pybind11::class_ PrecDefProbClass(m, "PrecDefaultProblem"); - bindConstructorDefaultPrec(PrecDefProbClass); - bindMethods(PrecDefProbClass); - - pybind11::class_ MaskedProbClass(m, "MaskedProblem"); - bindConstructorMasked(MaskedProbClass); - bindMethods(MaskedProbClass); - - pybind11::class_ PrecMaskedProbClass(m, "PrecMaskedProblem"); - bindConstructorMaskedPrec(PrecMaskedProbClass); - bindMethods(PrecMaskedProbClass); - - pybind11::class_ HypredProbClass(m, "HypredProblem"); - bindConstructorHypred(HypredProbClass); - bindMethods(HypredProbClass); - - pybind11::class_ PrecHypredProbClass(m, "PrecHypredProblem"); - bindConstructorHypredPrec(PrecHypredProbClass); - bindMethods(PrecHypredProbClass); - } - template< class SolverType, class T, pressio::mpl::enable_if_t::value, int> = 0 > - static void bindStepperCallOperator(pybind11::class_ & stepper) + static void bindStepperCallOperator(pybind11::class_ & object) { - stepper.def("__call__", - [](T & stepper, + object.def("__call__", + [](T & object, ::pressio4py::py_f_arr & state, ::pressio4py::scalar_t time, ::pressio4py::scalar_t dt, @@ -425,7 +376,7 @@ struct UnsteadyLSPGBinder SolverType & solver ) { - stepper(state, time, dt, step, solver); + object(state, time, dt, step, solver); }, pybind11::is_operator()); } @@ -433,10 +384,10 @@ struct UnsteadyLSPGBinder class SolverType, class T, pressio::mpl::enable_if_t<::pressio4py::is_solver_wrapper::value, int> = 0 > - static void bindStepperCallOperator(pybind11::class_ & stepper) + static void bindStepperCallOperator(pybind11::class_ & object) { - stepper.def("__call__", - [](T & stepper, + object.def("__call__", + [](T & object, ::pressio4py::py_f_arr & state, ::pressio4py::scalar_t time, ::pressio4py::scalar_t dt, @@ -445,91 +396,192 @@ struct UnsteadyLSPGBinder ) { UserDefinedNonLinSolverWrapper nlsw(pysolver); - stepper(state, time, dt, step, nlsw); + object(state, time, dt, step, nlsw); }, pybind11::is_operator()); } - template - static void bindStepperCallOperatorVar(pybind11::class_ & stepper) + template + static void bindStepperCallOperatorVar(pybind11::class_ & object) { - bindStepperCallOperator(stepper); - bindStepperCallOperator(stepper); + bindStepperCallOperator(object); + bindStepperCallOperator(object); } template - static void bindStepperOperatorMethods(pybind11::class_ & stepper) + static void bindStepperOperatorMethods(pybind11::class_ & object) { - stepper.def("createResidual", + object.def("createResidual", &T::createResidual, pybind11::return_value_policy::take_ownership); - stepper.def("createJacobian", + object.def("createJacobian", &T::createJacobian, pybind11::return_value_policy::take_ownership); - stepper.def("residual", &T::residual); - stepper.def("jacobian", &T::jacobian); + object.def("residual", &T::residual); + object.def("jacobian", &T::jacobian); } - template - static void bindStepperOperatorMethods2(pybind11::class_ & stepper) + template + static void bindStepperOperatorMethods2(pybind11::class_ & object) { - stepper.def("createResidual", + object.def("createResidual", &T::createResidual, pybind11::return_value_policy::take_ownership); - stepper.def("createJacobian", + object.def("createJacobian", &T::createJacobian, pybind11::return_value_policy::take_ownership); - constexpr auto n = T::numAuxStates; - stepper.def("residual", &T::template residual); - stepper.def("jacobian", &T::template jacobian); + object.def("residual", &T::template residual); + object.def("jacobian", &T::template jacobian); } template - static void bindSteppers(pybind11::module & m) + static void bindProblems(pybind11::module & m) { + pybind11::class_ HypredUpdaterClass(m, "StencilToSampleIndexing"); + HypredUpdaterClass.def(pybind11::init &>()); - // ---- disc-time 2 states ----- + // ---- discrete-time 2 states ---- + constexpr auto n = default_dt_n2_stepper_t::numAuxStates; + pybind11::class_ DefProbClassDTN2(m, "DiscreteTimeProblemTwoStates"); + bindConstructorDefaultDT (DefProbClassDTN2); + bindMethods (DefProbClassDTN2); + bindStepperCallOperatorVar(DefProbClassDTN2); + bindStepperOperatorMethods (DefProbClassDTN2); pybind11::class_ DefStepperClassDTN2(m, "DefaultStepperDTN2"); bindStepperCallOperatorVar(DefStepperClassDTN2); - bindStepperOperatorMethods2(DefStepperClassDTN2); + bindStepperOperatorMethods2 (DefStepperClassDTN2); + pybind11::class_ MaskedProbClassDTN2(m, "DiscreteTimeMaskedProblemTwoStates"); + bindConstructorMaskedDT (MaskedProbClassDTN2); + bindMethods (MaskedProbClassDTN2); + bindStepperCallOperatorVar(MaskedProbClassDTN2); + bindStepperOperatorMethods (MaskedProbClassDTN2); pybind11::class_ MaskedStepperClassDTN2(m, "MaskedStepperDTN2"); bindStepperCallOperatorVar(MaskedStepperClassDTN2); - bindStepperOperatorMethods2(MaskedStepperClassDTN2); + bindStepperOperatorMethods2 (MaskedStepperClassDTN2); - // ---- disc-time 3 states ----- + // ---- discrete-time 3 states ---- + constexpr auto k = default_dt_n3_stepper_t::numAuxStates; + pybind11::class_ DefProbClassDTN3(m, "DiscreteTimeProblemThreeStates"); + bindConstructorDefaultDT (DefProbClassDTN3); + bindMethods (DefProbClassDTN3); + bindStepperCallOperatorVar(DefProbClassDTN3); + bindStepperOperatorMethods (DefProbClassDTN3); pybind11::class_ DefStepperClassDTN3(m, "DefaultStepperDTN3"); bindStepperCallOperatorVar(DefStepperClassDTN3); - bindStepperOperatorMethods2(DefStepperClassDTN3); + bindStepperOperatorMethods2 (DefStepperClassDTN3); + pybind11::class_ MaskedProbClassDTN3(m, "DiscreteTimeMaskedProblemThreeStates"); + bindConstructorMaskedDT (MaskedProbClassDTN3); + bindMethods (MaskedProbClassDTN3); + bindStepperCallOperatorVar(MaskedProbClassDTN3); + bindStepperOperatorMethods (MaskedProbClassDTN3); pybind11::class_ MaskedStepperClassDTN3(m, "MaskedStepperDTN3"); bindStepperCallOperatorVar(MaskedStepperClassDTN3); - bindStepperOperatorMethods2(MaskedStepperClassDTN3); + bindStepperOperatorMethods2 (MaskedStepperClassDTN3); - // ---- cont-time ----- + // ----- cont-time ---- + pybind11::class_ DefProbClass(m, "DefaultProblem"); + bindConstructorDefault (DefProbClass); + bindMethods (DefProbClass); + bindStepperCallOperatorVar(DefProbClass); + bindStepperOperatorMethods (DefProbClass); pybind11::class_ DefStepperClass(m, "DefaultStepper"); bindStepperCallOperatorVar(DefStepperClass); - bindStepperOperatorMethods(DefStepperClass); + bindStepperOperatorMethods (DefStepperClass); + pybind11::class_ PrecDefProbClass(m, "PrecDefaultProblem"); + bindConstructorDefaultPrec (PrecDefProbClass); + bindMethods (PrecDefProbClass); + bindStepperCallOperatorVar(PrecDefProbClass); + bindStepperOperatorMethods (PrecDefProbClass); pybind11::class_ PrecDefStepperClass(m, "PrecDefaultStepper"); bindStepperCallOperatorVar(PrecDefStepperClass); - bindStepperOperatorMethods(PrecDefStepperClass); + bindStepperOperatorMethods (PrecDefStepperClass); + pybind11::class_ MaskedProbClass(m, "MaskedProblem"); + bindConstructorMasked (MaskedProbClass); + bindMethods (MaskedProbClass); + bindStepperCallOperatorVar(MaskedProbClass); + bindStepperOperatorMethods (MaskedProbClass); pybind11::class_ MaskedStepperClass(m, "MaskedStepper"); bindStepperCallOperatorVar(MaskedStepperClass); - bindStepperOperatorMethods(MaskedStepperClass); + bindStepperOperatorMethods (MaskedStepperClass); + pybind11::class_ PrecMaskedProbClass(m, "PrecMaskedProblem"); + bindConstructorMaskedPrec (PrecMaskedProbClass); + bindMethods (PrecMaskedProbClass); + bindStepperCallOperatorVar(PrecMaskedProbClass); + bindStepperOperatorMethods (PrecMaskedProbClass); pybind11::class_ PrecMaskedStepperClass(m, "PrecMaskedStepper"); bindStepperCallOperatorVar(PrecMaskedStepperClass); - bindStepperOperatorMethods(PrecMaskedStepperClass); + bindStepperOperatorMethods (PrecMaskedStepperClass); + pybind11::class_ HypredProbClass(m, "HypredProblem"); + bindConstructorHypred (HypredProbClass); + bindMethods (HypredProbClass); + bindStepperCallOperatorVar(HypredProbClass); + bindStepperOperatorMethods (HypredProbClass); pybind11::class_ HypredStepperClass(m, "HypredStepper"); bindStepperCallOperatorVar(HypredStepperClass); - bindStepperOperatorMethods(HypredStepperClass); + bindStepperOperatorMethods (HypredStepperClass); + pybind11::class_ PrecHypredProbClass(m, "PrecHypredProblem"); + bindConstructorHypredPrec (PrecHypredProbClass); + bindMethods (PrecHypredProbClass); + bindStepperCallOperatorVar(PrecHypredProbClass); + bindStepperOperatorMethods (PrecHypredProbClass); pybind11::class_ PrecHypredStepperClass(m, "PrecHypredStepper"); bindStepperCallOperatorVar(PrecHypredStepperClass); - bindStepperOperatorMethods(PrecHypredStepperClass); + bindStepperOperatorMethods (PrecHypredStepperClass); + } + + template + static void bindSteppers(pybind11::module & m) + { + + // // ---- disc-time 2 states ----- + // pybind11::class_ DefStepperClassDTN2(m, "DefaultStepperDTN2"); + // bindStepperCallOperatorVar(DefStepperClassDTN2); + // bindStepperOperatorMethods2(DefStepperClassDTN2); + + // pybind11::class_ MaskedStepperClassDTN2(m, "MaskedStepperDTN2"); + // bindStepperCallOperatorVar(MaskedStepperClassDTN2); + // bindStepperOperatorMethods2(MaskedStepperClassDTN2); + + // // ---- disc-time 3 states ----- + // pybind11::class_ DefStepperClassDTN3(m, "DefaultStepperDTN3"); + // bindStepperCallOperatorVar(DefStepperClassDTN3); + // bindStepperOperatorMethods2(DefStepperClassDTN3); + + // pybind11::class_ MaskedStepperClassDTN3(m, "MaskedStepperDTN3"); + // bindStepperCallOperatorVar(MaskedStepperClassDTN3); + // bindStepperOperatorMethods2(MaskedStepperClassDTN3); + + // // ---- cont-time ----- + // pybind11::class_ DefStepperClass(m, "DefaultStepper"); + // bindStepperCallOperatorVar(DefStepperClass); + // bindStepperOperatorMethods(DefStepperClass); + + // pybind11::class_ PrecDefStepperClass(m, "PrecDefaultStepper"); + // bindStepperCallOperatorVar(PrecDefStepperClass); + // bindStepperOperatorMethods(PrecDefStepperClass); + + // pybind11::class_ MaskedStepperClass(m, "MaskedStepper"); + // bindStepperCallOperatorVar(MaskedStepperClass); + // bindStepperOperatorMethods(MaskedStepperClass); + + // pybind11::class_ PrecMaskedStepperClass(m, "PrecMaskedStepper"); + // bindStepperCallOperatorVar(PrecMaskedStepperClass); + // bindStepperOperatorMethods(PrecMaskedStepperClass); + + // pybind11::class_ HypredStepperClass(m, "HypredStepper"); + // bindStepperCallOperatorVar(HypredStepperClass); + // bindStepperOperatorMethods(HypredStepperClass); + + // pybind11::class_ PrecHypredStepperClass(m, "PrecHypredStepper"); + // bindStepperCallOperatorVar(PrecHypredStepperClass); + // bindStepperOperatorMethods(PrecHypredStepperClass); } }; diff --git a/src/main_binder.cc b/src/main_binder.cc index af17ff7..8c67a55 100644 --- a/src/main_binder.cc +++ b/src/main_binder.cc @@ -291,58 +291,51 @@ PYBIND11_MODULE(MODNAME, topLevelModule) // *** galerkin *** using galerkin_binder = pressio4py::GalerkinBinder; - using galerkin_explicit_steppers = typename galerkin_binder::explicit_stepper_types; - using galerkin_implicit_steppers = typename galerkin_binder::implicit_stepper_types; - galerkin_binder::bindProblems(galerkinModule); - galerkin_binder::bindExplicitSteppers(galerkinModule); - // we need the solver type for the stepper's call operator - galerkin_binder::bindImplicitSteppers(galerkinModule); - - pressio4py::BindAdvanceFunctions::fixedStepSize(odeModule); - pressio4py::BindAdvanceFunctions::template arbitraryStepSize< + using galerkin_explicit_problems = typename galerkin_binder::explicit_problem_types; + using galerkin_implicit_problems = typename galerkin_binder::implicit_problem_types; + galerkin_binder::bindExplicitProblems(galerkinModule); + galerkin_binder::bindImplicitProblems< + pressio4py::UserDefinedNonLinSolverWrapper, newraph_solver_t>(galerkinModule); + + pressio4py::BindAdvanceFunctions::fixedStepSize(odeModule); + pressio4py::BindAdvanceFunctions::template arbitraryStepSize< pressio4py::ode_dt_setter_wrapper_type>(odeModule); - // // for implicit galerkin, we need the solver - // pressio4py::solvers::BindCreateHelperForTuple< - // newraphbinder_t, galerkin_implicit_steppers>::bindCreate(solversModule); - pressio4py::BindAdvanceFunctions< - galerkin_implicit_steppers>::template fixedStepSize(odeModule); + galerkin_implicit_problems>::template fixedStepSize(odeModule); pressio4py::BindAdvanceFunctions< - galerkin_implicit_steppers>::template arbitraryStepSize< + galerkin_implicit_problems>::template arbitraryStepSize< pressio4py::ode_dt_setter_wrapper_type, newraph_solver_t>(odeModule); pressio4py::BindAdvanceFunctions< - galerkin_implicit_steppers>::template fixedStepSizeUserSolver< + galerkin_implicit_problems>::template fixedStepSizeUserSolver< pressio4py::UserDefinedNonLinSolverWrapper>(odeModule); pressio4py::BindAdvanceFunctions< - galerkin_implicit_steppers>::template arbitraryStepSizeUserSolver< + galerkin_implicit_problems>::template arbitraryStepSizeUserSolver< pressio4py::ode_dt_setter_wrapper_type, pressio4py::UserDefinedNonLinSolverWrapper>(odeModule); // *** steady lspg *** using steady_lspg_binder = pressio4py::SteadyLSPGBinder; - using steady_lspg_steppers = typename steady_lspg_binder::system_types; + using steady_lspg_problems = typename steady_lspg_binder::system_types; steady_lspg_binder::bindProblems(steadyLspgModule); // *** unsteady lspg *** using unsteady_lspg_binder = pressio4py::UnsteadyLSPGBinder; - using unsteady_lspg_steppers = typename unsteady_lspg_binder::stepper_types; - unsteady_lspg_binder::bindProblems(unsteadyLspgModule); - unsteady_lspg_binder::bindSteppers(unsteadyLspgModule); + using unsteady_lspg_problems = typename unsteady_lspg_binder::problem_types; + unsteady_lspg_binder::bindProblems(unsteadyLspgModule); pressio4py::BindAdvanceFunctions< - unsteady_lspg_steppers>::template fixedStepSizeUserSolver< + unsteady_lspg_problems>::template fixedStepSizeUserSolver< pressio4py::UserDefinedNonLinSolverWrapper>(odeModule); pressio4py::BindAdvanceFunctions< - unsteady_lspg_steppers>::template arbitraryStepSizeUserSolver< + unsteady_lspg_problems>::template arbitraryStepSizeUserSolver< pressio4py::ode_dt_setter_wrapper_type, pressio4py::UserDefinedNonLinSolverWrapper>(odeModule); pressio4py::BindAdvanceFunctions< - unsteady_lspg_steppers>::template fixedStepSize(odeModule); + unsteady_lspg_problems>::template fixedStepSize(odeModule); pressio4py::BindAdvanceFunctions< - unsteady_lspg_steppers>::template arbitraryStepSize< + unsteady_lspg_problems>::template arbitraryStepSize< pressio4py::ode_dt_setter_wrapper_type, gn_neq_solver_t>(odeModule); } diff --git a/tests_functional_medium/unsteady_galerkin_burgers1d/test_unsteady_galerkin_burgers1d.py b/tests_functional_medium/unsteady_galerkin_burgers1d/test_unsteady_galerkin_burgers1d.py index d671e31..0c2a7e5 100755 --- a/tests_functional_medium/unsteady_galerkin_burgers1d/test_unsteady_galerkin_burgers1d.py +++ b/tests_functional_medium/unsteady_galerkin_burgers1d/test_unsteady_galerkin_burgers1d.py @@ -65,14 +65,13 @@ def test_euler(): yRom = np.zeros(romSize) # create problem scheme = ode.stepscheme.ForwardEuler - galerkinProblem = rom.galerkin.DefaultExplicitProblem(scheme, appObj, decoder, yRom, yRef) - stepper = galerkinProblem.stepper() + problem = rom.galerkin.DefaultExplicitProblem(scheme, appObj, decoder, yRom, yRef) - fomRecon = galerkinProblem.fomStateReconstructor() + fomRecon = problem.fomStateReconstructor() # the observer is called to monitor evolution of rom_state and # uses the reconstructor object to reconstruct FOM state myObs = OdeObserver(fomRecon) - ode.advance_n_steps_and_observe(stepper, yRom, 0., dt, Nsteps, myObs) + ode.advance_n_steps_and_observe(problem, yRom, 0., dt, Nsteps, myObs) # reconstruct full state at the end yFomFinal = fomRecon(yRom) diff --git a/tests_functional_medium/unsteady_lspg_burgers1d_gn_neq_custom_mapping/test_unsteady_lspg_burgers1d_gn_neq_custom_mapping.py b/tests_functional_medium/unsteady_lspg_burgers1d_gn_neq_custom_mapping/test_unsteady_lspg_burgers1d_gn_neq_custom_mapping.py index ade5f95..4288d99 100755 --- a/tests_functional_medium/unsteady_lspg_burgers1d_gn_neq_custom_mapping/test_unsteady_lspg_burgers1d_gn_neq_custom_mapping.py +++ b/tests_functional_medium/unsteady_lspg_burgers1d_gn_neq_custom_mapping/test_unsteady_lspg_burgers1d_gn_neq_custom_mapping.py @@ -61,12 +61,11 @@ def test_euler(): yRom = np.zeros(romSize) scheme = ode.stepscheme.BDF1 - lspgProblem = rom.lspg.unsteady.DefaultProblem(scheme, appObj, decoder, yRom, yRef) - stepper = lspgProblem.stepper() + problem = rom.lspg.unsteady.DefaultProblem(scheme, appObj, decoder, yRom, yRef) # linear and non linear solver lsO = MyLinSolver() - nlsO = solvers.create_gauss_newton(stepper, yRom, lsO) + nlsO = solvers.create_gauss_newton(problem, yRom, lsO) nlsTol, nlsMaxIt = 1e-13, 4 nlsO.setMaxIterations(nlsMaxIt) nlsO.setStoppingCriterion(solvers.stop.WhenCorrectionAbsoluteNormBelowTolerance) @@ -74,9 +73,9 @@ def test_euler(): # solve myObs = OdeObserver() - ode.advance_n_steps_and_observe(stepper, yRom, t0, dt, Nsteps, myObs, nlsO) + ode.advance_n_steps_and_observe(problem, yRom, t0, dt, Nsteps, myObs, nlsO) - fomRecon = lspgProblem.fomStateReconstructor() + fomRecon = problem.fomStateReconstructor() yFomFinal = fomRecon(yRom) print(yFomFinal) diff --git a/tests_functional_medium/unsteady_lspg_burgers1d_gn_qr/test_unsteady_lspg_burgers1d_gn_qr.py b/tests_functional_medium/unsteady_lspg_burgers1d_gn_qr/test_unsteady_lspg_burgers1d_gn_qr.py index 1d6ef27..bfffb9b 100755 --- a/tests_functional_medium/unsteady_lspg_burgers1d_gn_qr/test_unsteady_lspg_burgers1d_gn_qr.py +++ b/tests_functional_medium/unsteady_lspg_burgers1d_gn_qr/test_unsteady_lspg_burgers1d_gn_qr.py @@ -102,21 +102,20 @@ def test_euler(): yRom = np.zeros(romSize) # lspg problem scheme = ode.stepscheme.BDF1 - lspgProblem = rom.lspg.unsteady.DefaultProblem(scheme, appObj, decoder, yRom, yRef) - stepper = lspgProblem.stepper() + problem = rom.lspg.unsteady.DefaultProblem(scheme, appObj, decoder, yRom, yRef) # qr and non linear solver qrS = MyQRSolver(meshSize, romSize) - nlsO = solvers.create_gauss_newton_qr(stepper, yRom, qrS) + nlsO = solvers.create_gauss_newton_qr(problem, yRom, qrS) nlsO.setUpdatingCriterion(solvers.update.Standard) nlsO.setMaxIterations(2) nlsO.setStoppingCriterion(solvers.stop.AfterMaxIters) # solve myObs = OdeObserver() - ode.advance_n_steps_and_observe(stepper, yRom, t0,dt, Nsteps, myObs, nlsO) + ode.advance_n_steps_and_observe(problem, yRom, t0,dt, Nsteps, myObs, nlsO) - fomRecon = lspgProblem.fomStateReconstructor() + fomRecon = problem.fomStateReconstructor() yFomFinal = fomRecon(yRom) np.set_printoptions(precision=15) print(yFomFinal) @@ -151,21 +150,20 @@ def test_bdf2(): yRom = np.zeros(romSize) # lspg problem scheme = ode.stepscheme.BDF2 - lspgProblem = rom.lspg.unsteady.DefaultProblem(scheme, appObj, decoder, yRom, yRef) - stepper = lspgProblem.stepper() + problem = rom.lspg.unsteady.DefaultProblem(scheme, appObj, decoder, yRom, yRef) # qr and non linear solver qrS = MyQRSolver(meshSize, romSize) - nlsO = solvers.create_gauss_newton_qr(stepper, yRom, qrS) + nlsO = solvers.create_gauss_newton_qr(problem, yRom, qrS) nlsO.setUpdatingCriterion(solvers.update.Standard) nlsO.setMaxIterations(2) nlsO.setStoppingCriterion(solvers.stop.AfterMaxIters) # solve myObs = OdeObserver() - ode.advance_n_steps_and_observe(stepper, yRom, t0,dt, Nsteps, myObs, nlsO) + ode.advance_n_steps_and_observe(problem, yRom, t0,dt, Nsteps, myObs, nlsO) - fomRecon = lspgProblem.fomStateReconstructor() + fomRecon = problem.fomStateReconstructor() yFomFinal = fomRecon(yRom) np.set_printoptions(precision=15) print(yFomFinal) @@ -173,4 +171,4 @@ def test_bdf2(): for y1,y2 in zip(goldBdf2, yFomFinal): assert( np.abs(y1-y2) < 1e-10) - logger.finalize() \ No newline at end of file + logger.finalize() diff --git a/tests_functional_medium/unsteady_lspg_burgers1d_levenberg_marquardt/test_unsteady_lspg_burgers1d_levenberg_marquardt.py b/tests_functional_medium/unsteady_lspg_burgers1d_levenberg_marquardt/test_unsteady_lspg_burgers1d_levenberg_marquardt.py index c5f9ea3..0c75616 100755 --- a/tests_functional_medium/unsteady_lspg_burgers1d_levenberg_marquardt/test_unsteady_lspg_burgers1d_levenberg_marquardt.py +++ b/tests_functional_medium/unsteady_lspg_burgers1d_levenberg_marquardt/test_unsteady_lspg_burgers1d_levenberg_marquardt.py @@ -72,20 +72,19 @@ def test_euler(): yRom = np.zeros(romSize) scheme = ode.stepscheme.BDF1 - lspgProblem = rom.lspg.unsteady.DefaultProblem(scheme, appObj, decoder, yRom, yRef) - stepper = lspgProblem.stepper() + problem = rom.lspg.unsteady.DefaultProblem(scheme, appObj, decoder, yRom, yRef) # linear and non linear solver lsO = MyLinSolver() - nlsO = solvers.create_levenberg_marquardt(stepper, yRom, lsO) + nlsO = solvers.create_levenberg_marquardt(problem, yRom, lsO) nlsO.setUpdatingCriterion(solvers.update.LMSchedule1) nlsO.setMaxIterations(2) # solve myObs = OdeObserver() - ode.advance_n_steps_and_observe(stepper, yRom, t0,dt, Nsteps, myObs, nlsO) + ode.advance_n_steps_and_observe(problem, yRom, t0,dt, Nsteps, myObs, nlsO) - fomRecon = lspgProblem.fomStateReconstructor() + fomRecon = problem.fomStateReconstructor() yFomFinal = fomRecon(yRom) print(yFomFinal) diff --git a/tests_functional_medium/unsteady_lspg_burgers1d_trivially_weighted_gn_neq_custom_mapping/test_unsteady_lspg_burgers1d_trivially_weighted_gn_neq_custom_mapping.py b/tests_functional_medium/unsteady_lspg_burgers1d_trivially_weighted_gn_neq_custom_mapping/test_unsteady_lspg_burgers1d_trivially_weighted_gn_neq_custom_mapping.py index d6183f0..2f2764a 100755 --- a/tests_functional_medium/unsteady_lspg_burgers1d_trivially_weighted_gn_neq_custom_mapping/test_unsteady_lspg_burgers1d_trivially_weighted_gn_neq_custom_mapping.py +++ b/tests_functional_medium/unsteady_lspg_burgers1d_trivially_weighted_gn_neq_custom_mapping/test_unsteady_lspg_burgers1d_trivially_weighted_gn_neq_custom_mapping.py @@ -72,15 +72,14 @@ def test_euler(): yRom = np.zeros(romSize) scheme = ode.stepscheme.BDF1 - lspgProblem = rom.lspg.unsteady.DefaultProblem(scheme, appObj, decoder, yRom, yRef) - stepper = lspgProblem.stepper() + problem = rom.lspg.unsteady.DefaultProblem(scheme, appObj, decoder, yRom, yRef) # weighting operator wOp = MyWeigher() # linear and non linear solver lsO = MyLinSolver() - nlsO = solvers.create_weighted_gauss_newton(stepper, yRom, lsO, wOp) + nlsO = solvers.create_weighted_gauss_newton(problem, yRom, lsO, wOp) nlsTol, nlsMaxIt = 1e-13, 4 nlsO.setMaxIterations(nlsMaxIt) nlsO.setStoppingCriterion(solvers.stop.WhenCorrectionAbsoluteNormBelowTolerance) @@ -88,9 +87,9 @@ def test_euler(): # solve myObs = OdeObserver() - ode.advance_n_steps_and_observe(stepper, yRom, t0, dt, Nsteps, myObs, nlsO) + ode.advance_n_steps_and_observe(problem, yRom, t0, dt, Nsteps, myObs, nlsO) - fomRecon = lspgProblem.fomStateReconstructor() + fomRecon = problem.fomStateReconstructor() yFomFinal = fomRecon(yRom) print(yFomFinal) diff --git a/tests_functional_small/test_rom_galerkin_default_explicit.py b/tests_functional_small/test_rom_galerkin_default_explicit.py index 989dd23..e494140 100644 --- a/tests_functional_small/test_rom_galerkin_default_explicit.py +++ b/tests_functional_small/test_rom_galerkin_default_explicit.py @@ -45,11 +45,10 @@ def test_galerkin_cont_time_default_explicit1(): rom_state = np.array([0., 1., 2.]) scheme = ode.stepscheme.ForwardEuler problem = galerkin.DefaultExplicitProblem(scheme, sw, decoder, rom_state, fom_state) - stepper = problem.stepper() dt = 1. num_steps = 2 obs = MyObs() - ode.advance_n_steps_and_observe(stepper, rom_state, 0., dt, num_steps, obs) + ode.advance_n_steps_and_observe(problem, rom_state, 0., dt, num_steps, obs) print(rom_state) assert(rom_state[0] == 0.) assert(rom_state[1] == 2611.) @@ -74,11 +73,10 @@ def test_galerkin_cont_time_default_explicit2(): rom_state = np.array([0., 1., 2.]) scheme = ode.stepscheme.ForwardEuler problem = rom.galerkin.DefaultExplicitProblem(scheme, sw, decoder, rom_state, fom_state) - stepper = problem.stepper() dtCb = MyDtSetter() num_steps = 2 obs = MyObs() - ode.advance_n_steps_and_observe(stepper, rom_state, 0., dtCb, num_steps, obs) + ode.advance_n_steps_and_observe(problem, rom_state, 0., dtCb, num_steps, obs) print(rom_state) assert(rom_state[0] == 0.) assert(rom_state[1] == 2611.) @@ -98,9 +96,8 @@ def test_galerkin_cont_time_default_explicit3(): rom_state = np.array([0., 1., 2.]) scheme = ode.stepscheme.ForwardEuler problem = rom.galerkin.DefaultExplicitProblem(scheme, sw, decoder, rom_state, fom_state) - stepper = problem.stepper() dt = 1. - stepper(rom_state, 0., dt, 1) + problem(rom_state, 0., dt, 1) print(rom_state) assert(rom_state[0] == 0.) assert(rom_state[1] == 51.) diff --git a/tests_functional_small/test_rom_galerkin_default_implicit.py b/tests_functional_small/test_rom_galerkin_default_implicit.py index f36f196..a93ebc3 100644 --- a/tests_functional_small/test_rom_galerkin_default_implicit.py +++ b/tests_functional_small/test_rom_galerkin_default_implicit.py @@ -38,32 +38,31 @@ def __call__(self, step, time, state): print("MyObs2") print(state) -def test_galerkin_cont_time_default_implicit1(): - print("\n") - N = 10 - sw = FomSystem(N) - fom_state = np.zeros(N) - phi = np.zeros((N,3), order='F') - phi[:,0] = 0. - phi[:,1] = 1. - phi[:,2] = 2. - decoder = rom.Decoder(phi) - rom_state = np.array([0., 1., 2.]) - scheme = ode.stepscheme.BDF1 - problem = rom.galerkin.DefaultImplicitProblem(scheme, sw, decoder, rom_state, fom_state) - stepper = problem.stepper() - - # solvers - lsO = MyLinSolver() - nlsO = solvers.create_newton_raphson(stepper, rom_state, lsO) - nlsO.setUpdatingCriterion(solvers.update.Standard) - nlsO.setMaxIterations(2) - nlsO.setStoppingCriterion(solvers.stop.AfterMaxIters) - - dt, num_steps = 1., 1 - obs = MyObs2() - ode.advance_n_steps_and_observe(stepper, rom_state, 0., dt, num_steps, obs, nlsO) - print("final rom_state = ", rom_state) +# def test_galerkin_cont_time_default_implicit1(): +# print("\n") +# N = 10 +# sw = FomSystem(N) +# fom_state = np.zeros(N) +# phi = np.zeros((N,3), order='F') +# phi[:,0] = 0. +# phi[:,1] = 1. +# phi[:,2] = 2. +# decoder = rom.Decoder(phi) +# rom_state = np.array([0., 1., 2.]) +# scheme = ode.stepscheme.BDF1 +# problem = rom.galerkin.DefaultImplicitProblem(scheme, sw, decoder, rom_state, fom_state) + +# # solvers +# lsO = MyLinSolver() +# nlsO = solvers.create_newton_raphson(problem, rom_state, lsO) +# nlsO.setUpdatingCriterion(solvers.update.Standard) +# nlsO.setMaxIterations(2) +# nlsO.setStoppingCriterion(solvers.stop.AfterMaxIters) + +# dt, num_steps = 1., 1 +# obs = MyObs2() +# ode.advance_n_steps_and_observe(problem, rom_state, 0., dt, num_steps, obs, nlsO) +# print("final rom_state = ", rom_state) # ===================================================================================== @@ -112,7 +111,6 @@ def solve(self, system, x): assert(self.J[2,1] ==-120.) assert(self.J[2,2] ==-159.) - def test_galerkin_cont_time_default_implicit2(): print("\n") print("using advance") @@ -128,13 +126,12 @@ def test_galerkin_cont_time_default_implicit2(): rom_state = np.array([0., 1., 2.]) scheme = ode.stepscheme.BDF1 problem = rom.galerkin.DefaultImplicitProblem(scheme, sw, decoder, rom_state, fom_state) - stepper = problem.stepper() - mynlsO = MyNonLinSolver(stepper) + mynlsO = MyNonLinSolver(problem) dt, num_steps = 2., 2 obs = MyObs2() - ode.advance_n_steps_and_observe(stepper, rom_state, 0., dt, num_steps, obs, mynlsO) + ode.advance_n_steps_and_observe(problem, rom_state, 0., dt, num_steps, obs, mynlsO) print("final rom_state = ", rom_state) @@ -152,15 +149,7 @@ def test_galerkin_cont_time_default_implicit3(): rom_state = np.array([0., 1., 2.]) scheme = ode.stepscheme.BDF1 problem = rom.galerkin.DefaultImplicitProblem(scheme, sw, decoder, rom_state, fom_state) - stepper = problem.stepper() - mynlsO = MyNonLinSolver(stepper) - stepper(rom_state, 0., 2., 1, mynlsO) + mynlsO = MyNonLinSolver(problem) + problem(rom_state, 0., 2., 1, mynlsO) print("final rom_state = ", rom_state) - - # dtcb = MyDtSetter() - # #assert(rom_state[0] == 0.) - # #assert(rom_state[1] == 2611.) - # #assert(rom_state[2] == 5222.) - - # stepper(rom_state, 0., 1., 1, mynlsO) diff --git a/tests_functional_small/test_rom_galerkin_hypred_explicit.py b/tests_functional_small/test_rom_galerkin_hypred_explicit.py index 789fe16..cac8639 100644 --- a/tests_functional_small/test_rom_galerkin_hypred_explicit.py +++ b/tests_functional_small/test_rom_galerkin_hypred_explicit.py @@ -71,11 +71,11 @@ def test_galerkin_cont_time_hypred_explicit(): scheme = ode.stepscheme.ForwardEuler problem = rom.galerkin.HyperreducedExplicitProblem(scheme, sw, decoder, rom_state, \ fom_state, projector) - stepper = problem.stepper() + dt = 1. num_steps = 2 obs = MyObs() - ode.advance_n_steps_and_observe(stepper, rom_state, 0., dt, num_steps, obs) + ode.advance_n_steps_and_observe(problem, rom_state, 0., dt, num_steps, obs) print(rom_state) assert(rom_state[0] == 0.) assert(rom_state[1] == 2611.) diff --git a/tests_functional_small/test_rom_galerkin_masked_explicit.py b/tests_functional_small/test_rom_galerkin_masked_explicit.py index ebf6928..a0ca851 100644 --- a/tests_functional_small/test_rom_galerkin_masked_explicit.py +++ b/tests_functional_small/test_rom_galerkin_masked_explicit.py @@ -85,11 +85,11 @@ def test_galerkin_cont_time_masked_explicit(): scheme = ode.stepscheme.ForwardEuler problem = rom.galerkin.MaskedExplicitProblem(scheme, sw, decoder, rom_state, \ fom_state, projector, masker) - stepper = problem.stepper() + dt = 1. num_steps = 2 obs = MyObs() - ode.advance_n_steps_and_observe(stepper, rom_state, 0., dt, num_steps, obs) + ode.advance_n_steps_and_observe(problem, rom_state, 0., dt, num_steps, obs) print(rom_state) assert(rom_state[0] == 0.) assert(rom_state[1] == 2611.) diff --git a/tests_functional_small/test_rom_galerkin_masked_implicit_bdf1.py b/tests_functional_small/test_rom_galerkin_masked_implicit_bdf1.py index 59263cc..af00ef2 100755 --- a/tests_functional_small/test_rom_galerkin_masked_implicit_bdf1.py +++ b/tests_functional_small/test_rom_galerkin_masked_implicit_bdf1.py @@ -146,15 +146,14 @@ def test(): masker = MyMasker(sampleMeshIndices) scheme = ode.stepscheme.BDF1 - galerkinProblem = rom.galerkin.MaskedImplicitProblem(scheme, appObj, decoder, \ - yRom, yRef, projector, masker) - stepper = galerkinProblem.stepper() + problem = rom.galerkin.MaskedImplicitProblem(scheme, appObj, decoder, \ + yRom, yRef, projector, masker) # linear and non linear solver lsO = MyLinSolver() - nlsO = solvers.create_newton_raphson(stepper, yRom, lsO) + nlsO = solvers.create_newton_raphson(problem, yRom, lsO) nlsO.setUpdatingCriterion(solvers.update.Standard) nlsO.setMaxIterations(1) nlsO.setStoppingCriterion(solvers.stop.AfterMaxIters) - ode.advance_n_steps(stepper, yRom, 0., dt, Nsteps, nlsO) + ode.advance_n_steps(problem, yRom, 0., dt, Nsteps, nlsO) diff --git a/tests_functional_small/test_rom_lspg_unsteady_conttime_default.py b/tests_functional_small/test_rom_lspg_unsteady_conttime_default.py index 5a0008c..e7cde73 100644 --- a/tests_functional_small/test_rom_lspg_unsteady_conttime_default.py +++ b/tests_functional_small/test_rom_lspg_unsteady_conttime_default.py @@ -55,9 +55,8 @@ def test_lspg_cont_time_default_2(): rom_state = np.array([0., 1., 2.]) scheme = ode.stepscheme.BDF1 problem = rom.lspg.unsteady.DefaultProblem(scheme, sw, decoder, rom_state, fom_state) - stepper = problem.stepper() - mynlsO = MyNonLinSolver(stepper) + mynlsO = MyNonLinSolver(problem) dt, num_steps = 2., 1 - ode.advance_n_steps(stepper, rom_state, 0., dt, num_steps, mynlsO) + ode.advance_n_steps(problem, rom_state, 0., dt, num_steps, mynlsO) print("final rom_state = ", rom_state) diff --git a/tests_functional_small/test_rom_lspg_unsteady_discretetime_default_trivialapp_two_states.py b/tests_functional_small/test_rom_lspg_unsteady_discretetime_default_trivialapp_two_states.py index 6ede868..90d1902 100755 --- a/tests_functional_small/test_rom_lspg_unsteady_discretetime_default_trivialapp_two_states.py +++ b/tests_functional_small/test_rom_lspg_unsteady_discretetime_default_trivialapp_two_states.py @@ -83,15 +83,14 @@ def test(): decoder = rom.Decoder(phi) yRom = np.ones(romSize) problem = rom.lspg.unsteady.DiscreteTimeProblemTwoStates(appObj, decoder, yRom, yRef) - stepper = problem.stepper() lsO = MyLinSolver() - nlsO = solvers.create_gauss_newton(stepper, yRom, lsO) + nlsO = solvers.create_gauss_newton(problem, yRom, lsO) nlsO.setUpdatingCriterion(solvers.update.Standard) nlsO.setMaxIterations(2) nlsO.setStoppingCriterion(solvers.stop.AfterMaxIters) # solve - ode.advance_n_steps(stepper, yRom, 0., dt, 1, nlsO) + ode.advance_n_steps(problem, yRom, 0., dt, 1, nlsO) assert( np.allclose(yRom, np.array([2.,2.,2.]), 1e-12) ) logger.finalize() diff --git a/tests_functional_small/test_rom_lspg_unsteady_hyperreduced_trivialapp_bdf1.py b/tests_functional_small/test_rom_lspg_unsteady_hyperreduced_trivialapp_bdf1.py index 8edc720..6ea8904 100755 --- a/tests_functional_small/test_rom_lspg_unsteady_hyperreduced_trivialapp_bdf1.py +++ b/tests_functional_small/test_rom_lspg_unsteady_hyperreduced_trivialapp_bdf1.py @@ -185,23 +185,22 @@ def test(): indexing = rom.lspg.unsteady.StencilToSampleIndexing([1,4,5,7,8]) scheme = ode.stepscheme.BDF1 - lspgProblem = rom.lspg.unsteady.HypredProblem(scheme, appObj, decoder, yRom, yRef, indexing) - stepper = lspgProblem.stepper() + problem = rom.lspg.unsteady.HypredProblem(scheme, appObj, decoder, yRom, yRef, indexing) # linear and non linear solver lsO = MyLinSolver() - nlsO = solvers.create_gauss_newton(stepper, yRom, lsO) + nlsO = solvers.create_gauss_newton(problem, yRom, lsO) nlsO.setUpdatingCriterion(solvers.update.Standard) nlsO.setMaxIterations(2) nlsO.setStoppingCriterion(solvers.stop.AfterMaxIters) # solve myObs = OdeObserver() - ode.advance_n_steps_and_observe(stepper, yRom, 0., 0.2, 1, myObs, nlsO) + ode.advance_n_steps_and_observe(problem, yRom, 0., 0.2, 1, myObs, nlsO) print(yRom) # yRom should be [1 1 1] - fomRecon = lspgProblem.fomStateReconstructor() + fomRecon = problem.fomStateReconstructor() yFomFinal = fomRecon(yRom) np.set_printoptions(precision=15) diff --git a/tests_functional_small/test_rom_lspg_unsteady_hyperreduced_trivialapp_bdf2.py b/tests_functional_small/test_rom_lspg_unsteady_hyperreduced_trivialapp_bdf2.py index 1d192b8..6403cf9 100755 --- a/tests_functional_small/test_rom_lspg_unsteady_hyperreduced_trivialapp_bdf2.py +++ b/tests_functional_small/test_rom_lspg_unsteady_hyperreduced_trivialapp_bdf2.py @@ -233,21 +233,20 @@ def test(): indexing = rom.lspg.unsteady.StencilToSampleIndexing([1,4,5,7,8]) scheme = ode.stepscheme.BDF2 - lspgProblem = rom.lspg.unsteady.HypredProblem(scheme, appObj, decoder, yRom, yRef, indexing) - stepper = lspgProblem.stepper() + problem = rom.lspg.unsteady.HypredProblem(scheme, appObj, decoder, yRom, yRef, indexing) # linear and non linear solver lsO = MyLinSolver() - nlsO = solvers.create_gauss_newton(stepper, yRom, lsO) + nlsO = solvers.create_gauss_newton(problem, yRom, lsO) nlsO.setUpdatingCriterion(solvers.update.Standard) nlsO.setMaxIterations(2) nlsO.setStoppingCriterion(solvers.stop.AfterMaxIters) # solve myObs = OdeObserver() - ode.advance_n_steps_and_observe(stepper, yRom, 0., dt, 2, myObs, nlsO) + ode.advance_n_steps_and_observe(problem, yRom, 0., dt, 2, myObs, nlsO) - fomRecon = lspgProblem.fomStateReconstructor() + fomRecon = problem.fomStateReconstructor() yFomFinal = fomRecon(yRom) np.set_printoptions(precision=15) # the goldFomState = phi*[2 2 2] diff --git a/tests_functional_small/test_rom_lspg_unsteady_masked_trivialapp_bdf1.py b/tests_functional_small/test_rom_lspg_unsteady_masked_trivialapp_bdf1.py index 2570997..d9efec7 100755 --- a/tests_functional_small/test_rom_lspg_unsteady_masked_trivialapp_bdf1.py +++ b/tests_functional_small/test_rom_lspg_unsteady_masked_trivialapp_bdf1.py @@ -1,7 +1,7 @@ import numpy as np from scipy import linalg -from pressio4py import solvers, ode, rom +from pressio4py import solvers, ode, rom np.set_printoptions(linewidth=140) @@ -212,22 +212,21 @@ def test(): decoder = rom.Decoder(phi) yRom = np.zeros(romSize) scheme = ode.stepscheme.BDF1 - lspgProblem = rom.lspg.unsteady.MaskedProblem(scheme,appObj,decoder,yRom,yRef,masker) - stepper = lspgProblem.stepper() + problem = rom.lspg.unsteady.MaskedProblem(scheme,appObj,decoder,yRom,yRef,masker) # linear and non linear solver lsO = MyLinSolver() - nlsO = solvers.create_gauss_newton(stepper, yRom, lsO) + nlsO = solvers.create_gauss_newton(problem, yRom, lsO) nlsO.setUpdatingCriterion(solvers.update.Standard) nlsO.setMaxIterations(2) nlsO.setStoppingCriterion(solvers.stop.AfterMaxIters) # solve myObs = OdeObserver() - ode.advance_n_steps_and_observe(stepper, yRom, 0.,0.2, 1, myObs, nlsO) + ode.advance_n_steps_and_observe(problem, yRom, 0.,0.2, 1, myObs, nlsO) # yRom should be [1 1 1] - fomRecon = lspgProblem.fomStateReconstructor() + fomRecon = problem.fomStateReconstructor() yFomFinal = fomRecon(yRom) np.set_printoptions(precision=15) From 745175b10af1700950bc6d6d92e7ea3a29b42db0 Mon Sep 17 00:00:00 2001 From: Francesco Rizzi Date: Fri, 15 Oct 2021 15:41:44 +0200 Subject: [PATCH 2/2] sync pressio --- pressio | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pressio b/pressio index 5903636..5bee44a 160000 --- a/pressio +++ b/pressio @@ -1 +1 @@ -Subproject commit 5903636992346ceab852332f7050ed7f7e79ba43 +Subproject commit 5bee44a1cb9d2fc117d89da4a401bff8d0918605