-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #15 from OpenDA-Association/14-combining-pinns-and…
…-enkf 14 combining pinns and enkf
- Loading branch information
Showing
32 changed files
with
64,004 additions
and
20,941 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import numpy as np | ||
from openda.models.SaintVenantWithSmootherInstance import SaintVenantWithSmootherInstance | ||
|
||
|
||
class SaintVenantWithSmootherFactory: | ||
""" | ||
Interface of Saint-Venant Model Factory with Smoother | ||
@author Aron Schouten | ||
""" | ||
|
||
def __init__(self, f=None): | ||
""" | ||
Constructor | ||
""" | ||
if f is None: | ||
f = np.random.uniform(1e-4, 1e-3) | ||
|
||
names = ["D", "f", "g", "L", "n"] | ||
param_values = [15, f, 9.81, 55.e3, 11] | ||
param_uncertainty = [0, 0, 0, 0, 0] | ||
|
||
param = dict(zip(names, param_values)) | ||
param_uncertainty = dict(zip(names, param_uncertainty)) | ||
|
||
state = np.zeros(2*param['n'] + 1) | ||
state_uncertainty = np.ones(2*param['n'] + 1) * 0.02 | ||
state_uncertainty[-1] = 0 | ||
|
||
reftime = np.datetime64('2022-02-18T08:00:00') | ||
span = [reftime, np.timedelta64(5,'m'), reftime+np.timedelta64(2,'D')] # [0 seconds, 10 minutes, 2 days] | ||
|
||
self.model_attributes = (param, param_uncertainty, state, state_uncertainty, span) | ||
|
||
def get_instance(self, noise_config, main_or_ens): | ||
""" | ||
Create an instance of the stochastic Model. | ||
:param noise_config: dictionary as given by EnkfAlgorithm.xml for the noise configuration. | ||
:param main_or_ens: determines the ouput level of the model. | ||
:return: the stochastic Model instance. | ||
""" | ||
return SaintVenantWithSmootherInstance(self.model_attributes, noise_config, main_or_ens) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import numpy as np | ||
from scipy.sparse.linalg import spsolve | ||
from scipy.stats import norm | ||
import openda.utils.py4j_utils as utils | ||
from openda.costFunctions.JObjects import PyTime | ||
from openda.models.SaintVenantStochModelInstance import SaintVenantStochModelInstance | ||
|
||
|
||
class SaintVenantWithSmootherInstance(SaintVenantStochModelInstance): | ||
""" | ||
Interface of the Saint-Venant Stochastic Model Instance with Smoother | ||
@author Aron Schouten | ||
""" | ||
|
||
def compute(self, time): | ||
""" | ||
Let the stochastic model instance compute to the requested target time stamp. | ||
This function can not be used to go back in time. | ||
:param time: Time to compute to. | ||
:return: | ||
""" | ||
A, B, phi = self._get_model() | ||
self.prev_state = self.state.copy() | ||
end_time = time.get_start() | ||
std = np.sqrt(1-phi**2) * 0.2 # Std of model noise chosen according to desired std of AR(1) | ||
newx = self.state | ||
t_now = self.current_time.get_start() | ||
t_step = self.span[1] | ||
nsteps = round((end_time-t_now)/t_step) | ||
for _ in range(nsteps): | ||
self.t += self.span[1]/np.timedelta64(1,'s') | ||
x = self.state.copy() | ||
rhs = B.dot(x) | ||
rhs[0] += -0.25 + 1.25 * np.sin(2.0*np.pi/(12.42*60.*60.)*self.t) # Left boundary | ||
if self.auto_noise: | ||
rhs[-1] += norm(loc=0, scale=std).rvs() # White noise | ||
newx = spsolve(A, rhs) | ||
|
||
self.f += norm(loc=0, scale=0.0005*std).rvs() # White noise for Smoother (2000 times smaller than model noise) | ||
|
||
self.current_time = PyTime(end_time) | ||
self.state = newx | ||
|
||
def update_state(self, state_array, main_or_ens): | ||
""" | ||
Update the state vector of the model. | ||
:param state_array: numpy array used to update the model state. | ||
:param main_or_ens: "main" for updating the main model, "ens" for ensemble members. | ||
:return: | ||
""" | ||
if main_or_ens == "ens": | ||
delta = utils.input_to_py_list(state_array) | ||
self.state += delta[:-1] | ||
self.f[0] += delta[-1] | ||
elif main_or_ens == "main": | ||
delta_mean = utils.input_to_py_list(state_array) | ||
self.state = delta_mean[:-1] | ||
self.f = [delta_mean[-1]] | ||
|
||
def get_state(self): | ||
""" | ||
Returns the state of the model. | ||
:return: State vector. | ||
""" | ||
state = np.zeros(len(self.state) + 1) | ||
state[:-1] = self.state | ||
state[-1] = self.f[0] | ||
|
||
return state |
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.