deepxde
deepxde copied to clipboard
Add experimental data regarding derivatives
Overview
Dear @lululxvi,
I have one question regarding the PointSetBC
. Let's say I have the output quantity called u
but the measurement data is based on du
(It is derivative) then I can not use PointSetBC (If I am not wrong). What would be your suggestion?
Possible solution
OperatorBC
allows us to use derivatives. But I could not think about how to use it in this context?
Here is the specific example:
Let's say here is the measurement data (includes 3 columns (coordinates x,y and displacement du) and n samples)
ext_data = np.loadtxt("/home/a11btasa/git_repos/pinnswithdxde/elasticity_2d/bulk_train_anchors.txt")
if the experimental data would be u instead of du, I could use simply
ex_data_xy = ext_data[:,0:2]
observe_u = dde.PointSetBC(ex_data_xy, ext_data[:,2:3], component=0)
What would look like OpeatorBC?
dde.OperatorBC(geom, enforce_strain, domain_given)
def enforce_strain(x,y,X):
# this is calculated strain
eps_xx = dde.grad.jacobian(y, x, i=0, j=0)
# eps_yy = dde.grad.jacobian(y, x, i=1, j=1) # not needed
# eps_xy = 1/2*(dde.grad.jacobian(y, x, i=1, j=0)+dde.grad.jacobian(y, x, i=0, j=1)) # not needed
# measured strain
eps_xx_m = utils.return_tensor(ext_data[:,2:3])
eps_xx_m = bkd.as_tensor(eps_xx_m, dtype=config.real(bkd.lib)) # of course it has to be tensor
return eps_xx-eps_xx_m # some doubts if the dimensions will match??
def domain_given(x, on_boundary):
return np.isclose(x, ex_data_xy)
Do you think it would be correct? Of course, I should add the extra points to the domain as well using anchors. I also thought creating a custom class:
class PointSetBCFunc(object):
"""Dirichlet boundary condition for a set of points.
Compare the output (that associates with `points`) with `values` (target data).
Args:
points: An array of points where the corresponding target values are known and used for training.
values: An array of values that gives the exact solution of the problem.
component: The output component satisfying this BC.
"""
def __init__(self, points, values, component=0):
self.points = np.array(points, dtype=config.real(np))
if not isinstance(values, numbers.Number) and values.shape[1] != 1:
raise RuntimeError(
"PointSetBC should output 1D values. Use argument 'component' for different components."
)
self.values = bkd.as_tensor(values, dtype=config.real(bkd.lib))
self.component = component
self.func = func
def collocation_points(self, X):
return self.points
def error(self, X, inputs, outputs, beg, end):
return self.func(inputs, outputs, X)[beg:end]- self.values
Thanks in advance!
Best regards, Tarik
Both approaches can work. But using dde.OperatorBC
is a little tricky, and I suggest the second approach, i.e., adding a new class PointSetOperatorBC
. Actually, there is another "Issue" already talking about this.
Your implementation is basically correct. Feel free to submit a PR, and we can improve it then.
I have erased this reply, as I found a bug in my code. Hope the idea with the PointSetOperatorBC
will be brought to live. Thank you @lululxvi for your constant work on DeepXDE.
@lululxvi I have implemented PointSetOperatorBC and tested for an example of solid mechanics. I will make a PR as soon as I have time!