├── joss ├── paper.bib └── paper.md ├── src └── pinnde │ ├── legacy │ ├── ODE │ │ ├── __init__.py │ │ ├── SolveClasses │ │ │ └── __init__.py │ │ ├── SpecificTraining │ │ │ ├── __init__.py │ │ │ ├── BVP_Training │ │ │ │ └── __init__.py │ │ │ ├── IVP_Training │ │ │ │ └── __init__.py │ │ │ ├── DeepONet_Training │ │ │ │ ├── __init__.py │ │ │ │ ├── DeepONet_BVP │ │ │ │ │ └── __init__.py │ │ │ │ ├── DeepONet_IVP │ │ │ │ │ └── __init__.py │ │ │ │ ├── DeepONet_2EquationSystems │ │ │ │ │ └── __init__.py │ │ │ │ └── DeepONet_3EquationSystems │ │ │ │ │ └── __init__.py │ │ │ └── HyperDeepONet_Training │ │ │ │ └── __init__.py │ │ └── ode_Points.py │ ├── PDE │ │ ├── __init__.py │ │ ├── Boundaries │ │ │ └── __init__.py │ │ ├── ModelFuncs │ │ │ └── __init__.py │ │ ├── SolveClasses │ │ │ └── __init__.py │ │ ├── SpecificTraining │ │ │ ├── __init__.py │ │ │ ├── training_2variables │ │ │ │ ├── __init__.py │ │ │ │ ├── BCP_Training │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── pde_TrainingBCP_hard.py │ │ │ │ └── ICBCP_Training │ │ │ │ │ └── __init__.py │ │ │ ├── training_3variables │ │ │ │ ├── __init__.py │ │ │ │ └── ICBCP3_Training │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── pde_TrainingICBCP3_periodic_hard.py │ │ │ └── DeepONetTraining_2variables │ │ │ │ ├── __init__.py │ │ │ │ ├── DeepONet_BCP │ │ │ │ └── __init__.py │ │ │ │ └── DeepONet_ICBCP │ │ │ │ └── __init__.py │ │ ├── TrainingSelects │ │ │ ├── __init__.py │ │ │ └── pde_trainingSelect_3var.py │ │ ├── pde_Adaptivity.py │ │ └── pde_TimeSteppersDeepONet.py │ ├── __init__.py │ └── pde_Initials.py │ ├── selectors │ ├── __init__.py │ ├── adaptSampleSelector.py │ └── pinnSelectors.py │ ├── training │ └── __init__.py │ ├── models │ └── __init__.py │ ├── adaptives │ ├── __init__.py │ ├── adaptives.py │ └── RAR.py │ ├── boundaries │ ├── __init__.py │ ├── periodic.py │ ├── boundaries.py │ ├── neumann.py │ ├── odeicbc.py │ └── dirichlet.py │ ├── domain │ ├── __init__.py │ ├── timedomain.py │ └── NRect.py │ ├── __init__.py │ ├── data │ ├── __init__.py │ ├── data.py │ ├── timepinndata.py │ ├── pinndata.py │ ├── timeinvpinndata.py │ ├── invpinndata.py │ └── timedondata.py │ ├── plotters │ ├── __init__.py │ └── plotLosses.py │ └── initials.py ├── requirements.txt ├── docs ├── data │ ├── data.md │ ├── pinndata.md │ ├── dondata.md │ ├── invpinndata.md │ ├── timepinndata.md │ ├── timedondata.md │ └── timeinvpinndata.md ├── models │ ├── pinn.md │ ├── deeponet.md │ └── invpinn.md ├── domain │ ├── domain.md │ ├── NRect.md │ ├── timedomain.md │ ├── NEllipsoid.md │ ├── Time_NRect.md │ └── Time_NEllipsoid.md ├── adaptives │ ├── RAR.md │ ├── RAD.md │ ├── adaptives.md │ └── RARD.md ├── boundaries │ ├── neumann.md │ ├── periodic.md │ ├── boundaries.md │ ├── dirichlet.md │ └── odeicbc.md ├── initials │ └── initials.md ├── plotters │ ├── plotLosses.md │ └── plotPinnPredictions.md ├── Legacy │ ├── odeSolveClasses │ │ ├── ode_SolveClass.md │ │ ├── ode_SystemSolveClass.md │ │ ├── ode_DeepONetSolveClass.md │ │ └── ode_SystemDeepONetSolveClass.md │ ├── pdeSolveClasses │ │ ├── pde_SolveClass_tx.md │ │ ├── pde_SolveClass_xy.md │ │ ├── pde_DeepONetSolveClass_tx.md │ │ └── pde_DeepONetSolveClass_xy.md │ ├── pde_Initials.md │ ├── pde_Solvers.md │ ├── ode_Solvers.md │ ├── ode_trainingSelect.md │ ├── ode_Points.md │ ├── pde_ParamChecks.md │ ├── pde_trainingSelect_2var.md │ ├── pde_Points.md │ ├── ode_TimeSteppersDeepONet.md │ ├── pde_Boundaries_2var.md │ ├── SpecificTraining │ │ ├── BVP_Training │ │ │ ├── ode_TrainingBVP_soft.md │ │ │ └── ode_TrainingBVP_Hard.md │ │ ├── IVP_Training │ │ │ ├── ode_TrainingIVP_soft.md │ │ │ ├── ode_TrainingIVP_hard.md │ │ │ ├── ode_Training2SystemIVP_soft.md │ │ │ └── ode_Training3SystemIVP_soft.md │ │ └── DeepONet_Training │ │ │ ├── ode_TrainingDeepONetBVP.md │ │ │ ├── ode_TrainingDeepONetIVP.md │ │ │ ├── ode_TrainingDeepONet_2EquationSystems.md │ │ │ └── ode_TrainingDeepONet_3EquationSystems.md │ ├── ode_ParamChecks.md │ ├── SpecificTraining_2var │ │ ├── tx_Training │ │ │ ├── pde_TrainingICBCP_hard.md │ │ │ ├── pde_TrainingICBCP_neumann_soft.md │ │ │ ├── pde_TrainingICBCP_periodic_soft.md │ │ │ └── pde_TrainingICBCP_dirichlet_soft.md │ │ ├── xy_Training │ │ │ ├── pde_TrainingBCP_periodic.md │ │ │ ├── pde_TrainingBCP_neumann_soft.md │ │ │ ├── pde_TrainingBCP_dirichlet_hard.md │ │ │ └── pde_TrainingBCP_dirichlet_soft.md │ │ ├── xy_DeepONet_Training │ │ │ ├── pde_TrainingDeepONetBCP_neumann_soft.md │ │ │ ├── pde_TrainingDeepONetBCP_dirichlet_soft.md │ │ │ └── pde_TrainingDeepONetBCP_hard.md │ │ └── tx_DeepONet_Training │ │ │ ├── pde_TrainingDeepONetICBCP_neumann_soft.md │ │ │ ├── pde_TrainingDeepONetICBCP_dirichlet_soft.md │ │ │ ├── pde_TrainingDeepONetICBCP_periodic_hard.md │ │ │ └── pde_TrainingDeepONetICBCP_periodic_soft.md │ ├── ode_ModelFuncs.md │ ├── pde_Plotters.md │ ├── ode_Plotters.md │ └── ModelFuncs │ │ ├── pde_ModelFuncs_2var.md │ │ └── pde_DeepONetModelFuncs_2var.md ├── training │ ├── pinnTrainSteps.md │ ├── deeponetTrainSteps.md │ ├── invpinnTrainSteps.md │ └── lbfgsTrainSteps.md ├── InstallSetup.md ├── tutorials │ ├── invpinntutorials │ │ └── invpinntutorials.md │ ├── deeponettutorials │ │ ├── deeponettutorials.md │ │ ├── ode.md │ │ ├── 2helmholtz.md │ │ └── 2poisson1.md │ ├── pinntutorials │ │ ├── pinntutorials.md │ │ ├── odesys.md │ │ ├── 2helmholtz.md │ │ ├── 2poisson1.md │ │ └── 11advec.md │ └── legacy │ │ ├── Tutorials_PDEs_tx │ │ ├── PDE_tx_tutorials.md │ │ ├── Tutorials_PDEs_tx_PINN │ │ │ ├── linadvPeriodic.md │ │ │ ├── burgersPeriodic.md │ │ │ └── kvdHard.md │ │ └── Tutorials_PDEs_tx_DeepONet │ │ │ ├── heatPeriodic_don.md │ │ │ ├── kvdHard_don.md │ │ │ └── burgersPeriodic_don.md │ │ ├── Tutorials_PDEs_xy │ │ ├── PDE_xy_tutorials.md │ │ ├── Tutorials_PDEs_xy_PINN │ │ │ ├── helmholtz.md │ │ │ ├── lagaris.md │ │ │ ├── poisson1.md │ │ │ └── poisson2.md │ │ └── Tutorials_PDEs_xy_DeepONet │ │ │ ├── helmholtz_don.md │ │ │ ├── poisson1_don.md │ │ │ └── lagaris_don.md │ │ └── Tutorials_ODEs │ │ ├── Tutorials_ODEs_PINN │ │ ├── 3ordIVPhard.md │ │ ├── 2ordBVPhard.md │ │ ├── 2sysIVPsoft.md │ │ ├── 3sysIVPsoft.md │ │ ├── 3ordBVPsoft.md │ │ └── 2ordIVPsoft.md │ │ ├── ODE_Tutorials.md │ │ └── Tutorials_ODEs_DeepONet │ │ ├── 3ordIVPhard_don.md │ │ ├── 2sysIVPsoft_don.md │ │ ├── 2ordBVPhard_don.md │ │ ├── 3ordBVPsoft_don.md │ │ ├── 3sysIVPsoft_don.md │ │ └── 2ordIVPsoft_don.md ├── cite.md ├── javascripts │ └── mathjax.js ├── team.md └── index.md ├── .readthedocs.yaml ├── pyproject.toml └── README.md /joss/paper.bib: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/pinnde/legacy/ODE/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/PDE/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/selectors/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/training/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | mkdocstrings[python] -------------------------------------------------------------------------------- /src/pinnde/legacy/ODE/SolveClasses/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/PDE/Boundaries/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/PDE/ModelFuncs/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/PDE/SolveClasses/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/ODE/SpecificTraining/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/PDE/SpecificTraining/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/PDE/TrainingSelects/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/ODE/SpecificTraining/BVP_Training/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/ODE/SpecificTraining/IVP_Training/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/ODE/SpecificTraining/DeepONet_Training/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/ODE/SpecificTraining/HyperDeepONet_Training/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/PDE/SpecificTraining/training_2variables/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/PDE/SpecificTraining/training_3variables/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/PDE/SpecificTraining/DeepONetTraining_2variables/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/ODE/SpecificTraining/DeepONet_Training/DeepONet_BVP/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/ODE/SpecificTraining/DeepONet_Training/DeepONet_IVP/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/PDE/SpecificTraining/training_2variables/BCP_Training/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/PDE/SpecificTraining/training_2variables/ICBCP_Training/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/PDE/SpecificTraining/training_3variables/ICBCP3_Training/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/PDE/SpecificTraining/DeepONetTraining_2variables/DeepONet_BCP/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/PDE/SpecificTraining/DeepONetTraining_2variables/DeepONet_ICBCP/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/ODE/SpecificTraining/DeepONet_Training/DeepONet_2EquationSystems/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/legacy/ODE/SpecificTraining/DeepONet_Training/DeepONet_3EquationSystems/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pinnde/models/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = [ 2 | "pinn", 3 | "deeponet", 4 | "invpinn" 5 | ] 6 | 7 | from .pinn import pinn 8 | from .deeponet import deeponet 9 | from .invpinn import invpinn -------------------------------------------------------------------------------- /src/pinnde/adaptives/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = [ 2 | "RAR", 3 | "RAD", 4 | "RARD", 5 | "adaptives"] 6 | 7 | from .adaptives import adaptives 8 | from .RAR import RAR 9 | from .RAD import RAD 10 | from .RARD import RARD -------------------------------------------------------------------------------- /docs/data/data.md: -------------------------------------------------------------------------------- 1 | data 2 | ---------------- 3 | 4 | Abstract class which is used to implement data 5 | 6 | ::: src.pinnde.data.data 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/models/pinn.md: -------------------------------------------------------------------------------- 1 | pinn 2 | ---------------- 3 | 4 | Class which implements a pinn architecture 5 | 6 | ::: src.pinnde.models.pinn 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/data/pinndata.md: -------------------------------------------------------------------------------- 1 | pinndata 2 | ---------------- 3 | 4 | Class which is used to implement data for PINNs 5 | 6 | ::: src.pinnde.data.pinndata 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/domain/domain.md: -------------------------------------------------------------------------------- 1 | domain 2 | ---------------- 3 | 4 | Abstract class which is used to implement domains 5 | 6 | ::: src.pinnde.domain.domain 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/models/deeponet.md: -------------------------------------------------------------------------------- 1 | deeponet 2 | ---------------- 3 | 4 | Class which implements a deeponet architecture 5 | 6 | ::: src.pinnde.models.deeponet 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/models/invpinn.md: -------------------------------------------------------------------------------- 1 | invpinn 2 | ---------------- 3 | 4 | Class which implements an inverse pinn architecture 5 | 6 | ::: src.pinnde.models.invpinn 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/data/dondata.md: -------------------------------------------------------------------------------- 1 | dondata 2 | ---------------- 3 | 4 | Class which is used to implement data for DeepONets (don). 5 | 6 | ::: src.pinnde.data.dondata 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/adaptives/RAR.md: -------------------------------------------------------------------------------- 1 | RAR 2 | ---------------- 3 | 4 | Class which is used to implement residule-based adaptive refinement 5 | 6 | ::: src.pinnde.adaptives.RAR 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/boundaries/neumann.md: -------------------------------------------------------------------------------- 1 | neumann 2 | ---------------- 3 | 4 | Class which is used to implement neumann boundaries 5 | 6 | ::: src.pinnde.boundaries.neumann 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/domain/NRect.md: -------------------------------------------------------------------------------- 1 | NRect 2 | ---------------- 3 | 4 | Class which is used to implement N dimensional Hyperrectangles. 5 | 6 | ::: src.pinnde.domain.NRect 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/adaptives/RAD.md: -------------------------------------------------------------------------------- 1 | RAD 2 | ---------------- 3 | 4 | Class which is used to implement residule-based adaptive distribution 5 | 6 | ::: src.pinnde.adaptives.RAD 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/boundaries/periodic.md: -------------------------------------------------------------------------------- 1 | periodic 2 | ---------------- 3 | 4 | Class which is used to implement periodic boundaries 5 | 6 | ::: src.pinnde.boundaries.periodic 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/data/invpinndata.md: -------------------------------------------------------------------------------- 1 | invpinndata 2 | ---------------- 3 | 4 | Class which is used to implement data for inverse PINNs 5 | 6 | ::: src.pinnde.data.invpinndata 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/domain/timedomain.md: -------------------------------------------------------------------------------- 1 | timedomain 2 | ---------------- 3 | 4 | Abstract class which is used to implement timedomains 5 | 6 | ::: src.pinnde.domain.timedomain 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/boundaries/boundaries.md: -------------------------------------------------------------------------------- 1 | boundaries 2 | ---------------- 3 | 4 | Abstract class which is used to implement boundaries 5 | 6 | ::: src.pinnde.boundaries.boundaries 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/boundaries/dirichlet.md: -------------------------------------------------------------------------------- 1 | dirichlet 2 | ---------------- 3 | 4 | Class which is used to implement dirichlet boundaries 5 | 6 | ::: src.pinnde.boundaries.dirichlet 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/domain/NEllipsoid.md: -------------------------------------------------------------------------------- 1 | NEllipsoid 2 | ---------------- 3 | 4 | Class which is used to implement N dimensional ellipsoids. 5 | 6 | ::: src.pinnde.domain.NEllipsoid 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/adaptives/adaptives.md: -------------------------------------------------------------------------------- 1 | adaptives 2 | ---------------- 3 | 4 | Abstract class which is used to implement adaptive strategies 5 | 6 | ::: src.pinnde.adaptives.adaptives 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/initials/initials.md: -------------------------------------------------------------------------------- 1 | initials 2 | ---------------- 3 | 4 | Class which implements initial conditions for equations with time components 5 | 6 | ::: src.pinnde.initials 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/data/timepinndata.md: -------------------------------------------------------------------------------- 1 | timepinndata 2 | ---------------- 3 | 4 | Class which is used to implement data for PINNs with Time components. 5 | 6 | ::: src.pinnde.data.timepinndata 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/adaptives/RARD.md: -------------------------------------------------------------------------------- 1 | RARD 2 | ---------------- 3 | 4 | Class which is used to implement residule-based adaptive refinement with distribution 5 | 6 | ::: src.pinnde.adaptives.RARD 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/boundaries/odeicbc.md: -------------------------------------------------------------------------------- 1 | odeicbc 2 | ---------------- 3 | 4 | Class which is used to implement initial or boundary conditions for ode problems 5 | 6 | ::: src.pinnde.boundaries.odeicbc 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/data/timedondata.md: -------------------------------------------------------------------------------- 1 | timedondata 2 | ---------------- 3 | 4 | Class which is used to implement data for DeepONets (don) with Time components. 5 | 6 | ::: src.pinnde.data.timedondata 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/data/timeinvpinndata.md: -------------------------------------------------------------------------------- 1 | timeinvpinndata 2 | ---------------- 3 | 4 | Class which is used to implement data for inverse PINNs with time components 5 | 6 | ::: src.pinnde.data.timeinvpinndata 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/domain/Time_NRect.md: -------------------------------------------------------------------------------- 1 | Time_NRect 2 | ---------------- 3 | 4 | Class which is used to implement N dimensional Hyperrectangles with Time components. 5 | 6 | ::: src.pinnde.domain.Time_NRect 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/domain/Time_NEllipsoid.md: -------------------------------------------------------------------------------- 1 | Time_NEllipsoid 2 | ---------------- 3 | 4 | Class which is used to implement N dimensional ellipsoids with Time components. 5 | 6 | ::: src.pinnde.domain.Time_NEllipsoid 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/plotters/plotLosses.md: -------------------------------------------------------------------------------- 1 | # plotLosses 2 | 3 | Functions for plotting losses of models. 4 | 5 | ::: src.pinnde.plotters.plotLosses 6 | options: 7 | members_order: source 8 | rendering: 9 | show_root_heading: yes 10 | selection: 11 | members: 12 | - plot_epoch_loss -------------------------------------------------------------------------------- /docs/Legacy/odeSolveClasses/ode_SolveClass.md: -------------------------------------------------------------------------------- 1 | ODE Solve Class 2 | ---------------- 3 | 4 | Class which is returned in solveODE_IVP and solveODE_BVP calls 5 | 6 | ::: src.pinnde.legacy.ODE.SolveClasses.ode_SolveClass 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/Legacy/odeSolveClasses/ode_SystemSolveClass.md: -------------------------------------------------------------------------------- 1 | ODE System Solve Class 2 | ---------------- 3 | 4 | Class which is returned in solveODE_System_IVP calls 5 | 6 | ::: src.pinnde.legacy.ODE.SolveClasses.ode_SystemSolveClass 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/Legacy/pdeSolveClasses/pde_SolveClass_tx.md: -------------------------------------------------------------------------------- 1 | PDE Solve Class for PDE's in t and x 2 | ---------------- 3 | 4 | Class which is returned in solvePDE_tx calls 5 | 6 | ::: src.pinnde.legacy.PDE.SolveClasses.pde_SolveClass_tx 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/Legacy/pdeSolveClasses/pde_SolveClass_xy.md: -------------------------------------------------------------------------------- 1 | PDE Solve Class for PDE's in x and y 2 | ---------------- 3 | 4 | Class which is returned in solvePDE_xy calls 5 | 6 | ::: src.pinnde.legacy.PDE.SolveClasses.pde_SolveClass_xy 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/training/pinnTrainSteps.md: -------------------------------------------------------------------------------- 1 | # pinnTrainSteps 2 | 3 | Training steps for training PINNs. 4 | 5 | ::: src.pinnde.training.pinnTrainSteps 6 | options: 7 | members_order: source 8 | rendering: 9 | show_root_heading: yes 10 | selection: 11 | members: 12 | - trainStep 13 | - trainStepTime -------------------------------------------------------------------------------- /src/pinnde/boundaries/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = [ 2 | "boundaries", 3 | "dirichlet", 4 | "neumann", 5 | "periodic", 6 | "odeicbc" 7 | ] 8 | 9 | from .boundaries import boundaries 10 | from .dirichlet import dirichlet 11 | from .neumann import neumann 12 | from .periodic import periodic 13 | from .odeicbc import odeicbc -------------------------------------------------------------------------------- /docs/training/deeponetTrainSteps.md: -------------------------------------------------------------------------------- 1 | # deeponetTrainSteps 2 | 3 | Training steps for training DeepONets. 4 | 5 | ::: src.pinnde.training.deeponetTrainSteps 6 | options: 7 | members_order: source 8 | rendering: 9 | show_root_heading: yes 10 | selection: 11 | members: 12 | - trainStep 13 | - trainStepTime -------------------------------------------------------------------------------- /docs/training/invpinnTrainSteps.md: -------------------------------------------------------------------------------- 1 | # invpinnTrainSteps 2 | 3 | Training steps for training inverse PINNs. 4 | 5 | ::: src.pinnde.training.invpinnTrainSteps 6 | options: 7 | members_order: source 8 | rendering: 9 | show_root_heading: yes 10 | selection: 11 | members: 12 | - trainStep 13 | - trainStepTime -------------------------------------------------------------------------------- /docs/Legacy/pde_Initials.md: -------------------------------------------------------------------------------- 1 | # pde_Initials 2 | 3 | Main inital functions for setting up initials conditions required in solvePDE calls 4 | 5 | ::: src.pinnde.legacy.pde_Initials 6 | options: 7 | members_order: source 8 | rendering: 9 | show_root_heading: yes 10 | selection: 11 | members: 12 | - setup_initials_2var -------------------------------------------------------------------------------- /docs/Legacy/odeSolveClasses/ode_DeepONetSolveClass.md: -------------------------------------------------------------------------------- 1 | ODE DeepONet Solve Class 2 | ---------------- 3 | 4 | Class which is returned in solveODE_DeepONet_IVP and solveODE_DeepONet_BVP calls 5 | 6 | ::: src.pinnde.legacy.ODE.SolveClasses.ode_DeepONetSolveClass 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/Legacy/odeSolveClasses/ode_SystemDeepONetSolveClass.md: -------------------------------------------------------------------------------- 1 | ODE DeepONet System Solve Class 2 | ---------------- 3 | 4 | Class which is returned in solveODE_DeepONetSystem_IVP calls 5 | 6 | ::: src.pinnde.legacy.ODE.SolveClasses.ode_SystemDeepONetSolveClass 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/Legacy/pdeSolveClasses/pde_DeepONetSolveClass_tx.md: -------------------------------------------------------------------------------- 1 | PDE DeepONet Solve Class for PDE's in t and x 2 | ---------------- 3 | 4 | Class which is returned in solvePDE_DeepONet_tx calls 5 | 6 | ::: src.pinnde.legacy.PDE.SolveClasses.pde_DeepONetSolveClass_tx 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/Legacy/pdeSolveClasses/pde_DeepONetSolveClass_xy.md: -------------------------------------------------------------------------------- 1 | PDE DeepONet Solve Class for PDE's in x and y 2 | ---------------- 3 | 4 | Class which is returned in solvePDE_DeepONet_xy calls 5 | 6 | ::: src.pinnde.legacy.PDE.SolveClasses.pde_DeepONetSolveClass_xy 7 | options: 8 | members_order: source 9 | rendering: 10 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/Legacy/pde_Solvers.md: -------------------------------------------------------------------------------- 1 | # pde_Solvers 2 | 3 | Main solving functions for PDE's 4 | 5 | ::: src.pinnde.legacy.pde_Solvers 6 | options: 7 | members_order: source 8 | rendering: 9 | show_root_heading: yes 10 | selection: 11 | members: 12 | - solvePDE_tx 13 | - solvePDE_xy 14 | - solvePDE_DeepONet_tx 15 | - solvePDE_DeepONet_xy -------------------------------------------------------------------------------- /src/pinnde/domain/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = [ 2 | "domain", 3 | "timedomain", 4 | "NRect", 5 | "Time_NRect", 6 | "NEllipsoid", 7 | "Time_NEllipsoid" 8 | ] 9 | 10 | from .domain import domain 11 | from .timedomain import timedomain 12 | from .NRect import NRect 13 | from .Time_NRect import Time_NRect 14 | from .NEllipsoid import NEllipsoid 15 | from .Time_NEllipsoid import Time_NEllipsoid -------------------------------------------------------------------------------- /src/pinnde/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = [ 2 | "boundaries", 3 | "domain", 4 | "models", 5 | "plotters", 6 | "initials", 7 | "data", 8 | "legacy", 9 | "adaptives" 10 | ] 11 | 12 | from . import boundaries 13 | from . import domain 14 | from . import models 15 | from . import plotters 16 | from . import data 17 | from . import adaptives 18 | 19 | from . import initials 20 | 21 | from . import legacy -------------------------------------------------------------------------------- /src/pinnde/data/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = [ 2 | "pinndata", 3 | "timepinndata", 4 | "dondata", 5 | "timedondata", 6 | "timeinvpinndata", 7 | "invpinndata" 8 | ] 9 | 10 | from .pinndata import pinndata 11 | from .timepinndata import timepinndata 12 | from .dondata import dondata 13 | from .timedondata import timedondata 14 | from .timeinvpinndata import timeinvpinndata 15 | from .invpinndata import invpinndata -------------------------------------------------------------------------------- /docs/InstallSetup.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | This package requires *numpy*, *tensorflow*, *jax/flax/optax*, *matplotlib*, and *pyDOE*. These 4 | are all installed with the package. If version of a package already installed which is above the reqiements 5 | for PinnDE, then currently package won't be upgraded when installed. 6 | 7 | Installing can simply be done with pip in the command line with: 8 | 9 | pip install pinnde 10 | -------------------------------------------------------------------------------- /src/pinnde/plotters/__init__.py: -------------------------------------------------------------------------------- 1 | __all__= [ 2 | "plot_solution_prediction_time2D", 3 | "plot_solution_prediction_time1D", 4 | "plot_solution_prediction_2D", 5 | "plot_epoch_loss", 6 | "plot_solution_prediction_1D" 7 | ] 8 | 9 | from .plotPinnPredictions import plot_solution_prediction_time2D, \ 10 | plot_solution_prediction_2D, plot_solution_prediction_time1D, plot_solution_prediction_1D 11 | from .plotLosses import plot_epoch_loss -------------------------------------------------------------------------------- /docs/tutorials/invpinntutorials/invpinntutorials.md: -------------------------------------------------------------------------------- 1 | # Inverse PINN Tutorials 2 | 3 | Examples for solving differential equations with Inverse PINNs using PinnDE 4 | 5 | ## Spatio-Temporal 6 | 7 | * [Finding 1+1 Linear Advection Speed with periodic boundaries](11advec.md) 8 | * [Finding 1+1 Heat Diffusion with Dirichelt boundaries](11heat.md) 9 | 10 | ## Purely Spatial 11 | 12 | * [2D Poisson equation constant with Dirichlet boundaries](2poisson1.md) -------------------------------------------------------------------------------- /docs/Legacy/ode_Solvers.md: -------------------------------------------------------------------------------- 1 | # ode_Solvers 2 | 3 | Main solving functions for ODE's 4 | 5 | ::: src.pinnde.legacy.ode_Solvers 6 | options: 7 | members_order: source 8 | rendering: 9 | show_root_heading: yes 10 | selection: 11 | members: 12 | - solveODE_IVP 13 | - solveODE_BVP 14 | - solveODE_System_IVP 15 | - solveODE_DeepONet_IVP 16 | - solveODE_DeepONet_BVP 17 | - solveODE_DeepONetSystem_IVP -------------------------------------------------------------------------------- /docs/Legacy/ode_trainingSelect.md: -------------------------------------------------------------------------------- 1 | # ode_trainingSelect 2 | 3 | Functions for selecting what training file specific solveODE call directs too. 4 | 5 | While available to user, not meant to be used. 6 | 7 | ::: src.pinnde.legacy.ODE.ode_trainingSelect 8 | options: 9 | members_order: source 10 | rendering: 11 | show_root_heading: yes 12 | selection: 13 | members: 14 | - PINNtrainSelect_Standard 15 | - PINNtrainSelect_DeepONet -------------------------------------------------------------------------------- /docs/Legacy/ode_Points.md: -------------------------------------------------------------------------------- 1 | # ode_Points 2 | 3 | Functions for generating points for training model. 4 | 5 | While available to user, not meant to be used. Instead interface through 6 | N_pde parameter of solving functions detailed in "Main User Functions". 7 | 8 | ::: src.pinnde.legacy.ODE.ode_Points 9 | options: 10 | members_order: source 11 | rendering: 12 | show_root_heading: yes 13 | selection: 14 | members: 15 | - defineCollocationPoints -------------------------------------------------------------------------------- /docs/plotters/plotPinnPredictions.md: -------------------------------------------------------------------------------- 1 | # plotPinnPredictions 2 | 3 | Functions for plotting predictions of models. 4 | 5 | ::: src.pinnde.plotters.plotPinnPredictions 6 | options: 7 | members_order: source 8 | rendering: 9 | show_root_heading: yes 10 | selection: 11 | members: 12 | - plot_solution_prediction_1D 13 | - plot_solution_prediction_time1D 14 | - plot_solution_prediction_2D 15 | - plot_solution_prediction_time2D -------------------------------------------------------------------------------- /docs/cite.md: -------------------------------------------------------------------------------- 1 | # Citing 2 | 3 | If PinnDE is used in academic research, please cite the paper found [here](https://arxiv.org/abs/2408.10011), 4 | or with the corresponding BibTex citation 5 | 6 | @article{matthews2024pinnde, 7 | title={PinnDE: Physics-Informed Neural Networks for Solving Differential Equations}, 8 | author={Matthews, Jason and Bihlo, Alex}, 9 | journal={arXiv preprint arXiv:2408.10011}, 10 | year={2024} 11 | } 12 | -------------------------------------------------------------------------------- /docs/Legacy/pde_ParamChecks.md: -------------------------------------------------------------------------------- 1 | # pde_ParamChecks 2 | 3 | Functions for checking parameters of PDE solvers. 4 | 5 | While available to user, not meant to be used. 6 | 7 | ::: src.pinnde.legacy.PDE.pde_ParamChecks 8 | options: 9 | members_order: source 10 | rendering: 11 | show_root_heading: yes 12 | selection: 13 | members: 14 | - solvePDE_tx_ParamCheck 15 | - solvePDE_xy_ParamChecks 16 | - solvePDE_DeepONet_tx_ParamChecks 17 | - solvePDE_DeepONet_xy_ParamChecks 18 | -------------------------------------------------------------------------------- /docs/Legacy/pde_trainingSelect_2var.md: -------------------------------------------------------------------------------- 1 | # pde_trainingSelect_2var 2 | 3 | Functions for selecting what training file specific solvePDE call directs too. 4 | 5 | While available to user, not meant to be used. 6 | 7 | ::: src.pinnde.legacy.PDE.TrainingSelects.pde_trainingSelect_2var 8 | options: 9 | members: 10 | - PINNtrainSelect_tx 11 | - PINNtrainSelect_xy 12 | - PINNtrainSelect_DeepONet_tx 13 | - PINNtrainSelect_DeepONet_xy 14 | rendering: 15 | show_root_heading: yes -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # Read the Docs configuration file for MkDocs projects 2 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 3 | 4 | # Required 5 | version: 2 6 | 7 | # Set the version of Python and other tools you might need 8 | build: 9 | os: ubuntu-22.04 10 | tools: 11 | python: "3.12" 12 | 13 | mkdocs: 14 | configuration: mkdocs.yml 15 | 16 | # Optionally declare the Python requirements required to build your docs 17 | python: 18 | install: 19 | - requirements: requirements.txt -------------------------------------------------------------------------------- /docs/Legacy/pde_Points.md: -------------------------------------------------------------------------------- 1 | # pde_Points 2 | 3 | Functions for generating points for training model. 4 | 5 | While available to user, not meant to be used. Instead interface through 6 | N_pde, N_iv, N_sensors, sensor_range, and N_bc parameters of solving and boundary 7 | functions detailed in "Main User Functions". 8 | 9 | ::: src.pinnde.legacy.PDE.pde_Points 10 | rendering: 11 | show_root_heading: yes 12 | selection: 13 | members: 14 | - defineCollocationPoints_2var 15 | - defineCollocationPoints_DON_2var -------------------------------------------------------------------------------- /docs/javascripts/mathjax.js: -------------------------------------------------------------------------------- 1 | window.MathJax = { 2 | tex: { 3 | inlineMath: [["\\(", "\\)"]], 4 | displayMath: [["\\[", "\\]"]], 5 | processEscapes: true, 6 | processEnvironments: true 7 | }, 8 | options: { 9 | ignoreHtmlClass: ".*|", 10 | processHtmlClass: "arithmatex" 11 | } 12 | }; 13 | 14 | document$.subscribe(() => { 15 | MathJax.startup.output.clearCache() 16 | MathJax.typesetClear() 17 | MathJax.texReset() 18 | MathJax.typesetPromise() 19 | }) -------------------------------------------------------------------------------- /docs/Legacy/ode_TimeSteppersDeepONet.md: -------------------------------------------------------------------------------- 1 | # ode_TimeSteppersDeepONet 2 | 3 | Functions for time stepping a model trained with a DeepONet. Can only be done to hard constrainted IVPs. 4 | 5 | While available to user, not meant to be used. Instead interface through ode_DeepONetSolveClass 6 | or ode_SystemDeepONetSolveClass that are returned from solveODE_DeepONet calls. 7 | 8 | ::: src.pinnde.legacy.ODE.ode_TimeSteppersDeepONet 9 | options: 10 | members_order: source 11 | rendering: 12 | show_root_heading: yes 13 | selection: 14 | members: -------------------------------------------------------------------------------- /src/pinnde/selectors/adaptSampleSelector.py: -------------------------------------------------------------------------------- 1 | from ..data import pinndata, dondata, invpinndata 2 | 3 | def adaptSampleSelector(model, clps_group, data): 4 | if isinstance(data, pinndata): 5 | return model(clps_group) 6 | elif isinstance(data, dondata): 7 | usensors = data.generate_sensors() 8 | clps_group.append(usensors) 9 | return model(clps_group) 10 | elif isinstance(data, invpinndata): 11 | return model(clps_group)[0] 12 | 13 | raise TypeError("data passed not a valid type, please check for error internally") -------------------------------------------------------------------------------- /docs/team.md: -------------------------------------------------------------------------------- 1 | # Team 2 | 3 | PinnDE was developed by [Jason Matthews](https://github.com/JB55Matthews) with the support and oversight of 4 | [Dr. Alex Bihlo](https://www.math.mun.ca/~abihlo/#top) at [Memorial University](https://mun.ca/) 5 | from the summer of 2024 contininuing. Many examples of code for singular equations was provided by Dr. Alex Bihlo, and Jason Matthews designed, generalized, and implemented PinnDE himself. This project was supported by funding from Dr. Alex Bihlo through 6 | the [Department of Mathematics and Statistics](https://www.mun.ca/math/) at Memorial Univeristy -------------------------------------------------------------------------------- /docs/Legacy/pde_Boundaries_2var.md: -------------------------------------------------------------------------------- 1 | # pde_Boundaries_2var 2 | 3 | Main boundary functions for setting up boundaries required in solvePDE calls 4 | 5 | ::: src.pinnde.legacy.pde_Boundaries_2var 6 | options: 7 | members_order: source 8 | rendering: 9 | show_root_heading: yes 10 | selection: 11 | members: 12 | - setup_boundaries_periodic_tx 13 | - setup_boundaries_periodic_xy 14 | - setup_boundaries_dirichlet_tx 15 | - setup_boundaries_dirichlet_xy 16 | - setup_boundaries_neumann_tx 17 | - setup_boundaries_neumann_xy -------------------------------------------------------------------------------- /docs/training/lbfgsTrainSteps.md: -------------------------------------------------------------------------------- 1 | # lbfgsTrainSteps 2 | 3 | Training step and functions for training with the L-BFGS optimizer. 4 | 5 | This is implementation was adapted from a method for using L-BFGS in learning to function 6 | match with a keras sequential network, developed by [Pi-Yueh Chuang](https://gist.github.com/piyueh). 7 | 8 | ::: src.pinnde.training.lbfgsTrainSteps 9 | options: 10 | members_order: source 11 | rendering: 12 | show_root_heading: yes 13 | selection: 14 | members: 15 | - value_and_gradients_generator 16 | - lbfgsTrain -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining/BVP_Training/ode_TrainingBVP_soft.md: -------------------------------------------------------------------------------- 1 | # ode_TrainingBVP_soft 2 | 3 | Functions which trains a model for solving a solveODE_BVP call with soft constraints implemented in TensorFlow. 4 | 5 | While available to user, not meant to be used. Meant to be used through 6 | object returned from solveODE calls, where training file is selected through ode_trainingSelect 7 | 8 | ::: src.pinnde.legacy.ODE.SpecificTraining.BVP_Training.ode_TrainingBVP_soft 9 | rendering: 10 | show_root_heading: yes 11 | selection: 12 | members: 13 | - PINNtrain_IVP 14 | - train_network_BVP -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining/IVP_Training/ode_TrainingIVP_soft.md: -------------------------------------------------------------------------------- 1 | # ode_TrainingIVP_soft 2 | 3 | Functions which trains a model for solving a solveODE_IVP call with soft constraints implemented in TensorFlow. 4 | 5 | While available to user, not meant to be used. Meant to be used through 6 | object returned from solveODE calls, where training file is selected through ode_trainingSelect 7 | 8 | ::: src.pinnde.legacy.ODE.SpecificTraining.IVP_Training.ode_TrainingIVP_soft 9 | rendering: 10 | show_root_heading: yes 11 | selection: 12 | members: 13 | - PINNtrain_IVP 14 | - train_network_general_IVP -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining/BVP_Training/ode_TrainingBVP_Hard.md: -------------------------------------------------------------------------------- 1 | # ode_TrainingBVP_Hard 2 | 3 | Functions which trains a model for solving a solveODE_BVP call with hard constraints implemented in TensorFlow. 4 | 5 | While available to user, not meant to be used. Meant to be used through 6 | object returned from solveODE calls, where training file is selected through ode_trainingSelect 7 | 8 | ::: src.pinnde.legacy.ODE.SpecificTraining.BVP_Training.ode_TrainingBVP_Hard 9 | rendering: 10 | show_root_heading: yes 11 | selection: 12 | members: 13 | - PINNtrain_IVP_Hard 14 | - train_network_BVP_Hard -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining/IVP_Training/ode_TrainingIVP_hard.md: -------------------------------------------------------------------------------- 1 | # ode_TrainingIVP_Hard 2 | 3 | Functions which trains a model for solving a solveODE_IVP call with hard constraints implemented in TensorFlow. 4 | 5 | While available to user, not meant to be used. Meant to be used through 6 | object returned from solveODE calls, where training file is selected through ode_trainingSelect 7 | 8 | ::: src.pinnde.legacy.ODE.SpecificTraining.IVP_Training.ode_TrainingIVP_Hard 9 | rendering: 10 | show_root_heading: yes 11 | selection: 12 | members: 13 | - PINNtrain_IVP_Hard 14 | - train_network_IVP_Hard -------------------------------------------------------------------------------- /docs/Legacy/ode_ParamChecks.md: -------------------------------------------------------------------------------- 1 | # ode_ParamChecks 2 | 3 | Functions for checking parameters of ODE solvers. 4 | 5 | While available to user, not meant to be used. 6 | 7 | ::: src.pinnde.legacy.ODE.ode_ParamChecks 8 | options: 9 | members_order: source 10 | rendering: 11 | show_root_heading: yes 12 | selection: 13 | members: 14 | - solveODE_IVP_ParamChecks 15 | - solveODE_BVP_ParamChecks 16 | - solveODE_System_IVP_ParamChecks 17 | - solveODE_DeepONet_IVP_ParamChecks 18 | - solveODE_DeepONet_BVP_ParamChecks 19 | - solveODE_DeepONetSystem_IVP_ParamChecks 20 | -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining_2var/tx_Training/pde_TrainingICBCP_hard.md: -------------------------------------------------------------------------------- 1 | # pde_TrainingICBCP_hard 2 | 3 | Functions which trains a model for solving a solvePDE_tx call with hard constraints implemented in TensorFlow. 4 | 5 | While available to user, not meant to be used. Meant to be used through 6 | object returned from solvePDE calls, where training file is selected through pde_trainingSelects.PINNtrainSelect_tx() 7 | 8 | ::: src.pinnde.legacy.PDE.SpecificTraining.training_2variables.ICBCP_Training.pde_TrainingICBCP_hard 9 | rendering: 10 | show_root_heading: yes 11 | selection: 12 | members: 13 | - PINNtrain 14 | - trainStep -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining_2var/xy_Training/pde_TrainingBCP_periodic.md: -------------------------------------------------------------------------------- 1 | # pde_TrainingBCP_periodic 2 | 3 | Functions which trains a model for solving a solvePDE_xy call with periodic boundaries implemented in TensorFlow. 4 | 5 | While available to user, not meant to be used. Meant to be used through 6 | object returned from solvePDE calls, where training file is selected through pde_trainingSelects.PINNtrainSelect_xy() 7 | 8 | ::: src.pinnde.legacy.PDE.SpecificTraining.training_2variables.BCP_Training.pde_TrainingBCP_periodic 9 | rendering: 10 | show_root_heading: yes 11 | selection: 12 | members: 13 | - PINNtrain 14 | - trainStep -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining/IVP_Training/ode_Training2SystemIVP_soft.md: -------------------------------------------------------------------------------- 1 | # ode_Training2SystemIVP_soft 2 | 3 | Functions which trains a model for solving a solveODE_System_IVP call with 2 equations and soft constraints implemented in TensorFlow. 4 | 5 | While available to user, not meant to be used. Meant to be used through 6 | object returned from solveODE calls, where training file is selected through ode_trainingSelect 7 | 8 | ::: src.pinnde.legacy.ODE.SpecificTraining.IVP_Training.ode_Training2SystemIVP_soft 9 | rendering: 10 | show_root_heading: yes 11 | selection: 12 | members: 13 | - PINNtrain_2System_IVP 14 | - train_network_2system_IVP -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining/IVP_Training/ode_Training3SystemIVP_soft.md: -------------------------------------------------------------------------------- 1 | # ode_Training3SystemIVP_soft 2 | 3 | Functions which trains a model for solving a solveODE_System_IVP call with 3 equations and soft constraints implemented in TensorFlow. 4 | 5 | While available to user, not meant to be used. Meant to be used through 6 | object returned from solveODE calls, where training file is selected through ode_trainingSelect 7 | 8 | ::: src.pinnde.legacy.ODE.SpecificTraining.IVP_Training.ode_Training3SystemIVP_soft 9 | rendering: 10 | show_root_heading: yes 11 | selection: 12 | members: 13 | - PINNtrain_3System_IVP 14 | - train_network_3system_IVP -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining_2var/xy_Training/pde_TrainingBCP_neumann_soft.md: -------------------------------------------------------------------------------- 1 | # pde_TrainingBCP_neumann_soft 2 | 3 | Functions which trains a model for solving a solvePDE_xy call with neumann boundaries and soft constraints implemented in TensorFlow. 4 | 5 | While available to user, not meant to be used. Meant to be used through 6 | object returned from solvePDE calls, where training file is selected through pde_trainingSelects.PINNtrainSelect_xy() 7 | 8 | ::: src.pinnde.legacy.PDE.SpecificTraining.training_2variables.BCP_Training.pde_TrainingBCP_neumann_soft 9 | rendering: 10 | show_root_heading: yes 11 | selection: 12 | members: 13 | - PINNtrain 14 | - trainStep -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining_2var/tx_Training/pde_TrainingICBCP_neumann_soft.md: -------------------------------------------------------------------------------- 1 | # pde_TrainingICBCP_neumann_soft 2 | 3 | Functions which trains a model for solving a solvePDE_tx call with neumann boundaries and soft constraints implemented in TensorFlow. 4 | 5 | While available to user, not meant to be used. Meant to be used through 6 | object returned from solvePDE calls, where training file is selected through pde_trainingSelects.PINNtrainSelect_tx() 7 | 8 | ::: src.pinnde.legacy.PDE.SpecificTraining.training_2variables.ICBCP_Training.pde_TrainingICBCP_neumann_soft 9 | rendering: 10 | show_root_heading: yes 11 | selection: 12 | members: 13 | - PINNtrain 14 | - trainStep -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining_2var/xy_Training/pde_TrainingBCP_dirichlet_hard.md: -------------------------------------------------------------------------------- 1 | # pde_TrainingBCP_dirichlet_hard 2 | 3 | Functions which trains a model for solving a solvePDE_xy call with dirichlet boundaries and hard constraints implemented in TensorFlow. 4 | 5 | While available to user, not meant to be used. Meant to be used through 6 | object returned from solvePDE calls, where training file is selected through pde_trainingSelects.PINNtrainSelect_xy() 7 | 8 | ::: src.pinnde.legacy.PDE.SpecificTraining.training_2variables.BCP_Training.pde_TrainingBCP_dirichlet_hard 9 | rendering: 10 | show_root_heading: yes 11 | selection: 12 | members: 13 | - PINNtrain 14 | - trainStep -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining_2var/xy_Training/pde_TrainingBCP_dirichlet_soft.md: -------------------------------------------------------------------------------- 1 | # pde_TrainingBCP_dirichlet_soft 2 | 3 | Functions which trains a model for solving a solvePDE_xy call with dirichlet boundaries and soft constraints implemented in TensorFlow. 4 | 5 | While available to user, not meant to be used. Meant to be used through 6 | object returned from solvePDE calls, where training file is selected through pde_trainingSelects.PINNtrainSelect_xy() 7 | 8 | ::: src.pinnde.legacy.PDE.SpecificTraining.training_2variables.BCP_Training.pde_TrainingBCP_dirichlet_soft 9 | rendering: 10 | show_root_heading: yes 11 | selection: 12 | members: 13 | - PINNtrain 14 | - trainStep -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining_2var/tx_Training/pde_TrainingICBCP_periodic_soft.md: -------------------------------------------------------------------------------- 1 | # pde_TrainingICBCP_periodic_soft 2 | 3 | Functions which trains a model for solving a solvePDE_tx call with periodic boundaries and soft constraints implemented in TensorFlow. 4 | 5 | While available to user, not meant to be used. Meant to be used through 6 | object returned from solvePDE calls, where training file is selected through pde_trainingSelects.PINNtrainSelect_tx() 7 | 8 | ::: src.pinnde.legacy.PDE.SpecificTraining.training_2variables.ICBCP_Training.pde_TrainingICBCP_periodic_soft 9 | rendering: 10 | show_root_heading: yes 11 | selection: 12 | members: 13 | - PINNtrain 14 | - trainStep -------------------------------------------------------------------------------- /joss/paper.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'PinnDE: Physics-Informed Neural Networks for Differential Equations' 3 | tags: 4 | - python 5 | - deep learning 6 | - physics-informed neural networks 7 | - deep operator networks 8 | - scientific machine learning 9 | - differential equations 10 | authors: 11 | - name: Jason Matthews 12 | orcid: 0009-0002-2020-2278 13 | affiliation: "1" 14 | - name: Alex Bihlo 15 | orcid: 0000-0000-0000-0000 16 | affiliation: "1" 17 | affiliations: 18 | - name: Department of Mathematics and Statistics, Memorial University of Newfoundland 19 | - index: 1 20 | date: 15 August 2024 21 | bibliography: paper.bib 22 | --- 23 | 24 | # Introduction 25 | Deep learning 26 | -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining_2var/tx_Training/pde_TrainingICBCP_dirichlet_soft.md: -------------------------------------------------------------------------------- 1 | # pde_TrainingICBCP_dirichlet_soft 2 | 3 | Functions which trains a model for solving a solvePDE_tx call with dirichlet boundaries and soft constraints implemented in TensorFlow. 4 | 5 | While available to user, not meant to be used. Meant to be used through 6 | object returned from solvePDE calls, where training file is selected through pde_trainingSelects.PINNtrainSelect_tx() 7 | 8 | ::: src.pinnde.legacy.PDE.SpecificTraining.training_2variables.ICBCP_Training.pde_TrainingICBCP_dirichlet_soft 9 | rendering: 10 | show_root_heading: yes 11 | selection: 12 | members: 13 | - PINNtrain 14 | - trainStep -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining_2var/xy_DeepONet_Training/pde_TrainingDeepONetBCP_neumann_soft.md: -------------------------------------------------------------------------------- 1 | # pde_TrainingDeepONetBCP_neumann_soft 2 | 3 | Functions which trains a model for solving a solvePDE_DeepONet_xy call with neumann boundaries and soft constraints implemented in TensorFlow. 4 | 5 | While available to user, not meant to be used. Meant to be used through 6 | object returned from solvePDE calls, where training file is selected through pde_trainingSelects.PINNtrainSelect_DeepONet_xy() 7 | 8 | ::: src.pinnde.legacy.PDE.SpecificTraining.DeepONetTraining_2variables.DeepONet_BCP.pde_TrainingDeepONetBCP_neumann_soft 9 | rendering: 10 | show_root_heading: yes 11 | selection: 12 | members: 13 | - train 14 | - train_network -------------------------------------------------------------------------------- /src/pinnde/legacy/ODE/ode_Points.py: -------------------------------------------------------------------------------- 1 | from pyDOE import lhs 2 | 3 | #will be more useful file in future when constructing adapative point selection 4 | 5 | def defineCollocationPoints(t_bdry, N_pde): 6 | """ 7 | Function which generates collocation points along t. 8 | 9 | Args: 10 | t_bdry (list): list of two elements, the interval of t to be solved on. 11 | N_pde (int): Number of randomly sampled collocation points along t which PINN uses in training. 12 | 13 | Returns: 14 | ode_points (list): randomly and evenly sampled points along t, using pyDOE's lhs function 15 | 16 | """ 17 | 18 | # Sample points where to evaluate the PDE 19 | ode_points = t_bdry[0] + (t_bdry[1] - t_bdry[0])*lhs(1, N_pde) 20 | 21 | return ode_points -------------------------------------------------------------------------------- /src/pinnde/plotters/plotLosses.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as plt 3 | from ..domain import NRect 4 | 5 | def plot_epoch_loss(model): 6 | """ 7 | Plots epoch loss for a trained model. 8 | 9 | Args: 10 | model (model): Model which has been trained 11 | """ 12 | plt.figure() 13 | plt.semilogy(np.linspace(1, model.get_epochs(), model.get_epochs()),model.get_epoch_loss()) 14 | plt.grid() 15 | plt.xlabel('epochs') 16 | plt.ylabel('loss') 17 | plt.title("Epoch loss") 18 | if (isinstance(model.get_domain(), NRect) and (model.get_domain().get_dim() == 1)): 19 | plt.savefig("ODE-epoch-loss") 20 | else: 21 | plt.savefig("PDE-epoch-loss") 22 | plt.clf() 23 | return -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining_2var/tx_DeepONet_Training/pde_TrainingDeepONetICBCP_neumann_soft.md: -------------------------------------------------------------------------------- 1 | # pde_TrainingDeepONetICBCP_neumann_soft 2 | 3 | Functions which trains a model for solving a solvePDE_DeepONet_tx call with neuman boundaries and soft constraint implemented in TensorFlow. 4 | 5 | While available to user, not meant to be used. Meant to be used through 6 | object returned from solvePDE calls, where training file is selected through pde_trainingSelects.PINNtrainSelect_DeepONet_tx() 7 | 8 | ::: src.pinnde.legacy.PDE.SpecificTraining.DeepONetTraining_2variables.DeepONet_ICBCP.pde_TrainingDeepONetICBCP_neumann_soft 9 | rendering: 10 | show_root_heading: yes 11 | selection: 12 | members: 13 | - train 14 | - train_network -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining_2var/xy_DeepONet_Training/pde_TrainingDeepONetBCP_dirichlet_soft.md: -------------------------------------------------------------------------------- 1 | # pde_TrainingDeepONetBCP_dirichlet_soft 2 | 3 | Functions which trains a model for solving a solvePDE_DeepONet_xy call with dirichlet boundaries and soft constraints implemented in TensorFlow. 4 | 5 | While available to user, not meant to be used. Meant to be used through 6 | object returned from solvePDE calls, where training file is selected through pde_trainingSelects.PINNtrainSelect_DeepONet_xy() 7 | 8 | ::: src.pinnde.legacy.PDE.SpecificTraining.DeepONetTraining_2variables.DeepONet_BCP.pde_TrainingDeepONetBCP_dirichlet_soft 9 | rendering: 10 | show_root_heading: yes 11 | selection: 12 | members: 13 | - train 14 | - train_network -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining_2var/tx_DeepONet_Training/pde_TrainingDeepONetICBCP_dirichlet_soft.md: -------------------------------------------------------------------------------- 1 | # pde_TrainingDeepONetICBCP_dirichlet_soft 2 | 3 | Functions which trains a model for solving a solvePDE_DeepONet_tx call with dirichlet boundaries and soft constraint implemented in TensorFlow. 4 | 5 | While available to user, not meant to be used. Meant to be used through 6 | object returned from solvePDE calls, where training file is selected through pde_trainingSelects.PINNtrainSelect_DeepONet_tx() 7 | 8 | ::: src.pinnde.legacy.PDE.SpecificTraining.DeepONetTraining_2variables.DeepONet_ICBCP.pde_TrainingDeepONetICBCP_dirichlet_soft 9 | rendering: 10 | show_root_heading: yes 11 | selection: 12 | members: 13 | - train 14 | - train_network -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining_2var/tx_DeepONet_Training/pde_TrainingDeepONetICBCP_periodic_hard.md: -------------------------------------------------------------------------------- 1 | # pde_TrainingDeepONetICBCP_periodic_hard 2 | 3 | Functions which trains a model for solving a solvePDE_DeepONet_tx call with periodic boundaries and hard constraint implemented in TensorFlow. 4 | 5 | While available to user, not meant to be used. Meant to be used through 6 | object returned from solvePDE calls, where training file is selected through pde_trainingSelects.PINNtrainSelect_DeepONet_tx() 7 | 8 | ::: src.pinnde.legacy.PDE.SpecificTraining.DeepONetTraining_2variables.DeepONet_ICBCP.pde_TrainingDeepONetICBCP_periodic_hard 9 | rendering: 10 | show_root_heading: yes 11 | selection: 12 | members: 13 | - train 14 | - train_network -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining_2var/tx_DeepONet_Training/pde_TrainingDeepONetICBCP_periodic_soft.md: -------------------------------------------------------------------------------- 1 | # pde_TrainingDeepONetICBCP_periodic_soft 2 | 3 | Functions which trains a model for solving a solvePDE_DeepONet_tx call with periodic boundaries and soft constraint implemented in TensorFlow. 4 | 5 | While available to user, not meant to be used. Meant to be used through 6 | object returned from solvePDE calls, where training file is selected through pde_trainingSelects.PINNtrainSelect_DeepONet_tx() 7 | 8 | ::: src.pinnde.legacy.PDE.SpecificTraining.DeepONetTraining_2variables.DeepONet_ICBCP.pde_TrainingDeepONetICBCP_periodic_soft 9 | rendering: 10 | show_root_heading: yes 11 | selection: 12 | members: 13 | - train 14 | - train_network -------------------------------------------------------------------------------- /docs/tutorials/deeponettutorials/deeponettutorials.md: -------------------------------------------------------------------------------- 1 | # DeepONet Tutorials 2 | 3 | Examples for solving differential equations with DeepONets using PinnDE 4 | 5 | ## Spatio-Temporal 6 | 7 | * [1+2 Heat equation over unit circle with Dirichelt boundaries](12heatcircle.md) 8 | * [1+1 Linear Advection equation with periodic boundaries, specifying PINN architecture](11advec.md) 9 | * [1+1 Klein-Gordon equation with Dirichlet boundaries](11kg.md) 10 | * [1+1 Burger equation with periodic boundaries](11burg.md) 11 | 12 | ## Purely Spatial 13 | 14 | * [2D Poisson equation (#1) with Dirichlet boundaries with L-BFGS Optimization](2poisson1.md) 15 | * [ODE with initial values](ode.md) 16 | * [2D Helmholtz equation with Dirichlet boundaries](2helmholtz.md) 17 | * [2D Poisson equation (#2) with Dirichlet boundaries](2poisson2.md) -------------------------------------------------------------------------------- /docs/tutorials/pinntutorials/pinntutorials.md: -------------------------------------------------------------------------------- 1 | # PINN Tutorials 2 | 3 | Examples for solving differential equations with PINNs using PinnDE 4 | 5 | ## Spatio-Temporal 6 | 7 | * [1+2 Heat equation over unit circle with Dirichelt boundaries](12heatcircle.md) 8 | * [1+1 Linear Advection equation with periodic boundaries, specifying PINN architecture](11advec.md) 9 | * [1+1 Klein-Gordon equation with Dirichlet boundaries](11kg.md) 10 | * [1+1 System of Equations (Advection and Burgers)](11sys.md) 11 | 12 | ## Purely Spatial 13 | 14 | * [2D Poisson equation (#1) with Dirichlet boundaries with L-BFGS Optimization](2poisson1.md) 15 | * [System of ODEs with initial values](odesys.md) 16 | * [2D Helmholtz equation with Dirichlet boundaries](2helmholtz.md) 17 | * [2D Poisson equation (#2) with Dirichlet boundaries](2poisson2.md) -------------------------------------------------------------------------------- /src/pinnde/adaptives/adaptives.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | class adaptives(ABC): 4 | """ 5 | Abstract class for adaptive point strategies 6 | """ 7 | 8 | @abstractmethod 9 | def AdaptiveStrategy(self, model, domain, data, clps, ds_data, ds, i): 10 | """ 11 | Sampling stategy to call 12 | 13 | Args: 14 | model (network): Tensorflow network. 15 | domain (domain): Domain class solving over. 16 | data (data): Data classs olving with. 17 | clps (tensor): Current collocation points. 18 | ds_data (list): Data being packaged in training routine. 19 | ds (list): Current ds value of training routine. 20 | i (int): Iteration number. 21 | 22 | """ 23 | return -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining_2var/xy_DeepONet_Training/pde_TrainingDeepONetBCP_hard.md: -------------------------------------------------------------------------------- 1 | # pde_TrainingDeepONetBCP_hard 2 | 3 | Functions which trains a model for solving a solvePDE_DeepONet_xy call with dirichlet boundaries and hard constraints, and 4 | periodic boundaries with both soft and hard constraints (as there is no difference), implemented in TensorFlow. 5 | 6 | While available to user, not meant to be used. Meant to be used through 7 | object returned from solvePDE calls, where training file is selected through pde_trainingSelects.PINNtrainSelect_DeepONet_xy() 8 | 9 | ::: src.pinnde.legacy.PDE.SpecificTraining.DeepONetTraining_2variables.DeepONet_BCP.pde_TrainingDeepONetBCP_hard 10 | rendering: 11 | show_root_heading: yes 12 | selection: 13 | members: 14 | - train 15 | - train_network -------------------------------------------------------------------------------- /src/pinnde/selectors/pinnSelectors.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | 3 | FUNCTION_REGISTRY = {} 4 | 5 | def register(key): 6 | def decorator(func): 7 | FUNCTION_REGISTRY[key] = func 8 | return func 9 | return decorator 10 | 11 | @register("hard") 12 | def isHardConstrained(): 13 | return True 14 | 15 | @register("soft") 16 | def isHardConstrained(): 17 | return False 18 | 19 | @register("adam") 20 | def adam(lr): 21 | return tf.keras.optimizers.Adam(lr) 22 | 23 | @register("adagrad") 24 | def adagrad(lr): 25 | return tf.kerars.optimizers.Adagrad(lr) 26 | 27 | @register("sgd") 28 | def sgd(lr): 29 | return tf.keras.optimizers.SGD(lr) 30 | 31 | @register("rmsprop") 32 | def rmsprop(lr): 33 | return tf.keras.optimizers.RMSprop(lr) 34 | 35 | def pinnSelector(key): 36 | return FUNCTION_REGISTRY.get(key, lambda: print("Invalid key")) -------------------------------------------------------------------------------- /src/pinnde/boundaries/periodic.py: -------------------------------------------------------------------------------- 1 | from .boundaries import boundaries 2 | import numpy as np 3 | 4 | class periodic(boundaries): 5 | """ 6 | Class implementing periodic boundary conditions. 7 | """ 8 | 9 | def __init__(self, domain): 10 | """ 11 | Constructor for class 12 | 13 | Args: 14 | domain (domain): Domain for boundary to act on. 15 | """ 16 | 17 | super().__init__(domain, 1) 18 | return 19 | 20 | def boundaryPoints(self, n_bc): 21 | """ 22 | Samples boundary of domain, and computes zero-value boundary points as this is ignored in training. 23 | 24 | Args: 25 | n_bc (int): Number of boundary conditions to use. 26 | 27 | Returns: 28 | (tensor): Boundary points. 29 | """ 30 | sampled_boundary = self._domain.sampleBoundary(n_bc) 31 | sampled_boundary[:] = 0 32 | return sampled_boundary -------------------------------------------------------------------------------- /docs/Legacy/ode_ModelFuncs.md: -------------------------------------------------------------------------------- 1 | # ode_ModelFuncs 2 | 3 | Functions for creating PINN's in ODE solvers. 4 | 5 | While available to user, not meant to be used. Instead interface through 6 | net_layers, net_units, and constraint parameters of solving functions detailed 7 | in "Main User Functions". 8 | 9 | ::: src.pinnde.legacy.ODE.ode_ModelFuncs 10 | options: 11 | members_order: source 12 | rendering: 13 | show_root_heading: yes 14 | selection: 15 | members: 16 | - build_model 17 | - build_model_hardConstraint_order1_IVP 18 | - build_model_hardConstraint_order2_IVP 19 | - build_model_hardConstraint_order3_IVP 20 | - build_model_hardConstraint_order4_IVP 21 | - build_model_hardConstraint_order5_IVP 22 | - build_model_hardConstraint_order12_BVP 23 | - build_model_hardConstraint_order3_BVP 24 | - build_model_system2_IVP 25 | - build_model_system3_IVP -------------------------------------------------------------------------------- /docs/Legacy/pde_Plotters.md: -------------------------------------------------------------------------------- 1 | # pde_Plotters 2 | 3 | Functions for plotting data in PDE solution classes. 4 | 5 | While available to user, not meant to be used. Meant to be used through 6 | object returned from solvePDE calls, then calling plotting function of object 7 | calls plotting functions with correct data. See examples for how this is done. 8 | 9 | We encourage users to plot data by getting data from object (epoch loss, solution prediciton, 10 | etc.), and then making specific plots for each problem. These provide quick, easy to visualize 11 | plots of data from model available from solving function. 12 | 13 | 14 | ::: src.pinnde.legacy.PDE.pde_Plotters 15 | options: 16 | members_order: source 17 | rendering: 18 | show_root_heading: yes 19 | selection: 20 | members: 21 | - plot_solution_prediction 22 | - plot_epoch_loss 23 | - plot_iv_loss 24 | - plot_bc_loss 25 | - plot_pde_loss 26 | - plot_all_losses 27 | - plot_3D 28 | - plot_predicted_exact -------------------------------------------------------------------------------- /src/pinnde/data/data.py: -------------------------------------------------------------------------------- 1 | 2 | class data(): 3 | """ 4 | Class for implementing data 5 | """ 6 | 7 | def __init__(self, type): 8 | """ 9 | Constructor for class 10 | 11 | Args: 12 | type (int): Internal type int of data. 13 | """ 14 | self._data_type = type 15 | return 16 | 17 | def get_data_type(self): 18 | """ 19 | Returns: 20 | (int): Data type. 21 | """ 22 | return self._data_type 23 | 24 | def set_data_type(self, type): 25 | """ 26 | Args: 27 | type (int): Data type. 28 | """ 29 | self._data_type = type 30 | 31 | def set_clp(self, clp): 32 | """ 33 | Args: 34 | clp (tensor): New collocation points. 35 | """ 36 | self._clp = clp 37 | 38 | def set_n_clp(self, n_clp): 39 | """ 40 | Args: 41 | n_clp (tensor): New number of collocation points. 42 | """ 43 | self._n_clp = n_clp -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools>=65.0"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | name = "pinnde" 7 | version = "1.2.0" 8 | dependencies = [ 9 | "tensorflow >= 2.18.0", 10 | "tensorflow_probability >= 0.25.0", 11 | "tf_keras >= 2.18.0", 12 | "numpy", 13 | "pyDOE", 14 | "matplotlib", 15 | "jax >= 0.7.0", 16 | "flax >= 0.11.1", 17 | "optax >= 0.2.2" 18 | 19 | ] 20 | authors = [ 21 | { name="Jason Matthews", email = "jbmatthews@mun.ca"}, 22 | ] 23 | description = "A library for solving differential equations with PINNs and DeepONets" 24 | readme = "README.md" 25 | license = {file = "LICENSE.txt"} 26 | requires-python = ">=3.10.12" 27 | classifiers = [ 28 | "Programming Language :: Python :: 3", 29 | "License :: OSI Approved :: GNU Lesser General Public License v2 (LGPLv2)", 30 | "Topic :: Scientific/Engineering", 31 | "Topic :: Scientific/Engineering :: Artificial Intelligence", 32 | "Topic :: Scientific/Engineering :: Mathematics", 33 | ] 34 | -------------------------------------------------------------------------------- /docs/Legacy/ode_Plotters.md: -------------------------------------------------------------------------------- 1 | # ode_Plotters 2 | 3 | Functions for plotting data in ODE solution classes. 4 | 5 | While available to user, not meant to be used. Meant to be used through 6 | object returned from solveODE calls, then calling plotting function of object 7 | calls plotting functions with correct data. See examples for how this is done. 8 | 9 | We encourage users to plot data by getting data from object (epoch loss, solution prediciton, 10 | etc.), and then making specific plots for each problem. These provide quick, easy to visualize 11 | plots of data from model available from solving function. 12 | 13 | 14 | ::: src.pinnde.legacy.ODE.ode_Plotters 15 | options: 16 | members_order: source 17 | rendering: 18 | show_root_heading: yes 19 | selection: 20 | members: 21 | - plot_solution_prediction 22 | - plot_epoch_loss 23 | - plot_ivp_loss 24 | - plot_de_loss 25 | - plot_all_losses 26 | - plot_predicted_exact 27 | - plot_solution_prediction_system 28 | - plot_predicted_exact_system 29 | -------------------------------------------------------------------------------- /src/pinnde/domain/timedomain.py: -------------------------------------------------------------------------------- 1 | from .domain import domain 2 | from abc import ABC, abstractmethod 3 | 4 | class timedomain(domain): 5 | """ 6 | Class for domains with time components 7 | """ 8 | 9 | def __init__(self, dim, timeRange): 10 | """ 11 | Constructor for class 12 | 13 | Args: 14 | dim (int): Spatial dimension of domain. 15 | timeRange (list): Range of time to solve equation over, e.g, [0, 1]. 16 | """ 17 | super().__init__(dim) 18 | self._timeRange = timeRange 19 | 20 | def get_timeRange(self): 21 | """ 22 | Returns: 23 | (list): Range of time o solve equation over. 24 | """ 25 | return self._timeRange 26 | 27 | @abstractmethod 28 | def onInitial(self, point): 29 | """ 30 | Abstract method all timedomains must specify. Determines whether a point is an initial point. 31 | 32 | Args: 33 | point (list): Point in time+spatial dimensions of domain. 34 | 35 | Returns: 36 | (bool): True if point is an initial point, False otherwise. 37 | """ 38 | pass -------------------------------------------------------------------------------- /docs/Legacy/ModelFuncs/pde_ModelFuncs_2var.md: -------------------------------------------------------------------------------- 1 | # pde_ModelFuncs_2var 2 | 3 | Functions for creating PINN's in PDE solvers of tx and xy. 4 | 5 | While available to user, not meant to be used. Instead interface through 6 | net_layers, net_units, and constraint parameters of solving functions detailed 7 | in "Main User Functions". 8 | 9 | We have described commonly used layer classes used throughout many models, models for specific solvePDE_tx 10 | equations, and models for specifc solvePDE_xy equations. 11 | 12 | **Commonly used layer classes** 13 | 14 | ::: src.pinnde.legacy.PDE.ModelFuncs.pde_ModelFuncs_2var 15 | options: 16 | members: 17 | - Periodic 18 | - Normalize 19 | - select_model_tx 20 | - build_model_standard 21 | - build_model_periodic_tx 22 | - build_model_periodic_hardconstraint1_tx 23 | - build_model_periodic_hardconstraint2_tx 24 | - build_model_periodic_hardconstraint3_tx 25 | - select_model_xy 26 | - build_model_standard 27 | - build_model_periodic_xy 28 | - build_model_hardconstraint_xy 29 | rendering: 30 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining/DeepONet_Training/ode_TrainingDeepONetBVP.md: -------------------------------------------------------------------------------- 1 | # ode_TrainingDeepONetBVP 2 | 3 | Functions which trains a DeepONet for solving a solveODE_DeepONet_BVP calls implemented in JAX/FLAX 4 | 5 | Each of order 1,2, and 3 equations with hard and soft constraints have there own training file respectively. Almost all functions are same, with slight changes made to model and model-interacting functions for specific problems. Here we outline all these commonly used functions. All files can be found in github in ODE/SpecificTraining/DeepONet/DeepONetBVP directory. 6 | 7 | While available to user, not meant to be used. Meant to be used through 8 | object returned from solveODE calls, where training file is selected through ode_trainingSelect 9 | 10 | ::: src.pinnde.legacy.ODE.SpecificTraining.DeepONet_Training.DeepONet_BVP.documentation_TrainingDeepONetBVP 11 | options: 12 | members: 13 | - startTraining 14 | - Normalize 15 | - CombineBranches 16 | - HardConstraint 17 | - MLP 18 | - DeepONet 19 | - train_network 20 | - train_step 21 | - defineCollocationPoints 22 | group_by_category: no 23 | rendering: 24 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining/DeepONet_Training/ode_TrainingDeepONetIVP.md: -------------------------------------------------------------------------------- 1 | # ode_TrainingDeepONetIVP 2 | 3 | Functions which trains a DeepONet for solving a solveODE_DeepONet_IVP calls implemented in JAX/FLAX 4 | 5 | Each of order 1,2, and 3 equations with hard and soft constraints have there own training file respectively. Almost all functions are same, with slight changes made to model and model-interacting functions for specific problems. Here we outline all these commonly used functions. All files can be found in github in ODE/SpecificTraining/DeepONet/DeepONetIVP directory. 6 | 7 | While available to user, not meant to be used. Meant to be used through 8 | object returned from solveODE calls, where training file is selected through ode_trainingSelect 9 | 10 | ::: src.pinnde.legacy.ODE.SpecificTraining.DeepONet_Training.DeepONet_IVP.documentation_TrainingDeepONetIVP 11 | options: 12 | members: 13 | - startTraining 14 | - Normalize 15 | - CombineBranches 16 | - HardConstraint 17 | - MLP 18 | - DeepONet 19 | - train_network 20 | - train_step 21 | - defineCollocationPoints 22 | group_by_category: no 23 | rendering: 24 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_PDEs_tx/PDE_tx_tutorials.md: -------------------------------------------------------------------------------- 1 | # PDEs in t and x Tutorials 2 | 3 | Examples for solving time dependent PDE's using PinnDE 4 | 5 | ## Using PINNs 6 | 7 | Examples using PINN's 8 | 9 | * [Linear Advection equation with periodic boundaries](Tutorials_PDEs_tx_PINN/linadvPeriodic.md) 10 | * [Allen-Cahn equation with dirichelt boundaries](Tutorials_PDEs_tx_PINN/allencahnDirichlet.md) 11 | * [Klein-Gordon equation with periodic boundaries, specifying PINN architecture](Tutorials_PDEs_tx_PINN/kleingordon.md) 12 | * [KdV equation with hard constraint initial condition](Tutorials_PDEs_tx_PINN/kvdHard.md) 13 | * [Burgers equation with periodic boundaries](Tutorials_PDEs_tx_PINN/burgersPeriodic.md) 14 | 15 | ## Using DeepONets 16 | 17 | Examples using DeepONets 18 | 19 | * [Heat equation with periodic boundaries](Tutorials_PDEs_tx_DeepONet/heatPeriodic_don.md) 20 | * [Allen-Cahn equation with dirichelt boundaries](Tutorials_PDEs_tx_DeepONet/allencahnDirichlet_don.md) 21 | * [Klein-Gordon equation with periodic boundaries, specifying DeepONet architecture](Tutorials_PDEs_tx_DeepONet/kleingordon_don.md) 22 | * [KdV equation with hard constraint initial condition](Tutorials_PDEs_tx_DeepONet/kvdHard_don.md) 23 | * [Burgers equation with periodic boundaries](Tutorials_PDEs_tx_DeepONet/burgersPeriodic_don.md) -------------------------------------------------------------------------------- /docs/Legacy/ModelFuncs/pde_DeepONetModelFuncs_2var.md: -------------------------------------------------------------------------------- 1 | # pde_DeepONetModelFuncs_2var 2 | 3 | Functions for creating PINN's in PDE DeepONet solvers of tx and xy. 4 | 5 | While available to user, not meant to be used. Instead interface through 6 | net_layers, net_units, and constraint parameters of solving functions detailed 7 | in "Main User Functions". 8 | 9 | We have described commonly used layer classes and functions used throughout many models, models for specific 10 | solvePDE_DeepONet_tx equations, and models for specifc solvePDE_DeepONet_xy equations. 11 | 12 | **Commonly used layer classes and functions** 13 | 14 | ::: src.pinnde.legacy.PDE.ModelFuncs.pde_DeepONetModelFuncs_2var 15 | options: 16 | members: 17 | - PeriodicBCs 18 | - Normalize 19 | - mlp_network 20 | - select_DeepONet_tx 21 | - build_DeepONet_standard 22 | - build_DeepONet_periodic_tx 23 | - build_DeepONet_periodic_tx_hard1 24 | - build_DeepONet_periodic_tx_hard2 25 | - build_DeepONet_periodic_tx_hard3 26 | - select_DeepONet_xy 27 | - build_DeepONet_standard 28 | - build_DeepONet_periodic_xy 29 | - build_DeepONet_dirichlet_hardconstraint_xy 30 | rendering: 31 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_PDEs_xy/PDE_xy_tutorials.md: -------------------------------------------------------------------------------- 1 | # PDEs in x and y Tutorials 2 | 3 | Examples for solving time dependent PDE's using PinnDE 4 | 5 | ## Using PINNs 6 | 7 | Examples using PINN's 8 | 9 | Note: Periodic and Neumann boundaries are implemented as well, but not used as commonly 10 | 11 | * [Helmholtz equation with hard constrainted dirichlet boundaries](Tutorials_PDEs_xy_PINN/helmholtz.md) 12 | * [Poisson equation (#1) with dirichlet boundaries, specifying PINN architecture](Tutorials_PDEs_xy_PINN/poisson1.md) 13 | * [Lagaris #5 with hard constrainted dirichlet boundaries](Tutorials_PDEs_xy_PINN/lagaris.md) 14 | * [Poisson equation (#2) with dirichlet boundaries](Tutorials_PDEs_xy_PINN/poisson2.md) 15 | 16 | ## Using DeepONets 17 | 18 | Examples using DeepONets 19 | 20 | Note: Periodic and Neumann boundaries are implemented as well, but not used as commonly 21 | 22 | * [Helmholtz equation with hard constrainted dirichlet boundaries](Tutorials_PDEs_xy_DeepONet/helmholtz_don.md) 23 | * [Poisson equation (#1) with dirichlet boundaries, specifying PINN architecture](Tutorials_PDEs_xy_DeepONet/poisson1_don.md) 24 | * [Lagaris #5 with hard constrainted dirichlet boundaries](Tutorials_PDEs_xy_DeepONet/lagaris_don.md) 25 | * [Poisson equation (#2) with dirichlet boundaries](Tutorials_PDEs_xy_DeepONet/poisson2_don.md) -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining/DeepONet_Training/ode_TrainingDeepONet_2EquationSystems.md: -------------------------------------------------------------------------------- 1 | # ode_TrainingDeepONet_2EquationSystems 2 | 3 | Functions which trains a DeepONet for solving a solveODE_DeepONetSystem_IVP calls of 2 equations, implemented in JAX/FLAX 4 | 5 | Each combination of 1, 2, and 3 order equations with hard constraints only have there own training file respectively. Almost all functions are the same, with slight changes made to model and model-interacting functions for specific problems. Here we outline all these commonly used functions. All files can be found in github in ODE/SpecificTraining/DeepONet/DeepONet_2EquationSystems directory. 6 | 7 | While available to user, not meant to be used. Meant to be used through 8 | object returned from solveODE calls, where training file is selected through ode_trainingSelect 9 | 10 | ::: src.pinnde.legacy.ODE.SpecificTraining.DeepONet_Training.DeepONet_2EquationSystems.documentation_TrainingDeepONet_2EquationSystems 11 | options: 12 | members: 13 | - startTraining 14 | - Normalize 15 | - CombineBranches 16 | - HardConstraint 17 | - MLP 18 | - DeepONet 19 | - train_network 20 | - train_step 21 | - defineCollocationPoints 22 | group_by_category: no 23 | rendering: 24 | show_root_heading: yes -------------------------------------------------------------------------------- /docs/Legacy/SpecificTraining/DeepONet_Training/ode_TrainingDeepONet_3EquationSystems.md: -------------------------------------------------------------------------------- 1 | # ode_TrainingDeepONet_3EquationSystems 2 | 3 | Functions which trains a DeepONet for solving a solveODE_DeepONetSystem_IVP calls of 3 equations, implemented in JAX/FLAX 4 | 5 | Each combination of 1, 2, and 3 order equations with hard constraints only have there own training file respectively. Almost all functions are the same, with slight changes made to model and model-interacting functions for specific problems. Here we outline all these commonly used functions. All files can be found in github in ODE/SpecificTraining/DeepONet/DeepONet_3EquationSystems directory. 6 | 7 | While available to user, not meant to be used. Meant to be used through 8 | object returned from solveODE calls, where training file is selected through ode_trainingSelect 9 | 10 | ::: src.pinnde.legacy.ODE.SpecificTraining.DeepONet_Training.DeepONet_3EquationSystems.documentation_TrainingDeepONet_3EquationSystems 11 | options: 12 | members: 13 | - startTraining 14 | - Normalize 15 | - CombineBranches 16 | - HardConstraint 17 | - MLP 18 | - DeepONet 19 | - train_network 20 | - train_step 21 | - defineCollocationPoints 22 | group_by_category: no 23 | rendering: 24 | show_root_heading: yes -------------------------------------------------------------------------------- /src/pinnde/legacy/PDE/pde_Adaptivity.py: -------------------------------------------------------------------------------- 1 | from . import pde_Points 2 | import numpy as np 3 | import tensorflow as tf 4 | 5 | def SelectAdaptivity(adaptivity, model, pdes, ds_init, ds, N_pde, i, f_bdry, s_bdry): 6 | if adaptivity[0] == "RAR": 7 | return AdaptiveRAR(adaptivity[1], adaptivity[2], model, pdes, ds_init, ds, N_pde, i, f_bdry, s_bdry) 8 | 9 | def AdaptiveRAR(freq, N_adp, model1, pdes1, ds_init1, ds1, N_pde1, i, f_bdry, s_bdry): 10 | if ((np.mod(i, freq)==0) and (i != 0)): # controll how often 11 | print("here") 12 | X = pde_Points.defineCollocationPoints_2var([f_bdry[0],f_bdry[1]],[s_bdry[0],s_bdry[1]],10000) 13 | 14 | f = model1([X[:,:1], X[:,1:2]]) 15 | err_eq = np.absolute(f) 16 | for j in range(N_adp): #controll how many 17 | x_id = np.argmax(err_eq) 18 | t_point = X[x_id][0] 19 | x_point = X[x_id][1] 20 | new_point = [[t_point, x_point]] 21 | pdes1 = tf.concat([pdes1, new_point], 0) 22 | err_eq = np.delete(err_eq, x_id, 0) 23 | # print(err_eq) 24 | # print(x_id) 25 | 26 | #print(pdes) 27 | bs_pdes1 = len(pdes1[:,:1])//10 28 | 29 | ds_pde1 = tf.data.Dataset.from_tensor_slices(pdes1) 30 | ds_pde1 = ds_pde1.cache().shuffle(N_pde1).batch(bs_pdes1) 31 | 32 | ds1 = tf.data.Dataset.zip((ds_pde1, ds_init1)) 33 | ds1 = ds1.prefetch(tf.data.experimental.AUTOTUNE) 34 | print(len(pdes1)) 35 | return ds1, pdes1 -------------------------------------------------------------------------------- /src/pinnde/data/timepinndata.py: -------------------------------------------------------------------------------- 1 | from .pinndata import pinndata 2 | 3 | class timepinndata(pinndata): 4 | """ 5 | Class for data on spato-temporal problems with a pinn. 6 | """ 7 | 8 | def __init__(self, domain, boundaries, initials, 9 | n_clp=10000, n_bc=600, n_ic=600): 10 | """ 11 | Constructor for class 12 | 13 | Args: 14 | domain (domain): Domain to generate data on. 15 | boundaries (boundaries): Boundary to generate data on. 16 | initials (initials): Initial conditions to generate data on. 17 | n_clp (int): Number of collocation points. 18 | n_bc (int): Number of boundary condition points. 19 | n_ic (int): Number of initial condition points. 20 | """ 21 | 22 | super().__init__(domain, boundaries, n_clp, n_bc) 23 | self.set_data_type(2) 24 | self._initials = initials 25 | self._n_iv = n_ic 26 | self._icp = initials.sampleInitials(n_ic) 27 | 28 | def get_icp(self): 29 | """ 30 | Returns: 31 | (tensor): Sampled initial condition points. 32 | """ 33 | return self._icp 34 | 35 | def get_initials(self): 36 | """ 37 | Returns: 38 | (initials): Initial conditions data is generated on. 39 | """ 40 | return self._initials 41 | 42 | def get_n_ic(self): 43 | """ 44 | Returns: 45 | (int): Number of initial points sampled. 46 | """ 47 | return self._n_iv -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_ODEs/Tutorials_ODEs_PINN/3ordIVPhard.md: -------------------------------------------------------------------------------- 1 | # Solving a Third Order ODE Initial Value Problem with Hard Constraints 2 | 3 | ## Problem 4 | We will look at solving the ODE 5 | 6 | $$u'''(t) - 2u''(t) + u(t) = 0$$ 7 | 8 | Over $t\in[0,1]$, with inital values 9 | 10 | $$u(0) = 0, u'(0) = 1, u''(0) = 0$$ 11 | 12 | ## Implementation 13 | 14 | First import package. We will only import ode_Solvers as that is all that is needed. 15 | 16 | import pinnde.ode_Solvers as ode_Solvers 17 | 18 | Next, we declare our equation, order, inital values, t boundary, number of points, and epochs 19 | 20 | eqn = "uttt - 2*utt + u" 21 | order = 3 22 | inits = [0, 1, 0] 23 | t_bdry = [0,1] 24 | N_pde = 200 25 | epochs = 1000 26 | 27 | To solve, we simply call the corresponding solving function to our problem, and we will declare we want 28 | to hard constraint 29 | 30 | mymodel = ode_Solvers.solveODE_IVP(eqn, order, inits, t_bdry, N_pde, epochs, constraint = "hard") 31 | 32 | If we want to quickly vizualize our data from training we can add after the solving function 33 | 34 | mymodel.plot_epoch_loss() 35 | 36 | mymodel.plot_solution_prediction() 37 | 38 | ## All Code 39 | 40 | import pinnde.ode_Solvers as ode_Solvers 41 | 42 | eqn = "uttt - 2*utt + u" 43 | order = 3 44 | inits = [0, 1, 0] 45 | t_bdry = [0,1] 46 | N_pde = 200 47 | epochs = 1000 48 | 49 | mymodel = ode_Solvers.solveODE_IVP(eqn, order, inits, t_bdry, N_pde, epochs, constraint = "hard") 50 | 51 | mymodel.plot_epoch_loss() 52 | 53 | mymodel.plot_solution_prediction() -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_ODEs/ODE_Tutorials.md: -------------------------------------------------------------------------------- 1 | # ODE Tutorials 2 | 3 | Examples for solving ODEs using PinnDE 4 | 5 | ## Using PINNs 6 | 7 | Examples using PINNs 8 | 9 | * [Second order ODE, inital value problem with soft constraints](Tutorials_ODEs_PINN/2ordIVPsoft.md) 10 | * [Third order ODE, inital value problem with hard constraints](Tutorials_ODEs_PINN/3ordIVPhard.md) 11 | * [Second order ODE, boundary value problem with hard constraints](Tutorials_ODEs_PINN/2ordBVPhard.md) 12 | * [Third order ODE, boundary value problem with soft constraints, specifying PINN architecture](Tutorials_ODEs_PINN/3ordBVPsoft.md) 13 | 14 | * [System of 2 ODEs, inital value problem with soft constraints](Tutorials_ODEs_PINN/2sysIVPsoft.md) 15 | * [System of 3 ODEs, inital value problem with soft constraints](Tutorials_ODEs_PINN/3sysIVPsoft.md) 16 | 17 | ## Using DeepONets 18 | 19 | Examples using DeepONets 20 | 21 | * [Second order ODE, inital value problem with soft constraints and time stepping](Tutorials_ODEs_DeepONet/2ordIVPsoft_don.md) 22 | * [Third order ODE, inital value problem with hard constraints](Tutorials_ODEs_DeepONet/3ordIVPhard_don.md) 23 | * [Second order ODE, boundary value problem with hard constraints](Tutorials_ODEs_DeepONet/2ordBVPhard_don.md) 24 | * [Third order ODE, boundary value problem with soft constraints, specifying DeepONet architecture](Tutorials_ODEs_DeepONet/3ordBVPsoft_don.md) 25 | 26 | * [System of 2 ODEs, inital value problem with soft constraints](Tutorials_ODEs_DeepONet/2sysIVPsoft_don.md) 27 | * [System of 3 ODEs, inital value problem with soft constraints and time stepping](Tutorials_ODEs_DeepONet/3sysIVPsoft_don.md) -------------------------------------------------------------------------------- /src/pinnde/boundaries/boundaries.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | # from .dirichlet import dirichlet 3 | # from .neumann import neumann 4 | # from .periodic import periodic 5 | 6 | class boundaries(ABC): 7 | """ 8 | Abstract class for boundaries 9 | """ 10 | # periodic = 1 11 | # dirichlet = 2 12 | # neumann = 3 13 | # odeicbc = 4 14 | 15 | def __init__(self, domain, type): 16 | """ 17 | Constructor for class 18 | 19 | Args: 20 | domain (domain): Domain for differential equation, class implementing domain. 21 | type (int): Internal type given to each boundary. Self-created boundary should use 0. 22 | 23 | """ 24 | self._domain = domain 25 | self._bdry_type = type 26 | 27 | def get_domain(self): 28 | """ 29 | Returns: 30 | (domain): domain for boundary 31 | """ 32 | return self._domain 33 | 34 | def get_bdry_type(self): 35 | """ 36 | Returns: 37 | (int): Internal boundary type indicator. 38 | """ 39 | return self._bdry_type 40 | 41 | def set_bdry_type(self, bdry): 42 | # periodic = 1 43 | # dirichlet = 2 44 | # neumann = 3 45 | """ 46 | Args: 47 | bdry (int): Boundary type to set. 48 | """ 49 | self._bdry_type = bdry 50 | 51 | @abstractmethod 52 | def boundaryPoints(self, n_bc): 53 | """ 54 | Abstract function which must describe how to determine the boundary values of domain. Used in domain.sampleBoundary calls. 55 | 56 | Args: 57 | n_bc (int): Number of boundary condition points to sample. 58 | 59 | Returns sampled boundary values. 60 | """ 61 | # must implement taking domain.sampleBoundary and adding boundary function points if any 62 | return -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_ODEs/Tutorials_ODEs_PINN/2ordBVPhard.md: -------------------------------------------------------------------------------- 1 | # Solving a Second Order ODE Boundary Value Problem with Hard Constraints 2 | 3 | ## Problem 4 | We will look at solving the ODE 5 | 6 | $$u''(t) = -4u(t)$$ 7 | 8 | Over $t\in[0,\pi/4]$, with boundary values 9 | 10 | $$u(0) = -2, u(\pi/4) = 10$$ 11 | 12 | ## Implementation 13 | 14 | First import package. We will only import ode_Solvers from PinnDE as that is all that is needed. Since we need to represent 15 | pi for the boundary, we also import numpy. 16 | 17 | import pinnde.ode_Solvers as ode_Solvers 18 | import numpy as np 19 | 20 | Next, we declare our equation, order, inital values, t boundary, number of points, and epochs. Equation must be in form eqn = 0 21 | 22 | eqn = "utt + 4*u" 23 | order = 2 24 | inits = [-2, 10] 25 | t_bdry = [0,np.pi/4] 26 | N_pde = 100 27 | epochs = 1000 28 | 29 | To solve, we simply call the corresponding solving function to our problem, and we will declare a hard constraint on boundaries 30 | 31 | mymodel = ode_Solvers.solveODE_BVP(eqn, order, inits, t_bdry, N_pde, epochs, constraint = "hard") 32 | 33 | If we want to quickly vizualize our data from training we can add after the solving function 34 | 35 | mymodel.plot_epoch_loss() 36 | 37 | mymodel.plot_solution_prediction() 38 | 39 | ## All Code 40 | 41 | import pinnde.ode_Solvers as ode_Solvers 42 | import numpy as np 43 | 44 | eqn = "utt + 4*u" 45 | order = 2 46 | inits = [-2, 10] 47 | t_bdry = [0,np.pi/4] 48 | N_pde = 100 49 | epochs = 1000 50 | 51 | mymodel = ode_Solvers.solveODE_BVP(eqn, order, inits, t_bdry, N_pde, epochs) 52 | 53 | mymodel.plot_epoch_loss() 54 | 55 | mymodel.plot_solution_prediction() -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_ODEs/Tutorials_ODEs_PINN/2sysIVPsoft.md: -------------------------------------------------------------------------------- 1 | # Solving a System of 2 ODEs as Initial Value Problem with soft Constraints 2 | 3 | ## Problem 4 | We will look at solving the ODEs 5 | 6 | $$u''(t) - u'(t)^2 = 0$$ 7 | 8 | $$x'(t) + u'(t) = x(t)$$ 9 | 10 | Over $t\in[0,1]$, with initial values 11 | 12 | $$u(0) = 1, u'(0) = 1/2$$ 13 | 14 | $$x(0) = 1$$ 15 | 16 | ## Implementation 17 | 18 | First import package. We will only import ode_Solvers from PinnDE as that is all that is needed 19 | 20 | import pinnde.ode_Solvers as ode_Solvers 21 | 22 | Next, we declare our equations, orders, inital values, t boundary, number of points, and epochs. Equation must be in form eqn = 0 23 | 24 | eqn1 = "utt - ut**2" 25 | eqn2 = "xt + ut - x" 26 | eqns = [eqn1, eqn2] 27 | orders = [2, 1] 28 | inits = [[1, 0.5], [1]] 29 | t_bdry = [0,1] 30 | N_pde = 100 31 | epochs = 1000 32 | 33 | To solve, we simply call the corresponding solving function to our problem 34 | 35 | mymodel = ode_Solvers.solveODE_System_IVP(eqns, orders, inits, t_bdry, N_pde, epochs) 36 | 37 | If we want to quickly vizualize our data from training we can add after the solving function 38 | 39 | mymodel.plot_epoch_loss() 40 | 41 | mymodel.plot_solution_prediction() 42 | 43 | ## All Code 44 | 45 | import pinnde.ode_Solvers as ode_Solvers 46 | 47 | eqn1 = "utt - ut**2" 48 | eqn2 = "xt + ut - x" 49 | eqns = [eqn1, eqn2] 50 | orders = [2, 1] 51 | inits = [[1, 0.5], [1]] 52 | t_bdry = [0,1] 53 | N_pde = 100 54 | epochs = 1000 55 | 56 | mymodel = ode_Solvers.solveODE_System_IVP(eqns, orders, inits, t_bdry, N_pde, epochs) 57 | 58 | mymodel.plot_epoch_loss() 59 | 60 | mymodel.plot_solution_prediction() -------------------------------------------------------------------------------- /src/pinnde/legacy/PDE/pde_TimeSteppersDeepONet.py: -------------------------------------------------------------------------------- 1 | import jax 2 | from functools import partial 3 | import numpy as np 4 | import matplotlib.pyplot as plt 5 | 6 | def timeStep_ordert1(steps, t_bdry, deeponet, u0, T, X, x_bdry, N_iv): 7 | l, n = 50, N_iv 8 | t = np.linspace(t_bdry[0], t_bdry[1], l) 9 | x = np.linspace(x_bdry[0], x_bdry[1], n) 10 | T, X = np.meshgrid(t, x, indexing='ij') 11 | 12 | u = [] 13 | x_points = np.linspace(x_bdry[0], x_bdry[1], N_iv) 14 | usensor = u0(np.expand_dims(x_points, axis=0)).numpy() 15 | tfinal = steps*t_bdry[1] 16 | 17 | for i in range(steps): 18 | #zinit = np.repeat(np.expand_dims(zinit, axis=0), len(t), axis=0) 19 | 20 | u_c = deeponet([np.expand_dims(T.flatten(), axis=1), 21 | np.expand_dims(X.flatten(), axis=1), 22 | usensor])[:,0] 23 | u_c = np.reshape(u_c, (l, n)) 24 | #print(np.shape(u_c)) 25 | 26 | uinit = np.repeat(usensor, repeats=l, axis=0) 27 | #print(np.shape(uinit)) 28 | 29 | # For form u(t,x) = u0(x) + t/tf*v(t,x) 30 | u_c = uinit + T/t_bdry[1]*u_c 31 | 32 | # # For form u(t,x) = u0(x)*(1-t/tf) + t/tf*v(t,x) 33 | #u_c = uinit*(1-T/t_bdry[1]) + T/t_bdry[1]*u_c 34 | 35 | u.append(u_c[:-1,]) 36 | 37 | # Next initial condition 38 | usensor = u_c[-1:,:] 39 | 40 | u = np.concatenate(u) 41 | 42 | t = np.linspace(t_bdry[0], steps*t_bdry[1], steps*(l-1)) 43 | x = np.linspace(x_bdry[0], x_bdry[1], n) 44 | TAll, XAll = np.meshgrid(t, x, indexing='ij') 45 | 46 | plt.figure() 47 | plt.contourf(TAll, XAll, u, 200, cmap=plt.cm.jet) 48 | plt.title('Neural network solution') 49 | plt.xlabel('t') 50 | plt.ylabel('x') 51 | plt.colorbar() 52 | plt.savefig("PDE-timeStep") 53 | plt.clf() 54 | return -------------------------------------------------------------------------------- /src/pinnde/data/pinndata.py: -------------------------------------------------------------------------------- 1 | from .data import data 2 | 3 | class pinndata(data): 4 | """ 5 | Class for data on purely spatial problems with a pinn. 6 | """ 7 | 8 | def __init__(self, domain, boundaries, n_clp=10000, n_bc=600): 9 | """ 10 | Constructor for class 11 | 12 | Args: 13 | domain (domain): Domain to generate data on. 14 | boundaries (boundaries): Boundary to generate data on. 15 | n_clp (int): Number of collocation points. 16 | n_bc (int): Number of boundary condition points. 17 | """ 18 | super().__init__(1) 19 | self._domain = domain 20 | self._boundaries = boundaries 21 | self._n_clp = n_clp 22 | self._n_bc = n_bc 23 | self._clp = domain.sampleDomain(n_clp) 24 | self._bcp = boundaries.boundaryPoints(n_bc) 25 | return 26 | 27 | def get_clp(self): 28 | """ 29 | Returns: 30 | (tensor): Sampled collocation points. 31 | """ 32 | return self._clp 33 | 34 | def get_bcp(self): 35 | """ 36 | Returns: 37 | (tensor): Sampled boundary points. 38 | """ 39 | return self._bcp 40 | 41 | def get_domain(self): 42 | """ 43 | Returns: 44 | (domain): Domain data is generated on. 45 | """ 46 | return self._domain 47 | 48 | def get_boundaries(self): 49 | """ 50 | Returns: 51 | (boundaries): Boundary data is generated on. 52 | """ 53 | return self._boundaries 54 | 55 | def get_n_clp(self): 56 | """ 57 | Returns: 58 | (int): Number of collocation points sampled. 59 | """ 60 | return self._n_clp 61 | 62 | def get_n_bc(self): 63 | """ 64 | Returns: 65 | (int): Number of boundary points sampled. 66 | """ 67 | return self._n_bc -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_ODEs/Tutorials_ODEs_PINN/3sysIVPsoft.md: -------------------------------------------------------------------------------- 1 | # Solving a System of 3 ODEs as Initial Value Problem with soft Constraints 2 | 3 | ## Problem 4 | We will look at solving the ODEs 5 | 6 | $$u''(t) - u'(t)^2 = 0$$ 7 | 8 | $$x'(t) + u'(t) = x(t)$$ 9 | 10 | $$y'''(t) - x''(t) = -u(t)$$ 11 | 12 | Over $t\in[0,1]$, with initial values 13 | 14 | $$u(0) = 1, u'(0) = 1/2$$ 15 | 16 | $$x(0) = 1$$ 17 | 18 | $$y(0) = 1, y'(0) = -1/2, y''(0) = 0$$ 19 | 20 | ## Implementation 21 | 22 | First import package. We will only import ode_Solvers from PinnDE as that is all that is needed 23 | 24 | import pinnde.ode_Solvers as ode_Solvers 25 | 26 | Next, we declare our equations, orders, inital values, t boundary, number of points, and epochs. Equation must be in form eqn = 0 27 | 28 | eqn1 = "utt - ut**2" 29 | eqn2 = "xt + ut - x" 30 | eqn3 = "yttt - xtt + u" 31 | eqns = [eqn1, eqn2, eqn3] 32 | orders = [2, 1, 3] 33 | inits = [[1, 0.5], [1], [1, -0.5, 0]] 34 | t_bdry = [0,1] 35 | N_pde = 100 36 | epochs = 1000 37 | 38 | To solve, we simply call the corresponding solving function to our problem 39 | 40 | mymodel = ode_Solvers.solveODE_System_IVP(eqns, orders, inits, t_bdry, N_pde, epochs) 41 | 42 | If we want to quickly vizualize our data from training we can add after the solving function 43 | 44 | mymodel.plot_epoch_loss() 45 | 46 | mymodel.plot_solution_prediction() 47 | 48 | ## All Code 49 | 50 | import pinnde.ode_Solvers as ode_Solvers 51 | 52 | eqn1 = "utt - ut**2" 53 | eqn2 = "xt + ut - x" 54 | eqn3 = "yttt - xtt + u" 55 | eqns = [eqn1, eqn2, eqn3] 56 | orders = [2, 1, 3] 57 | inits = [[1, 0.5], [1], [1, -0.5, 0]] 58 | t_bdry = [0,1] 59 | N_pde = 100 60 | epochs = 1000 61 | 62 | mymodel = ode_Solvers.solveODE_System_IVP(eqns, orders, inits, t_bdry, N_pde, epochs) 63 | 64 | mymodel.plot_epoch_loss() 65 | 66 | mymodel.plot_solution_prediction() -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_ODEs/Tutorials_ODEs_DeepONet/3ordIVPhard_don.md: -------------------------------------------------------------------------------- 1 | # Solving a Third Order ODE Initial Value Problem with Hard Constraints with a DeepONet 2 | 3 | ## Problem 4 | We will look at solving the ODE 5 | 6 | $$u'''(t) - 2u''(t) + u(t) = 0$$ 7 | 8 | Over $t\in[0,1]$, with inital values 9 | 10 | $$u(0) = 0, u'(0) = 1, u''(0) = 0$$ 11 | 12 | ## Implementation 13 | 14 | First import package. We will only import ode_Solvers as that is all that is needed. 15 | 16 | import pinnde.ode_Solvers as ode_Solvers 17 | 18 | Next, we declare our equation, order, inital values, t boundary, number of points, sensor_range, num_sensors, 19 | and epochs 20 | 21 | eqn = "uttt - 2*utt + u" 22 | order = 3 23 | inits = [0, 1, 0] 24 | t_bdry = [0,1] 25 | N_pde = 200 26 | sensor_range = [-3, 3] 27 | num_sensors = 4000 28 | epochs = 2000 29 | 30 | To solve, we simply call the corresponding solving function to our problem, and we will declare we want 31 | to hard constraint 32 | 33 | mymodel = ode_Solvers.solveODE_DeepONet_IVP(eqn, order, inits, t_bdry, N_pde, sensor_range, 34 | num_sensors, epochs, constraint = "hard") 35 | 36 | If we want to quickly vizualize our data from training we can add after the solving function 37 | 38 | mymodel.plot_epoch_loss() 39 | 40 | mymodel.plot_solution_prediction() 41 | 42 | ## All Code 43 | 44 | import pinnde.ode_Solvers as ode_Solvers 45 | 46 | eqn = "uttt - 2*utt + u" 47 | order = 3 48 | inits = [0, 1, 0] 49 | t_bdry = [0,1] 50 | N_pde = 200 51 | sensor_range = [-3, 3] 52 | num_sensors = 4000 53 | epochs = 2000 54 | 55 | mymodel = ode_Solvers.solveODE_DeepONet_IVP(eqn, order, inits, t_bdry, N_pde, sensor_range, 56 | num_sensors, epochs, constraint = "hard") 57 | 58 | mymodel.plot_epoch_loss() 59 | 60 | mymodel.plot_solution_prediction() -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_ODEs/Tutorials_ODEs_PINN/3ordBVPsoft.md: -------------------------------------------------------------------------------- 1 | # Solving a Third Order ODE Boundary Value Problem with Soft Constraints 2 | 3 | ## Problem 4 | We will look at solving the ODE 5 | 6 | $$u'''(t) - 2u''(t) + u(t) = 0$$ 7 | 8 | Over $t\in[0,1]$, with boundary values 9 | 10 | $$u(0) = 0, u(1) = 0.93, u'(0) = 1, u'(1) = 0.7$$ 11 | 12 | ## Implementation 13 | 14 | First import package. We will only import ode_Solvers as that is all that is needed. 15 | 16 | import pinnde.ode_Solvers as ode_Solvers 17 | 18 | Next, we declare our equation, order, inital values, t boundary, number of points, and epochs 19 | 20 | eqn = "uttt - 2*utt + u" 21 | order = 3 22 | inits = [0, 0.93, 1, 0.7] 23 | t_bdry = [0,1] 24 | N_pde = 200 25 | epochs = 1500 26 | 27 | If we also want to change the default number of internal layers (4) and nodes (40) per layer in our PINN, we can declare them as well 28 | 29 | layers = 6 30 | nodes = 50 31 | 32 | To solve, we simply call the corresponding solving function to our problem, and we will not delcare a constraint as it 33 | defaults to soft 34 | 35 | mymodel = ode_Solvers.solveODE_BVP(eqn, order, inits, t_bdry, N_pde, epochs, 36 | net_layers=layers, net_units=nodes) 37 | 38 | If we want to quickly vizualize our data from training we can add after the solving function 39 | 40 | mymodel.plot_epoch_loss() 41 | 42 | mymodel.plot_solution_prediction() 43 | 44 | ## All Code 45 | 46 | import pinnde.ode_Solvers as ode_Solvers 47 | 48 | eqn = "uttt - 2*utt + u" 49 | order = 3 50 | inits = [0, 0.93, 1, 0.7] 51 | t_bdry = [0,1] 52 | N_pde = 200 53 | epochs = 1500 54 | layers = 6 55 | nodes = 50 56 | 57 | mymodel = ode_Solvers.solveODE_BVP(eqn, order, inits, t_bdry, N_pde, epochs, 58 | net_layers=layers, net_units=nodes) 59 | 60 | mymodel.plot_epoch_loss() 61 | 62 | mymodel.plot_solution_prediction() -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_ODEs/Tutorials_ODEs_PINN/2ordIVPsoft.md: -------------------------------------------------------------------------------- 1 | # Solving a Second Order ODE Initial Value Problem with Soft Constraints 2 | 3 | ## Problem 4 | We will look at solving the ODE 5 | 6 | $$u''(t) = u'(t)^2$$ 7 | 8 | Over $t\in[0,1]$, with inital values 9 | 10 | $$u(0) = 1, u'(0) = 1/2$$ 11 | 12 | ## Implementation 13 | 14 | First import package. We will only import ode_Solvers from PinnDE as that is all that is needed. We will also import numpy to plot 15 | the exact solution 16 | 17 | import pinnde.ode_Solvers as ode_Solvers 18 | import numpy as np 19 | 20 | Next, we declare our equation, order, inital values, t boundary, number of points, and epochs. Equation must be in form eqn = 0 21 | 22 | eqn = "utt - ut**2" 23 | order = 2 24 | inits = [1, 0.5] 25 | t_bdry = [0,1] 26 | N_pde = 100 27 | epochs = 1000 28 | 29 | To solve, we simply call the corresponding solving function to our problem, and we will leave constraint undeclared as it defaults to soft 30 | 31 | mymodel = ode_Solvers.solveODE_IVP(eqn, order, inits, t_bdry, N_pde, epochs) 32 | 33 | If we want to quickly vizualize our data from training we can add after the solving function 34 | 35 | mymodel.plot_epoch_loss() 36 | 37 | mymodel.plot_solution_prediction() 38 | 39 | We can also plot the predicted solution against an exact solution if we have one with 40 | 41 | exact_eqn = "-(np.log(abs(t-2))) + np.log(2) + 1" 42 | mymodel.plot_predicted_exact(exact_eqn) 43 | 44 | ## All Code 45 | 46 | import pinnde.ode_Solvers as ode_Solvers 47 | import numpy as np 48 | 49 | eqn = "utt - ut**2" 50 | order = 2 51 | inits = [1, 0.5] 52 | t_bdry = [0,1] 53 | N_pde = 100 54 | epochs = 1000 55 | 56 | mymodel = ode_Solvers.solveODE_IVP(eqn, order, inits, t_bdry, N_pde, epochs) 57 | 58 | mymodel.plot_epoch_loss() 59 | 60 | mymodel.plot_solution_prediction() 61 | 62 | exact_eqn = "-(np.log(abs(t-2))) + np.log(2) + 1" 63 | mymodel.plot_predicted_exact(exact_eqn) 64 | -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_ODEs/Tutorials_ODEs_DeepONet/2sysIVPsoft_don.md: -------------------------------------------------------------------------------- 1 | # Solving a System of 2 ODEs as Initial Value Problem with soft Constraints with a DeepONet 2 | 3 | ## Problem 4 | We will look at solving the ODEs 5 | 6 | $$u''(t) - u'(t)^2 = 0$$ 7 | 8 | $$x'(t) + u'(t) = x(t)$$ 9 | 10 | Over $t\in[0,1]$, with initial values 11 | 12 | $$u(0) = 1, u'(0) = 1/2$$ 13 | 14 | $$x(0) = 1$$ 15 | 16 | ## Implementation 17 | 18 | First import package. We will only import ode_Solvers from PinnDE as that is all that is needed 19 | 20 | import pinnde.ode_Solvers as ode_Solvers 21 | 22 | Next, we declare our equations, orders, inital values, t boundary, number of points, sensor_range, num_sensors, and epochs. 23 | Equation must be in form eqn = 0 24 | 25 | eqn1 = "utt - ut**2" 26 | eqn2 = "xt + ut - x" 27 | eqns = [eqn1, eqn2] 28 | orders = [2, 1] 29 | inits = [[1, 0.5], [1]] 30 | t_bdry = [0,1] 31 | N_pde = 100 32 | sensor_range = [-3, 3] 33 | num_sensors = 3000 34 | epochs = 1500 35 | 36 | To solve, we simply call the corresponding solving function to our problem 37 | 38 | mymodel = ode_Solvers.solveODE_DeepONetSystem_IVP(eqns, orders, inits, t_bdry, 39 | N_pde, sensor_range, num_sensors, epochs) 40 | 41 | If we want to quickly vizualize our data from training we can add after the solving function 42 | 43 | mymodel.plot_epoch_loss() 44 | 45 | mymodel.plot_solution_prediction() 46 | 47 | ## All Code 48 | 49 | import pinnde.ode_Solvers as ode_Solvers 50 | 51 | eqn1 = "utt - ut**2" 52 | eqn2 = "xt + ut - x" 53 | eqns = [eqn1, eqn2] 54 | orders = [2, 1] 55 | inits = [[1, 0.5], [1]] 56 | t_bdry = [0,1] 57 | N_pde = 100 58 | sensor_range = [-3, 3] 59 | num_sensors = 3000 60 | epochs = 1500 61 | 62 | mymodel = ode_Solvers.solveODE_DeepONetSystem_IVP(eqns, orders, inits, t_bdry, 63 | N_pde, sensor_range, num_sensors, epochs) 64 | 65 | mymodel.plot_epoch_loss() 66 | 67 | mymodel.plot_solution_prediction() -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_ODEs/Tutorials_ODEs_DeepONet/2ordBVPhard_don.md: -------------------------------------------------------------------------------- 1 | # Solving a Second Order ODE Boundary Value Problem with Hard Constraints with a DeepONet 2 | 3 | ## Problem 4 | We will look at solving the ODE 5 | 6 | $$u''(t) = -4u(t)$$ 7 | 8 | Over $t\in[0,\pi/4]$, with boundary values 9 | 10 | $$u(0) = -2, u(\pi/4) = 10$$ 11 | 12 | ## Implementation 13 | 14 | First import package. We will only import ode_Solvers from PinnDE as that is all that is needed. Since we need to represent 15 | pi for the boundary, we also import numpy. 16 | 17 | import pinnde.ode_Solvers as ode_Solvers 18 | import numpy as np 19 | 20 | Next, we declare our equation, order, inital values, t boundary, number of points, sensor_range, num_sensors, and epochs. 21 | Equation must be in form eqn = 0 22 | 23 | eqn = "utt + 4*u" 24 | order = 2 25 | inits = [-2, 10] 26 | t_bdry = [0,np.pi/4] 27 | N_pde = 100 28 | sensor_range = [-2, 2] 29 | num_sensors = 3000 30 | epochs = 1500 31 | 32 | To solve, we simply call the corresponding solving function to our problem, and we will declare a hard constraint on boundaries 33 | 34 | mymodel = ode_Solvers.solveODE_DeepONet_BVP(eqn, order, inits, t_bdry, N_pde, sensor_range, 35 | num_sensors, epochs, constraint = "hard") 36 | 37 | If we want to quickly vizualize our data from training we can add after the solving function 38 | 39 | mymodel.plot_epoch_loss() 40 | 41 | mymodel.plot_solution_prediction() 42 | 43 | ## All Code 44 | 45 | import pinnde.ode_Solvers as ode_Solvers 46 | import numpy as np 47 | 48 | eqn = "utt + 4*u" 49 | order = 2 50 | inits = [-2, 10] 51 | t_bdry = [0,np.pi/4] 52 | N_pde = 100 53 | sensor_range = [-2, 2] 54 | num_sensors = 3000 55 | epochs = 1500 56 | 57 | mymodel = ode_Solvers.solveODE_DeepONet_BVP(eqn, order, inits, t_bdry, N_pde, sensor_range, 58 | num_sensors, epochs, constraint = "hard") 59 | 60 | mymodel.plot_epoch_loss() 61 | 62 | mymodel.plot_solution_prediction() -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_ODEs/Tutorials_ODEs_DeepONet/3ordBVPsoft_don.md: -------------------------------------------------------------------------------- 1 | # Solving a Third Order ODE Boundary Value Problem with Soft Constraints with a DeepONet 2 | 3 | ## Problem 4 | We will look at solving the ODE 5 | 6 | $$u'''(t) - 2u''(t) + u(t) = 0$$ 7 | 8 | Over $t\in[0,1]$, with boundary values 9 | 10 | $$u(0) = 0, u(1) = 0.93, u'(0) = 1, u'(1) = 0.7$$ 11 | 12 | ## Implementation 13 | 14 | First import package. We will only import ode_Solvers as that is all that is needed. 15 | 16 | import pinnde.ode_Solvers as ode_Solvers 17 | 18 | Next, we declare our equation, order, inital values, t boundary, number of points, sensor_range, num_sensors, 19 | and epochs 20 | 21 | eqn = "uttt - 2*utt + u" 22 | order = 3 23 | inits = [0, 0.93, 1, 0.7] 24 | t_bdry = [0,1] 25 | N_pde = 200 26 | sensor_range = [-2, 2] 27 | num_sensors = 3000 28 | epochs = 1500 29 | 30 | If we also want to change the default number of internal layers (4) and nodes (40) per layer in our DeepoNet, we can declare them as well 31 | 32 | layers = 6 33 | nodes = 50 34 | 35 | To solve, we simply call the corresponding solving function to our problem, and we will not delcare a constraint as it 36 | defaults to soft 37 | 38 | mymodel = ode_Solvers.solveODE_DeepONet_BVP(eqn, order, inits, t_bdry, N_pde, sensor_range, 39 | num_sensors, epochs, net_layers=layers, net_units=nodes) 40 | 41 | If we want to quickly vizualize our data from training we can add after the solving function 42 | 43 | mymodel.plot_epoch_loss() 44 | 45 | mymodel.plot_solution_prediction() 46 | 47 | ## All Code 48 | 49 | import pinnde.ode_Solvers as ode_Solvers 50 | 51 | eqn = "uttt - 2*utt + u" 52 | order = 3 53 | inits = [0, 0.93, 1, 0.7] 54 | t_bdry = [0,1] 55 | N_pde = 200 56 | sensor_range = [-2, 2] 57 | num_sensors = 3000 58 | epochs = 1500 59 | 60 | mymodel = ode_Solvers.solveODE_DeepONet_BVP(eqn, order, inits, t_bdry, N_pde, sensor_range, 61 | num_sensors, epochs, net_layers=layers, net_units=nodes) 62 | 63 | mymodel.plot_epoch_loss() 64 | 65 | mymodel.plot_solution_prediction() -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PinnDE 2 | -------- 3 | 4 | Physics Informed Neural Networks for Differential Equations (PinnDE) is an open-source library 5 | in Python 3 for solving ordinary and partial differential equations (ODEs and PDEs) using both 6 | physics informed neural networks (PINNs) and deep operator networks (DeepONets). The goal of PinnDE is to 7 | provide a user-friendly library as an alternative to the more powerful but more complex alternative packages 8 | that are available within this field. This library provides simple, user-friendly interfacing of solving methods which can easily be used in collaboration with 9 | non-proficient users of python or the library, where collaborators should be able to understand the contents of 10 | the code quickly and without having to learn the library themselves. We also propose the use of PinnDE for education use. 11 | Methods in this field may be taught by educators at a low level may be understandable to students, but the code to implement 12 | these ideas can be large and more difficult to grasp. PinnDE provides simple implementations where students can experiment with different 13 | variations of model parameters and training methods without needing to delve into low level implementations. 14 | 15 | The documentation can be found [here](https://pinnde.readthedocs.io/en/latest/) 16 | 17 | Installation 18 | ---------- 19 | This package requires *numpy*, *tensorflow*, *jax/flax/optax*, *matplotlib*, and *pyDOE*. These 20 | are all installed with the package. If version of a package already installed which is above the requirements 21 | for PinnDE, then currently package won't be upgraded when installed. 22 | 23 | Installing can simply be done with pip in the command line with 24 | 25 | pip install pinnde 26 | 27 | Citing 28 | ------- 29 | If PinnDE is used in academic research, please cite the paper found [here](https://arxiv.org/abs/2408.10011), 30 | or with the corresponding BibTex citation 31 | 32 | @article{matthews2024pinnde, 33 | title={PinnDE: Physics-Informed Neural Networks for Solving Differential Equations}, 34 | author={Matthews, Jason and Bihlo, Alex}, 35 | journal={arXiv preprint arXiv:2408.10011}, 36 | year={2024} 37 | } 38 | -------------------------------------------------------------------------------- /src/pinnde/legacy/pde_Initials.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from pyDOE import lhs 3 | 4 | def setup_initials_2var(t_bdry, x_bdry, t_order, initial_t, N_iv=100): 5 | """ 6 | Main function for setting up initial conditions for equations in t and x 7 | 8 | Args: 9 | t_bdry (list): list of two elements, the interval of t to be solved on. 10 | t_order (int): Order of t in equation (highest derivative of t used). Can be 1-3 11 | initial_t (list/Lambda): List of Inital functions for t=t0, as a python lambda funcitons, with t0 being inital t in t_bdry. 12 | One for each order. **Must** be of only 1 variable. See examples for how to make. 13 | N_iv (int): Number of randomly sampled collocation points along inital t which PINN uses in training. 14 | 15 | Returns: 16 | inits (list): List of setup sampled initial condition points 17 | t_order (int): Order of t in equation 18 | initial_t (list/Lambda): List of Inital functions for t=t0, as a python lambda funcitons, with t0 being inital t in t_bdry. 19 | One for each order. 20 | N_iv (int): Number of randomly sampled collocation points along inital t which PINN uses in training. 21 | 22 | """ 23 | 24 | if t_order == 1: 25 | u0 = initial_t[0] 26 | elif t_order == 2: 27 | u0, ut0 = initial_t[0], initial_t[1] 28 | elif t_order == 3: 29 | u0, ut0 = initial_t[0], initial_t[1] 30 | utt0 = initial_t[2] 31 | 32 | # Sample points where to evaluate the initial values 33 | tx_min = np.array([t_bdry[0], x_bdry[0]]) 34 | tx_max = np.array([t_bdry[1], x_bdry[1]]) 35 | init_points = tx_min[1:] + (tx_max[1:] - tx_min[1:])*lhs(1, N_iv) 36 | 37 | x_init = init_points 38 | t_init = t_bdry[0]+ 0.0*x_init 39 | if t_order == 1: 40 | u_init = u0(x_init) 41 | inits = np.column_stack([t_init, x_init, u_init]).astype(np.float64) 42 | elif t_order == 2: 43 | u_init = u0(x_init) 44 | ut_init = ut0(x_init) 45 | inits = np.column_stack([t_init, x_init, u_init, ut_init]).astype(np.float64) 46 | elif t_order == 3: 47 | u_init = u0(x_init) 48 | ut_init = ut0(x_init) 49 | utt_init = utt0(x_init) 50 | inits = np.column_stack([t_init, x_init, u_init, ut_init, utt_init]).astype(np.float64) 51 | 52 | return [inits, t_order, initial_t, N_iv] -------------------------------------------------------------------------------- /docs/tutorials/deeponettutorials/ode.md: -------------------------------------------------------------------------------- 1 | # Solving an ode with a DeepONet 2 | 3 | ## Problem 4 | We will look at solving the ODE 5 | 6 | $$u''(x) + u(x) = 0$$ 7 | 8 | Over $x\in[0,1]$, with initial value 9 | 10 | $$u(0) = 1/2, u'(0) = 1$$ 11 | 12 | ## Implementation 13 | First import package. 14 | 15 | import pinnde as p 16 | 17 | We then first create our domain. For ODEs, we must use a one dimensional interval, so a NRect with 1 dimension. 18 | 19 | re = p.domain.NRect(1, [0], [1]) 20 | 21 | We then define the boundaries for the domain. We use the odeicbc boundaries when solving ODEs. As we are doing initial conditions, 22 | we use the flag ic and pass in the initial conditions. 23 | 24 | uinits = [0.5, 1] 25 | cond = p.boundaries.odeicbc(re, [uinits], "ic") 26 | 27 | We then create the data for the deeponet to train on. As we have no time component and we will use a deeponet, we create a dondata object. 28 | 29 | dat = p.data.dondata(re, cond, 1000, 100, 500) 30 | 31 | Then, we create the deeponet model class and train the model for our desired epochs. When defining our equation, all spatial variables are denoted 32 | x1, x2, etc. So our equation is defined as follows. 33 | 34 | eqn = "ux1x1 + u" 35 | mymodel = p.models.pinn(dat, [eqn]) 36 | mymodel.train(1000) 37 | 38 | If we want to quickly visualize our solution and epoch loss, we call the in-built plotting functions for this type of equation. 39 | 40 | p.plotters.plot_solution_prediction_1D(mymodel) 41 | p.plotters.plot_epoch_loss(mymodel) 42 | 43 | ## All Code 44 | 45 | import pinnde as p 46 | 47 | re = p.domain.NRect(1, [0], [1]) 48 | 49 | uinits = [0.5, 1] 50 | cond = p.boundaries.odeicbc(re, [uinits], "ic") 51 | 52 | dat = p.data.dondata(re, cond, 1000, 100, 500) 53 | 54 | eqn = "ux1x1 + u" 55 | mymodel = p.models.deeponet(dat, [eqn]) 56 | mymodel.train(1000) 57 | 58 | p.plotters.plot_solution_prediction_1D(mymodel) 59 | p.plotters.plot_epoch_loss(mymodel) 60 | 61 | Or more concisely, 62 | 63 | import pinnde as p 64 | 65 | re = p.domain.NRect(1, [0], [1]) 66 | cond = p.boundaries.odeicbc(re, [0.5, 1], "ic") 67 | dat = p.data.pinndata(re, cond, 1000, 100, 500) 68 | mymodel = p.models.pinn(dat, ["ux1x1 + u"]) 69 | mymodel.train(1000) 70 | p.plotters.plot_solution_prediction_1D(mymodel) 71 | p.plotters.plot_epoch_loss(mymodel) -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_ODEs/Tutorials_ODEs_DeepONet/3sysIVPsoft_don.md: -------------------------------------------------------------------------------- 1 | # Solving a System of 3 ODEs as Initial Value Problem with soft Constraints with a DeepONet 2 | 3 | ## Problem 4 | We will look at solving the ODEs 5 | 6 | $$u''(t) - u'(t)^2 = 0$$ 7 | 8 | $$x'(t) + u'(t) = x(t)$$ 9 | 10 | $$y'''(t) - x''(t) = -u(t)$$ 11 | 12 | Over $t\in[0,1]$, with initial values 13 | 14 | $$u(0) = 1, u'(0) = 1/2$$ 15 | 16 | $$x(0) = 1$$ 17 | 18 | $$y(0) = 1, y'(0) = -1/2, y''(0) = 0$$ 19 | 20 | ## Implementation 21 | 22 | First import package. We will only import ode_Solvers from PinnDE as that is all that is needed 23 | 24 | import pinnde.ode_Solvers as ode_Solvers 25 | 26 | Next, we declare our equations, orders, inital values, t boundary, number of points, sensor_range, num_sensors, and epochs. 27 | Equation must be in form eqn = 0 28 | 29 | eqn1 = "utt - ut**2" 30 | eqn2 = "xt + ut - x" 31 | eqn3 = "yttt - xtt + u" 32 | eqns = [eqn1, eqn2, eqn3] 33 | orders = [2, 1, 3] 34 | inits = [[1, 0.5], [1], [1, -0.5, 0]] 35 | t_bdry = [0,1] 36 | N_pde = 100 37 | sensor_range = [-2, 2] 38 | num_sensors = 3000 39 | epochs = 2500 40 | 41 | To solve, we simply call the corresponding solving function to our problem 42 | 43 | mymodel = ode_Solvers.solveODE_DeepONetSystem_IVP(eqns, orders, inits, t_bdry, N_pde, sensor_range, 44 | num_sensors, epochs) 45 | 46 | If we wanted to timeStep this network to t = 5, we can easily do this by calling the method 47 | 48 | mymodel.timeStep(5) 49 | 50 | If we want to quickly vizualize our data from training we can add after the solving function 51 | 52 | mymodel.plot_epoch_loss() 53 | 54 | mymodel.plot_solution_prediction() 55 | 56 | ## All Code 57 | 58 | import pinnde.ode_Solvers as ode_Solvers 59 | 60 | eqn1 = "utt - ut**2" 61 | eqn2 = "xt + ut - x" 62 | eqn3 = "yttt - xtt + u" 63 | eqns = [eqn1, eqn2, eqn3] 64 | orders = [2, 1, 3] 65 | inits = [[1, 0.5], [1], [1, -0.5, 0]] 66 | t_bdry = [0,1] 67 | N_pde = 100 68 | sensor_range = [-2, 2] 69 | num_sensors = 3000 70 | epochs = 2500 71 | 72 | mymodel = ode_Solvers.solveODE_DeepONetSystem_IVP(eqns, orders, inits, t_bdry, N_pde, sensor_range, 73 | num_sensors, epochs) 74 | 75 | mymodel.timeStep(5) 76 | 77 | mymodel.plot_epoch_loss() 78 | 79 | mymodel.plot_solution_prediction() -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_ODEs/Tutorials_ODEs_DeepONet/2ordIVPsoft_don.md: -------------------------------------------------------------------------------- 1 | # Solving a Second Order ODE Initial Value Problem with Soft Constraints with a DeepONet 2 | 3 | ## Problem 4 | We will look at solving the ODE 5 | 6 | $$u''(t) = u'(t)^2$$ 7 | 8 | Over $t\in[0,1]$, with inital values 9 | 10 | $$u(0) = 1, u'(0) = 1/2$$ 11 | 12 | ## Implementation 13 | 14 | First import package. We will only import ode_Solvers from PinnDE as that is all that is needed. We will also import numpy to plot 15 | the exact solution 16 | 17 | import pinnde.ode_Solvers as ode_Solvers 18 | import numpy as np 19 | 20 | Next, we declare our equation, order, inital values, t boundary, number of points, sensor_range, num_sensors, and epochs. 21 | Equation must be in form eqn = 0 22 | 23 | eqn = "utt - ut**2" 24 | order = 1 25 | inits = [1, 0.5] 26 | t_bdry = [0,1] 27 | N_pde = 100 28 | sensor_range = [-2, 2] 29 | num_sensors = 3000 30 | epochs = 1500 31 | 32 | To solve, we simply call the corresponding solving function to our problem, and we will leave constraint undeclared as it defaults to soft 33 | 34 | mymodel = ode_Solvers.solveODE_DeepONet_IVP(eqn, order, inits, t_bdry, N_pde, sensor_range, 35 | num_sensors, epochs) 36 | 37 | If we wanted to timeStep this network to t = 5, we can easily do this by calling the method 38 | 39 | mymodel.timeStep(5) 40 | 41 | If we want to quickly vizualize our data from training we can add after the solving function 42 | 43 | mymodel.plot_epoch_loss() 44 | 45 | mymodel.plot_solution_prediction() 46 | 47 | We can also plot the predicted solution against an exact solution if we have one with 48 | 49 | exact_eqn = "-(np.log(abs(t-2))) + np.log(2) + 1" 50 | mymodel.plot_predicted_exact(exact_eqn) 51 | 52 | ## All Code 53 | 54 | import pinnde.ode_Solvers as ode_Solvers 55 | import numpy as np 56 | 57 | eqn = "utt - ut**2" 58 | order = 1 59 | inits = [1, 0.5] 60 | t_bdry = [0,1] 61 | N_pde = 100 62 | sensor_range = [-2, 2] 63 | num_sensors = 3000 64 | epochs = 1500 65 | 66 | mymodel = ode_Solvers.solveODE_DeepONet_IVP(eqn, order, inits, t_bdry, N_pde, sensor_range, n 67 | num_sensors, epochs) 68 | 69 | mymodel.timeStep(5) 70 | 71 | mymodel.plot_epoch_loss() 72 | 73 | mymodel.plot_solution_prediction() 74 | 75 | exact_eqn = "-(np.log(abs(t-2))) + np.log(2) + 1" 76 | mymodel.plot_predicted_exact(exact_eqn) -------------------------------------------------------------------------------- /docs/tutorials/pinntutorials/odesys.md: -------------------------------------------------------------------------------- 1 | # Solving a system of odes with a PINN 2 | 3 | ## Problem 4 | We will look at solving the ODEs 5 | 6 | $$u1''(x) + u1(x) = 0$$ 7 | 8 | $$u2'(x) + u1(x) = 0$$ 9 | 10 | Over $x\in[0,1]$, with initial values 11 | 12 | $$u1(0) = 1/2, u1'(0) = 1$$ 13 | 14 | $$u2(0) = 2$$ 15 | 16 | ## Implementation 17 | First import package. 18 | 19 | import pinnde as p 20 | 21 | We then first create our domain. For ODEs, we must use a one dimensional interval, so a NRect with 1 dimension. 22 | 23 | re = p.domain.NRect(1, [0], [1]) 24 | 25 | We then define the boundaries for the domain. We use the odeicbc boundaries when solving ODEs. As we are doing initial conditions, 26 | we use the flag ic and pass in the initial conditions for each equation 27 | 28 | u1inits = [0.5, 1] 29 | u2inits = [2] 30 | cond = p.boundaries.odeicbc(re, [u1inits, u2inits], "ic") 31 | 32 | We then create the data for the pinn to train on. As we have no time component and we will use a pinn, we create a pinndata object. 33 | 34 | dat = p.data.pinndata(re, cond, 1000, 100) 35 | 36 | Then, we create the pinn model class and train the model for our desired epochs. When defining our equation, all spatial variables are denoted 37 | x1, x2, etc. So our equation is defined as follows. 38 | 39 | eqn1 = "u1x1x1 + u1" 40 | eqn2 = "u2x1+u1" 41 | mymodel = p.models.pinn(dat, [eqn1, eqn2]) 42 | mymodel.train(500) 43 | 44 | If we want to quickly visualize our solution and epoch loss, we call the in-built plotting functions for this type of equation. 45 | 46 | p.plotters.plot_solution_prediction_1D(mymodel) 47 | p.plotters.plot_epoch_loss(mymodel) 48 | 49 | ## All Code 50 | 51 | import pinnde as p 52 | 53 | re = p.domain.NRect(1, [0], [1]) 54 | 55 | u1inits = [0.5, 1] 56 | u2inits = [2] 57 | cond = p.boundaries.odeicbc(re, [u1inits, u2inits], "ic") 58 | 59 | dat = p.data.pinndata(re, cond, 1000, 100) 60 | 61 | eqn1 = "u1x1x1 + u1" 62 | eqn2 = "u2x1+u1" 63 | mymodel = p.models.pinn(dat, [eqn1, eqn2]) 64 | mymodel.train(500) 65 | 66 | p.plotters.plot_solution_prediction_1D(mymodel) 67 | p.plotters.plot_epoch_loss(mymodel) 68 | 69 | Or more concisely, 70 | 71 | import pinnde as p 72 | 73 | re = p.domain.NRect(1, [0], [1]) 74 | cond = p.boundaries.odeicbc(re, [[0.5, 1], [2]], "ic") 75 | dat = p.data.pinndata(re, cond, 1000, 100) 76 | mymodel = p.models.pinn(dat, ["u1x1x1 + u1", "u2x1+u1"]) 77 | mymodel.train(500) 78 | p.plotters.plot_solution_prediction_1D(mymodel) 79 | p.plotters.plot_epoch_loss(mymodel) -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # Welcome to PinnDE! 2 | 3 | Physics Informed Neural Networks for Differential Equations (PinnDE) is an open-source library 4 | in Python 3 for solving ordinary and partial differential equations (ODEs and PDEs) using both 5 | physics informed neural networks (PINNs) and deep operator networks (DeepONets). The goal of PinnDE is to 6 | provide a user-friendly library as an alternative to the more powerful but more complex alternative packages 7 | that are available within this field. This library provides simple, user-friendly interfacing of solving methods which can easily be used in collaboration with 8 | non-proficient users of python or the library, where collaborators should be able to understand the contents of 9 | the code quickly and without having to learn the library themselves. We also propose the use of PinnDE for education use. 10 | Methods in this field may be taught by educators at a low level may be understandable to students, but the code to implement 11 | these ideas can be large and more difficult to grasp. PinnDE provides simple implementations where students can experiment with different 12 | variations of model parameters and training methods without needing to delve into low level implementations. 13 | 14 | We currently provide implementations to solve the following problems 15 | 16 | PINNs 17 | ---- 18 | * Arbitrary order ODEs/PDEs 19 | * Arbitrary Systems of ODEs/PDEs 20 | * Domains 21 | * Generalized N dimensional hyperrectangles 22 | * Generalized N dimensional ellipsoids 23 | * Solve spatio-temporal equations (1+n) 24 | * Solve purely spatial equations 25 | * Simple to use plotting modules for 1+1, 1+2, spatio-temporal equations, and 1 and 2 dimensional spatial equations 26 | 27 | * **Inverse PINNs** 28 | * Solving inverse problems for constants on any problem described above 29 | 30 | DeepONets 31 | ----- 32 | * Arbitrary order ODEs/PDEs 33 | * Domains 34 | * Generalized N dimensional hyperrectangles 35 | * Generalized N dimensional ellipsoids 36 | * Solve spatio-temporal equations (1+n) 37 | * Solve purely spatial equations 38 | * Simple to use plotting modules for 1+1, 1+2, spatio-temporal equations, and 1 and 2 dimensional spatial equations 39 | 40 | We provide Periodic, Dirichlet, and Neumann boundary conditions for each of these PDE problems. 41 | 42 | We provide L-BFGS optimization for these networks. 43 | 44 | We provide Residual-Based Adaptive Refinement, Residual-Based Adaptive Distribution, and Residual-Based Adaptive Refinement with Distribution, 45 | (RAR, RAD, RAR-D) adaptive sampling strategies for PINNs and Inverse PINNS. -------------------------------------------------------------------------------- /src/pinnde/adaptives/RAR.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | import numpy as np 3 | from .adaptives import adaptives 4 | from ..selectors.adaptSampleSelector import adaptSampleSelector 5 | 6 | class RAR(adaptives): 7 | """ 8 | Class which implements stategy to call Residule-based Adaptive Refinement, based on 9 | [DeepXDE: A deep learning library for solving differential equations](https://arxiv.org/abs/1907.04502) 10 | """ 11 | 12 | def __init__(self, frequency, pointsperfreq): 13 | """ 14 | Args: 15 | frequency (int): How many epochs between sampling new collocation points. 16 | pointsperfreq (int): How many points to add in each sample. 17 | """ 18 | self._frequency = frequency 19 | self._pointsperfreq = pointsperfreq 20 | 21 | def get_frequency(self): 22 | """ 23 | Returns: 24 | (int): How many epochs between sampling new collocation points. 25 | """ 26 | return self._frequency 27 | 28 | def get_pointsperfreq(self): 29 | """ 30 | Returns: 31 | (int): How many points to add in each sample. 32 | """ 33 | return self._pointsperfreq 34 | 35 | def AdaptiveStrategy(self, model, domain, data, clps, ds_data, ds, i): 36 | """ 37 | Sampling stategy to call Residule-based Adaptive Refinement. 38 | 39 | Args: 40 | model (network): Tensorflow network. 41 | domain (domain): Domain class solving over. 42 | data (data): Data class solving with. 43 | clps (tensor): Current collocation points. 44 | ds_data (list): Data being packaged in training routine. 45 | ds (list): Current ds value of training routine. 46 | i (int): Iteration number. 47 | 48 | """ 49 | if ((np.mod(i, self._frequency)==0) and (i != 0)): 50 | points = domain.sampleDomain(data.get_n_clp()) 51 | clps_group = [] 52 | for i in range(points.shape[1]): 53 | clps_group.append(points[:,i:i+1]) 54 | f = adaptSampleSelector(model, clps_group, data) 55 | err_eq = np.absolute(f) 56 | 57 | data.set_n_clp(data.get_n_clp()+self._pointsperfreq) 58 | N_clp = data.get_n_clp() 59 | for j in range(self._pointsperfreq): 60 | points_id = np.argmax(err_eq) 61 | new_point_inner = [] 62 | for k in range(points.shape[1]): 63 | new_point_inner.append(points[points_id][k]) 64 | new_point = [new_point_inner] 65 | clps = tf.concat([clps, new_point], 0) 66 | err_eq = np.delete(err_eq, points_id, 0) 67 | ds_clp = tf.data.Dataset.from_tensor_slices(clps) 68 | ds_clp = ds_clp.cache().shuffle(N_clp).batch(N_clp) 69 | 70 | ds_data.insert(0, ds_clp) 71 | 72 | ds = tf.data.Dataset.zip(tuple(ds_data)) 73 | 74 | return ds, clps -------------------------------------------------------------------------------- /src/pinnde/boundaries/neumann.py: -------------------------------------------------------------------------------- 1 | from .boundaries import boundaries 2 | import numpy as np 3 | import tensorflow as tf 4 | import inspect 5 | 6 | class neumann(boundaries): 7 | """ 8 | Class implementing neumann boundary conditions. 9 | """ 10 | #lambdas len = 1, all boundary, if not, have to have every boundary coverd 11 | def __init__(self, domain, lambdas): 12 | """ 13 | Constructor for class 14 | 15 | Args: 16 | domain (domain): Domain for boundary to act on. 17 | lambdas (list): List of boundary functions as lambda functions, each function in full time and 18 | spatial dimension, e.g, a 1+2 equation would have [lambda t, x1, x2: function]. 19 | """ 20 | super().__init__(domain, 3) 21 | self._lambdas = lambdas 22 | 23 | for func in lambdas: 24 | args = (inspect.getfullargspec(func))[0] 25 | if (len(args) != domain.get_dim()) and (len(args) != domain.get_dim()+1): 26 | raise ValueError("Lambda functions for boundaries must be functions of time+spatial dimensions, even if variables not used. \ 27 | Examples; lambda t, x1: 0+0*x1+0*t, or lambda x1, x2, x3: 2*x2") 28 | 29 | if (len(lambdas) == 1): 30 | new_lambdas = [] 31 | for i in range(domain.get_bdry_components()): 32 | new_lambdas.append(lambdas[0]) 33 | self._lambdas = new_lambdas 34 | 35 | def get_lambdas(self): 36 | """ 37 | Returns: 38 | (list): Boundary lambda functions 39 | """ 40 | return self._lambdas 41 | 42 | def boundaryPoints(self, n_bc): 43 | """ 44 | Samples boundary of domain, and computes boundary functions to generate boundary data. 45 | 46 | Args: 47 | n_bc (int): Number of boundary conditions to use. 48 | 49 | Returns: 50 | (tensor): Boundary points. 51 | """ 52 | sampled_boundary = self._domain.sampleBoundary(n_bc) 53 | 54 | # if isinstance(self._domain, timedomain): 55 | # time_points = sampled_boundary[:,0] 56 | # pure_boundary = sampled_boundary[:,1:,] 57 | # else: 58 | # pure_boundary = sampled_boundary 59 | 60 | pure_boundary = sampled_boundary 61 | 62 | func_inputs = [] 63 | comp_boundary = pure_boundary.reshape(-1, self._domain.get_bdry_component_size(), pure_boundary.shape[1]) 64 | for comp in comp_boundary: 65 | components = [] 66 | for dim in range(np.shape(comp)[1]): 67 | components.append(comp[:, dim]) 68 | func_inputs.append(components) 69 | out = [] 70 | 71 | for i in range(self._domain.get_bdry_components()): 72 | out.append(self._lambdas[i](*func_inputs[i])) 73 | 74 | boundary_points = np.column_stack([pure_boundary, np.array(out).flatten()]) 75 | 76 | return boundary_points -------------------------------------------------------------------------------- /src/pinnde/data/timeinvpinndata.py: -------------------------------------------------------------------------------- 1 | from .invpinndata import invpinndata 2 | import numpy as np 3 | 4 | class timeinvpinndata(invpinndata): 5 | """ 6 | Class for data on spato-temporal inverse problems with a pinn. 7 | """ 8 | 9 | def __init__(self, domain, boundaries, initials, dimdata, udata, 10 | n_clp=10000, n_bc=600, n_ic=600): 11 | """ 12 | Constructor for class 13 | 14 | Args: 15 | domain (domain): Domain to generate data on. 16 | boundaries (boundaries): Boundary to generate data on. 17 | initials (initials): Initial conditions to generate data on. 18 | dimdata (list): List of data across time+spatial dimensions in which udata is recorded on for each u, 19 | each as (N,) shape tensors. 20 | udata (list): List containing data for each u solving for to solve inverse cosntants, each as 21 | (N,) shape tensors 22 | n_clp (int): Number of collocation points. 23 | n_bc (int): Number of boundary condition points. 24 | n_ic (int): Number of initial condition points. 25 | """ 26 | 27 | super().__init__(domain, boundaries, dimdata, udata, n_clp, n_bc) 28 | self.set_data_type(6) 29 | self._initials = initials 30 | self._n_iv = n_ic 31 | self._icp = initials.sampleInitials(n_ic) 32 | self._n_invp = np.shape(udata[0])[0] 33 | self._invp = self.makeInverseData(dimdata, udata) 34 | 35 | def get_icp(self): 36 | """ 37 | Returns: 38 | (tensor): Sampled initial condition points. 39 | """ 40 | return self._icp 41 | 42 | def get_initials(self): 43 | """ 44 | Returns: 45 | (initials): Initial conditions data is generated on. 46 | """ 47 | return self._initials 48 | 49 | def get_n_ic(self): 50 | """ 51 | Returns: 52 | (int): Number of initial points sampled. 53 | """ 54 | return self._n_iv 55 | 56 | # def get_n_invp(self): 57 | # """ 58 | # Returns: 59 | # (int): Number of data points for inverse data given. 60 | # """ 61 | # return self._n_invp 62 | 63 | # def get_invp(self): 64 | # """ 65 | # Returns: 66 | # (tensor): Sampled data points for inverse data. 67 | # """ 68 | # return self._invp 69 | 70 | # def makeInverseData(self, dimdata, udata): 71 | # """ 72 | # Combines data user provided into consistent trainable set 73 | 74 | # Args: 75 | # dimdata (list): List of data across time+spatial dimensions in which udata is recorded on for each u, 76 | # each as (N,) shape tensors. 77 | # udata (list): List containing data for each u solving for to solve inverse cosntants, each as 78 | # (N,) shape tensors 79 | # """ 80 | # ddata = np.column_stack(dimdata) 81 | # funcdata = np.column_stack(udata) 82 | # data = np.column_stack([ddata, funcdata]) 83 | # return data -------------------------------------------------------------------------------- /src/pinnde/initials.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import tensorflow as tf 3 | from pyDOE import lhs 4 | 5 | class initials(): 6 | """ 7 | Class implementing initial conditions. 8 | """ 9 | 10 | def __init__(self, domain, lambdas): 11 | """ 12 | Constructor for class 13 | 14 | Args: 15 | domain (domain): Domain for boundary to act on. 16 | lambdas (list): List of initial functions as lambda functions, each function in full 17 | spatial dimensions, e.g, a 1+2 equation would have [lambda x1, x2: function]. 18 | """ 19 | self._domain = domain 20 | self._lambdas = lambdas 21 | self._orders = [] 22 | self._init_block_size = None 23 | 24 | def get_domain(self): 25 | """ 26 | Returns: 27 | (domain): Domain for boundary 28 | """ 29 | return self._domain 30 | 31 | def get_lambdas(self): 32 | """ 33 | Returns: 34 | (list): Initial lambda functions 35 | """ 36 | return self._lambdas 37 | 38 | def get_init_block_size(self): 39 | """ 40 | Returns: 41 | (int): Block size of each initial component 42 | """ 43 | return self._init_block_size 44 | 45 | def get_orders(self): 46 | """ 47 | Returns: 48 | (list): Orders of t in each equation sampled 49 | """ 50 | return self._orders 51 | 52 | def set_init_block_size(self, block_size): 53 | """ 54 | Args: 55 | block_size (int): Block size of each initial component 56 | """ 57 | self._init_block_size = block_size 58 | 59 | 60 | def sampleInitials(self, n_iv): 61 | """ 62 | Samples initial of domain, and computes initial functions to generate boundary data. 63 | 64 | Args: 65 | n_iv (int): Number of initial condition points to use. 66 | 67 | Returns: 68 | (tensor): Initial points. 69 | """ 70 | flat_lambdas = self._lambdas 71 | self._orders = [len(self._lambdas)] 72 | # multiple eqns, [[lambdas], [lambdas]] 73 | if (type(self._lambdas[0]) == list): 74 | flat_lambdas = [] 75 | self._orders = [] 76 | for funcs in self._lambdas: 77 | i = 0 78 | for func in funcs: 79 | flat_lambdas.append(func) 80 | i += 1 81 | self._orders.append(i) 82 | 83 | # flat_lambdas = [x for xs in self._lambdas for x in xs] 84 | 85 | 86 | points = self._domain.sampleDomain(n_iv) 87 | func_points = [] 88 | cols = np.shape(points)[1] 89 | for i in range(cols-1): 90 | func_points.append(points[:, i+1]) 91 | for func in flat_lambdas: 92 | next_points = func(*func_points) 93 | points = np.column_stack([points, next_points]) 94 | 95 | points[:, 0] = self._domain.get_timeRange()[0] 96 | # print(points) 97 | # time_points = self._domain.get_timeRange()[0] + 0*lhs(1, n_iv).astype(np.float32) 98 | # points = np.column_stack((time_points, points)) 99 | return points -------------------------------------------------------------------------------- /src/pinnde/boundaries/odeicbc.py: -------------------------------------------------------------------------------- 1 | from .boundaries import boundaries 2 | from ..initials import initials 3 | import inspect 4 | import numpy as np 5 | import tensorflow as tf 6 | 7 | class odeicbc(boundaries): 8 | """ 9 | Class implementing ode initial and boundary conditions. 10 | """ 11 | 12 | def __init__(self, domain, conditions, flag="ic"): 13 | """ 14 | Constructor for class 15 | 16 | Args: 17 | domain (domain): Domain for boundary to act on. Must time NRect with 1 dimension 18 | conditions (list): List of initial or boundary values of equations. 19 | flag (string): ic or bc to determine what condition is being used. 20 | **Only ic implemented currently**. 21 | """ 22 | # ic: conditions [u0, ux10, ..] 23 | # bc: conditions [u0, uf, ux10, ux1f, ...] 24 | if (flag != "ic" and flag != "bc"): 25 | raise ValueError("flag must be ic or bc - initial conditions for ode or boundary conditions for ode") 26 | 27 | super().__init__(domain, 4) 28 | self._conditions = conditions 29 | self._flag = flag 30 | self._orders = None 31 | 32 | def get_conditions(self): 33 | """ 34 | Returns: 35 | (list): ic or bc conditions 36 | """ 37 | return self._conditions 38 | 39 | def get_flag(self): 40 | """ 41 | Returns: 42 | (string): flag, ic or bc 43 | """ 44 | return self._flag 45 | 46 | def get_orders(self): 47 | """ 48 | Returns: 49 | (list): order(s) of equations 50 | """ 51 | return self._orders 52 | 53 | def boundaryPoints(self, n_bc): 54 | """ 55 | Samples boundary of domain, and computes boundary functions to generate boundary data. 56 | 57 | Args: 58 | n_bc (int): Number of boundary conditions to use. 59 | 60 | Returns: 61 | (tensor): Boundary points. 62 | """ 63 | if self._flag == "ic": 64 | flat_conds = self._conditions 65 | self._orders = [len(self._conditions)] 66 | # multiple eqns, [[lambdas], [lambdas]] 67 | if (type(self._conditions[0]) == list): 68 | flat_conds = [] 69 | self._orders = [] 70 | for conds in self._conditions: 71 | i = 0 72 | for cond in conds: 73 | flat_conds.append(cond) 74 | i += 1 75 | self._orders.append(i) 76 | 77 | points = self._domain.sampleBoundary(n_bc) 78 | points[:] = points[0][0] 79 | pts_shape = points 80 | for cond in flat_conds: 81 | next_points = cond+0*pts_shape 82 | points = np.column_stack([points, next_points]) 83 | 84 | return points -------------------------------------------------------------------------------- /src/pinnde/legacy/PDE/SpecificTraining/training_3variables/ICBCP3_Training/pde_TrainingICBCP3_periodic_hard.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import tensorflow as tf 3 | import ast 4 | tf.keras.backend.set_floatx('float64') 5 | 6 | @tf.function 7 | def trainStep(pdes, model, eqnparam): 8 | 9 | t_pde, x_pde, y_pde = pdes[:,:1], pdes[:,1:2], pdes[:,2:3] 10 | 11 | # Outer gradient for tuning network parameters 12 | with tf.GradientTape() as tape: 13 | # # Inner gradient for derivatives of u wrt x and t 14 | with tf.GradientTape(persistent=True) as tape1: 15 | tape1.watch(t_pde), tape1.watch(x_pde), tape1.watch(y_pde) 16 | u = model([t_pde, x_pde, y_pde]) 17 | [ut, ux, uy] = tape1.gradient(u, [t_pde, x_pde, y_pde]) 18 | uxx = tape1.gradient(ux, x_pde) 19 | uxxx = tape1.gradient(uxx, x_pde) 20 | utt = tape1.gradient(ut, t_pde) 21 | uttt = tape1.gradient(utt, t_pde) 22 | uyy = tape1.gradient(uy, y_pde) 23 | uyyy = tape1.gradient(uyy, y_pde) 24 | 25 | t = t_pde 26 | x = x_pde 27 | y = y_pde 28 | 29 | parse_tree = ast.parse(eqnparam, mode="eval") 30 | eqn = eval(compile(parse_tree, "", "eval")) 31 | 32 | # Define the PDE loss 33 | PDEloss = tf.reduce_mean(tf.square(eqn)) 34 | 35 | 36 | # Global loss 37 | loss = PDEloss + 0 38 | 39 | # Compute the gradient of the global loss wrt the model parameters 40 | grads = tape.gradient(loss, model.trainable_variables) 41 | 42 | return PDEloss, grads 43 | 44 | def PINNtrain(pde_points, setup_boundries, epochs, eqn, N_pde, N_iv, model): 45 | 46 | # Optimizer to be used 47 | lr = tf.keras.optimizers.schedules.PolynomialDecay(1e-3, epochs, 1e-4) 48 | opt = tf.keras.optimizers.Adam(lr) 49 | 50 | bs_pdes, bs_inits = N_pde//10, N_iv//10 51 | 52 | ds_pde = tf.data.Dataset.from_tensor_slices(pde_points) 53 | ds_pde = ds_pde.cache().shuffle(N_pde).batch(bs_pdes) 54 | 55 | ds = tf.data.Dataset.zip((ds_pde)) 56 | ds = ds.prefetch(tf.data.experimental.AUTOTUNE) 57 | 58 | epoch_loss = np.zeros(epochs) 59 | iv_loss = np.zeros(epochs) 60 | pde_loss = np.zeros(epochs) 61 | bc_loss = np.zeros(epochs) 62 | 63 | # Main training loop 64 | for i in range(epochs): 65 | 66 | n_batches = 0 67 | for (pdes) in ds: 68 | 69 | PDEloss, grads = trainStep(pdes, model, eqn) 70 | 71 | # Gradient step 72 | opt.apply_gradients(zip(grads, model.trainable_variables)) 73 | # One more batch done 74 | n_batches += 1 75 | epoch_loss[i] += PDEloss 76 | pde_loss[i] += PDEloss 77 | 78 | 79 | epoch_loss[i] /= n_batches 80 | 81 | 82 | if (np.mod(i, 100)==0): 83 | print("PDE loss, IV loss in {}th epoch: {: 6.4f}.".format(i, PDEloss.numpy())) 84 | 85 | return epoch_loss, iv_loss, bc_loss, pde_loss, model -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_PDEs_tx/Tutorials_PDEs_tx_PINN/linadvPeriodic.md: -------------------------------------------------------------------------------- 1 | # Solving the Linear Advection equation with Periodic boundaries 2 | 3 | ## Problem 4 | We will look at solving the Linear Advection equation 5 | 6 | $$\frac{\partial u}{\partial t} + \frac{\partial u}{\partial x} = 0$$ 7 | 8 | Over $t\in[0,1], x\in[-1,1]$, with initial condition 9 | 10 | $$u(x, 0) = \cos(\pi x)$$ 11 | 12 | ## Implementation 13 | 14 | First import package. We will only import pde_Solvers, pde_Initials and pde_Boundaries_2var from PinnDE as that is all that is needed. Since we need to represent pi for the initial condition, we also import numpy. We also use tensorflow's cos (we could use numpy in this instance, however with hard constraints we need tensorflows so we use this always). 15 | 16 | import pinnde.pde_Solvers as pde_Solvers 17 | import pinnde.pde_Initials as pde_Initials 18 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 19 | import numpy as np 20 | import tensorflow as tf 21 | 22 | We first can create our initial condition as a python lambda function. This **must** be of 1 variable in a time dependent equation. 23 | We declare t boundary, x_boundary, the order of t, and number of points along initial t. 24 | 25 | u0 = lambda x: tf.cos(np.pi*x) 26 | t_bdry = [0,1] 27 | x_bdry = [-1,1] 28 | t_order = 1 29 | N_iv = 100 30 | initials = pde_Initials.setup_initials_2var(t_bdry, x_bdry, t_order, [u0], N_iv) 31 | 32 | We then setup the boundaries. As we are using periodic boundaries this is done easily 33 | 34 | boundaries = pde_Boundaries_2var.setup_boundaries_periodic_tx(t_bdry, x_bdry) 35 | 36 | Next, we declare our equation,number of points, and epochs. Equation must be in form eqn = 0 37 | 38 | eqn = "ut+ux" 39 | N_pde = 10000 40 | epochs = 1200 41 | 42 | To solve, we simply call the corresponding solving function to our problem, and train the model 43 | 44 | mymodel = pde_Solvers.solvePDE_tx(eqn, initials, boundaries, N_pde) 45 | mymodel.train_model(epochs) 46 | 47 | If we want to quickly vizualize our data from training we can add after the solving function 48 | 49 | mymodel.plot_epoch_loss() 50 | 51 | mymodel.plot_solution_prediction() 52 | 53 | ## All Code 54 | 55 | import pinnde.pde_Solvers as pde_Solvers 56 | import pinnde.pde_Initials as pde_Initials 57 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 58 | import numpy as np 59 | import tensorflow as tf 60 | 61 | u0 = lambda x: tf.cos(np.pi*x) 62 | t_bdry = [0,1] 63 | x_bdry = [-1,1] 64 | t_order = 1 65 | N_iv = 100 66 | initials = pde_Initials.setup_initials_2var(t_bdry, x_bdry, t_order, [u0], N_iv) 67 | 68 | boundaries = pde_Boundaries_2var.setup_boundaries_periodic_tx(t_bdry, x_bdry) 69 | 70 | eqn = "ut+ux" 71 | N_pde = 10000 72 | epochs = 1200 73 | 74 | mymodel = pde_Solvers.solvePDE_tx(eqn, initials, boundaries, N_pde) 75 | mymodel.train_model(epochs) 76 | 77 | mymodel.plot_epoch_loss() 78 | 79 | mymodel.plot_solution_prediction() -------------------------------------------------------------------------------- /src/pinnde/boundaries/dirichlet.py: -------------------------------------------------------------------------------- 1 | from .boundaries import boundaries 2 | from ..domain.timedomain import timedomain 3 | import inspect 4 | import numpy as np 5 | import tensorflow as tf 6 | 7 | class dirichlet(boundaries): 8 | """ 9 | Class implementing dirichlet boundary conditions. 10 | """ 11 | 12 | #lambdas len = 1, all boundary, if not, have to have every boundary coverd 13 | def __init__(self, domain, lambdas): 14 | """ 15 | Constructor for class 16 | 17 | Args: 18 | domain (domain): Domain for boundary to act on. 19 | lambdas (list): List of boundary functions as lambda functions, each function in full time and 20 | spatial dimension, e.g, a 1+2 equation would have [lambda t, x1, x2: function]. 21 | """ 22 | super().__init__(domain, 2) 23 | self._lambdas = lambdas 24 | 25 | for func in lambdas: 26 | args = (inspect.getfullargspec(func))[0] 27 | if (len(args) != domain.get_dim()) and (len(args) != domain.get_dim()+1): 28 | raise ValueError("Lambda functions for boundaries must be functions of time+spatial dimensions, even if variables not used. \ 29 | Examples; lambda t, x1: 0+0*x1+0*t, or lambda x1, x2, x3: 2*x2") 30 | 31 | if (len(lambdas) == 1): 32 | new_lambdas = [] 33 | for i in range(domain.get_bdry_components()): 34 | new_lambdas.append(lambdas[0]) 35 | self._lambdas = new_lambdas 36 | 37 | def get_lambdas(self): 38 | """ 39 | Returns: 40 | (list): Boundary lambda functions 41 | """ 42 | return self._lambdas 43 | 44 | def boundaryPoints(self, n_bc): 45 | """ 46 | Samples boundary of domain, and computes boundary functions to generate boundary data. 47 | 48 | Args: 49 | n_bc (int): Number of boundary conditions to use. 50 | 51 | Returns: 52 | (tensor): Boundary points. 53 | """ 54 | sampled_boundary = self._domain.sampleBoundary(n_bc) 55 | 56 | # if isinstance(self._domain, timedomain): 57 | # time_points = sampled_boundary[:,0] 58 | # pure_boundary = sampled_boundary[:,1:,] 59 | # else: 60 | # pure_boundary = sampled_boundary 61 | 62 | pure_boundary = sampled_boundary 63 | 64 | func_inputs = [] 65 | comp_boundary = pure_boundary.reshape(-1, self._domain.get_bdry_component_size(), pure_boundary.shape[1]) 66 | for comp in comp_boundary: 67 | components = [] 68 | for dim in range(np.shape(comp)[1]): 69 | components.append(comp[:, dim]) 70 | func_inputs.append(components) 71 | out = [] 72 | 73 | for i in range(self._domain.get_bdry_components()): 74 | out.append(self._lambdas[i](*func_inputs[i])) 75 | 76 | boundary_points = np.column_stack([pure_boundary, np.array(out).flatten()]) 77 | 78 | # if (isinstance(self._domain, timedomain)): 79 | # boundary_points = np.column_stack([time_points, boundary_points]) 80 | # print(boundary_points) 81 | return boundary_points -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_PDEs_tx/Tutorials_PDEs_tx_PINN/burgersPeriodic.md: -------------------------------------------------------------------------------- 1 | # Solving the Burgers equation with Periodic boundaries 2 | 3 | ## Problem 4 | We will look at solving a specific instance of the Burgers equation (v = $\frac{0.01}{\pi}$) 5 | 6 | $$\frac{\partial u}{\partial t} + u\frac{\partial u}{\partial x} = (\frac{0.01}{\pi})\frac{\partial^2 u}{\partial x^2} $$ 7 | 8 | Over $t\in[0,1], x\in[-1,1]$, with initial condition 9 | 10 | $$u(x, 0) = -\sin(\pi x)$$ 11 | 12 | ## Implementation 13 | 14 | First import package. We will only import pde_Solvers, pde_Initials and pde_Boundaries_2var from PinnDE as that is all that is needed. Since we need to represent pi for the initial condition, we also import numpy. We also use tensorflow's cos (we could use numpy in this instance, however with hard constraints we need tensorflows so we use this always). 15 | 16 | import pinnde.pde_Solvers as pde_Solvers 17 | import pinnde.pde_Initials as pde_Initials 18 | import pinnde.pde_Boundaries_2var as pde_Boundaries 19 | import numpy as np 20 | import tensorflow as tf 21 | 22 | We first can create our initial condition as a python lambda function. This **must** be of 1 variable in a time dependent equation. 23 | We declare t boundary, x_boundary, the order of t, and number of points along initial t. 24 | 25 | u0 = lambda x: -tf.sin(np.pi*x) 26 | t_bdry = [0,1] 27 | x_bdry = [-1,1] 28 | t_order = 1 29 | N_iv = 100 30 | initials = pde_Initials.setup_initials_2var(t_bdry, x_bdry, t_order, [u0], N_iv) 31 | 32 | We then setup the boundaries. As we are using periodic boundaries this is done easily 33 | 34 | boundaries = pde_Boundaries.setup_boundaries_periodic_tx(t_bdry, x_bdry) 35 | 36 | Next, we declare our equation, number of points, and epochs. Equation must be in form eqn = 0 37 | 38 | eqn = "ut+u*ux-(0.01/np.pi)*uxx" 39 | N_pde = 10000 40 | epochs = 1000 41 | 42 | To solve, we simply call the corresponding solving function to our problem, and train the model 43 | 44 | mymodel = pde_Solvers.solvePDE_tx(eqn, initials, boundaries, N_pde) 45 | mymodel.train_model(epochs) 46 | 47 | If we want to quickly vizualize our data from training we can add after the solving function 48 | 49 | mymodel.plot_epoch_loss() 50 | 51 | mymodel.plot_solution_prediction() 52 | 53 | ## All Code 54 | 55 | import pinnde.pde_Solvers as pde_Solvers 56 | import pinnde.pde_Initials as pde_Initials 57 | import pinnde.pde_Boundaries_2var as pde_Boundaries 58 | import numpy as np 59 | import tensorflow as tf 60 | 61 | u0 = lambda x: -tf.sin(np.pi*x) 62 | t_bdry = [0,1] 63 | x_bdry = [-1,1] 64 | t_order = 1 65 | N_iv = 100 66 | initials = pde_Initials.setup_initials_2var(t_bdry, x_bdry, t_order, [u0], N_iv) 67 | 68 | boundaries = pde_Boundaries.setup_boundaries_periodic_tx(t_bdry, x_bdry) 69 | 70 | eqn = "ut+u*ux-(0.01/np.pi)*uxx" 71 | N_pde = 10000 72 | epochs = 1000 73 | 74 | mymodel = pde_Solvers.solvePDE_tx(eqn, initials, boundaries, N_pde) 75 | mymodel.train_model(epochs) 76 | 77 | mymodel.plot_epoch_loss() 78 | 79 | mymodel.plot_solution_prediction() -------------------------------------------------------------------------------- /docs/tutorials/pinntutorials/2helmholtz.md: -------------------------------------------------------------------------------- 1 | # Solving the Helmholtz equation with Dirichlet boundaries with a PINN 2 | 3 | ## Problem 4 | We will look at solving a specific instance of the Helmholtz equation 5 | 6 | $$\frac{\partial^2 u}{\partial x^2} + \frac{\partial^2 u}{\partial y^2} + 4\pi^2\sin(2\pi x)\sin(2\pi y) 7 | = -4\pi^2 u $$ 8 | 9 | Over $x\in[0,1], y\in[0,1]$, with boundary conditions 10 | 11 | $$u(x, 0) = u(x, 1) = u(0, y) = u(1, y) = 0 $$ 12 | 13 | ## Implementation 14 | First import package. Since we need to represent pi for the equation, we also import numpy. We also use tensorflow's cos. 15 | 16 | import pinnde as p 17 | import numpy as np 18 | import tensorflow as tf 19 | 20 | We then first create our domain. We will solve this on the square from 0 to 1, so we create a NRect with 2 spatial dimensions, with xmins 21 | [0, 0] and xmaxs [1, 1]. 22 | 23 | re = p.domain.NRect(2, [0, 0], [1, 1]) 24 | 25 | We then define the boundaries for the domain. We will use Dirichlet boundaries set to zero. Note our lambda function 26 | must be of all dimensions, x1 and x2. 27 | 28 | bdryfunc = lambda x1, x2: 0+x1*0 29 | bound = p.boundaries.dirichlet(re, [bdryfunc]) 30 | 31 | We then create the data for the pinn to train on. As we have no time component and we will use a pinn, we create a pinndata object. 32 | 33 | dat = p.data.pinndata(re, bound, 12000, 800) 34 | 35 | Then, we create the pinn model class and train the model for our desired epochs. When defining our equation, all spatial variables are denoted 36 | x1, x2, etc. So our equation is defined as follows. 37 | 38 | eqn = "ux1x1 + ux2x2 + ((np.pi*2)**2)*u + ((np.pi*2)**2)*tf.sin((np.pi*2)*x1)*tf.sin((np.pi*2)*x2)" 39 | mymodel = p.models.pinn(dat, [eqn]) 40 | mymodel.train(2500) 41 | 42 | If we want to quickly visualize our solution and epoch loss, we call the in-built plotting functions for this type of equation. 43 | 44 | p.plotters.plot_solution_prediction_2D(mymodel) 45 | p.plotters.plot_epoch_loss(mymodel) 46 | 47 | ## All Code 48 | 49 | import pinnde as p 50 | import numpy as np 51 | import tensorflow as tf 52 | 53 | re = p.domain.NRect(2, [0, 0], [1, 1]) 54 | 55 | bdryfunc = lambda x1, x2: 0+x1*0 56 | bound = p.boundaries.dirichlet(re, [bdryfunc]) 57 | 58 | dat = p.data.pinndata(re, bound, 12000, 800) 59 | 60 | eqn = "ux1x1 + ux2x2 + ((np.pi*2)**2)*u + ((np.pi*2)**2)*tf.sin((np.pi*2)*x1)*tf.sin((np.pi*2)*x2)" 61 | mymodel = p.models.pinn(dat, [eqn]) 62 | mymodel.train(2500) 63 | 64 | p.plotters.plot_solution_prediction_2D(mymodel) 65 | p.plotters.plot_epoch_loss(mymodel) 66 | 67 | Or more concisely, 68 | 69 | import pinnde as p 70 | import numpy as np 71 | import tensorflow as tf 72 | 73 | re = p.domain.NRect(2, [0, 0], [1, 1]) 74 | bound = p.boundaries.dirichlet(re, [lambda x1, x2: 0+x1*0]) 75 | dat = p.data.pinndata(re, bound, 12000, 800) 76 | mymodel = p.models.pinn(dat, ["ux1x1 + ux2x2 + ((np.pi*2)**2)*u + ((np.pi*2)**2)*tf.sin((np.pi*2)*x1)*tf.sin((np.pi*2)*x2)"]) 77 | mymodel.train(2500) 78 | p.plotters.plot_solution_prediction_2D(mymodel) 79 | p.plotters.plot_epoch_loss(mymodel) -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_PDEs_xy/Tutorials_PDEs_xy_PINN/helmholtz.md: -------------------------------------------------------------------------------- 1 | # Solving the Helmholtz equation with Hard constrainted Dirichlet boundaries 2 | 3 | ## Problem 4 | We will look at solving a specific instance of the Helmholtz equation 5 | 6 | $$\frac{\partial^2 u}{\partial x^2} + \frac{\partial^2 u}{\partial y^2} + 2\pi^2\sin(2\pi x)\sin(2\pi y) 7 | = -2\pi^2 $$ 8 | 9 | Over $x\in[0,1], y\in[0,1]$, with boundary conditions 10 | 11 | $$u(x, 0) = u(x, 1) = u(0, y) = u(1, y) = 0 $$ 12 | 13 | ## Implementation 14 | 15 | First import package. We will only import pde_Solvers and pde_Boundaries_2var from PinnDE as that is all that is needed. Since we need to represent pi for the equation, we also import numpy. We also use tensorflow's sin (we could not use numpy in this instance as with hard constraints we need tensorflows). 16 | 17 | import pinnde.pde_Solvers as pde_Solvers 18 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 19 | import numpy as np 20 | import tensorflow as tf 21 | 22 | We then setup the boundaries. We just declare the x boundary, y boundary, number of points along bondary, and declare the 23 | boundary conditions as a python lambda function which **must** be of 2 variable in a time independent equation. Note 24 | how we must use the vairbale declared even just for making the boundaries a constant 25 | 26 | x_bdry = [0, 1] 27 | y_bdry = [0, 1] 28 | N_bc = 100 29 | boundary = lambda x, y: 0+0*x 30 | boundaries = pde_Boundaries_2var.setup_boundaries_dirichlet_xy(x_bdry, y_bdry, N_bc, 31 | all_boundaries_cond=boundary) 32 | 33 | Next, we declare our equation, number of points, and epochs. Equation must be in form eqn = 0 34 | 35 | eqn = "uxx + uyy + ((np.pi*2)**2)*u + ((np.pi*2)**2)*tf.sin((np.pi*2)*x)*tf.sin((np.pi*2)*y)" 36 | N_pde = 10000 37 | epochs = 1500 38 | 39 | To solve, we simply call the corresponding solving function to our problem, declaring a hard constraint, and train the model 40 | 41 | mymodel = pde_Solvers.solvePDE_xy(eqn, boundaries, N_pde, constraint = "hard") 42 | mymodel.train_model(epochs) 43 | 44 | If we want to quickly vizualize our data from training we can add after the solving function 45 | 46 | mymodel.plot_epoch_loss() 47 | 48 | mymodel.plot_solution_prediction() 49 | 50 | ## All Code 51 | 52 | import pinnde.pde_Solvers as pde_Solvers 53 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 54 | import numpy as np 55 | import tensorflow as tf 56 | 57 | x_bdry = [0, 1] 58 | y_bdry = [0, 1] 59 | N_bc = 100 60 | boundary = lambda x, y: 0+0*x 61 | boundaries = pde_Boundaries_2var.setup_boundaries_dirichlet_xy(x_bdry, y_bdry, N_bc, 62 | all_boundaries_cond=boundary) 63 | 64 | eqn = "uxx + uyy + ((np.pi*2)**2)*u + ((np.pi*2)**2)*tf.sin((np.pi*2)*x)*tf.sin((np.pi*2)*y)" 65 | N_pde = 10000 66 | epochs = 1500 67 | 68 | mymodel = pde_Solvers.solvePDE_xy(eqn, boundaries, N_pde, constraint = "hard") 69 | mymodel.train_model(epochs) 70 | 71 | mymodel.plot_epoch_loss() 72 | 73 | mymodel.plot_solution_prediction() -------------------------------------------------------------------------------- /docs/tutorials/deeponettutorials/2helmholtz.md: -------------------------------------------------------------------------------- 1 | # Solving the Helmholtz equation with Dirichlet boundaries with a DeepONet 2 | 3 | ## Problem 4 | We will look at solving a specific instance of the Helmholtz equation 5 | 6 | $$\frac{\partial^2 u}{\partial x^2} + \frac{\partial^2 u}{\partial y^2} + 4\pi^2\sin(2\pi x)\sin(2\pi y) 7 | = -4\pi^2 u $$ 8 | 9 | Over $x\in[0,1], y\in[0,1]$, with boundary conditions 10 | 11 | $$u(x, 0) = u(x, 1) = u(0, y) = u(1, y) = 0 $$ 12 | 13 | ## Implementation 14 | First import package. Since we need to represent pi for the equation, we also import numpy. We also use tensorflow's cos. 15 | 16 | import pinnde as p 17 | import numpy as np 18 | import tensorflow as tf 19 | 20 | We then first create our domain. We will solve this on the square from 0 to 1, so we create a NRect with 2 spatial dimensions, with xmins 21 | [0, 0] and xmaxs [1, 1]. 22 | 23 | re = p.domain.NRect(2, [0, 0], [1, 1]) 24 | 25 | We then define the boundaries for the domain. We will use Dirichlet boundaries set to zero. Note our lambda function 26 | must be of all dimensions, x1 and x2. 27 | 28 | bdryfunc = lambda x1, x2: 0+x1*0 29 | bound = p.boundaries.dirichlet(re, [bdryfunc]) 30 | 31 | We then create the data for the deeponet to train on. As we have no time component and we will use a deeponet, we create a dondata object. 32 | 33 | dat = p.data.dondata(re, bound, 12000, 800, 1000) 34 | 35 | Then, we create the deeponet model class and train the model for our desired epochs. When defining our equation, all spatial variables are denoted 36 | x1, x2, etc. So our equation is defined as follows. 37 | 38 | eqn = "ux1x1 + ux2x2 + ((np.pi*2)**2)*u + ((np.pi*2)**2)*tf.sin((np.pi*2)*x1)*tf.sin((np.pi*2)*x2)" 39 | mymodel = p.models.deeponet(dat, [eqn]) 40 | mymodel.train(2500) 41 | 42 | If we want to quickly visualize our solution and epoch loss, we call the in-built plotting functions for this type of equation. 43 | 44 | p.plotters.plot_solution_prediction_2D(mymodel) 45 | p.plotters.plot_epoch_loss(mymodel) 46 | 47 | ## All Code 48 | 49 | import pinnde as p 50 | import numpy as np 51 | import tensorflow as tf 52 | 53 | re = p.domain.NRect(2, [0, 0], [1, 1]) 54 | 55 | bdryfunc = lambda x1, x2: 0+x1*0 56 | bound = p.boundaries.dirichlet(re, [bdryfunc]) 57 | 58 | dat = p.data.dondata(re, bound, 12000, 800, 1000) 59 | 60 | eqn = "ux1x1 + ux2x2 + ((np.pi*2)**2)*u + ((np.pi*2)**2)*tf.sin((np.pi*2)*x1)*tf.sin((np.pi*2)*x2)" 61 | mymodel = p.models.deeponet(dat, [eqn]) 62 | mymodel.train(2500) 63 | 64 | p.plotters.plot_solution_prediction_2D(mymodel) 65 | p.plotters.plot_epoch_loss(mymodel) 66 | 67 | Or more concisely, 68 | 69 | import pinnde as p 70 | import numpy as np 71 | import tensorflow as tf 72 | 73 | re = p.domain.NRect(2, [0, 0], [1, 1]) 74 | bound = p.boundaries.dirichlet(re, [lambda x1, x2: 0+x1*0]) 75 | dat = p.data.dondata(re, bound, 12000, 800, 1000) 76 | mymodel = p.models.deeponet(dat, ["ux1x1 + ux2x2 + ((np.pi*2)**2)*u + ((np.pi*2)**2)*tf.sin((np.pi*2)*x1)*tf.sin((np.pi*2)*x2)"]) 77 | mymodel.train(2500) 78 | p.plotters.plot_solution_prediction_2D(mymodel) 79 | p.plotters.plot_epoch_loss(mymodel) -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_PDEs_tx/Tutorials_PDEs_tx_PINN/kvdHard.md: -------------------------------------------------------------------------------- 1 | # Solving the Korteweg–De Vries equation with periodic boundaries and Hard constraint Initial condition 2 | 3 | ## Problem 4 | We will look at solving a specific instance of the KdV equation 5 | 6 | $$\frac{\partial u}{\partial t} + u\frac{\partial u}{\partial x} - (-0.0025)\frac{\partial^3 u}{\partial x^3} = 0 $$ 7 | 8 | Over $t\in[0,1], x\in[-1,1]$, with initial condition 9 | 10 | $$u(x, 0) = \cos(\pi x)$$ 11 | 12 | ## Implementation 13 | 14 | First import package. We will only import pde_Solvers, pde_Initials, and pde_Boundaries_2var from PinnDE as that is all that is needed. Since we need to represent pi for the initial condition, we also import numpy. We also use tensorflow's cos (we could not use numpy in this instance as with hard constraints we need tensorflows). 15 | 16 | import pinnde.pde_Solvers as pde_Solvers 17 | import pinnde.pde_Initials as pde_Initials 18 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 19 | import numpy as np 20 | import tensorflow as tf 21 | 22 | We first can create our initial condition as a python lambda function. This **must** be of 1 variable in a time dependent equation. 23 | We declare t boundary, x_boundary, the order of t, and number of points along initial t. 24 | 25 | u0 = lambda x: tf.cos(np.pi*x) 26 | t_bdry = [0,1] 27 | x_bdry = [-1,1] 28 | t_order = 1 29 | N_iv = 100 30 | initials = pde_Initials.setup_initials_2var(t_bdry, x_bdry, t_order, [u0], N_iv) 31 | 32 | We then setup the boundaries. As we are using periodic boundaries this is done easily 33 | 34 | boundaries = pde_Boundaries_2var.setup_boundaries_periodic_tx(t_bdry, x_bdry) 35 | 36 | Next, we declare our equation, number of points, and epochs. 37 | Equation must be in form eqn = 0 38 | 39 | eqn = "ut+u*ux-(-0.0025)*uxxx" 40 | N_pde = 10000 41 | epochs = 2500 42 | 43 | To solve, we simply call the corresponding solving function to our problem, specifying the constraint as hard, and train the model 44 | 45 | mymodel = pde_Solvers.solvePDE_tx(eqn, initials, boundaries, N_pde, constraint = "hard") 46 | mymodel.train_model(epochs) 47 | 48 | If we want to quickly vizualize our data from training we can add after the solving function 49 | 50 | mymodel.plot_epoch_loss() 51 | 52 | mymodel.plot_solution_prediction() 53 | 54 | ## All Code 55 | 56 | import pinnde.pde_Solvers as pde_Solvers 57 | import pinnde.pde_Initials as pde_Initials 58 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 59 | import numpy as np 60 | import tensorflow as tf 61 | 62 | u0 = lambda x: tf.cos(np.pi*x) 63 | t_bdry = [0,1] 64 | x_bdry = [-1,1] 65 | t_order = 1 66 | N_iv = 100 67 | initials = pde_Initials.setup_initials_2var(t_bdry, x_bdry, t_order, [u0], N_iv) 68 | 69 | boundaries = pde_Boundaries_2var.setup_boundaries_periodic_tx(t_bdry, x_bdry) 70 | 71 | eqn = "ut+u*ux-(-0.0025)*uxxx" 72 | N_pde = 10000 73 | epochs = 2500 74 | 75 | mymodel = pde_Solvers.solvePDE_tx(eqn, initials, boundaries, N_pde, constraint = "hard") 76 | mymodel.train_model(epochs) 77 | 78 | mymodel.plot_epoch_loss() 79 | 80 | mymodel.plot_solution_prediction() -------------------------------------------------------------------------------- /docs/tutorials/pinntutorials/2poisson1.md: -------------------------------------------------------------------------------- 1 | # Solving the Poisson equation with Dirichlet boundaries with a PINN mymodel.train(500, opt="lbfgs") 2 | 3 | ## Problem 4 | We will look at solving a specific instance of the Poisson equation 5 | 6 | $$\frac{\partial^2 u}{\partial x^2} + \frac{\partial^2 u}{\partial y^2} = -2\pi^2\cos(\pi x)\sin(\pi y)$$ 7 | 8 | Over $x\in[-1,1], y\in[-1,1]$, with boundary conditions 9 | 10 | $$u(x, -1) = u(x, 1) = u(-1, y) = u(1, y) = \cos(\pi x)\sin(\pi y)$$ 11 | 12 | ## Implementation 13 | First import package. Since we need to represent pi for the boundary condition, we also import numpy. We also use tensorflow's cos. 14 | 15 | import pinnde as p 16 | import numpy as np 17 | import tensorflow as tf 18 | 19 | We then first create our domain. We will solve this on the square from -1 to 1, so we create a NRect with 2 spatial dimensions, with xmins 20 | [-1, -1] and xmaxs [1, 1]. 21 | 22 | re = p.domain.NRect(2, [-1, -1], [1, 1]) 23 | 24 | We then define the boundaries for the domain. We will use Dirichlet boundaries set to zero. Note our lambda function 25 | must be of all dimensions, x1 and x2. 26 | 27 | bdryfunc = lambda x1, x2: tf.cos(np.pi*x1)*tf.sin(np.pi*x2) 28 | bound = p.boundaries.dirichlet(re, [bdryfunc]) 29 | 30 | We then create the data for the pinn to train on. As we have no time component and we will use a pinn, we create a pinndata object. 31 | 32 | dat = p.data.pinndata(re, bound, 12000, 800) 33 | 34 | Then, we create the pinn model class and train the model for our desired epochs. When defining our equation, all spatial variables are denoted 35 | x1, x2, etc. So our equation is defined as follows. 36 | 37 | eqn = "ux1x1 + ux2x2 - (-2*np.pi**2*tf.cos(np.pi*x1)*tf.sin(np.pi*x2))" 38 | mymodel = p.models.pinn(dat, [eqn]) 39 | mymodel.train(500, opt="lbfgs") 40 | 41 | If we want to quickly visualize our solution and epoch loss, we call the in-built plotting functions for this type of equation. 42 | 43 | p.plotters.plot_solution_prediction_2D(mymodel) 44 | p.plotters.plot_epoch_loss(mymodel) 45 | 46 | ## All Code 47 | 48 | import pinnde as p 49 | import numpy as np 50 | import tensorflow as tf 51 | 52 | re = p.domain.NRect(2, [-1, -1], [1, 1]) 53 | 54 | bdryfunc = lambda x1, x2: tf.cos(np.pi*x1)*tf.sin(np.pi*x2) 55 | bound = p.boundaries.dirichlet(re, [bdryfunc]) 56 | 57 | dat = p.data.pinndata(re, bound, 12000, 800) 58 | 59 | eqn = "ux1x1 + ux2x2 - (-2*np.pi**2*tf.cos(np.pi*x1)*tf.sin(np.pi*x2))" 60 | mymodel = p.models.pinn(dat, [eqn]) 61 | mymodel.train(500, opt="lbfgs") 62 | 63 | p.plotters.plot_solution_prediction_2D(mymodel) 64 | p.plotters.plot_epoch_loss(mymodel) 65 | 66 | Or more concisely, 67 | 68 | import pinnde as p 69 | import numpy as np 70 | import tensorflow as tf 71 | 72 | re = p.domain.NRect(2, [-1, -1], [1, 1]) 73 | bound = p.boundaries.dirichlet(re, [lambda x1, x2: tf.cos(np.pi*x1)*tf.sin(np.pi*x2)]) 74 | dat = p.data.pinndata(re, bound, 12000, 800) 75 | mymodel = p.models.pinn(dat, ["ux1x1 + ux2x2 - (-2*np.pi**2*tf.cos(np.pi*x1)*tf.sin(np.pi*x2))"]) 76 | mymodel.train(500, opt="lbfgs") 77 | p.plotters.plot_solution_prediction_2D(mymodel) 78 | p.plotters.plot_epoch_loss(mymodel) -------------------------------------------------------------------------------- /docs/tutorials/deeponettutorials/2poisson1.md: -------------------------------------------------------------------------------- 1 | # Solving the Poisson equation with Dirichlet boundaries with a DeepONet with LBFGS Optimization 2 | 3 | ## Problem 4 | We will look at solving a specific instance of the Poisson equation 5 | 6 | $$\frac{\partial^2 u}{\partial x^2} + \frac{\partial^2 u}{\partial y^2} = -2\pi^2\cos(\pi x)\sin(\pi y)$$ 7 | 8 | Over $x\in[-1,1], y\in[-1,1]$, with boundary conditions 9 | 10 | $$u(x, -1) = u(x, 1) = u(-1, y) = u(1, y) = \cos(\pi x)\sin(\pi y)$$ 11 | 12 | ## Implementation 13 | First import package. Since we need to represent pi for the boundary condition, we also import numpy. We also use tensorflow's cos. 14 | 15 | import pinnde as p 16 | import numpy as np 17 | import tensorflow as tf 18 | 19 | We then first create our domain. We will solve this on the square from -1 to 1, so we create a NRect with 2 spatial dimensions, with xmins 20 | [-1, -1] and xmaxs [1, 1]. 21 | 22 | re = p.domain.NRect(2, [-1, -1], [1, 1]) 23 | 24 | We then define the boundaries for the domain. We will use Dirichlet boundaries set to zero. Note our lambda function 25 | must be of all dimensions, x1 and x2. 26 | 27 | bdryfunc = lambda x1, x2: tf.cos(np.pi*x1)*tf.sin(np.pi*x2) 28 | bound = p.boundaries.dirichlet(re, [bdryfunc]) 29 | 30 | We then create the data for the deeponet to train on. As we have no time component and we will use a deeponet, we create a deeponetdata 31 | object. 32 | 33 | dat = p.data.dondata(re, bound, 12000, 1000, 2000) 34 | 35 | Then, we create the deeponet model class and train the model for our desired epochs. When defining our equation, all spatial variables are denoted 36 | x1, x2, etc. So our equation is defined as follows. 37 | 38 | eqn = "ux1x1 + ux2x2 - (-2*np.pi**2*tf.cos(np.pi*x1)*tf.sin(np.pi*x2))" 39 | mymodel = p.models.deeponet(dat, [eqn]) 40 | mymodel.train(500, opt="lbfgs") 41 | 42 | If we want to quickly visualize our solution and epoch loss, we call the in-built plotting functions for this type of equation. 43 | 44 | p.plotters.plot_solution_prediction_2D(mymodel) 45 | p.plotters.plot_epoch_loss(mymodel) 46 | 47 | ## All Code 48 | 49 | import pinnde as p 50 | import numpy as np 51 | import tensorflow as tf 52 | 53 | re = p.domain.NRect(2, [-1, -1], [1, 1]) 54 | 55 | bdryfunc = lambda x1, x2: tf.cos(np.pi*x1)*tf.sin(np.pi*x2) 56 | bound = p.boundaries.dirichlet(re, [bdryfunc]) 57 | 58 | dat = p.data.dondata(re, bound, 12000, 1000, 2000) 59 | 60 | eqn = "ux1x1 + ux2x2 - (-2*np.pi**2*tf.cos(np.pi*x1)*tf.sin(np.pi*x2))" 61 | mymodel = p.models.deeponet(dat, [eqn]) 62 | mymodel.train(500, opt="lbfgs") 63 | 64 | p.plotters.plot_solution_prediction_2D(mymodel) 65 | p.plotters.plot_epoch_loss(mymodel) 66 | 67 | Or more concisely, 68 | 69 | import pinnde as p 70 | import numpy as np 71 | import tensorflow as tf 72 | 73 | re = p.domain.NRect(2, [-1, -1], [1, 1]) 74 | bound = p.boundaries.dirichlet(re, [lambda x1, x2: tf.cos(np.pi*x1)*tf.sin(np.pi*x2)]) 75 | dat = p.data.dondata(re, bound, 12000, 1000, 2000) 76 | mymodel = p.models.deeponet(dat, ["ux1x1 + ux2x2 - (-2*np.pi**2*tf.cos(np.pi*x1)*tf.sin(np.pi*x2))"]) 77 | mymodel.train(500, opt="lbfgs") 78 | p.plotters.plot_solution_prediction_2D(mymodel) 79 | p.plotters.plot_epoch_loss(mymodel) -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_PDEs_xy/Tutorials_PDEs_xy_PINN/lagaris.md: -------------------------------------------------------------------------------- 1 | # Solving Problem 5 in Lagaris with Hard constrainted Dirichlet boundaries 2 | 3 | ## Problem 4 | We will look at solving problem 5 found in [Lagaris et al.](https://arxiv.org/abs/physics/9705023), which demonstrates 5 | how to hard constraint dirichlet boundary conditions 6 | 7 | $$\frac{\partial^2 u}{\partial x^2} + \frac{\partial^2 u}{\partial y^2} = e^{-x}(x-2+y^3+6y) $$ 8 | 9 | Over $x\in[0,1], y\in[0,1]$, with boundary conditions 10 | 11 | $$u(0, y) = y^3, u(1, y) = (1+y^3)e^{-1} $$ 12 | 13 | $$u(x, 0) = xe^{-x}, u(x, 1) = e^{-x}(x+1)$$ 14 | 15 | The analytic solution is $e^{-x}(x + y^3)$ 16 | 17 | ## Implementation 18 | 19 | First import package. We will only import pde_Solvers and pde_Boundaries_2var from PinnDE as that is all that is needed. Since we need to represent e for the equation, we also import numpy. 20 | 21 | import pinnde.pde_Solvers as pde_Solvers 22 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 23 | import numpy as np 24 | 25 | We then setup the boundaries. We just declare the x boundary, y boundary, number of points along bondary, and declare the 26 | boundary conditions as a python lambda function which **must** be of 2 variable in a time independent equation. 27 | 28 | x_bdry = [0, 1] 29 | y_bdry = [0, 1] 30 | N_bc = 400 31 | x_left = lambda x, y: y**3 32 | x_right = lambda x, y: (1+y**3)/(np.e) 33 | y_lower = lambda x, y: x/(np.e**x) 34 | y_upper = lambda x, y: (x+1)/(np.e**x) 35 | 36 | boundaries = pde_Boundaries_2var.setup_boundaries_dirichlet_xy(x_bdry,y_bdry,N_bc, xleft_boundary_cond=x_left, 37 | xright_boundary_cond=x_right, ylower_boundary_cond=y_lower, yupper_upper_cond=y_upper) 38 | 39 | Next, we declare our equation, number of points, and epochs. Equation must be in form eqn = 0 40 | 41 | eqn = "uxx+uyy - (x-2+6*y+y**3)/(np.e**x)" 42 | N_pde = 10000 43 | epochs = 1000 44 | 45 | To solve, we simply call the corresponding solving function to our problem, declaring a hard constraint, and train the model 46 | 47 | mymodel = pde_Solvers.solvePDE_xy(eqn, boundaries, N_pde, constraint = "hard") 48 | mymodel.train_model(epochs) 49 | 50 | If we want to quickly vizualize our data from training we can add after the solving function 51 | 52 | mymodel.plot_epoch_loss() 53 | 54 | mymodel.plot_solution_prediction() 55 | 56 | ## All Code 57 | 58 | import pinnde.pde_Solvers as pde_Solvers 59 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 60 | import numpy as np 61 | 62 | x_bdry = [0, 1] 63 | y_bdry = [0, 1] 64 | N_bc = 400 65 | x_left = lambda x, y: y**3 66 | x_right = lambda x, y: (1+y**3)/(np.e) 67 | y_lower = lambda x, y: x/(np.e**x) 68 | y_upper = lambda x, y: (x+1)/(np.e**x) 69 | 70 | boundaries = pde_Boundaries_2var.setup_boundaries_dirichlet_xy(x_bdry,y_bdry,N_bc, xleft_boundary_cond=x_left, 71 | xright_boundary_cond=x_right, ylower_boundary_cond=y_lower, yupper_boundary_cond=y_upper) 72 | 73 | eqn = "uxx+uyy - (x-2+6*y+y**3)/(np.e**x)" 74 | N_pde = 10000 75 | epochs = 1000 76 | 77 | mymodel = pde_Solvers.solvePDE_xy(eqn, boundaries, N_pde, constraint = "hard") 78 | mymodel.train_model(epochs) 79 | 80 | mymodel.plot_epoch_loss() 81 | 82 | mymodel.plot_solution_prediction() -------------------------------------------------------------------------------- /src/pinnde/legacy/PDE/SpecificTraining/training_2variables/BCP_Training/pde_TrainingBCP_hard.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import tensorflow as tf 3 | import ast 4 | tf.keras.backend.set_floatx('float64') 5 | 6 | @tf.function 7 | def trainStep(pdes, model, eqnparam, extra_ders): 8 | 9 | x_pde, y_pde = pdes[:,:1], pdes[:,1:2] 10 | 11 | # Outer gradient for tuning network parameters 12 | with tf.GradientTape() as tape: 13 | # # Inner gradient for derivatives of u wrt x and t 14 | with tf.GradientTape(persistent=True) as tape1: 15 | tape1.watch(x_pde), tape1.watch(y_pde) 16 | u = model([x_pde, y_pde]) 17 | [ux, uy] = tape1.gradient(u, [x_pde, y_pde]) 18 | uxx = tape1.gradient(ux, x_pde) 19 | uxxx = tape1.gradient(uxx, x_pde) 20 | uyy = tape1.gradient(uy, y_pde) 21 | uyyy = tape1.gradient(uyy, y_pde) 22 | if extra_ders != None: 23 | for i in extra_ders: 24 | global uxy, uyx 25 | uxy = uyx = tape1.gradient(ux, y_pde) 26 | if ((i == "uxxy") or (i == "uxyx") or (i == "uyxx")): 27 | global uyxx, uxyx, uxxy 28 | uxxy = uxyx = uyxx = tape1.gradient(uyx, x_pde) 29 | if ((i == "uyyx") or (i == "uyxy") or (i == "uxyy")): 30 | global uyyx, uyxy, uxyy 31 | uxyy = uyxy = uyyx = tape1.gradient(uxy, y_pde) 32 | 33 | y = y_pde 34 | x = x_pde 35 | 36 | parse_tree = ast.parse(eqnparam, mode="eval") 37 | eqn = eval(compile(parse_tree, "", "eval")) 38 | 39 | # Define the PDE loss 40 | PDEloss = tf.reduce_mean(tf.square(eqn)) 41 | 42 | # Global loss 43 | loss = PDEloss + 0 44 | 45 | # Compute the gradient of the global loss wrt the model parameters 46 | grads = tape.gradient(loss, model.trainable_variables) 47 | 48 | return PDEloss, grads 49 | 50 | def PINNtrain(pde_points, epochs, eqn, N_pde, model, extra_ders): 51 | 52 | 53 | # Optimizer to be used 54 | lr = tf.keras.optimizers.schedules.PolynomialDecay(1e-3, epochs, 1e-4) 55 | opt = tf.keras.optimizers.Adam(lr) 56 | 57 | bs_pdes = N_pde//10 58 | 59 | ds_pde = tf.data.Dataset.from_tensor_slices(pde_points) 60 | ds_pde = ds_pde.cache().shuffle(N_pde).batch(bs_pdes) 61 | 62 | ds = tf.data.Dataset.zip((ds_pde)) 63 | ds = ds.prefetch(tf.data.experimental.AUTOTUNE) 64 | 65 | epoch_loss = np.zeros(epochs) 66 | iv_loss = np.zeros(epochs) 67 | pde_loss = np.zeros(epochs) 68 | bc_loss = np.zeros(epochs) 69 | 70 | # Main training loop 71 | for i in range(epochs): 72 | 73 | n_batches = 0 74 | for (pdes) in ds: 75 | 76 | PDEloss, grads = trainStep(pdes, model, eqn, extra_ders) 77 | 78 | # Gradient step 79 | opt.apply_gradients(zip(grads, model.trainable_variables)) 80 | ## One more batch done 81 | n_batches += 1 82 | epoch_loss[i] += PDEloss 83 | pde_loss[i] += PDEloss 84 | 85 | epoch_loss[i] /= n_batches 86 | 87 | 88 | if (np.mod(i, 100)==0): 89 | print("PDE loss in {}th epoch: {: 6.4f}.".format(i, PDEloss.numpy())) 90 | 91 | return epoch_loss, iv_loss, bc_loss, pde_loss, model -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_PDEs_tx/Tutorials_PDEs_tx_DeepONet/heatPeriodic_don.md: -------------------------------------------------------------------------------- 1 | # Solving the Heat equation with Periodic boundaries with a DeepONet 2 | 3 | ## Problem 4 | We will look at solving a specific instance of the Heat equation 5 | 6 | $$ 0.08\frac{\partial^2 u}{\partial x^2}= \frac{\partial u}{\partial t} $$ 7 | 8 | Over $t\in[0,1], x\in[0,1]$, with initial condition 9 | 10 | $$u(x, 0) = \sin(\pi x)$$ 11 | 12 | ## Implementation 13 | 14 | First import package. We will only import pde_Solvers, pde_Initials, and pde_Boundaries_2var from PinnDE as that is all that is needed. Since we need to represent pi for the initial condition, we also import numpy. We also use tensorflow's sin (we could use numpy in this instance, however with hard constraints we need tensorflows so we use this always). 15 | 16 | import pinnde.pde_Solvers as pde_Solvers 17 | import pinnde.pde_Initials as pde_Initials 18 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 19 | import numpy as np 20 | import tensorflow as tf 21 | 22 | We first can create our initial condition as a python lambda function. This **must** be of 1 variable in a time dependent equation. 23 | We declare t boundary, x_boundary, the order of t, and number of points along initial t. 24 | 25 | u0 = lambda x: tf.sin(np.pi*x) 26 | t_bdry = [0,1] 27 | x_bdry = [0,1] 28 | t_order = 1 29 | N_iv = 100 30 | initials = pde_Initials.setup_initials_2var(t_bdry, x_bdry, t_order, [u0], N_iv) 31 | 32 | We then setup the boundaries. As we are using periodic boundaries this is done easily 33 | 34 | boundaries = pde_Boundaries_2var.setup_boundaries_periodic_tx(t_bdry, x_bdry) 35 | 36 | Next, we declare our equation, number of points, number of sensors, sensor range, and epochs. Equation must be in form eqn = 0 37 | 38 | eqn = "0.08*uxx - ut" 39 | N_pde = 10000 40 | N_sensors = 50000 41 | sensor_range = [-2, 2] 42 | epochs = 1000 43 | 44 | To solve, we simply call the corresponding solving function to our problem, and train the model 45 | 46 | mymodel = pde_Solvers.solvePDE_DeepONet_tx(eqn, initials, boundaries, N_pde, 47 | N_sensors, sensor_range) 48 | mymodel.train_model(epochs) 49 | 50 | If we want to quickly vizualize our data from training we can add after the solving function 51 | 52 | mymodel.plot_epoch_loss() 53 | 54 | mymodel.plot_solution_prediction() 55 | 56 | ## All Code 57 | 58 | import pinnde.pde_Solvers as pde_Solvers 59 | import pinnde.pde_Initials as pde_Initials 60 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 61 | import numpy as np 62 | import tensorflow as tf 63 | 64 | u0 = lambda x: tf.sin(np.pi*x) 65 | t_bdry = [0,1] 66 | x_bdry = [0,1] 67 | t_order = 1 68 | N_iv = 100 69 | initials = pde_Initials.setup_initials_2var(t_bdry, x_bdry, t_order, [u0], N_iv) 70 | 71 | boundaries = pde_Boundaries_2var.setup_boundaries_periodic_tx(t_bdry, x_bdry) 72 | 73 | eqn = "0.08*uxx - ut" 74 | N_pde = 10000 75 | N_sensors = 50000 76 | sensor_range = [-2, 2] 77 | epochs = 1000 78 | 79 | mymodel = pde_Solvers.solvePDE_DeepONet_tx(eqn, initials, boundaries, N_pde, 80 | N_sensors, sensor_range) 81 | mymodel.train_model(epochs) 82 | 83 | mymodel.plot_epoch_loss() 84 | 85 | mymodel.plot_solution_prediction() -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_PDEs_xy/Tutorials_PDEs_xy_PINN/poisson1.md: -------------------------------------------------------------------------------- 1 | # Solving the Poisson equation (#1) with Dirichlet boundaries, specifying the PINN architecture 2 | 3 | ## Problem 4 | We will look at solving a specific instance of the Poisson equation 5 | 6 | $$\frac{\partial^2 u}{\partial x^2} + \frac{\partial^2 u}{\partial y^2} = -2\pi^2\cos(\pi x)\sin(\pi y)$$ 7 | 8 | Over $x\in[-1,1], y\in[-1,1]$, with boundary conditions 9 | 10 | $$u(x, -1) = u(x, 1) = u(-1, y) = u(1, y) = \cos(\pi x)\sin(\pi y)$$ 11 | 12 | ## Implementation 13 | 14 | First import package. We will only import pde_Solvers and pde_Boundaries_2var from PinnDE as that is all that is needed. Since we need to represent pi for the equation, we also import numpy. We also use tensorflow's sin and cos (we could not use numpy in this instance as with hard constraints we need tensorflows). 15 | 16 | import pinnde.pde_Solvers as pde_Solvers 17 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 18 | import numpy as np 19 | import tensorflow as tf 20 | 21 | We then setup the boundaries. We just declare the x boundary, y boundary, number of points along bondary, and declare the 22 | boundary conditions as a python lambda function which **must** be of 2 variable in a time independent equation 23 | 24 | x_bdry = [-1, 1] 25 | y_bdry = [-1, 1] 26 | N_bc = 100 27 | all_boundary = lambda x, y: tf.cos(np.pi*x)*tf.sin(np.pi*y) 28 | boundaries = pde_Boundaries_2var.setup_boundaries_dirichlet_xy(x_bdry, y_bdry, N_bc, 29 | all_boundaries_cond=all_boundary) 30 | 31 | Next, we declare our equation, number of points, and epochs. Equation must be in form eqn = 0 32 | 33 | eqn = "uxx + uyy - (-2*np.pi**2*tf.cos(np.pi*x)*tf.sin(np.pi*y))" 34 | N_pde = 10000 35 | epochs = 1000 36 | 37 | If we also want to change the default number of internal layers (4) and nodes (60) per layer in our PINN, we can declare them as well 38 | 39 | layers = 6 40 | nodes = 50 41 | 42 | To solve, we simply call the corresponding solving function to our problem, and train the model 43 | 44 | mymodel = pde_Solvers.solvePDE_xy(eqn, boundaries, N_pde, 45 | net_layers = layers, net_units = nodes) 46 | mymodel.train_model(epochs) 47 | 48 | If we want to quickly vizualize our data from training we can add after the solving function 49 | 50 | mymodel.plot_epoch_loss() 51 | 52 | mymodel.plot_solution_prediction() 53 | 54 | ## All Code 55 | 56 | import pinnde.pde_Solvers as pde_Solvers 57 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 58 | import numpy as np 59 | import tensorflow as tf 60 | 61 | x_bdry = [-1, 1] 62 | y_bdry = [-1, 1] 63 | N_bc = 100 64 | all_boundary = lambda x, y: tf.cos(np.pi*x)*tf.sin(np.pi*y) 65 | boundaries = pde_Boundaries_2var.setup_boundaries_dirichlet_xy(x_bdry, y_bdry, N_bc, 66 | all_boundaries_cond=all_boundary) 67 | 68 | eqn = "uxx + uyy - (-2*np.pi**2*tf.cos(np.pi*x)*tf.sin(np.pi*y))" 69 | N_pde = 10000 70 | epochs = 1000 71 | layers = 6 72 | nodes = 50 73 | 74 | mymodel = pde_Solvers.solvePDE_xy(eqn, boundaries, N_pde, 75 | net_layers = layers, net_units = nodes) 76 | mymodel.train_model(epochs) 77 | 78 | mymodel.plot_epoch_loss() 79 | 80 | mymodel.plot_solution_prediction() 81 | -------------------------------------------------------------------------------- /src/pinnde/data/invpinndata.py: -------------------------------------------------------------------------------- 1 | from .data import data 2 | import numpy as np 3 | 4 | class invpinndata(data): 5 | """ 6 | Class for data on purely spatial inverse problems with a pinn. 7 | """ 8 | 9 | def __init__(self, domain, boundaries, dimdata, udata, n_clp=10000, n_bc=600): 10 | """ 11 | Constructor for class 12 | 13 | Args: 14 | domain (domain): Domain to generate data on. 15 | boundaries (boundaries): Boundary to generate data on. 16 | dimdata (list): List of data across spatial dimensions in which udata is recorded on for each u, 17 | each as (N,) shape tensors. 18 | udata (list): List containing data for each u solving for to solve inverse cosntants, each as 19 | (N,) shape tensors 20 | n_clp (int): Number of collocation points. 21 | n_bc (int): Number of boundary condition points. 22 | """ 23 | super().__init__(5) 24 | self._domain = domain 25 | self._boundaries = boundaries 26 | self._n_clp = n_clp 27 | self._n_bc = n_bc 28 | self._clp = domain.sampleDomain(n_clp) 29 | self._bcp = boundaries.boundaryPoints(n_bc) 30 | self._udata = udata 31 | self._dimdata = dimdata 32 | self._n_invp = np.shape(udata[0])[0] 33 | self._invp = self.makeInverseData(dimdata, udata) 34 | return 35 | 36 | def get_clp(self): 37 | """ 38 | Returns: 39 | (tensor): Sampled collocation points. 40 | """ 41 | return self._clp 42 | 43 | def get_bcp(self): 44 | """ 45 | Returns: 46 | (tensor): Sampled boundary points. 47 | """ 48 | return self._bcp 49 | 50 | def get_domain(self): 51 | """ 52 | Returns: 53 | (domain): Domain data is generated on. 54 | """ 55 | return self._domain 56 | 57 | def get_boundaries(self): 58 | """ 59 | Returns: 60 | (boundaries): Boundary data is generated on. 61 | """ 62 | return self._boundaries 63 | 64 | def get_n_clp(self): 65 | """ 66 | Returns: 67 | (int): Number of collocation points sampled. 68 | """ 69 | return self._n_clp 70 | 71 | def get_n_bc(self): 72 | """ 73 | Returns: 74 | (int): Number of boundary points sampled. 75 | """ 76 | return self._n_bc 77 | 78 | def get_n_invp(self): 79 | """ 80 | Returns: 81 | (int): Number of data points for inverse data given. 82 | """ 83 | return self._n_invp 84 | 85 | def get_invp(self): 86 | """ 87 | Returns: 88 | (tensor): Sampled data points for inverse data. 89 | """ 90 | return self._invp 91 | 92 | def makeInverseData(self, dimdata, udata): 93 | """ 94 | Combines data user provided into consistent trainable set 95 | 96 | Args: 97 | dimdata (list): List of data across spatial dimensions in which udata is recorded on for each u, 98 | each as (N,) shape tensors. 99 | udata (list): List containing data for each u solving for to solve inverse cosntants, each as 100 | (N,) shape tensors 101 | """ 102 | ddata = np.column_stack(dimdata) 103 | funcdata = np.column_stack(udata) 104 | data = np.column_stack([ddata, funcdata]) 105 | return data -------------------------------------------------------------------------------- /src/pinnde/domain/NRect.py: -------------------------------------------------------------------------------- 1 | from .domain import domain 2 | import numpy as np 3 | import tensorflow as tf 4 | from pyDOE import lhs 5 | 6 | class NRect(domain): 7 | """ 8 | Class for solving purely spatial problems on N dimensional hyperrectangles 9 | """ 10 | 11 | def __init__(self, dim, xmins, xmaxs): 12 | """ 13 | Constructor for class 14 | 15 | Args: 16 | dim (int): Spatial dimension of domain. 17 | xmins (list): Minimum values along each dimension, e.g, [-1, -1]. 18 | xmaxs (list): Maximum values along each dimension, e.g, [1, 1]. 19 | """ 20 | super().__init__(dim) 21 | super().set_bdry_components(self._dim * 2) 22 | super().set_max_dim_vals(xmaxs) 23 | super().set_min_dim_vals(xmins) 24 | self._xmins = xmins 25 | self._xmaxs = xmaxs 26 | 27 | def isInside(self, point): 28 | """ 29 | Args: 30 | point (list): Point in spatial dimensions of the hyperrectangle 31 | 32 | Returns: 33 | (bool): True if point is interior to the hyperrectangle, False otherwise 34 | """ 35 | for i in range(self._dim): 36 | if ((self._xmins[i] > point[i]) or (self._xmaxs[i] < point[i])): 37 | return False 38 | return True 39 | 40 | def onBoundary(self, point): 41 | """ 42 | Args: 43 | point (list): Point in spatial dimensions of the hyperrectangle 44 | 45 | Returns: 46 | (bool): True if point is on the boundary of the hyperrectangle, False otherwise 47 | """ 48 | for i in range(self._dim): 49 | # maybe replace with isclose to 50 | if ((self._xmins[i] == point[i]) or (self._xmaxs[i] == point[i])): 51 | return True 52 | return False 53 | 54 | def sampleBoundary(self, n_bc): 55 | """ 56 | Samples boundary of hyperrectangle. 57 | 58 | Args: 59 | n_bc (int): Number of points to sample in the boundary. 60 | 61 | Returns: 62 | (tensor): Sampled boundary points. 63 | """ 64 | sample_blocks = self._dim * 2 65 | sample_sizes = round(n_bc / sample_blocks) 66 | super().set_bdry_component_size(sample_sizes) 67 | super().set_bdry_components(self._dim * 2) 68 | min_points = lhs(self._dim, sample_sizes) 69 | min_points[:, 0] = 0 70 | max_points = lhs(self._dim, sample_sizes) 71 | max_points[:, 0] = 1 72 | points = np.concatenate((min_points, max_points), axis=0) 73 | for i in range(self._dim-1): 74 | min_points = lhs(self._dim, sample_sizes) 75 | min_points[:, i+1] = 0 76 | max_points = lhs(self._dim, sample_sizes) 77 | max_points[:, i+1] = 1 78 | points = np.concatenate((points, min_points), axis=0) 79 | points = np.concatenate((points, max_points), axis=0) 80 | for i in range (self._dim): 81 | points[:, i] = self._xmins[i] + (self._xmaxs[i] - self._xmins[i])*points[:, i] 82 | return points 83 | 84 | def sampleDomain(self, n_clp): 85 | """ 86 | Samples interior of hyperrectangle. 87 | 88 | Args: 89 | n_clp (int): Number of points to sample in the interior of the ellipsoid. 90 | 91 | Returns: 92 | (tensor): Sampled interior points. 93 | """ 94 | points = lhs(self._dim, n_clp) 95 | for i in range (self._dim): 96 | points[:, i] = self._xmins[i] + (self._xmaxs[i] - self._xmins[i])*points[:, i] 97 | return points 98 | -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_PDEs_tx/Tutorials_PDEs_tx_DeepONet/kvdHard_don.md: -------------------------------------------------------------------------------- 1 | # Solving the Korteweg–De Vries equation with periodic boundaries and Hard constraint Initial condition with a DeepONet 2 | 3 | ## Problem 4 | We will look at solving a specific instance of the KdV equation 5 | 6 | $$\frac{\partial u}{\partial t} + u\frac{\partial u}{\partial x} - (-0.0025)\frac{\partial^3 u}{\partial x^3} = 0 $$ 7 | 8 | Over $t\in[0,1], x\in[-1,1]$, with initial condition 9 | 10 | $$u(x, 0) = \cos(\pi x)$$ 11 | 12 | ## Implementation 13 | 14 | First import package. We will only import pde_Solvers, pde_Initials, and pde_Boundaries_2var from PinnDE as that is all that is needed. Since we need to represent pi for the initial condition, we also import numpy. We also use tensorflow's cos (we could not use numpy in this instance as with hard constraints we need tensorflows). 15 | 16 | import pinnde.pde_Solvers as pde_Solvers 17 | import pde_Initials as pde_Initials 18 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 19 | import numpy as np 20 | import tensorflow as tf 21 | 22 | We first can create our initial condition as a python lambda function. This **must** be of 1 variable in a time dependent equation. 23 | We declare t boundary, x_boundary, the order of t, and number of points along initial t. 24 | 25 | u0 = lambda x: tf.cos(np.pi*x) 26 | t_bdry = [0,1] 27 | x_bdry = [-1,1] 28 | t_oder = 1 29 | N_iv = 100 30 | initials = pde_Initials.setup_initials_2var(t_bdry, x_bdry, t_order, [u0], N_iv) 31 | 32 | We then setup the boundaries. As we are using periodic boundaries this is done easily 33 | 34 | boundaries = pde_Boundaries_2var.setup_boundaries_periodic_tx(t_bdry, x_bdry) 35 | 36 | Next, we declare our equation, number of points, number of sensors, sensor range, and epochs. Equation must be in form eqn = 0 37 | 38 | eqn = "ut+u*ux-(-0.0025)*uxxx" 39 | N_pde = 10000 40 | N_sensors = 10000 41 | sensor_range = [-2, 2] 42 | epochs = 2500 43 | 44 | To solve, we simply call the corresponding solving function to our problem, specifying the constraint as hard, and train the model 45 | 46 | mymodel = pde_Solvers.solvePDE_DeepONet_tx(eqn, initials, boundaries, N_pde, 47 | N_sensors, sensor_range, constraint = "hard") 48 | mymodel.train_model(epochs) 49 | 50 | If we want to quickly vizualize our data from training we can add after the solving function 51 | 52 | mymodel.plot_epoch_loss() 53 | 54 | mymodel.plot_solution_prediction() 55 | 56 | ## All Code 57 | 58 | import pinnde.pde_Solvers as pde_Solvers 59 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 60 | import numpy as np 61 | import tensorflow as tf 62 | 63 | u0 = lambda x: tf.cos(np.pi*x) 64 | t_bdry = [0,1] 65 | x_bdry = [-1,1] 66 | t_oder = 1 67 | N_iv = 100 68 | initials = pde_Initials.setup_initials_2var(t_bdry, x_bdry, t_order, [u0], N_iv) 69 | 70 | boundaries = pde_Boundaries_2var.setup_boundaries_periodic_tx(t_bdry, x_bdry) 71 | 72 | eqn = "ut+u*ux-(-0.0025)*uxxx" 73 | N_pde = 10000 74 | N_sensors = 10000 75 | sensor_range = [-2, 2] 76 | epochs = 2500 77 | 78 | mymodel = pde_Solvers.solvePDE_DeepONet_tx(eqn, initials, boundaries, N_pde, 79 | N_sensors, sensor_range, constraint = "hard") 80 | mymodel.train_model(epochs) 81 | 82 | mymodel.plot_epoch_loss() 83 | 84 | mymodel.plot_solution_prediction() -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_PDEs_xy/Tutorials_PDEs_xy_PINN/poisson2.md: -------------------------------------------------------------------------------- 1 | # Solving the Poisson equation (#2) with Dirichlet boundaries 2 | 3 | ## Problem 4 | We will look at solving a specific instance of the Poisson equation 5 | 6 | $$\frac{\partial^2 u}{\partial x^2} + \frac{\partial^2 u}{\partial y^2} = -(0.4\pi^2\sin(2\pi x) + \frac{200\tanh(10x)}{\cosh(10x)^2}) 7 | \sin(2\pi y) $$ 8 | 9 | $$- 4\pi^2(0.1\sin(2\pi x) + \tanh(10x))\sin(2\pi y)$$ 10 | 11 | Over $x\in[-1,1], y\in[-1,1]$, with boundary conditions 12 | 13 | $$u(x, -1) = u(x, 1) = u(-1, y) = u(1, y) = (0.1\sin(2\pi x) + \tanh(10x))\sin(2\pi y)$$ 14 | 15 | ## Implementation 16 | 17 | First import package. We will only import pde_Solvers and pde_Boundaries_2var from PinnDE as that is all that is needed. Since we need to represent pi for the equation, we also import numpy. We also use tensorflow's trig funcs (we could not use numpy in this instance as with hard constraints we need tensorflows). 18 | 19 | import pinnde.pde_Solvers as pde_Solvers 20 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 21 | import numpy as np 22 | import tensorflow as tf 23 | 24 | We then setup the boundaries. We just declare the x boundary, y boundary, number of points along bondary, and declare the 25 | boundary conditions as a python lambda function which **must** be of 2 variable in a time independent equation 26 | 27 | x_bdry = [-1, 1] 28 | y_bdry = [-1, 1] 29 | N_bc = 200 30 | all_boundary = lambda x, y: (0.1*tf.sin(2*np.pi*x) + tf.math.tanh(10*x))*tf.sin(2*np.pi*y) 31 | 32 | boundaries = pde_Boundaries_2var.setup_boundaries_dirichlet_xy(x_bdry, y_bdry, N_bc, 33 | all_boundaries_cond=all_boundary) 34 | 35 | Next, we declare our equation, number of points, and epochs. Equation must be in form eqn = 0 36 | 37 | eqn = "uxx + uyy - (-(0.4*np.pi**2*tf.sin(2*np.pi*x)+200*tf.math.tanh(10*x)/tf.math.cosh(10*x)**2) 38 | *tf.sin(2*np.pi*y) - 4*np.pi**2*(0.1*tf.sin(2*np.pi*x) + tf.math.tanh(10*x))*tf.sin(2*np.pi*y))" 39 | N_pde = 10000 40 | epochs = 2500 41 | 42 | To solve, we simply call the corresponding solving function to our problem, and train the model 43 | 44 | mymodel = pde_Solvers.solvePDE_xy(eqn, boundaries, N_pde) 45 | mymodel.train_model(epochs) 46 | 47 | If we want to quickly vizualize our data from training we can add after the solving function 48 | 49 | mymodel.plot_epoch_loss() 50 | 51 | mymodel.plot_solution_prediction() 52 | 53 | ## All Code 54 | 55 | import pinnde.pde_Solvers as pde_Solvers 56 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 57 | import numpy as np 58 | import tensorflow as tf 59 | 60 | x_bdry = [-1, 1] 61 | y_bdry = [-1, 1] 62 | N_bc = 200 63 | all_boundary = lambda x, y: (0.1*tf.sin(2*np.pi*x) + tf.math.tanh(10*x))*tf.sin(2*np.pi*y) 64 | 65 | boundaries = pde_Boundaries_2var.setup_boundaries_dirichlet_xy(x_bdry, y_bdry, N_bc, 66 | all_boundaries_cond=all_boundary) 67 | 68 | eqn = "uxx + uyy - (-(0.4*np.pi**2*tf.sin(2*np.pi*x)+200*tf.math.tanh(10*x)/tf.math.cosh(10*x)**2)*\ 69 | tf.sin(2*np.pi*y) - 4*np.pi**2*(0.1*tf.sin(2*np.pi*x) + tf.math.tanh(10*x))*tf.sin(2*np.pi*y))" 70 | N_pde = 10000 71 | epochs = 2500 72 | 73 | mymodel = pde_Solvers.solvePDE_xy(eqn, boundaries, N_pde) 74 | mymodel.train_model(epochs) 75 | 76 | mymodel.plot_epoch_loss() 77 | 78 | mymodel.plot_solution_prediction() 79 | -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_PDEs_tx/Tutorials_PDEs_tx_DeepONet/burgersPeriodic_don.md: -------------------------------------------------------------------------------- 1 | # Solving the Burgers equation with Periodic boundaries with a DeepONet 2 | 3 | ## Problem 4 | We will look at solving a specific instance of the Burgers equation (v = $\frac{0.01}{\pi}$) 5 | 6 | $$\frac{\partial u}{\partial t} + u\frac{\partial u}{\partial x} = (\frac{0.01}{\pi})\frac{\partial^2 u}{\partial x^2} $$ 7 | 8 | Over $t\in[0,1], x\in[-1,1]$, with initial condition 9 | 10 | $$u(x, 0) = -\sin(\pi x)$$ 11 | 12 | ## Implementation 13 | 14 | First import package. We will only import pde_Solvers, pde_Initials, and pde_Boundaries_2var from PinnDE as that is all that is needed. Since we need to represent pi for the initial condition, we also import numpy. We also use tensorflow's sin (we could use numpy in this instance, however with hard constraints we need tensorflows so we use this always). 15 | 16 | import pinnde.pde_Solvers as pde_Solvers 17 | import pinnde.pde_Initials as pde_Initials 18 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 19 | import numpy as np 20 | import tensorflow as tf 21 | 22 | We first can create our initial condition as a python lambda function. This **must** be of 1 variable in a time dependent equation. 23 | We declare t boundary, x_boundary, the order of t, and number of points along initial t. 24 | 25 | u0 = lambda x: -tf.sin(np.pi*x) 26 | t_bdry = [0,1] 27 | x_bdry = [-1,1] 28 | t_order = 1 29 | N_iv = 100 30 | initials = pde_Initials.setup_initials_2var(t_bdry, x_bdry, t_order, [u0], N_iv) 31 | 32 | We then setup the boundaries. As we are using periodic boundaries this is done easily 33 | 34 | boundaries = pde_Boundaries_2var.setup_boundaries_periodic_tx(t_bdry, x_bdry) 35 | 36 | Next, we declare our equation, number of points, number of sensors, sensor range, and epochs. Equation must be in form eqn = 0 37 | 38 | eqn = "ut+u*ux-(0.01/np.pi)*uxx" 39 | N_pde = 10000 40 | N_sensors = 50000 41 | sensor_range = [-2, 2] 42 | epochs = 1000 43 | 44 | To solve, we simply call the corresponding solving function to our problem, and train the model 45 | 46 | mymodel = pde_Solvers.solvePDE_DeepONet_tx(eqn, initials, boundaries, N_pde, 47 | N_sensors, sensor_range) 48 | mymodel.train_model(epochs) 49 | 50 | If we want to quickly vizualize our data from training we can add after the solving function 51 | 52 | mymodel.plot_epoch_loss() 53 | 54 | mymodel.plot_solution_prediction() 55 | 56 | ## All Code 57 | 58 | import pinnde.pde_Solvers as pde_Solvers 59 | import pinnde.pde_Initials as pde_Initials 60 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 61 | import numpy as np 62 | import tensorflow as tf 63 | 64 | u0 = lambda x: -tf.sin(np.pi*x) 65 | t_bdry = [0,1] 66 | x_bdry = [-1,1] 67 | t_order = 1 68 | N_iv = 100 69 | initials = pde_Initials.setup_initials_2var(t_bdry, x_bdry, t_order, [u0], N_iv) 70 | 71 | boundaries = pde_Boundaries_2var.setup_boundaries_periodic_tx(t_bdry, x_bdry) 72 | 73 | eqn = "ut+u*ux-(0.01/np.pi)*uxx" 74 | N_pde = 10000 75 | N_sensors = 50000 76 | sensor_range = [-2, 2] 77 | epochs = 1000 78 | 79 | mymodel = pde_Solvers.solvePDE_DeepONet_tx(eqn, initials, boundaries, N_pde, 80 | N_sensors, sensor_range) 81 | mymodel.train_model(epochs) 82 | 83 | mymodel.plot_epoch_loss() 84 | 85 | mymodel.plot_solution_prediction() -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_PDEs_xy/Tutorials_PDEs_xy_DeepONet/helmholtz_don.md: -------------------------------------------------------------------------------- 1 | # Solving the Helmholtz equation with Hard constrainted Dirichlet boundaries 2 | 3 | ## Problem 4 | We will look at solving a specific instance of the Helmholtz equation 5 | 6 | $$\frac{\partial^2 u}{\partial x^2} + \frac{\partial^2 u}{\partial y^2} + 2\pi^2\sin(2\pi x)\sin(2\pi y) 7 | = -2\pi^2 $$ 8 | 9 | Over $x\in[0,1], y\in[0,1]$, with boundary conditions 10 | 11 | $$u(x, 0) = u(x, 1) = u(0, y) = u(1, y) = 0 $$ 12 | 13 | ## Implementation 14 | 15 | First import package. We will only import pde_Solvers and pde_Boundaries_2var from PinnDE as that is all that is needed. Since we need to represent pi for the equation, we also import numpy. We also use tensorflow's sin (we could not use numpy in this instance as with hard constraints we need tensorflows). 16 | 17 | import pinnde.pde_Solvers as pde_Solvers 18 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 19 | import numpy as np 20 | import tensorflow as tf 21 | 22 | We then setup the boundaries. We just declare the x boundary, y boundary, number of points along bondary, and declare the 23 | boundary conditions as a python lambda function which **must** be of 2 variable in a time independent equation. Note 24 | how we must use the vairbale declared even just for making the boundaries a constant 25 | 26 | x_bdry = [0, 1] 27 | y_bdry = [0, 1] 28 | N_bc = 100 29 | boundary = lambda x, y: 0+0*x 30 | boundaries = pde_Boundaries_2var.setup_boundaries_dirichlet_xy(x_bdry, y_bdry, N_bc, 31 | all_boundaries_cond=boundary) 32 | 33 | Next, we declare our equation, number of points, number of sensors, sensor range, and epochs. Equation must be in form eqn = 0 34 | 35 | eqn = "uxx + uyy + ((np.pi*2)**2)*u + ((np.pi*2)**2)*tf.sin((np.pi*2)*x)*tf.sin((np.pi*2)*y)" 36 | N_pde = 10000 37 | epochs = 1500 38 | N_sensors = 40000 39 | sensor_range = [-2, 2] 40 | 41 | To solve, we simply call the corresponding solving function to our problem, declaring a hard constraint, and train the model 42 | 43 | mymodel = pde_Solvers.solvePDE_DeepONet_xy(eqn, boundaries, N_pde, N_sensors, 44 | sensor_range, constraint = "hard") 45 | mymodel.train_model(epochs) 46 | 47 | If we want to quickly vizualize our data from training we can add after the solving function 48 | 49 | mymodel.plot_epoch_loss() 50 | 51 | mymodel.plot_solution_prediction() 52 | 53 | ## All Code 54 | 55 | import pinnde.pde_Solvers as pde_Solvers 56 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 57 | import numpy as np 58 | import tensorflow as tf 59 | 60 | x_bdry = [0, 1] 61 | y_bdry = [0, 1] 62 | N_bc = 100 63 | boundary = lambda x, y: 0+0*x 64 | boundaries = pde_Boundaries_2var.setup_boundaries_dirichlet_xy(x_bdry, y_bdry, N_bc, 65 | all_boundaries_cond=boundary) 66 | 67 | eqn = "uxx + uyy + ((np.pi*2)**2)*u + ((np.pi*2)**2)*tf.sin((np.pi*2)*x)*tf.sin((np.pi*2)*y)" 68 | N_pde = 10000 69 | epochs = 1500 70 | N_sensors = 40000 71 | sensor_range = [-2, 2] 72 | 73 | mymodel = pde_Solvers.solvePDE_DeepONet_xy(eqn, boundaries, N_pde, N_sensors, 74 | sensor_range, constraint = "hard") 75 | mymodel.train_model(epochs) 76 | 77 | mymodel.plot_epoch_loss() 78 | 79 | mymodel.plot_solution_prediction() -------------------------------------------------------------------------------- /src/pinnde/data/timedondata.py: -------------------------------------------------------------------------------- 1 | from .dondata import dondata 2 | import numpy as np 3 | import tensorflow as tf 4 | from ..boundaries import odeicbc 5 | 6 | class timedondata(dondata): 7 | """ 8 | Class for data on spato-temporal problems with a deep operator network. 9 | """ 10 | 11 | def __init__(self, domain, boundaries, initials, 12 | n_clp=10000, n_bc=600, n_ic=600, n_sensors=1000): 13 | """ 14 | Constructor for class 15 | 16 | Args: 17 | domain (domain): Domain to generate data on. 18 | boundaries (boundaries): Boundary to generate data on. 19 | initials (initials): Initial conditions to generate data on. 20 | n_clp (int): Number of collocation points. 21 | n_bc (int): Number of boundary condition points. 22 | n_ic (int): Number of initial condition points. 23 | n_sensors (int): Number of sensors to sample u with. 24 | """ 25 | 26 | self._initials = initials 27 | self._n_iv = n_ic 28 | self._icp = initials.sampleInitials(n_ic) 29 | super().__init__(domain, boundaries, n_clp, n_bc, n_sensors) 30 | # self._sensors = self.generate_sensors() 31 | self.set_data_type(4) 32 | 33 | def generate_sensors(self): 34 | """ 35 | Function to generate sensors for network. 36 | 37 | Returns: 38 | (tensor): Sampled sensors. 39 | """ 40 | if isinstance(self._boundaries, odeicbc): 41 | u = np.random.uniform(min(self._boundaries.get_conditions())-1, max(self._boundaries.get_conditions())+1, (self._n_clp,self._n_sensors)) 42 | usensors = np.float32(u) 43 | return usensors 44 | 45 | else: 46 | # initfunc = self._initials.get_lambdas()[0] 47 | # scalars = np.linspace(-2, 2, self._n_clp) 48 | # # scalars = np.random.uniform(-2, 2, self._n_clp) 49 | # clps = self._domain.sampleDomain(self._n_sensors) 50 | # func_points = [] 51 | # cols = np.shape(clps)[1] 52 | # for i in range(cols-1): 53 | # func_points.append(clps[:, i+1]) 54 | # u = initfunc(*func_points) 55 | 56 | # sensors = tf.tile(tf.expand_dims(u, 0), [self._n_clp, 1]) 57 | # sensors = scalars[:, None] * sensors 58 | # return sensors 59 | max_waves = 3 60 | clps = self._domain.sampleDomain(self._n_sensors) 61 | 62 | amplitudes = np.random.randn(self._n_clp, max_waves) 63 | phases = -np.pi*np.random.rand(self._n_clp, max_waves) + np.pi/2 64 | 65 | 66 | u = 0.0*np.repeat(np.expand_dims(clps[:,0:1].flatten(), axis=0), repeats=self._n_clp, axis=0) 67 | for i in range(max_waves): 68 | u += amplitudes[:,i:i+1] 69 | for i in range(self._domain.get_dim()): 70 | u = u*tf.sin((i+1)*np.repeat(np.expand_dims(clps[:, i:i+1].flatten(), axis=0), repeats=self._n_clp, axis=0) + phases[:,i:i+1]) 71 | usensors = np.float32(u.numpy()) 72 | return usensors 73 | 74 | def get_icp(self): 75 | """ 76 | Returns: 77 | (tensor): Sampled initial condition points. 78 | """ 79 | return self._icp 80 | 81 | def get_initials(self): 82 | """ 83 | Returns: 84 | (initials): Initial conditions data is generated on. 85 | """ 86 | return self._initials 87 | 88 | def get_n_ic(self): 89 | """ 90 | Returns: 91 | (int): Number of initial points sampled. 92 | """ 93 | return self._n_iv -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_PDEs_xy/Tutorials_PDEs_xy_DeepONet/poisson1_don.md: -------------------------------------------------------------------------------- 1 | # Solving the Poisson equation (#1) with Dirichlet boundaries, specifying the DeepONet architecture 2 | 3 | ## Problem 4 | We will look at solving a specific instance of the Poisson equation 5 | 6 | $$\frac{\partial^2 u}{\partial x^2} + \frac{\partial^2 u}{\partial y^2} = -2\pi^2\cos(\pi x)\sin(\pi y)$$ 7 | 8 | Over $x\in[-1,1], y\in[-1,1]$, with boundary conditions 9 | 10 | $$u(x, -1) = u(x, 1) = u(-1, y) = u(1, y) = \cos(\pi x)\sin(\pi y)$$ 11 | 12 | ## Implementation 13 | 14 | First import package. We will only import pde_Solvers and pde_Boundaries_2var from PinnDE as that is all that is needed. Since we need to represent pi for the equation, we also import numpy. We also use tensorflow's sin and cos (we could not use numpy in this instance as with hard constraints we need tensorflows). 15 | 16 | import pinnde.pde_Solvers as pde_Solvers 17 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 18 | import numpy as np 19 | import tensorflow as tf 20 | 21 | We then setup the boundaries. We just declare the x boundary, y boundary, number of points along bondary, and declare the 22 | boundary conditions as a python lambda function which **must** be of 2 variable in a time independent equation 23 | 24 | x_bdry = [-1, 1] 25 | y_bdry = [-1, 1] 26 | N_bc = 100 27 | all_boundary = lambda x, y: tf.cos(np.pi*x)*tf.sin(np.pi*y) 28 | boundaries = pde_Boundaries_2var.setup_boundaries_dirichlet_xy(x_bdry, y_bdry, N_bc, 29 | all_boundaries_cond=all_boundary) 30 | 31 | Next, we declare our equation, number of points, and epochs. Equation must be in form eqn = 0 32 | 33 | eqn = "uxx + uyy - (-2*np.pi**2*tf.cos(np.pi*x)*tf.sin(np.pi*y))" 34 | N_pde = 10000 35 | epochs = 1000 36 | N_sensors = 50000 37 | sensor_range = [-2, 2] 38 | 39 | If we also want to change the default number of internal layers (4) and nodes (60) per layer in our PINN, we can declare them as well 40 | 41 | layers = 6 42 | nodes = 50 43 | 44 | To solve, we simply call the corresponding solving function to our problem, and train the model 45 | 46 | mymodel = pde_Solvers.solvePDE_DeepONet_xy(eqn, boundaries, N_pde, N_sensors, 47 | sensor_range, net_layers = layers, net_units = nodes) 48 | mymodel.train_model(epochs) 49 | 50 | If we want to quickly vizualize our data from training we can add after the solving function 51 | 52 | mymodel.plot_epoch_loss() 53 | 54 | mymodel.plot_solution_prediction() 55 | 56 | ## All Code 57 | 58 | import pinnde.pde_Solvers as pde_Solvers 59 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 60 | import numpy as np 61 | import tensorflow as tf 62 | 63 | x_bdry = [-1, 1] 64 | y_bdry = [-1, 1] 65 | N_bc = 100 66 | all_boundary = lambda x, y: tf.cos(np.pi*x)*tf.sin(np.pi*y) 67 | boundaries = pde_Boundaries_2var.setup_boundaries_dirichlet_xy(x_bdry, y_bdry, N_bc, 68 | all_boundaries_cond=all_boundary) 69 | 70 | eqn = "uxx + uyy - (-2*np.pi**2*tf.cos(np.pi*x)*tf.sin(np.pi*y))" 71 | N_pde = 10000 72 | epochs = 1000 73 | N_sensors = 50000 74 | sensor_range = [-2, 2] 75 | layers = 6 76 | nodes = 50 77 | 78 | mymodel = pde_Solvers.solvePDE_DeepONet_xy(eqn, boundaries, N_pde, N_sensors, 79 | sensor_range, net_layers = layers, net_units = nodes) 80 | mymodel.train_model(epochs) 81 | 82 | mymodel.plot_epoch_loss() 83 | 84 | mymodel.plot_solution_prediction() -------------------------------------------------------------------------------- /docs/tutorials/legacy/Tutorials_PDEs_xy/Tutorials_PDEs_xy_DeepONet/lagaris_don.md: -------------------------------------------------------------------------------- 1 | # Solving Problem 5 in Lagaris with Hard constrainted Dirichlet boundaries 2 | 3 | ## Problem 4 | We will look at solving problem 5 found in [Lagaris et al.](https://arxiv.org/abs/physics/9705023), which demonstrates 5 | how to hard constraint dirichlet boundary conditions 6 | 7 | $$\frac{\partial^2 u}{\partial x^2} + \frac{\partial^2 u}{\partial y^2} = e^{-x}(x-2+y^3+6y) $$ 8 | 9 | Over $x\in[0,1], y\in[0,1]$, with boundary conditions 10 | 11 | $$u(0, y) = y^3, u(1, y) = (1+y^3)e^{-1} $$ 12 | 13 | $$u(x, 0) = xe^{-x}, u(x, 1) = e^{-x}(x+1)$$ 14 | 15 | The analytic solution is $e^{-x}(x + y^3)$ 16 | 17 | ## Implementation 18 | 19 | First import package. We will only import pde_Solvers and pde_Boundaries_2var from PinnDE as that is all that is needed. Since we need to represent e for the equation, we also import numpy. 20 | 21 | import pinnde.pde_Solvers as pde_Solvers 22 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 23 | import numpy as np 24 | 25 | We then setup the boundaries. We just declare the x boundary, y boundary, number of points along bondary, and declare the 26 | boundary conditions as a python lambda function which **must** be of 2 variable in a time independent equation. 27 | 28 | x_bdry = [0, 1] 29 | y_bdry = [0, 1] 30 | N_bc = 400 31 | x_left = lambda x, y: y**3 32 | x_right = lambda x, y: (1+y**3)/(np.e) 33 | y_lower = lambda x, y: x/(np.e**x) 34 | y_upper = lambda x, y: (x+1)/(np.e**x) 35 | 36 | boundaries = pde_Boundaries_2var.setup_boundaries_dirichlet_xy(x_bdry,y_bdry,N_bc, xleft_boundary_cond=x_left, 37 | xright_boundary_cond=x_right, ylower_boundary_cond=y_lower, yupper_upper_cond=y_upper) 38 | 39 | Next, we declare our equation, number of points, and epochs. Equation must be in form eqn = 0 40 | 41 | eqn = "uxx+uyy - (x-2+6*y+y**3)/(np.e**x)" 42 | N_pde = 10000 43 | epochs = 1000 44 | N_sensors = 10000 45 | sensor_range = [-2, 2] 46 | 47 | To solve, we simply call the corresponding solving function to our problem, declaring a hard constraint, and train the model 48 | 49 | mymodel = pde_Solvers.solvePDE_DeepONet_xy(eqn, boundaries, N_pde, N_sensors, 50 | sensor_range, constraint = "hard") 51 | mymodel.train_model(epochs) 52 | 53 | If we want to quickly vizualize our data from training we can add after the solving function 54 | 55 | mymodel.plot_epoch_loss() 56 | 57 | mymodel.plot_solution_prediction() 58 | 59 | ## All Code 60 | 61 | import pinnde.pde_Solvers as pde_Solvers 62 | import pinnde.pde_Boundaries_2var as pde_Boundaries_2var 63 | import numpy as np 64 | 65 | x_bdry = [0, 1] 66 | y_bdry = [0, 1] 67 | N_bc = 400 68 | x_left = lambda x, y: y**3 69 | x_right = lambda x, y: (1+y**3)/(np.e) 70 | y_lower = lambda x, y: x/(np.e**x) 71 | y_upper = lambda x, y: (x+1)/(np.e**x) 72 | 73 | boundaries = pde_Boundaries_2var.setup_boundaries_dirichlet_xy(x_bdry,y_bdry,N_bc, xleft_boundary_cond=x_left, 74 | xright_boundary_cond=x_right, ylower_boundary_cond=y_lower, yupper_boundary_cond=y_upper) 75 | 76 | eqn = "uxx+uyy - (x-2+6*y+y**3)/(np.e**x)" 77 | N_pde = 10000 78 | epochs = 1000 79 | N_sensors = 10000 80 | sensor_range = [-2, 2] 81 | 82 | mymodel = pde_Solvers.solvePDE_DeepONet_xy(eqn, boundaries, N_pde, N_sensors, 83 | sensor_range, constraint = "hard") 84 | mymodel.train_model(epochs) 85 | 86 | mymodel.plot_epoch_loss() 87 | 88 | mymodel.plot_solution_prediction() -------------------------------------------------------------------------------- /docs/tutorials/pinntutorials/11advec.md: -------------------------------------------------------------------------------- 1 | # Solving the 1+1 linear advection equation with periodic boundaries with a PINN 2 | 3 | ## Problem 4 | We will look at solving the linear advection equation 5 | 6 | $$\frac{\partial u}{\partial t} + \frac{\partial u}{\partial x} = 0$$ 7 | 8 | Over $t\in[0,1], x\in[-1,1]$, with initial condition 9 | 10 | $$u(x, 0) = \cos(\pi x)$$ 11 | 12 | ## Implementation 13 | First import package. Since we need to represent pi for the initial condition, we also import numpy. We also use tensorflow's cos. 14 | 15 | import pinnde as p 16 | import numpy as np 17 | import tensorflow as tf 18 | 19 | We then first create our domain. We will solve this on the interval -1 to 1, and this equation has a time component, so 20 | we create a Time_NRect with 1 spatial dimensions, with xmins [-1] and xmaxs [1]. We will solve 21 | from time t=0 to t=1. 22 | 23 | timerange = [0, 1] 24 | tre = p.domain.Time_NRect(1, [-1], [1], timerange) 25 | 26 | We then define the boundaries for the domain. We will use periodic boundaries, and so we simply call the function 27 | 28 | bound = p.boundaries.periodic(tre) 29 | 30 | As we have a time component, we also must define our initial condition. Derivatives of t has order 1, so we have one initial function. 31 | This is done similarly to our boundaries. 32 | 33 | u0func = lambda x1: tf.cos(np.pi*x1) 34 | inits = p.initials.initials(tre, [u0func]) 35 | 36 | We then create the data for the pinn to train on. As we have a time component and we will use a pinn, we create a timepinndata object. 37 | Note that since we use periodic boundaries, no points will be used in training, however we still sample dummy points, so we provide only 38 | 10 to not slow down training. 39 | 40 | dat = p.data.timepinndata(tre, bound, inits, 12000, 10, 200) 41 | 42 | Then, we create the pinn model class and train the model for our desired epochs. When defining our equation, all spatial variables are denoted 43 | x1, x2, etc. So our equation is defined as follows. We also show how to define the internal layers and nodes to use. 44 | 45 | eqn = "ut+ux1" 46 | mymodel = p.models.pinn(dat, [eqn], layers=6, units=40) 47 | mymodel.train(500) 48 | 49 | If we want to quickly visualize our solution and epoch loss, we call the in-built plotting functions for this type of equation. 50 | 51 | p.plotters.plot_solution_prediction_time1D(mymodel) 52 | p.plotters.plot_epoch_loss(mymodel) 53 | 54 | ## All Code 55 | 56 | import pinnde as p 57 | import numpy as np 58 | import tensorflow as tf 59 | 60 | timerange = [0, 1] 61 | tre = p.domain.Time_NRect(1, [-1], [1], timerange) 62 | 63 | bound = p.boundaries.periodic(tre) 64 | 65 | u0func = lambda x1: tf.cos(np.pi*x1) 66 | inits = p.initials.initials(tre, [u0func]) 67 | 68 | dat = p.data.timepinndata(tre, bound, inits, 12000, 10, 200) 69 | 70 | eqn = "ut+ux1" 71 | mymodel = p.models.pinn(dat, [eqn], layers=6, units=40) 72 | mymodel.train(500) 73 | 74 | p.plotters.plot_solution_prediction_time1D(mymodel) 75 | p.plotters.plot_epoch_loss(mymodel) 76 | 77 | Or more concisely, 78 | 79 | import pinnde as p 80 | import numpy as np 81 | import tensorflow as tf 82 | 83 | tre = p.domain.Time_NRect(1, [-1], [1], [0,1]) 84 | bound = p.boundaries.periodic(tre) 85 | inits = p.initials.initials(tre, [lambda x1: tf.cos(np.pi*x1)]) 86 | dat = p.data.timepinndata(tre, bound, inits, 10000, 10, 200) 87 | mymodel = p.models.pinn(dat, ["ut+ux1"], layers=6, units=40) 88 | mymodel.train(500) 89 | p.plotters.plot_solution_prediction_time1D(mymodel) 90 | p.plotters.plot_epoch_loss(mymodel) -------------------------------------------------------------------------------- /src/pinnde/legacy/PDE/TrainingSelects/pde_trainingSelect_3var.py: -------------------------------------------------------------------------------- 1 | # import SpecificTraining.training_2variables.BCP_Training.pde_TrainingBCP_dirichlet_soft as trainBCP_dirichlet_soft 2 | # import SpecificTraining.training_2variables.BCP_Training.pde_TrainingBCP_periodic as trainBCP_periodic 3 | # import SpecificTraining.training_2variables.IBCP_Training.pde_TrainingIBCP_dirichlet_soft as trainIBCP_dirichlet_soft 4 | # import SpecificTraining.training_2variables.IBCP_Training.pde_TrainingIBCP_hard as trainIBCP_hard 5 | # import SpecificTraining.training_2variables.BCP_Training.pde_TrainingBCP_dirichlet_hard as trainBCP_dirichlet_hard 6 | # import SpecificTraining.training_2variables.BCP_Training.pde_TrainingBCP_neumann_soft as trainBCP_neumann_soft 7 | # import SpecificTraining.training_2variables.IBCP_Training.pde_TrainingIBCP_neumann_soft as trainIBCP_neumann_soft 8 | 9 | # import SpecificTraining.DeepONetTraining_2variables.DeepONet_IBCP.pde_TrainingDeepONetIBCP_periodic_hard as trainIBCPDON_periodic_hard 10 | # import SpecificTraining.DeepONetTraining_2variables.DeepONet_IBCP.pde_TrainingDeepONetIBCP_periodic_soft as trainIBCPDON_periodic_soft 11 | # import SpecificTraining.DeepONetTraining_2variables.DeepONet_IBCP.pde_TrainingDeepONetIBCP_dirichlet_soft as trainIBCPDON_dirichlet_soft 12 | # import SpecificTraining.DeepONetTraining_2variables.DeepONet_IBCP.pde_TrainingDeepONetIBCP_neumann_soft as trainIBCPDON_neumann_soft 13 | # import SpecificTraining.DeepONetTraining_2variables.DeepONet_BCP.pde_TrainingDeepONetBCP_periodic_hard as trainBCPDON_periodic_hard 14 | # import SpecificTraining.DeepONetTraining_2variables.DeepONet_BCP.pde_TrainingDeepONetBCP_dirichlet_soft as trainBCPDON_dirichlet_soft 15 | # import SpecificTraining.DeepONetTraining_2variables.DeepONet_BCP.pde_TrainingDeepONetBCP_neumann_soft as trainBCPDON_neumann_soft 16 | 17 | from ..SpecificTraining.training_3variables.ICBCP3_Training import pde_TrainingICBCP3_periodic_soft as trainICBCP3_periodic_soft 18 | from ..SpecificTraining.training_3variables.ICBCP3_Training import pde_TrainingICBCP3_periodic_hard as trainICBCP3_periodic_hard 19 | from ..SpecificTraining.training_3variables.ICBCP3_Training import pde_TrainingICBCP3_dirichlet_soft as trainICBCP3_dirichlet_soft 20 | 21 | 22 | 23 | def PINNtrainSelect_txy(pde_points, init_points, epochs, eqn, t_order, N_pde, N_iv, setup_boundaries, model, constraint, flag): #selecting which to train 24 | boundary_type = setup_boundaries[0] 25 | 26 | if flag == "ICBCP-txy": 27 | if boundary_type == "periodic_timeDependent": 28 | if constraint == "soft": 29 | return trainICBCP3_periodic_soft.PINNtrain(pde_points, init_points, t_order, setup_boundaries, epochs, eqn, N_pde, N_iv, model) 30 | elif constraint == "hard": 31 | return trainICBCP3_periodic_hard.PINNtrain(pde_points, setup_boundaries, epochs, eqn, N_pde, N_iv, model) 32 | 33 | elif boundary_type == "dirichlet_timeDependent": 34 | if constraint == "soft": 35 | return trainICBCP3_dirichlet_soft.PINNtrain(pde_points, init_points, t_order, setup_boundaries, epochs, eqn, N_pde, N_iv, model) 36 | elif constraint == "hard": 37 | return #trainIBCP_hard.PINNtrain(pde_points, init_points, t_order, setup_boundaries, epochs, eqn, N_pde, N_iv, model) 38 | 39 | elif boundary_type == "neumann_timeDependent": 40 | if constraint == "soft": 41 | return #trainIBCP_neumann_soft.PINNtrain(pde_points, init_points, t_order, setup_boundaries, epochs, eqn, N_pde, N_iv, model) 42 | 43 | else: 44 | raise Exception("Order/Constraint Not supported, please review") 45 | 46 | 47 | --------------------------------------------------------------------------------