def __init__(self, RedDataFilesList, **kargs): if kargs.has_key('num_modes'): self.num_modes = kargs['num_modes'] else: self.num_modes = len(RedDataFilesList) Nvars = len(RedDataFilesList[0].data[0, 2:]) N = RedDataFilesList[0].params['N'] podInput = np.array([ rr.data[:, 2:].reshape(rr.params['N'] * len(rr.data[0, 2:])) for rr in RedDataFilesList ]) modes, self.eig_vals = MR.compute_POD_matrices_snaps_method( podInput.T, range(self.num_modes)) self.modes = list() for m in modes.T: self.modes.append(m.reshape((N, Nvars))) self.baseRedFile = RedDataFilesList[0].copyForWriting() print self.baseRedFile.data.shape print RedDataFilesList[0].data.shape for v in RedDataFilesList[0].variables[2:]: self.baseRedFile.appendVariable(v + '_mode')
def ro0_POD_base(rigid, deformable, num_modes=11, verbose=False): if modred.__version__[0] != '1': print 'modred version 1 is needed!' import sys sys.exit(1) vecs = numpy.transpose(numpy.array(rigid + deformable)) if verbose: svec = vecs.shape[0] nvec = vecs.shape[1] print 'Calculating', num_modes, 'POD modes for', nvec, 'input vectors of size', svec, '...' modes, eig_vals = modred.compute_POD_matrices_snaps_method( vecs, list(range(num_modes))) #modes, eig_vals = modred.compute_POD_matrices_direct_method(vecs, list(range(num_modes))) if verbose: print 'POD eigen values:' print eig_vals[0:num_modes] mod = numpy.transpose(modes).tolist() base = [x for vec in mod for x in vec] val = eig_vals.tolist() return (val[0:len(mod)], base)
def ro0_POD_base(rigid, deformable, num_modes=11, verbose=False): if modred.__version__[0] != '1': print 'modred version 1 is needed!' import sys sys.exit(1) vecs = numpy.transpose(numpy.array(rigid+deformable)) if verbose: svec = vecs.shape[0] nvec = vecs.shape[1] print 'Calculating', num_modes, 'POD modes for', nvec, 'input vectors of size', svec, '...' modes, eig_vals = modred.compute_POD_matrices_snaps_method(vecs, list(range(num_modes))) #modes, eig_vals = modred.compute_POD_matrices_direct_method(vecs, list(range(num_modes))) if verbose: print 'POD eigen values:' print eig_vals[0:num_modes] mod = numpy.transpose(modes).tolist() base = [x for vec in mod for x in vec] val = eig_vals.tolist() return (val[0:len(mod)], base)
def calculate_pod(saved_modes_number): with open('data_loaded.txt') as file: data = np.loadtxt(file) data_accumulate = data - data.mean(axis=1, keepdims=True) modes, eigen_values = mr.compute_POD_matrices_snaps_method( data_accumulate, list(range(saved_modes_number))) np.savetxt('modes.txt', modes) np.savetxt('eigen_values.txt', eigen_values)
def ro0_POD_base_keep_rigid(rigid, deformable, num_modes=11, verbose=False): vecs = numpy.transpose(numpy.array(deformable)) if verbose: svec = vecs.shape[0] nvec = vecs.shape[1] print 'Calculating', num_modes - 6, 'POD modes for', nvec, 'input vectors of size', svec, '...' modes, eig_vals = modred.compute_POD_matrices_snaps_method( vecs, list(range(num_modes - 6))) #modes, eig_vals = modred.compute_POD_matrices_direct_method(vecs, list(range(num_modes-6))) if verbose: print 'POD eigen values:' print eig_vals[0:num_modes - 6] defo = numpy.transpose(modes).tolist() # re-orthogonalize deformable modes with # respect to the 6 rigid modes and themselves for i in range(0, len(defo)): for j in range(0, i): # defo(i) _|_ defo(j<i) x = defo[i] y = defo[j] dot = numpy.dot(x, y) z = numpy.array(x) - dot * numpy.array(y) defo[i] = z.tolist() for y in rigid: # defo(i) _|_ rigid x = defo[i] dot = numpy.dot(x, y) z = numpy.array(x) - dot * numpy.array(y) defo[i] = z.tolist() # normalize x = defo[i] invlen = 1.0 / numpy.dot(x, x)**0.5 z = numpy.array(x) * invlen defo[i] = z.tolist() ''' for i in range(0,len(defo)): for j in range(0,len(defo)): x = defo[i] y = defo[j] dot = numpy.dot(x, y) print 'dot(%d,%d) = %g' % (i, j, dot) for y in rigid: x = defo[i] dot = numpy.dot(x, y) print 'dot(%d,rigid) = %g' % (i, dot) ''' base = [x for vec in (rigid + defo) for x in vec] val = eig_vals.tolist() return ([0.] * 6 + [1.] * (num_modes - 6), base)
def ro0_POD_base_keep_rigid(rigid, deformable, num_modes=11, verbose=False): vecs = numpy.transpose(numpy.array(deformable)) if verbose: svec = vecs.shape[0] nvec = vecs.shape[1] print 'Calculating', num_modes-6, 'POD modes for', nvec, 'input vectors of size', svec, '...' modes, eig_vals = modred.compute_POD_matrices_snaps_method(vecs, list(range(num_modes-6))) #modes, eig_vals = modred.compute_POD_matrices_direct_method(vecs, list(range(num_modes-6))) if verbose: print 'POD eigen values:' print eig_vals[0:num_modes-6] defo = numpy.transpose(modes).tolist() # re-orthogonalize deformable modes with # respect to the 6 rigid modes and themselves for i in range(0,len(defo)): for j in range(0, i): # defo(i) _|_ defo(j<i) x = defo[i] y = defo[j] dot = numpy.dot(x, y) z = numpy.array(x) - dot*numpy.array(y) defo[i] = z.tolist() for y in rigid: # defo(i) _|_ rigid x = defo[i] dot = numpy.dot(x, y) z = numpy.array(x) - dot*numpy.array(y) defo[i] = z.tolist() # normalize x = defo[i] invlen = 1.0/numpy.dot(x, x)**0.5 z = numpy.array(x) * invlen defo[i] = z.tolist() ''' for i in range(0,len(defo)): for j in range(0,len(defo)): x = defo[i] y = defo[j] dot = numpy.dot(x, y) print 'dot(%d,%d) = %g' % (i, j, dot) for y in rigid: x = defo[i] dot = numpy.dot(x, y) print 'dot(%d,rigid) = %g' % (i, dot) ''' base = [x for vec in (rigid+defo) for x in vec] val = eig_vals.tolist() return ([0.]*6+[1.]*(num_modes-6), base)
def decompose(self, nMode, method='snap', subtractMean=False): ''' Compute the Porper Orthogonal Decomposition (POD) from a list of N snapshots. The snapshots are PIV surfaces of size (surfX,surfY) of field F. F can be any scalar field (Ux, ux, T, vorticity, R11,...) Arguments: *nMode*: python integer. Number of modes of the POD. *PODmethod*: python string. Default='snap' Type of POD algorithm used. For the snapshot method, use PODmethod='snap' and for the direct method, use PODmewthod='direct'. The default value is 'snap'. How to choose between 'snap' and 'direct': if surfX*surfY > N**2, use the snap method, it should increase the coputational speed for only a little loss in precision. Returns: None ''' nSnap = self.vecs.shape[1] self.result['nMode'] = nMode self.result['nSnap'] = nSnap if np.any(self.vecs): self.vecs = np.nan_to_num(self.vecs) if subtractMean: self.vecs = self.vecs - np.mean(self.vecs, axis=1, keepdims=True) if method == 'snap': modesPOD, eigVals = modred.compute_POD_matrices_snaps_method( self.vecs, range(nMode)) elif method == 'direct': modesPOD, eigVals = modred.compute_POD_matrices_direct_method( self.vecs, range(nMode)) else: print('error: argument ' + str(method) + ' is not valid. Use \'snap\' or \'direct\'') # convert modesPOD in an numpy array modesPOD = np.asarray(modesPOD) self.result['raw_modes'] = modesPOD self.result['eigVals'] = eigVals ai = self.projectOnMode(self.vecs) self.result['ai'] = ai
def decompose(self,nMode,method='snap',subtractMean=False): ''' Compute the Porper Orthogonal Decomposition (POD) from a list of N snapshots. The snapshots are PIV surfaces of size (surfX,surfY) of field F. F can be any scalar field (Ux, ux, T, vorticity, R11,...) Arguments: *nMode*: python integer. Number of modes of the POD. *PODmethod*: python string. Default='snap' Type of POD algorithm used. For the snapshot method, use PODmethod='snap' and for the direct method, use PODmewthod='direct'. The default value is 'snap'. How to choose between 'snap' and 'direct': if surfX*surfY > N**2, use the snap method, it should increase the coputational speed for only a little loss in precision. Returns: None ''' nSnap = self.vecs.shape[1] self.result['nMode']=nMode self.result['nSnap']=nSnap if np.any(self.vecs): self.vecs = np.nan_to_num(self.vecs) if subtractMean: self.vecs=self.vecs-np.mean(self.vecs,axis=1,keepdims=True) if method=='snap': modesPOD, eigVals = modred.compute_POD_matrices_snaps_method(self.vecs, range(nMode)) elif method=='direct': modesPOD, eigVals = modred.compute_POD_matrices_direct_method(self.vecs, range(nMode)) else: print('error: argument '+str(method)+' is not valid. Use \'snap\' or \'direct\'') # convert modesPOD in an numpy array modesPOD = np.asarray(modesPOD) self.result['raw_modes']=modesPOD self.result['eigVals']=eigVals ai=self.projectOnMode(self.vecs) self.result['ai']=ai
def compare_modred_sparse(): """Compare output from modred with our sparse method.""" import modred as mr import gc_turbulence as g run = g.ProcessedRun(g.default_processed + 'r13_12_16a.hdf5') # slice with no nans # ( or use # complement(find_nan_slice(run.Uf_[:])) ) good_slice = (slice(None), slice(None), slice(46L, None)) data = run.Uf_[good_slice] snapshots = sparse_dmd.SparseDMD.to_snaps(data, decomp_axis=1) modes, ritz_values, norms \ = mr.compute_DMD_matrices_snaps_method(snapshots, slice(None)) pmodes, pnorms \ = mr.compute_POD_matrices_snaps_method(snapshots, slice(None)) dmd = sparse_dmd.SparseDMD(snapshots)
def __init__(self, RedDataFilesList, **kargs): if kargs.has_key('num_modes'): self.num_modes = kargs['num_modes'] else: self.num_modes = len(RedDataFilesList) Nvars = len(RedDataFilesList[0].data[0,2:]) N = RedDataFilesList[0].params['N'] podInput = np.array([ rr.data[:,2:].reshape(rr.params['N']*len(rr.data[0,2:])) for rr in RedDataFilesList ]) modes, self.eig_vals = MR.compute_POD_matrices_snaps_method(podInput.T, range(self.num_modes)) self.modes = list() for m in modes.T: self.modes.append( m.reshape((N,Nvars)) ) self.baseRedFile = RedDataFilesList[0].copyForWriting() print self.baseRedFile.data.shape print RedDataFilesList[0].data.shape for v in RedDataFilesList[0].variables[2:]: self.baseRedFile.appendVariable(v+'_mode')
datarray = np.array([data(np.random.random(4)) for i in range(nr_data)]) true_vx = np.array([0.45, 0.55, 0.75, 0.35]) datb_true = data(true_vx) datb = datb_true.copy() datb[30:70] *= np.NaN # # # plot the data (snapshots in black and missing in red) pl.figure(1) pl.plot(datarray.T, 'k', alpha=0.5) pl.plot(datb, 'r', lw=3) pl.title('Data snapshots used (black) and gappy data (red)') # # # decompose datarray using the method of snapshots modes, eig_vals, eig_vecs = mr.compute_POD_matrices_snaps_method( datarray.T, range(nr_reconstr), return_all=True)[:3] # modes used for reconstruction scaled_modes = modes.copy() for i in range(nr_reconstr): scaled_modes[:, i] *= np.sqrt(eig_vals[i]) # plot the scaled modes used in reconstruction: pl.figure(2) for i in range(nr_reconstr): pl.plot(scaled_modes[:, i], label='Mode %i' % (i + 1)) pl.legend() pl.title('Scaled (proper orthogonal) modes') # # # # used masked modes in reconstruction: mask = np.where(np.isfinite(datb))[0]
import numpy as N import modred as MR num_vecs = 30 # Arbitrary data vecs = N.random.random((100, num_vecs)) num_modes = 5 modes, eig_vals = MR.compute_POD_matrices_snaps_method(vecs, range(num_modes))
from future.builtins import range import numpy as np import modred as mr num_vecs = 30 # Arbitrary data vecs = np.random.random((100, num_vecs)) num_modes = 5 modes, eig_vals = mr.compute_POD_matrices_snaps_method(vecs, list(range(num_modes)))
def main(argv): import vtk from vtk.numpy_interface import dataset_adapter as dsa from vtk.numpy_interface import algorithms as algs import numpy as np ### get parameters import os if not os.path.exists(OD): os.makedirs(OD) print '!!!Output to DIR: ',OD if not read_fields_from_file: ### Readin stage # using parallel openfoam reader ofr = vtk.vtkPOpenFOAMReader() # set reader's options ofr.SetFileName(ID+IF) print '!!!open file: ',ID+IF ofr.SetDecomposePolyhedra(0) ofr.CacheMeshOn() ofr.SetCreateCellToPoint(0) ofr.DisableAllCellArrays() ofr.SetCellArrayStatus(fieldname,1) ofr.Update() # VTKArray is same as numpy array times = dsa.vtkDataArrayToVTKArray( ofr.GetTimeValues() ,ofr) # select the timestep between t0 and tf times = [t for t in times if t>=t0 and t<=tf] print '!!!available time steps: ',times N = len(times) np.save(times_filename,times) # using CellQuality to get cell's volumes as weight cq = vtk.vtkCellQuality() cq.SetInputConnection(0,ofr.GetOutputPort(0)) cq.SetQualityMeasureToVolume() cq.Update() # cq is a composite dataset so I need GetBlock(0) geom = cq.GetOutputDataObject(0).GetBlock(0) # get volumes of cells V, size = L (number of cells) V = np.copy(dsa.WrapDataObject(geom).CellData['CellQuality']) # normalize it as weight Vtotal = sum(V) V /= Vtotal # delete all other CellDataArray in geom DataSet, preserve its mesh structure and topology structure for i in range(geom.GetCellData().GetNumberOfArrays()): geom.GetCellData().RemoveArray(0) # add volume weight to it for saving geom.GetCellData().AddArray(dsa.numpyTovtkDataArray(V,'vol_weight')) # using *.vtu file format to save the vol_weight ugw = vtk.vtkXMLUnstructuredGridWriter() ugw.SetInputDataObject(geom) print '!!!Output vol_weight to file: ',geom_filename ugw.SetFileName(geom_filename) # using binary format ugw.SetDataModeToBinary() # enable compression ugw.SetCompressorTypeToZLib() # write to the file ugw.Write() # disconnect cq and ofr in order to isolate this dataset object from Update() cq.RemoveAllInputConnections(0) L = V.size # number of cells N = len(times) #number of timesteps # vector data is larger in size if field_is_vector == True: fields = np.zeros([N,L,3]) else: fields = np.zeros([N,L]) pipepout = ofr for i in range(N): t = times[i] print '!!!reading time:{}'.format(t) # set time value pipepout.GetOutputInformation(0).Set(vtk.vtkStreamingDemandDrivenPipeline.UPDATE_TIME_STEP(),t) # read in field data of new timestep pipepout.Update() # d = dsa.WrapDataObject(pipepout.GetOutput().GetBlock(0)) print '!!!reading field:{}'.format(fieldname) field = d.CellData[fieldname] # get the first component of composite dataset, it is the internalField fields[i]=np.copy(field) # write data to file print '!!!write field data to file:',fields_filename np.savez(fields_filename,fields) else: #read fields from file fields = np.load(fields_filename)['arr_0'] ugr = vtk.vtkXMLUnstructuredGridReader() ugr.SetFileName(geom_filename) ugr.Update() geom = ugr.GetOutputDataObject(0) V = np.copy(dsa.WrapDataObject(geom).CellData['vol_weight']) times = np.load(times_filename) assert times.shape[0] == fields.shape[0] assert fields.shape[1] == V.shape[0] N = times.shape[0] L = fields.shape[1] print 'Read in dataset complete' ### POD section # calculate average field_avg = np.average(fields, axis=0) if subtractAvg: fields = fields - field_avg import modred as mr if do_POD: # if field is a vector, reshape the fields and corresponding volument weight if field_is_vector: shp_vec = fields.shape shp_flat = (fields.shape[0],fields.shape[1]*fields.shape[2]) fields = fields.reshape(shp_flat) V = np.tile(V,shp_vec[2]) # POD print '!!!Doing POD analysis' modes, eigen_vals, eigen_vecs, correlation_mat = mr.compute_POD_matrices_snaps_method(fields.T,range(M),inner_product_weights=V,return_all=True) # if field is a vector, reshape the output matrix if field_is_vector: fields = fields.reshape(shp_vec) modes = np.asarray(modes).T.reshape((modes.shape[1],shp_vec[1],shp_vec[2])) V = V[:shp_vec[1]] if output_correlation_matrix: print "!!!output POD correlation matrix",POD_cm_filename np.savetxt(POD_cm_filename,correlation_mat,delimiter=',') if output_POD_temporal_modes: print "!!!output POD temporal modes",POD_tm_filename # output temporal modes singular_vals = eigen_vals**0.5 POD_mode_energy_normalized = eigen_vals/correlation_mat.trace()[0,0] cumsum_POD_mode_energy_normalized = np.cumsum(POD_mode_energy_normalized) # generate header string header_str = 'temporal modes\n' header_str += 'time,eigen value,singular value,normalized eigen value,accumulated normalized eigen value' for i in range(N-1): header_str += ',Mode{}'.format(i) header_str += '\n' for i in range(N-1): header_str += ',SV ={}'.format(singular_vals[i]) header_str += '\n' for i in range(N-1): header_str += ',EV ={}'.format(eigen_vals[i]) header_str += '\n' for i in range(N-1): header_str += ',NEnergy ={}'.format(POD_mode_energy_normalized[i]) header_str += '\n' for i in range(N-1): header_str += ',CumsumEnergy ={}'.format(cumsum_POD_mode_energy_normalized[i]) header_str += '\n' np.savetxt(POD_tm_filename, \ np.c_[times, \ eigen_vecs], \ delimiter = ',', \ header = header_str) if output_POD_spatial_modes: print "!!!output POD spatial Modes to ",POD_sm_filename #output to xml vtk unstructured grid file ugcd = geom.GetCellData() ugcd.Reset() ugcd.CopyAllOff() for i in range(ugcd.GetNumberOfArrays()): ugcd.RemoveArray(0) # import POD mode for i in range(M): ugcd.AddArray(dsa.numpyTovtkDataArray(modes[i],prefix+'_POD_mode_{}_{}'.format(fieldname,i))) # add average field ugcd.AddArray(dsa.numpyTovtkDataArray(field_avg,'field_{}_avg'.format(fieldname))) ugw = vtk.vtkXMLUnstructuredGridWriter() ugw.SetInputDataObject(geom) ugw.SetFileName(POD_sm_filename) ugw.Write() if doReconstruction: print "!!! do Reconstrution with {} POD modes at time {}".format(MR,ReconTime) #get an empty mesh ugcd = geom.GetCellData() ugcd.Reset() ugcd.CopyAllOff() for i in range(ugcd.GetNumberOfArrays()): ugcd.RemoveArray(0) # reconstruct from first MR POD modes # ReconN = np.searchsorted(times,ReconTime) print "!!!actually, reconstruction is done at time {} rather than time {}".format(times[ReconN],ReconTime) recon_field = np.einsum("i...,i,i",modes[:MR],eigen_vals[:MR]**0.5,np.asarray(eigen_vecs)[ReconN,:MR])+field_avg; ugcd.AddArray(dsa.numpyTovtkDataArray(recon_field,prefix+'_POD_{}_Reconstructed_{}_{}'.format(MR,fieldname,ReconTime))) ugw = vtk.vtkXMLUnstructuredGridWriter() ugw.SetInputDataObject(geom) ugw.SetFileName(POD_reconstruction_filename) ugw.Write() if do_DMD: print "!!!Begin to calculate DMD modes" # if field is a vector, reshape the fields and corresponding volument weight if field_is_vector: shp_vec = fields.shape shp_flat = (fields.shape[0],fields.shape[1]*fields.shape[2]) fields = fields.reshape(shp_flat) V = np.tile(V,shp_vec[2]) # DMD, I do not know which mode is important, so I have to discard modes_ modes_, ritz_vals, mode_norms, build_coeffs = mr.compute_DMD_matrices_snaps_method(fields.T,[],inner_product_weights=V,return_all=True) # if field is a vector, reshape the fields, V and output matrix if field_is_vector: fields = fields.reshape(shp_vec) V = V[:shp_vec[1]] # sorting eorder = np.argsort(mode_norms)[::-1] # re-order the outputs ritz_vals = ritz_vals[eorder] mode_norms = mode_norms[eorder] build_coeffs = build_coeffs[:,eorder] #build the DMD_modes DMD_modes = np.einsum('ijk,il->ljk', fields,build_coeffs[:,:M_DMD]) if output_DMD_info: print "!!!output DMD info to :",DMD_info_filename # output modes info header_str = 'DMD modes info\n' header_str += 'ritz_vals.real,ritz_vals.imag,growth_rate, frequency, mode_norms\n' header_str += r'AU,AU,1/s, Hz, AU' dt = np.average(times[1:]-times[:-1]) #time step np.savetxt(DMD_info_filename, \ np.c_[ np.real(ritz_vals), \ np.imag(ritz_vals), \ np.log(np.abs(ritz_vals))/dt, \ np.angle(ritz_vals)/dt, \ mode_norms], \ delimiter = ',', \ header = header_str) if output_DMD_build_coeffs: print "!!!output DMD build coeffs. to :",DMD_build_coeffs_filename np.savez(DMD_build_coeffs_filename, build_coeffs) if output_DMD_spatial_modes: print "!!!output DMD info to :",DMD_sm_filename #output to xml vtk unstructured grid file ugcd = geom.GetCellData() ugcd.Reset() ugcd.CopyAllOff() for i in range(ugcd.GetNumberOfArrays()): ugcd.RemoveArray(0) #import pi from numpy import pi for i in range(M_DMD): ugcd.AddArray(dsa.numpyTovtkDataArray(np.abs(DMD_modes[i]),prefix+'_DMD_mode_abs_{}_{}'.format(fieldname,i))) ugcd.AddArray(dsa.numpyTovtkDataArray(np.angle(DMD_modes[i])*180/pi,prefix+'_DMD_mode_angle_{}_{}'.format(fieldname,i))) ugw = vtk.vtkXMLUnstructuredGridWriter() ugw.SetInputDataObject(geom) ugw.SetFileName(DMD_sm_filename) ugw.Write()
fb2_rig = RIGID_DISPLACEMENTS (fb2) ib1_rig = RIGID_DISPLACEMENTS (ib1) ib2_rig = RIGID_DISPLACEMENTS (ib2) pod_input = [(fb1_rig, fb1_defo, 'FB1', fbmod), (fb2_rig, fb2_defo, 'FB2', fbmod), (ib1_rig, ib1_defo, 'IB1', ibmod), (ib2_rig, ib2_defo, 'IB2', ibmod)] for (rig, defo, label, num_modes) in pod_input: vecs = numpy.transpose(numpy.array(rig+defo)) svec = vecs.shape[0] nvec = vecs.shape[1] print '%s:' % label, 'calculating', num_modes, 'POD modes from', nvec, 'input vectors of size', svec, '...' try: modes, vals = modred.compute_POD_matrices_snaps_method(vecs, list(range(num_modes))) except: print 'POD generation has failed --> it is possible that you tried to extract too many modes' if label[0:2] == 'FB': print ' try using [-fbmod a_smaller_number] and re-run' else: print ' try using [-ibmod a_smaller_number] and re-run' sys.exit () mod = numpy.transpose(modes).tolist() val = vals.tolist() basevec = [x for vec in mod for x in vec] podbase = (val[0:len(mod)], basevec) path = afile.replace ('.inp','_' + label + '_base.pickle.gz') print 'Saving: %s' % path pickle.dump(podbase, gzip.open(path,'wb'))