I am working on a relatively simple model with 3 Explicit Components (Leg, Cable, BCan) and 1 Implicit (LegCableBal).
The implicit component has a number of residual equations. For most of the state variables, the best initial guess would be a value calculated as Output of the Explicit Components. For example, the final length of a cable element is best approximated by its initial length, which is calculated as 'output' by the Cable component based on the end point coordinates that are inputs to that component.
I have been trying to use the guess_nonlinear
method for the group, but I do not think I can access the outputs of the other Components, as they may have not executed yet.
Within the Explicit Components, the outputs could default to the input values, and that would take care of it, but I do not know whether I can create pass-through (input--output) for output default values.
Is there a strategy for these situations? Or is a full rearrangement of the problem required?
Thank you in advance!
Additionally, I am facing a problem with this setup:
self.add_subsystem('Leg',Leg(rho_w=rho_w,concrete=concrete,rebar=rebar, tie=tiesteel,tendon=tendon, nlreinf_sets=self.options['nlreinf_sets'],npreinf_sets=self.options['npreinf_sets'],nsreinf_sets=self.options['nsreinf_sets']), promotes_inputs=['*']) #
self.add_subsystem('Cable1',Cable(rho_w=rho_w, mat=cable1mat, loss=C_1loss, Cflag=1), promotes_inputs=['L_L0','a','b','c'] )
self.add_subsystem('Cable2',Cable(rho_w=rho_w, mat=cable2mat, loss=C_2loss, Cflag=2), promotes_inputs=['L_L0','a','b','c'] )
self.add_subsystem('BCan',BCan(rho_w=rho_w, canmat=canmat,F_c=self.options['F_c']), promotes_inputs=['*'])
self.add_subsystem('LegCableBal',LegCableBal(cable1mat=cable1mat,cable2mat=cable2mat,canmat=canmat), promotes_inputs='L_L0','b_eff','B_c','M_c','Fx_c'], promotes_outputs=['*'])
this is within the LegCableBal
group, and I thought 'L_L0' (or other promoted inputs) would be assigned for all components when I issue: prob.set_val('L_L0', 31.)
in my main where I set all initial values . This is not the case, in fact, L_L0 does not make it into any of the components, however variables such as 'D_L', which is only promoted by Leg
, indeed get assigned fine after prob.set_val('D_L', 2.1)
. This assessment is from within def guess_nonlinear(self, inputs, outputs, residuals)
where I am trying to use say outputs['L_Lf']= inputs['Leg.L_L0']
. This returns [1.] (should be my assigned 31.), but inputs['Leg.D_L']
is the correct 2.1.
Just a snippet of the ImplicitComponent
N_C1 = outputs['N_C1']
[...]
residuals['N_C1'] = N_C1 - _N_C(E_pC1, A_C1, eps_C1) #Definition of N_C1
residuals['N_C2'] = N_C2 -_N_C(E_pC2, A_C2, eps_C2) #Definition of N_C2
alpha = np.sqrt(N_e/(E_c * J_Lxxceff)) #definition of alpha
residuals['u_B']= N_C1 * np.cos(Tht_C1f) - N_e * np.cos(Tht_Lf) + N_C2 * np.cos(Tht_C2f) +F_c # force balance along normal to stem's axis
residuals['u_B']= -N_C1 * np.sin(Tht_C1f) + N_e * np.sin(Tht_Lf) + N_C2 * np.sin(Tht_C2f) +B_eff # force balance along stem's axis
residuals['N_e']= (E_c * A_Leff * (L_Lf-L_L0) )/L_L0 - ( -N_e - (m_eff*g*np.cos(Tht_Lf))**2 / (12.*E_c*J_Lxxceff) * L_L0**4 * (1./ (L_L0**2 * alpha**2) + 12./ (L_L0**4 * alpha**4) - 24./ (L_L0**5*alpha**5) * np.tan(alpha*L_L0/2.) ) - E_c * A_Leff * (m_eff*g*np.cos(Tht_Lf))**2 / (24.* E_c**2 *J_Lxxceff**2) * L_L0**6 * (1./ (L_L0**4 * alpha**4) - 60./ (L_L0**7 * alpha**7) * np.tan(alpha*L_L0/2) + 24./ (L_L0**6 * alpha**6) + 12.*(1.-np.cos(alpha*L_L0))/(L_L0**6 * alpha**6 * np.sin(alpha*L_L0)**2 ) ) )``````
Here all the terms in these equations are either inputs coming from outputs of other components, or other states (e.g., 'N_C1') for which i have other residual equations.
In guess_nonlinear
for the group LegCableBal
, I resorted to brutally calling the compute of the other components to get the outputs available.
#Get some guesses by executing the cable component, horrible but I am not sure how else to pass these initial guesses that should just be the outputs of other components
Cable1=Cable(rho_w=self.options['rho_w'],loss=self.options['C_1loss'], mat=self.options['cable1mat'],Cflag=1)
Cable2=Cable(rho_w=self.options['rho_w'],loss=self.options['C_2loss'], mat=self.options['cable2mat'],Cflag=2)
cable1_ins={'D_C':inputs['Cable1.D_C'],'L_L0':inputs['Leg.L_L0'],'a':inputs['Cable1.a'],'b':inputs['Cable1.b'],'c':inputs['Cable1.c'],'sig_Cpt0':inputs['Cable1.sig_Cpt0']}
cable2_ins={'D_C':inputs['Cable2.D_C'],'L_L0':inputs['Leg.L_L0'],'a':inputs['Cable1.a'],'b':inputs['Cable1.b'],'c':inputs['Cable1.c'],'sig_Cpt0':inputs['Cable2.sig_Cpt0']}
cable1_outs={}
cable2_outs={}
Cable1.compute(cable1_ins,cable1_outs)
Cable2.compute(cable2_ins,cable2_outs)
#Now set the initial guesses
outputs['L_C1f']= cable1_outs['L_C0']```
Thank you for your time Justin,
R