0
votes

I am solving an implicit system of equations for vector of temperatures 'T' (call it "Temp" component):

residuals['T'] = GL.dot(T)-GR*(T**4)+QS+QI

where "GL, GR, QS, QI" are inputs. Matrix "GL" depends on some design variables of interest (let's call them "var"). Therefore I have to make an explicit component (call it "GLmtxComp") that assembles square "GL" matrix by doing some simple calculations:

def compute(self, inputs, outputs):
    GL = self.options['GL_init']
    SF = self.options['SF']
    nodes = self.options['nodes'] 
    for var in inputs:
        idx = nodes[var]
        GL[idx] = SF[var]*inputs[var] # updates GL values based on input var

Here only some elements of "GL" are changed (those defined in {nodes} dictionary), other elements are unchanged and take initial values from option "GL_init".

When I run the implicit component alone with raw initial input values, it solves. But as soon as I connect it to my new "GLmtxComp" explicit component that provides the "GL" matrix as input, the linear solver fails with message:

raise RuntimeError(format_singular_csc_error(system, matrix))

RuntimeError: Identical rows or columns found in jacobian in 'temp'. Problem is underdetermined.

I use non linear Newton and linear Direct solver to converge the implicit 'temp' component. If I change to other solvers, I don't get the error message, but the solution does not converge anyway. Interestingly, the error goes away if I set nonlinear Newton solver to solve for sub-systems, but then it does not converge (it diverges quite violently after tens of iterations). So is it related to the "GLmtxComp" explicit component, or is it somehow related to implicit residual partials? I tried to use both finite difference and exact derivatives for "GLmtxComp", but the problem persists. How do I debug this problem? N2 diagram of the group

1
What version of OpenMDAO are you using? We recently merged some changes into the current master branch on github at are intended to make diagnosing these singularities a bit easier. These changes weren't included in 2.10.1 or 3.0.0. If possible, it might be worth a try to see if you get a more descriptive message. - Rob Falck
@RobFalck i use 3.0.0. I installed from cloned openmdao repo, but the error message is the same. Interestingly, the error goes away if I set nonlinear Newton solver to solve for sub-systems, but then it does not converge (it diverges quite violently after tens of iterations) - Laurynas Mačiulis
We'll need to at least see the n2 diagram to help a bit more. But if you can post the code to a gist or something, that would be much better. If the equations are as simple as you posted, then it should be possible to condense it down to one file and give us an example case we can worth with. Also, have you tried any of the ideas in the newton solver debugging page: openmdao.org/twodocs/versions/3.0.0/features/debugging/… - Justin Gray
@JustinGray I finally solved, see my answer. I attached n2 diagrams before and after correction. It seems that it was a wrong solver topology, maybe you could comment. - Laurynas Mačiulis

1 Answers

0
votes

So eventually it was a bug in my code that messed up the explicit component. Thanks @JustinGray for comment. I was incorrectly referencing the reference array in the line:

GL = self.options['GL_init'])

not realizing that I am actually messing my initial values of "GL_init" with each iteration of new GL calculation. Modifying this with:

GL = numpy.copy(self.options['GL_init'])

creates a copy of "GL_init" without changing it in successive iterations of GL. So now everything works with Newton solver set to "solve_subsystems = True".