Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

residual function #253

Closed
cmichelenstrofer opened this issue Jul 11, 2023 · 3 comments
Closed

residual function #253

cmichelenstrofer opened this issue Jul 11, 2023 · 3 comments
Assignees
Labels
enhancement New feature or request

Comments

@cmichelenstrofer
Copy link
Member

The hydrodynamic bodies's residual constraint is built in the core solver. One can recreate it with the post-processed time-series, but it might be useful to just supply a function that does this calculation. The main residual (and any other equality constraint) could also be printed during the optimization output.

@cmichelenstrofer cmichelenstrofer added the enhancement New feature or request label Jul 11, 2023
@ryancoe
Copy link
Collaborator

ryancoe commented Oct 6, 2023

@cmichelenstrofer - I'm a bit confused by your comment above. The scaled residual function is indeed created in wot.solve,

# system dynamics through equality constraint, ma - Σf = 0
def scaled_resid_fun(x):
x_s = x/scale
x_wec, x_opt = self.decompose_state(x_s)
return self._resid_fun(x_wec, x_opt, waves)

but there is a hidden function for the residual equation that a user can call

def _resid_fun(self, x_wec, x_opt, waves):
if not self.inertia_in_forces:
ri = self.inertia(self, x_wec, x_opt, waves)
else:
ri = np.zeros([self.ncomponents, self.ndof])
# forces, -Σf
for f in self.forces.values():
ri = ri - f(self, x_wec, x_opt, waves)
return self.dofmat_to_vec(ri)

@cmichelenstrofer
Copy link
Member Author

@ryancoe yes, you are right! I suggest we make it a regular function (not a hidden one). And check that we can use it (e.g. as callback) to print out the value during the solve. This is something @gbacelli has asked for a few times. Should give us insight into the convergence of the optimization.

@cmichelenstrofer cmichelenstrofer self-assigned this Oct 10, 2023
cmichelenstrofer added a commit to cmichelenstrofer/WecOptTool that referenced this issue Oct 11, 2023
@cmichelenstrofer
Copy link
Member Author

  • changed the residual function to be non-hidden.
  • fixed a bug with callback (state x was not being scaled)

To print all the residuals (each DOF at each time step) you can do something like this:

def callback(wec, x_wec, x_opt, waves):
    wot._log.info(f"dynamic equation residual: {wec.residual(x_wec, x_opt, waves)}")
    return 

or to just check if it is satisfied:

def callback(wec, x_wec, x_opt, waves):
    wot._log.info(f"dynamic equation residual: {np.allclose(wec.residual(x_wec, x_opt, waves), 0)}")
    return 

The callback is called after each iteration. I tried it with Tutorial 1 and the condition is satisfied after the first iteration (never prints false).

Similarly the callback could include user defined constraints functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants