def _eval_opts(self, opts, default=None): # Boundary conditions, much like initial conditions, can be # parameterized by values in [constants] so we must bring these # into scope when evaluating the boundary conditions cc = self.cfg.items_as('constants', float) cfg, sect = self.cfg, self.cfgsect # Evaluate any BC specific arguments from the config file if default is not None: return [npeval(cfg.getexpr(sect, k, default), cc) for k in opts] else: return [npeval(cfg.getexpr(sect, k), cc) for k in opts]
def set_ics_from_cfg(self): # Bring simulation constants into scope vars = self._cfg.items_as('constants', float) if any(d in vars for d in 'xyz'): raise ValueError('Invalid constants (x, y, or z) in config file') # Construct the physical location operator matrix plocop = self._basis.sbasis.nodal_basis_at(self._basis.upts) # Apply the operator to the mesh elements and reshape plocupts = np.dot(plocop, self._eles.reshape(self.nspts, -1)) plocupts = plocupts.reshape(self.nupts, self.neles, self.ndims) # Extract the components of the mesh coordinates coords = np.rollaxis(plocupts, 2) vars.update(dict(zip('xyz', coords))) # Evaluate the ICs from the config file ics = [npeval(self._cfg.get('soln-ics', dv), vars) for dv in self._privarmap[self.ndims]] # Allocate self._scal_upts = np.empty((self.nupts, self.nvars, self.neles)) # Convert from primitive to conservative form for i, v in enumerate(self._process_ics(ics)): self._scal_upts[:,i,:] = v
def _eval_acc_exprs(self, intg): exprs = [] # Get the primitive variable names pnames = self.elementscls.privarmap[self.ndims] # Iterate over each element type in the simulation for idx, etype, rgn in self._ele_regions: soln = intg.soln[idx][..., rgn].swapaxes(0, 1) # Convert from conservative to primitive variables psolns = self.elementscls.con_to_pri(soln, self.cfg) # Prepare the substitutions dictionary subs = dict(zip(pnames, psolns)) # Prepare any required gradients if self._gradpinfo: # Compute the gradients grad_soln = np.rollaxis(intg.grad_soln[idx], 2)[..., rgn] # Transform from conservative to primitive gradients pgrads = self.elementscls.grad_con_to_pri(soln, grad_soln, self.cfg) # Add them to the substitutions dictionary for pname, idx in self._gradpinfo: for dim, grad in zip('xyz', pgrads[idx]): subs[f'grad_{pname}_{dim}'] = grad # Evaluate the expressions exprs.append([npeval(v, subs) for v in self.aexprs]) # Stack up the expressions for each element type and return return [np.dstack(exs).swapaxes(1, 2) for exs in exprs]
def set_ics_from_cfg(self): # Bring simulation constants into scope vars = self._cfg.items_as('constants', float) if any(d in vars for d in 'xyz'): raise ValueError('Invalid constants (x, y, or z) in config file') # Construct the physical location operator matrix plocop = self._basis.sbasis.nodal_basis_at(self._basis.upts) # Apply the operator to the mesh elements and reshape plocupts = np.dot(plocop, self._eles.reshape(self.nspts, -1)) plocupts = plocupts.reshape(self.nupts, self.neles, self.ndims) # Extract the components of the mesh coordinates coords = np.rollaxis(plocupts, 2) vars.update(dict(zip('xyz', coords))) # Evaluate the ICs from the config file ics = [ npeval(self._cfg.get('soln-ics', dv), vars) for dv in self._dynvarmap[self.ndims] ] # Allocate self._scal_upts = np.empty((self.nupts, self.nvars, self.neles)) # Convert from primitive to conservative form for i, v in enumerate(self._process_ics(ics)): self._scal_upts[:, i, :] = v
def set_ics_from_cfg(self): # Bring simulation constants into scope vars = self._cfg.items_as('constants', float) if any(d in vars for d in 'xyz'): raise ValueError('Invalid constants (x, y, or z) in config file') # Construct the physical location operator matrix plocop = np.asanyarray(self._basis.sbasis_at(self._basis.upts), dtype=np.float) # Apply the operator to the mesh elements and reshape plocupts = np.dot(plocop, self._eles.reshape(self.nspts, -1)) plocupts = plocupts.reshape(self.nupts, self.neles, self.ndims) # Extract the components of the mesh coordinates coords = np.rollaxis(plocupts, 2) vars.update(dict(zip('xyz', coords))) # Evaluate the ICs from the config file ics = [npeval(self._cfg.get('soln-ics', dv), vars) for dv in self._dynvarmap[self.ndims]] # Allow subclasses to process these ICs ics = np.dstack(self._process_ics(ics)) # Handle the case of uniform (scalar) ICs if ics.shape[:2] == (1, 1): ics = ics*np.ones((self.nupts, self.neles, 1)) self._scal_upts = ics
def _eval_fun_exprs(self, intg, accex): exprs = [] # Iterate over each element type our averaging region for avals in accex: # Prepare the substitution dictionary subs = dict(zip(self.anames, avals.swapaxes(0, 1))) exprs.append([npeval(v, subs) for v in self.fexprs]) # Stack up the expressions for each element type and return return [np.dstack(exs).swapaxes(1, 2) for exs in exprs]
def _eval_exprs(self, intg): intvals = np.zeros(len(self.exprs)) # Get the primitive variable names pnames = self.elementscls.privarmap[self.ndims] # Iterate over each element type in the simulation for i, (soln, eleinfo) in enumerate(zip(intg.soln, self.eleinfo)): plocs, wts, m0, eset, emask = eleinfo # Subset and transpose the solution soln = soln[..., eset].swapaxes(0, 1) # Interpolate the solution to the quadrature points if m0 is not None: soln = m0 @ soln # Convert from conservative to primitive variables psolns = self.elementscls.con_to_pri(soln, self.cfg) # Prepare the substitutions dictionary subs = dict(zip(pnames, psolns)) subs.update(zip('xyz', plocs), t=intg.tcurr) # Prepare any required gradients if self._gradpinfo: # Compute the gradients grad_soln = np.rollaxis(intg.grad_soln[i], 2)[..., eset] # Interpolate the gradients to the quadrature points if m0 is not None: grad_soln = m0 @ grad_soln # Transform from conservative to primitive gradients pgrads = self.elementscls.grad_con_to_pri( soln, grad_soln, self.cfg) # Add them to the substitutions dictionary for pname, idx in self._gradpinfo: for dim, grad in zip('xyz', pgrads[idx]): subs[f'grad_{pname}_{dim}'] = grad for j, v in enumerate(self.exprs): # Evaluate the expression at each point iex = wts * npeval(v, subs) # Accumulate intvals[j] += np.sum(iex) - np.sum(iex[emask]) return intvals
def _eval_exprs(self, intg): intvals = np.zeros(len(self.exprs)) # Get the primitive variable names pnames = self.elementscls.privarmap[self.ndims] # Iterate over each element type in the simulation for i, (soln, eleinfo) in enumerate(zip(intg.soln, self.eleinfo)): plocs, wts, eset, emask = eleinfo # Subset and transpose the solution soln = soln[..., eset].swapaxes(0, 1) # Convert from conservative to primitive variables psolns = self.elementscls.con_to_pri(soln, self.cfg) # Prepare the substitutions dictionary subs = dict(zip(pnames, psolns)) subs.update(zip('xyz', plocs)) # Compute any required gradients if self._gradpnames: # Gradient operator and J^-T matrix gradop, rcpjact = self._gradop[i], self._rcpjact[i] nupts = gradop.shape[1] for pname in self._gradpnames: psoln = subs[pname] # Compute the transformed gradient tgradpn = gradop @ psoln tgradpn = tgradpn.reshape(self.ndims, nupts, -1) # Untransform this to get the physical gradient gradpn = np.einsum('ijkl,jkl->ikl', rcpjact, tgradpn) gradpn = gradpn.reshape(self.ndims, nupts, -1) for dim, grad in zip('xyz', gradpn): subs[f'grad_{pname}_{dim}'] = grad for j, v in enumerate(self.exprs): # Evaluate the expression at each point iex = wts * npeval(v, subs) # Accumulate intvals[j] += np.sum(iex) - np.sum(iex[emask]) return intvals
def _eval_exprs(self, intg): exprs = [] # Iterate over each element type in the simulation for soln, ploc in zip(intg.soln, self.plocs): # Get the primitive variable names and solutions pnames = self.elementscls.privarmap[self.ndims] psolns = self.elementscls.con_to_pri(soln.swapaxes(0, 1), self.cfg) # Prepare the substitutions dictionary ploc = dict(zip('xyz', ploc.swapaxes(0, 1))) subs = dict(zip(pnames, psolns), t=intg.tcurr, **ploc) # Evaluate the expressions exprs.append([npeval(v, subs) for k, v in self.exprs]) # Stack up the expressions for each element type and return return [np.dstack(exs).swapaxes(1, 2) for exs in exprs]
def _eval_exprs(self, intg): exprs = [] # Get the primitive variable names pnames = self.elementscls.privarmap[self.ndims] # Iterate over each element type in the simulation for i, (soln, ploc) in enumerate(zip(intg.soln, self.plocs)): # Convert from conservative to primitive variables psolns = self.elementscls.con_to_pri(soln.swapaxes(0, 1), self.cfg) # Prepare the substitutions dictionary subs = dict(zip(pnames, psolns)) subs.update(zip('xyz', ploc.swapaxes(0, 1))) # Compute any required gradients if self._gradpnames: # Gradient operator and J^-T matrix gradop, rcpjact = self._gradop[i], self._rcpjact[i] nupts = gradop.shape[1] for pname in self._gradpnames: psoln = subs[pname] # Compute the transformed gradient tgradpn = gradop @ psoln tgradpn = tgradpn.reshape(self.ndims, nupts, -1) # Untransform this to get the physical gradient gradpn = np.einsum('ijkl,jkl->ikl', rcpjact, tgradpn) gradpn = gradpn.reshape(self.ndims, nupts, -1) for dim, grad in zip('xyz', gradpn): subs['grad_{0}_{1}'.format(pname, dim)] = grad # Evaluate the expressions exprs.append([npeval(v, subs) for k, v in self.exprs]) # Stack up the expressions for each element type and return return [np.dstack(exs).swapaxes(1, 2) for exs in exprs]
def set_ics_from_cfg(self): # Bring simulation constants into scope vars = self.cfg.items_as('constants', float) if any(d in vars for d in 'xyz'): raise ValueError('Invalid constants (x, y, or z) in config file') # Get the physical location of each solution point coords = self.ploc_at_np('upts').swapaxes(0, 1) vars.update(dict(zip('xyz', coords))) # Evaluate the ICs from the config file ics = [npeval(self.cfg.get('soln-ics', dv), vars) for dv in self.privarmap[self.ndims]] # Allocate self._scal_upts = np.empty((self.nupts, self.nvars, self.neles)) # Convert from primitive to conservative form for i, v in enumerate(self.pri_to_conv(ics, self.cfg)): self._scal_upts[:, i, :] = v
def set_ics_from_cfg(self): # Bring simulation constants into scope vars = self.cfg.items_as('constants', float) if any(d in vars for d in 'xyz'): raise ValueError('Invalid constants (x, y, or z) in config file') # Get the physical location of each solution point coords = self.ploc_at_np('upts').swapaxes(0, 1) vars.update(dict(zip('xyz', coords))) # Evaluate the ICs from the config file ics = [npeval(self.cfg.getexpr('soln-ics', dv), vars) for dv in self.privarmap[self.ndims]] # Allocate self._scal_upts = np.empty((self.nupts, self.nvars, self.neles)) # Convert from primitive to conservative form for i, v in enumerate(self.pri_to_con(ics, self.cfg)): self._scal_upts[:, i, :] = v