1

I'm working on a panel method code at the moment. To keep us from being bogged down in the minutia, I won't show the code - this is a question about overall program structure.

Currently, I solve my system by:

  1. Generating the corresponding rows of the A matrix and b vector in an explicit component for each boundary condition
  2. Assembling the partial outputs into the full A, b.
  3. Solving the linear system, Ax=b, using a LinearSystemComp.

Here's a (crude) diagram: Current method of assembling explicit components

I would prefer to be able to do this by just writing one implicit component to represent each boundary condition, vectorising the inputs/outputs to represent multiple rows/cols in the matrix, then allowing openMDAO to solve for the x while driving the residual for each boundary condition to 0.

I've run into trouble trying to make this work, as each implicit component is underdetermined (more rows in the output vector x than the component output residuals; that is, A1.x - b1= R1, length(R1) < length(x). Essentially, I would like openMDAO to take each of these underdetermined implicit systems, and find the value of x that solves the determined full system - without needing to do all of the assembling stuff myself.

Something like this: Desired method of assembling inviscid components.

To try and make my goal clearer, I'll explain what I actually want from the perspective of my panel method. I'd like a component, let's say Influence, that computes the potential induced by a given panel at a given point in the panel's reference frame. I'd like to vectorise the input panels and points such that it can compute the influence coefficent of many panels on one point, of many points on one panel, or of many points on many panels.

Influence coefficient calculation

I'd then like a system of implicit boundary conditions to find the correct value of mu to solve the system. These boundary conditions, again, should be able to be vectorised to compute the violation of the boundary condition at many points under the influence of many panels.

I get confused again at this part. Not every boundary condition will use the influence coefficient values - some, like the Kutta condition, are just enforced on the mu vector, e.g Kutta condition. How would I implement this as an implicit component? It has no inputs, and doesn't output the full mu vector.

enter image description here

I appreciate that the question is rather long and rambling, but I'm pretty confused. To summarise:

  1. How can I use openMDAO to solve multiple individually underdetermined (but combined, fully determined) implicit systems?
  2. How can I use openMDAO to write an implicit component that takes no inputs and only uses a portion of the overall solution vector?
BeeperTeeper
  • 151
  • 7
  • Hi Beeper, I don't immediately have an answer but I wanted to let you know of a package that helps me make XDSM diagrams like you've made: https://github.com/mdolab/pyXDSM I find it helpful to quickly and programatically make those diagrams. I love the effort and context you put into this post. – John Jasa Oct 28 '20 at 13:18
  • Oh, I'm aware of pyXDSM, and I've used it before. Ironically, you say you love the effort, but I made crappy paint XDSMs because I was too lazy to write it in pyXDSM :D – BeeperTeeper Oct 28 '20 at 13:40
  • Haha, to each their own! – John Jasa Oct 28 '20 at 13:42
  • @BeeperTeeper or you can directly make an XDSM from your OpenMDAO model with this plug-in: https://github.com/onodip/OpenMDAO-XDSM – onodip Oct 28 '20 at 15:16
  • I understand, but like I said, the aim was to communicate abstract program structure – BeeperTeeper Oct 28 '20 at 15:35

1 Answers1

0

In the OpenMDAO docs there is a close analog to what you are trying to accomplish, with the node-voltage analysis tutorial. In that code, the balance comp is used to create an implicit relationship that is similar to what you're describing. Its singular on its own, but part of a larger group is a well defined system.

You'll need to find a way to build similar components for your model. Each "row" in your equation will be associated with one state variables (one entry in your x vector).

In the simplest case, each row (or set of rows) would have one input which is the associated row of the A matrix, and a second input which is ALL of the other values for x, and a final input which is the entry of the b vector (right hand side vector). Then you could evaluate the residual for that specific row, which would be the following

R['x_i'] = np.sum(A*x_full) - b

where x_full is the assembly of the full x-vector from the x_other input and the x_i state variable.

#########

Having proposed the above solution, I have to say that I don't think this is a particularly efficient way to build or solve this linear system. It is modular, and might give you some flexibility, but you're jumping through a lot of hoops to avoid doing some index-math, and shoving everything into a matrix.

Granted, the derivatives might be a bit easier in your design, because the matrix assembly is going to get handled "magically" by the connections you have to create between the various row-components. So maybe its worth the trade... but i would say you might be better of trying a more traditional coding approach and using JAX or some other AD code to make the derivatives easier.

Justin Gray
  • 5,605
  • 1
  • 11
  • 16