[docs]classHorseshoeCirculations(om.ExplicitComponent):""" Convert the previously-computed vortex ring circulations into horseshoe circulations. Vortex rings and horseshoe vortices produce the same linear space, but with a different parameterization. It's easier to compute the circulations using a vortex ring approach, but it's easier to compute the forces acting on the surface by using the horseshoe circulations. That's why we have this component, to convert from one circulation space to the other. Parameters ---------- circulations[system_size] : numpy array The vortex ring circulations obtained by solving the AIC linear system. Returns ------- horseshoe_circulations[system_size] : numpy array The equivalent horseshoe circulations obtained by intelligently summing the vortex ring circulations, accounting for overlaps between rings. """definitialize(self):self.options.declare("surfaces",types=list)defsetup(self):surfaces=self.options["surfaces"]system_size=0# Loop through all the surfaces to obtain the total system size,# which is the number of panels in the total system.forsurfaceinsurfaces:mesh=surface["mesh"]nx=mesh.shape[0]ny=mesh.shape[1]system_size+=(nx-1)*(ny-1)self.system_size=system_sizeself.add_input("circulations",shape=system_size,units="m**2/s",tags=["mphys_coupling"])self.add_output("horseshoe_circulations",shape=system_size,units="m**2/s")# To convert between the two circulations, we simply need to set up a# matrix that linearly transforms the vortex ring circulations to# the horseshoe circulations. Again, because this is a linear# transformation, the derivatives are in fact the matrix itself.data=[np.ones(system_size)]rows=[np.arange(system_size)]cols=[np.arange(system_size)]ind_1=0ind_2=0forsurfaceinsurfaces:mesh=surface["mesh"]nx=mesh.shape[0]ny=mesh.shape[1]num=(nx-1)*(ny-1)ind_2+=numarange=np.arange(num).reshape((nx-1),(ny-1))data_=-np.ones((nx-2)*(ny-1))rows_=ind_1+arange[1:,:].flatten()cols_=ind_1+arange[:-1,:].flatten()data.append(data_)rows.append(rows_)cols.append(cols_)ind_1+=numdata=np.concatenate(data)rows=np.concatenate(rows)cols=np.concatenate(cols)# Actually create the sparse matrix based on these rows and colsself.mtx=csc_matrix((data,(rows,cols)),shape=(system_size,system_size))self.declare_partials("horseshoe_circulations","circulations",val=data,rows=rows,cols=cols)defcompute(self,inputs,outputs):outputs["horseshoe_circulations"]=self.mtx.dot(inputs["circulations"])