<s> """<STR_LIT>""" <EOL> from collections import OrderedDict <EOL> import numpy as np <EOL> from scipy . linalg import lu_factor , lu_solve <EOL> from openmdao . solvers . solver_base import MultLinearSolver <EOL> class DirectSolver ( MultLinearSolver ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self ) : <EOL> super ( DirectSolver , self ) . __init__ ( ) <EOL> self . options . remove_option ( "<STR_LIT>" ) <EOL> self . options . add_option ( '<STR_LIT>' , '<STR_LIT>' , values = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] , <EOL> desc = "<STR_LIT>" + <EOL> "<STR_LIT>" + <EOL> "<STR_LIT>" , <EOL> lock_on_setup = True ) <EOL> self . options . add_option ( '<STR_LIT>' , '<STR_LIT>' , values = [ '<STR_LIT>' , '<STR_LIT>' ] , <EOL> desc = "<STR_LIT>" + <EOL> "<STR_LIT>" + <EOL> "<STR_LIT>" + <EOL> "<STR_LIT>" + <EOL> "<STR_LIT>" + <EOL> "<STR_LIT>" ) <EOL> self . options . add_option ( '<STR_LIT>' , '<STR_LIT>' , values = [ '<STR_LIT>' , '<STR_LIT>' ] , <EOL> desc = "<STR_LIT>" + <EOL> "<STR_LIT>" ) <EOL> self . jacobian = None <EOL> self . lup = None <EOL> self . mode = None <EOL> self . icache = { } <EOL> def setup ( self , system ) : <EOL> """<STR_LIT>""" <EOL> if self . options [ '<STR_LIT>' ] == '<STR_LIT>' : <EOL> return <EOL> u_vec = system . unknowns <EOL> self . jacobian = - np . eye ( u_vec . vec . size ) <EOL> self . icache = { } <EOL> def solve ( self , rhs_mat , system , mode ) : <EOL> """<STR_LIT>""" <EOL> self . system = system <EOL> if self . mode is None : <EOL> self . mode = mode <EOL> sol_buf = OrderedDict ( ) <EOL> for voi , rhs in rhs_mat . items ( ) : <EOL> self . voi = None <EOL> if system . _jacobian_changed : <EOL> self . jacobian = self . _assemble_jacobian ( rhs , mode ) <EOL> system . _jacobian_changed = False <EOL> if self . options [ '<STR_LIT>' ] == '<STR_LIT>' : <EOL> self . lup = lu_factor ( self . jacobian ) <EOL> if self . options [ '<STR_LIT>' ] == '<STR_LIT>' : <EOL> deriv = lu_solve ( self . lup , rhs ) <EOL> else : <EOL> deriv = np . linalg . solve ( self . jacobian , rhs ) <EOL> self . system = None <EOL> sol_buf [ voi ] = deriv <EOL> return sol_buf <EOL> def _assemble_jacobian ( self , rhs , mode ) : <EOL> """<STR_LIT>""" <EOL> system = self . system <EOL> if self . options [ '<STR_LIT>' ] == '<STR_LIT>' : <EOL> self . mode = mode <EOL> n_edge = len ( rhs ) <EOL> ident = np . eye ( n_edge ) <EOL> partials = np . empty ( ( n_edge , n_edge ) ) <EOL> for i in range ( n_edge ) : <EOL> partials [ : , i ] = self . mult ( ident [ : , i ] ) <EOL> else : <EOL> if self . mode != mode : <EOL> self . setup ( system ) <EOL> self . mode = mode <EOL> sys_name = system . name + '<STR_LIT:.>' <EOL> partials = self . jacobian <EOL> u_vec = system . unknowns <EOL> icache = self . icache <EOL> conn = system . connections <EOL> sys_prom_name = system . _sysdata . to_prom_name <EOL> for sub in system . components ( recurse = True , include_self = True ) : <EOL> jac = sub . _jacobian_cache <EOL> if jac is None : <EOL> msg = "<STR_LIT>" + "<STR_LIT>" % sub . pathname <EOL> raise RuntimeError ( msg ) <EOL> sub_u = sub . unknowns <EOL> sub_name = sub . pathname <EOL> for key in jac : <EOL> o_var , i_var = key <EOL> key2 = ( sub_name , key ) <EOL> if key2 not in icache : <EOL> o_var_abs = '<STR_LIT:.>' . join ( ( sub_name , o_var ) ) <EOL> i_var_abs = '<STR_LIT:.>' . join ( ( sub_name , i_var ) ) <EOL> i_var_pro = sys_prom_name [ i_var_abs ] <EOL> o_var_pro = sys_prom_name [ o_var_abs ] <EOL> if i_var in sub . states : <EOL> pass <EOL> elif i_var_pro not in u_vec : <EOL> if i_var_abs not in conn : <EOL> continue <EOL> i_var_src = conn [ i_var_abs ] [ <NUM_LIT:0> ] <EOL> i_var_pro = sys_prom_name [ i_var_src ] <EOL> o_start , o_end = u_vec . _dat [ o_var_pro ] . slice <EOL> i_start , i_end = u_vec . _dat [ i_var_pro ] . slice <EOL> icache [ key2 ] = ( o_start , o_end , i_start , i_end ) <EOL> else : <EOL> ( o_start , o_end , i_start , i_end ) = icache [ key2 ] <EOL> if mode == '<STR_LIT>' : <EOL> partials [ o_start : o_end , i_start : i_end ] = jac [ o_var , i_var ] <EOL> else : <EOL> partials [ i_start : i_end , o_start : o_end ] = jac [ o_var , i_var ] . T <EOL> return partials </s>
