def generate_qw(ndim, param, sp='full', type='LU'): # get quad points and weights x = uqtkarray.dblArray2D() w = uqtkarray.dblArray1D() #print 'Create an instance of Quad class' q = uqtkquad.Quad(type, sp, ndim, param) #print 'Now set and get the quadrature rule...' q.SetRule() q.GetRule(x, w) # print out x and w #print 'Displaying the quadrature points and weights:\n' #print x #print w n = len(x) # get quad points x_np = zeros((n, ndim)) x.getnpdblArray(x_np) # get quad weights w_np = zeros(n) w.getnpdblArray(w_np) xpts = array((x_np)) return xpts, w_np
def evaluate_pce(pc_model, pc_coeffs, germ_samples): """ Evaluate PCE at a set of samples of the germ of this PCE Input: pc_model: PC object with into about PCE pc_coeffs: numpy array with PC coefficients of the RVs to be evaluated. Each column corresponds to one RV. germ_samples: numpy array with samples of the PCE grem at which the RVs are to be evaluated. Each line is one sample. The number of colums is the number of RVs. Output: Numpy array with PCE evaluations """ # Get data set dimensions etc. n_test_samples = germ_samples.shape[0] ndim = germ_samples.shape[1] npce = pc_model.GetNumberPCTerms() # Put PC germ samples in a UQTk array std_samples_uqtk = uqtkarray.dblArray2D(n_test_samples, ndim) std_samples_uqtk.setnpdblArray(np.asfortranarray(germ_samples)) # Numpy array to store all RVs evaluated from sampled PCEs rvs_sampled = np.zeros((n_test_samples, ndim)) # Evaluate PCE for RVs in each dimension for idim in range(ndim): # Create and fill UQTk array for PC coefficients c_k_1d_uqtk = uqtkarray.dblArray1D(npce, 0.0) for ip in range(npce): c_k_1d_uqtk[ip] = pc_coeffs[ip, idim] # Create UQTk array to store outputs in rv_from_pce_uqtk = uqtkarray.dblArray1D(n_test_samples, 0.0) # Evaluate the PCEs for reach input RV at those random samples pc_model.EvalPCAtCustPoints(rv_from_pce_uqtk, std_samples_uqtk, c_k_1d_uqtk) # Put evaluated samples in full 2D numpy array for isamp in range(n_test_samples): rvs_sampled[isamp, idim] = rv_from_pce_uqtk[isamp] # return numpy array of PCE evaluations return rvs_sampled
def get_quadpts(pc_model,ndim): """ Generates quadrature points Input: pc_model: PC object with info about PCE ndim: number of dimensions of the PCE Output: qdpts: numpy array of quadrature points """ # Get the quadrature points qdpts_uqtk = uqtkarray.dblArray2D() pc_model.GetQuadPoints(qdpts_uqtk) totquat = pc_model.GetNQuadPoints() # Total number of quadrature points # Convert quad points to a numpy array qdpts = np.zeros((totquat,ndim)) qdpts_uqtk.getnpdblArray(qdpts) return qdpts, totquat
def map2pce(pc_model, rvs_in, verbose=0): """Obtain PC representation for the random variables that are described by samples. Employ a Rosenblatt transformation to build a map between the input RVs and the space of the PC germ. Input: pc_model: object with properties of the PCE to be constructed rvs_in : numpy array with input RV samples. Each line is a sample. The columns represent the dimensions of the input RV. verbose : verbosity level (more output for higher values) Output: Numpy array with PC coefficients for each RV in the original rvs_in input """ # Dimensionality and number of samples of input RVs ndim = rvs_in.shape[1] nsamp = rvs_in.shape[0] # Algorithm parameters bw = -1 # KDE bandwidth for Rosenblatt (on interval 0.1) iiout = 500 # interval for output to screen # Number of PCE terms npce = pc_model.GetNumberPCTerms() # Get the default quadrature points qdpts = uqtkarray.dblArray2D() pc_model.GetQuadPoints(qdpts) totquat = pc_model.GetNQuadPoints() print "Total number of quadrature points =", totquat # Set up transpose of input data for the inverse Rosenblatt transformation in a UQTk array ydata_t = uqtkarray.dblArray2D(ndim, nsamp) ydata_t.setnpdblArray(np.asfortranarray(rvs_in.T)) # Set up numpy array for mapped quadrature points invRosData = np.zeros((totquat, ndim)) # Map all quadrature points in chosen PC set to the distribution given by the data # using the inverse Rosenblatt transformation for ipt in range(totquat): # print "Converting quadrature point #",ipt # Set up working arrays quadunif = uqtkarray.dblArray1D(ndim, 0.0) invRosData_1s = uqtkarray.dblArray1D(ndim, 0.0) # First map each point to uniform[0,1] # PCtoPC maps to [-1,1], which then gets remapped to [0,1] for idim in range(ndim): quadunif[idim] = (uqtktools.PCtoPC( qdpts[ipt, idim], pc_model.GetPCType(), pc_model.GetAlpha(), pc_model.GetBeta(), "LU", 0.0, 0.0) + 1.0) / 2.0 # Map each point from uniform[0,1] to the distribution given by the original samples via inverse Rosenblatt if bw > 0: uqtktools.invRos(quadunif, ydata_t, invRosData_1s, bw) else: uqtktools.invRos(quadunif, ydata_t, invRosData_1s) # Store results for idim in range(ndim): invRosData[ipt, idim] = invRosData_1s[idim] # Screen diagnostic output if ((ipt + 1) % iiout == 0) or ipt == 0 or (ipt + 1) == totquat: print "Inverse Rosenblatt for Galerkin projection:", ( ipt + 1), "/", totquat, "=", (ipt + 1) * 100 / totquat, "% completed" # Get PC coefficients by Galerkin projection # Set up numpy array for PC coefficients (one column for each transformed random variable) c_k = np.zeros((npce, ndim)) # Project each random variable one by one for idim in range(ndim): # UQTk array for PC coefficients for one variable c_k_1d = uqtkarray.dblArray1D(npce, 0.0) # UQTk array for map evaluations at quadrature points for that variable invRosData_1d = uqtkarray.dblArray1D(totquat, 0.0) # invRosData_1d.setnpdblArray(np.asfortranarray(invRosData[:,idim]) for ipt in range(totquat): invRosData_1d[ipt] = invRosData[ipt, idim] # Galerkin Projection pc_model.GalerkProjection(invRosData_1d, c_k_1d) # Put coefficients in full array for ip in range(npce): c_k[ip, idim] = c_k_1d[ip] # Return numpy array of PC coefficients return c_k
def run_ddd(components, working_directory, max_iter=30, tolerance=0.01, pce_order=3, exo_links=[], restart=False): """ Perform deterministic domain decomposition wrapped in NISP """ working_directory = os.path.abspath(working_directory) # Calculate pce dimension (total number of exogenous ports in network) pce_dim = 0 for comp in components: pce_dim += comp.get_num_exogenous_ports() pce_dim -= len(exo_links) print("Network has %d exogenous ports." % pce_dim) # Generate PCE model pc_type = "HG" pc_alpha = 0.0 pc_beta = 1.0 param = pce_order + 1 # Parameter for quadrature point generation. Equal to number of quad points per dimension for full quadrature pc_model = uqtkpce.PCSet("NISP", pce_order, pce_dim, pc_type, pc_alpha, pc_beta) pc_model.SetQuadRule(pc_type, 'full', param) for comp in components: comp.pc_model = pc_model # Get Quadrature Points qdpts_uqtk = uqtkarray.dblArray2D() pc_model.GetQuadPoints(qdpts_uqtk) totquat = pc_model.GetNQuadPoints() qdpts = np.zeros((totquat, pce_dim)) qdpts_uqtk.getnpdblArray(qdpts) # Create and populate working directories for each simulation if not restart: if os.path.isdir(working_directory): shutil.rmtree(working_directory) os.makedirs(working_directory) for quad_iter in range(totquat): # Create subdirectory for each quadrature point # and copy required files into it newfolder = os.path.join(working_directory, "qdpt_%d" % quad_iter) if not os.path.isdir(newfolder): os.makedirs(newfolder) for c in components: for f in c.get_required_files(): shutil.copy2(f, newfolder) # Perform iterations for jacobi_iter in range(max_iter): print("Performing iteration %d..." % jacobi_iter) old_endo_data = [] new_endo_data = [] exo_port_idx = [] exogenous_idx = 0 for compidx, comp in enumerate(components): old_endo_data.append(comp.get_endogenous_data()) running_jobs = [] for quad_iter in range(totquat): targetfolder = os.path.join(working_directory, "qdpt_%d" % quad_iter) os.chdir(targetfolder) unique_ports = 0 my_ports = [] for portidx, port in enumerate(comp.exogenous_ports): found = False for link in exo_links: if compidx == link[2] and portidx == link[3]: port.value = port.mean + port.std * qdpts[ quad_iter, exo_port_idx[link[0]][link[1]]] my_ports.append(exo_port_idx[link[0]][link[1]]) found = True if not found: port.value = port.mean + port.std * qdpts[ quad_iter, exogenous_idx + unique_ports] my_ports.append(exogenous_idx + unique_ports) unique_ports += 1 job = comp.execute() running_jobs.append(job) exo_port_idx.append(my_ports) exogenous_idx += len(my_ports) # Wait for all simulations to complete print("Waiting for aria jobs to complete...") for job in running_jobs: job.communicate() new_endo_data.append(comp.get_endogenous_data()) # Check for convergence maxdiff = 0 for comp_idx in range(len(components)): for timestep, nodal_data in enumerate(old_endo_data[comp_idx]): for nid in nodal_data: diff = abs(new_endo_data[comp_idx][timestep][nid] - old_endo_data[comp_idx][timestep][nid]) maxdiff = max(maxdiff, diff) print(maxdiff) if maxdiff < tolerance: break # Collect update PCE coefficients print("Collect Data") QoI_pce_coeffs = [] for comp in components: QoI_data = np.zeros( (totquat, comp.get_num_QoI() * comp.get_num_timesteps())) for quad_iter in range(totquat): targetfolder = os.path.join(working_directory, "qdpt_%d" % quad_iter) os.chdir(targetfolder) QoI_at_qdpt = comp.get_QoI_data() for i, QoI in enumerate(comp.QoIs): QoI_data[[quad_iter], (i * comp.get_num_timesteps()):( (i + 1) * comp.get_num_timesteps())] = QoI_at_qdpt[QoI] QoI_ck = np.zeros((QoI_data.shape[1], pc_model.GetNumberPCTerms())) for i in range(QoI_data.shape[1]): QoI_ck[i, ...] = GalerkinProjection(pc_model, QoI_data[:, i]) QoI_pce_coeffs.append(QoI_ck) return QoI_pce_coeffs
def mkBlnkDbl2D(): return uqtkarray.dblArray2D()
def mkSzDbl2D(dim1, dim2): return uqtkarray.dblArray2D(dim1, dim2)
def mkSetDbl2D(v_np): v_uqtk = uqtkarray.dblArray2D(v_np.shape[0], v_np.shape[1]) v_uqtk.setnpdblArray(v_np) return v_uqtk