def update(self, velocity_from_body, mu, v_inf, omega, verbose): """Updates the shape of the wake based on solved flow results. Parameters ---------- velocity_from_body : callable Function which will return the velocity induced by the body at a given set of points. mu : ndarray Vector of doublet strengths. v_inf : ndarray Freestream velocity vector. omega : ndarray Angular rate vector. verbose : bool """ # Update number of segments self.N_segments += 1 if verbose: print() prog = OneLineProgress( self.N_segments + 1, msg=" Updating wake shape with {0} segments".format( self.N_segments)) # Initialize storage new_locs = np.zeros((self.N, self.N_segments, 3)) # Get starting locations (offset slightly from origin to avoid singularities) curr_loc = self._vertices[:, 0, :] + self._filament_dirs * 0.01 if verbose: prog.display() # Loop through filament segments (the first vertex never changes) next_loc = np.zeros((self.N, 3)) for i in range(1, self.N_segments + 1): # Determine velocities at current point v0 = velocity_from_body(curr_loc) + v_inf[ np.newaxis, :] - vec_cross(omega, curr_loc) v0 += self._get_velocity_from_other_filaments_and_edges( curr_loc, mu) # Guess of next location next_loc = curr_loc + self.l * v0 / vec_norm(v0)[:, np.newaxis] # Iteratively correct for j in range(self._corrector_iterations): # Velocities at next location v1 = velocity_from_body(next_loc) + v_inf[np.newaxis, :] v1 += self._get_velocity_from_other_filaments_and_edges( next_loc, mu) # Correct location v_avg = 0.5 * (v0 + v1) next_loc = curr_loc + self.l * v_avg / vec_norm( v_avg)[:, np.newaxis] # Store new_locs[:, i - 1, :] = np.copy(next_loc) # Move downstream curr_loc = np.copy(next_loc) if verbose: prog.display() # Store the new locations self._vertices[:, 1:self.N_segments + 1, :] = new_locs