示例#1
0
    def __init__(self, intg, cfgsect, suffix=None):
        super().__init__(intg, cfgsect, suffix)

        # Construct the solution writer
        basedir = self.cfg.getpath(cfgsect, 'basedir', '.')
        basename = self.cfg.get(cfgsect, 'basename')
        self._writer = NativeWriter(intg,
                                    self.nvars,
                                    basedir,
                                    basename,
                                    prefix='soln')

        # Output time step and next output time
        self.dt_out = self.cfg.getfloat(cfgsect, 'dt-out')
        self.tout_next = intg.tcurr

        # Output field names
        self.fields = intg.system.elementscls.convarmap[self.ndims]

        # Register our output times with the integrator
        intg.call_plugin_dt(self.dt_out)

        # If we're not restarting then write out the initial solution
        if not intg.isrestart:
            self(intg)
        else:
            self.tout_next += self.dt_out
示例#2
0
    def __init__(self, intg, cfgsect, suffix=None):
        super().__init__(intg, cfgsect, suffix)

        # Underlying elements class
        self.elementscls = intg.system.elementscls

        # Expressions to time average
        c = self.cfg.items_as('constants', float)
        self.exprs = [(k, self.cfg.getexpr(cfgsect, k, subs=c))
                      for k in self.cfg.items(cfgsect)
                      if k.startswith('avg-')]

        # Save a reference to the physical solution point locations
        self.plocs = intg.system.ele_ploc_upts

        # Output file directory, base name, and writer
        basedir = self.cfg.getpath(cfgsect, 'basedir', '.')
        basename = self.cfg.get(cfgsect, 'basename')
        self._writer = NativeWriter(intg, len(self.exprs), basedir, basename,
                                    prefix='tavg')

        # Time averaging parameters
        self.dtout = self.cfg.getfloat(cfgsect, 'dt-out')
        self.nsteps = self.cfg.getint(cfgsect, 'nsteps')
        self.tout = intg.tcurr + self.dtout

        # Register our output times with the integrator
        intg.call_plugin_dt(self.dtout)

        # Time averaging state
        self.prevt = intg.tcurr
        self.prevex = self._eval_exprs(intg)
        self.accmex = [np.zeros_like(p) for p in self.prevex]
示例#3
0
文件: writer.py 项目: vavrines/PyFR
    def __init__(self, intg, cfgsect, suffix=None):
        super().__init__(intg, cfgsect, suffix)

        # Base output directory and file name
        basedir = self.cfg.getpath(self.cfgsect, 'basedir', '.', abs=True)
        basename = self.cfg.get(self.cfgsect, 'basename')

        # Construct the solution writer
        self._writer = NativeWriter(intg, basedir, basename, 'soln')

        # Output time step and last output time
        self.dt_out = self.cfg.getfloat(cfgsect, 'dt-out')
        self.tout_last = intg.tcurr

        # Output field names
        self.fields = intg.system.elementscls.convarmap[self.ndims]

        # Output data type
        self.fpdtype = intg.backend.fpdtype

        # Register our output times with the integrator
        intg.call_plugin_dt(self.dt_out)

        # If we're not restarting then make sure we write out the initial
        # solution when we are called for the first time
        if not intg.isrestart:
            self.tout_last -= self.dt_out
示例#4
0
class WriterPlugin(BasePlugin):
    name = 'writer'
    systems = ['*']

    def __init__(self, intg, cfgsect, suffix=None):
        super().__init__(intg, cfgsect, suffix)

        # Construct the solution writer
        basedir = self.cfg.getpath(cfgsect, 'basedir', '.')
        basename = self.cfg.get(cfgsect, 'basename')
        self._writer = NativeWriter(intg,
                                    self.nvars,
                                    basedir,
                                    basename,
                                    prefix='soln')

        # Output time step and next output time
        self.dt_out = self.cfg.getfloat(cfgsect, 'dt-out')
        self.tout_next = intg.tcurr

        # Output field names
        self.fields = intg.system.elementscls.convarmap[self.ndims]

        # Register our output times with the integrator
        intg.call_plugin_dt(self.dt_out)

        # If we're not restarting then write out the initial solution
        if not intg.isrestart:
            self(intg)
        else:
            self.tout_next += self.dt_out

    def __call__(self, intg):
        if abs(self.tout_next - intg.tcurr) > intg.dtmin:
            return

        stats = Inifile()
        stats.set('data', 'fields', ','.join(self.fields))
        stats.set('data', 'prefix', 'soln')
        intg.collect_stats(stats)

        metadata = dict(config=self.cfg.tostr(),
                        stats=stats.tostr(),
                        mesh_uuid=intg.mesh_uuid)

        self._writer.write(intg.soln, metadata, intg.tcurr)

        self.tout_next += self.dt_out
示例#5
0
文件: base.py 项目: tarikdzanic/PyFR
    def _init_writer_for_region(self, intg, nout, prefix, *, fpdtype=None):
        # Base output directory and file name
        basedir = self.cfg.getpath(self.cfgsect, 'basedir', '.', abs=True)
        basename = self.cfg.get(self.cfgsect, 'basename')

        # Data type
        if fpdtype is None:
            fpdtype = intg.backend.fpdtype
        elif fpdtype == 'single':
            fpdtype = np.float32
        elif fpdtype == 'double':
            fpdtype = np.float64
        else:
            raise ValueError('Invalid floating point data type')

        # Region of interest
        region = self.cfg.get(self.cfgsect, 'region', '*')

        # All elements
        if region == '*':
            mdata = self._prepare_mdata_all(intg, fpdtype, nout, prefix)
            self._add_region_data = self._add_region_data_all
        # All elements inside a box
        elif '(' in region or '[' in region:
            box = self.cfg.getliteral(self.cfgsect, 'region')
            mdata = self._prepare_mdata_box(intg, fpdtype, nout, prefix, *box)
            self._add_region_data = self._add_region_data_subset
        # All elements on a boundary
        else:
            mdata = self._prepare_mdata_bcs(intg, fpdtype, nout, prefix,
                                            region)
            self._add_region_data = self._add_region_data_subset

        # Construct the file writer
        return NativeWriter(intg, mdata, basedir, basename)
示例#6
0
    def __init__(self, intg, cfgsect, suffix=None):
        super().__init__(intg, cfgsect, suffix)

        # Underlying elements class
        self.elementscls = intg.system.elementscls

        # Expressions to time average
        c = self.cfg.items_as('constants', float)
        self.exprs = [(k, self.cfg.getexpr(cfgsect, k, subs=c))
                      for k in self.cfg.items(cfgsect)
                      if k.startswith('avg-')]

        # Save a reference to the physical solution point locations
        self.plocs = intg.system.ele_ploc_upts

        # Output file directory, base name, and writer
        basedir = self.cfg.getpath(cfgsect, 'basedir', '.')
        basename = self.cfg.get(cfgsect, 'basename')
        self._writer = NativeWriter(intg, len(self.exprs), basedir, basename,
                                    prefix='tavg')

        # Time averaging parameters
        self.dtout = self.cfg.getfloat(cfgsect, 'dt-out')
        self.nsteps = self.cfg.getint(cfgsect, 'nsteps')
        self.tout = intg.tcurr + self.dtout

        # Register our output times with the integrator
        intg.call_plugin_dt(self.dtout)

        # Time averaging state
        self.prevt = intg.tcurr
        self.prevex = self._eval_exprs(intg)
        self.accmex = [np.zeros_like(p) for p in self.prevex]
示例#7
0
文件: writer.py 项目: uberstig/PyFR
class WriterPlugin(BasePlugin):
    name = 'writer'
    systems = ['*']

    def __init__(self, intg, cfgsect, suffix=None):
        super().__init__(intg, cfgsect, suffix)

        # Construct the solution writer
        basedir = self.cfg.getpath(cfgsect, 'basedir', '.')
        basename = self.cfg.get(cfgsect, 'basename')
        self._writer = NativeWriter(intg, self.nvars, basedir, basename,
                                    prefix='soln')

        # Output time step and next output time
        self.dt_out = self.cfg.getfloat(cfgsect, 'dt-out')
        self.tout_next = intg.tcurr

        # Output field names
        self.fields = intg.system.elementscls.convarmap[self.ndims]

        # Register our output times with the integrator
        intg.call_plugin_dt(self.dt_out)

        # If we're not restarting then write out the initial solution
        if not intg.isrestart:
            self(intg)
        else:
            self.tout_next += self.dt_out

    def __call__(self, intg):
        if abs(self.tout_next - intg.tcurr) > intg.dtmin:
            return

        stats = Inifile()
        stats.set('data', 'fields', ','.join(self.fields))
        stats.set('data', 'prefix', 'soln')
        intg.collect_stats(stats)

        metadata = dict(config=self.cfg.tostr(),
                        stats=stats.tostr(),
                        mesh_uuid=intg.mesh_uuid)

        self._writer.write(intg.soln, metadata, intg.tcurr)

        self.tout_next += self.dt_out
示例#8
0
文件: writer.py 项目: yifanb/PyFR
class WriterPlugin(BasePlugin):
    name = 'writer'
    systems = ['*']
    formulations = ['dual', 'std']

    def __init__(self, intg, cfgsect, suffix=None):
        super().__init__(intg, cfgsect, suffix)

        # Construct the solution writer
        basedir = self.cfg.getpath(cfgsect, 'basedir', '.', abs=True)
        basename = self.cfg.get(cfgsect, 'basename')
        self._writer = NativeWriter(intg,
                                    self.nvars,
                                    basedir,
                                    basename,
                                    prefix='soln')

        # Output time step and next output time
        self.dt_out = self.cfg.getfloat(cfgsect, 'dt-out')
        self.tout_next = intg.tcurr

        # Output field names
        self.fields = intg.system.elementscls.convarmap[self.ndims]

        # Register our output times with the integrator
        intg.call_plugin_dt(self.dt_out)

        # If we're not restarting then write out the initial solution
        if not intg.isrestart:
            self(intg)
        else:
            self.tout_next += self.dt_out

    def __call__(self, intg):
        if abs(self.tout_next - intg.tcurr) > self.tol:
            return

        stats = Inifile()
        stats.set('data', 'fields', ','.join(self.fields))
        stats.set('data', 'prefix', 'soln')
        intg.collect_stats(stats)

        # Prepare the metadata
        metadata = dict(intg.cfgmeta,
                        stats=stats.tostr(),
                        mesh_uuid=intg.mesh_uuid)

        # Write out the file
        solnfname = self._writer.write(intg.soln, metadata, intg.tcurr)

        # If a post-action has been registered then invoke it
        self._invoke_postaction(mesh=intg.system.mesh.fname,
                                soln=solnfname,
                                t=intg.tcurr)

        # Compute the next output time
        self.tout_next = intg.tcurr + self.dt_out
示例#9
0
    def __init__(self, intg, cfgsect, suffix=None):
        super().__init__(intg, cfgsect, suffix)

        # Underlying elements class
        self.elementscls = intg.system.elementscls

        # Expressions to time average
        c = self.cfg.items_as('constants', float)
        self.exprs = [(k, self.cfg.getexpr(cfgsect, k, subs=c))
                      for k in self.cfg.items(cfgsect)
                      if k.startswith('avg-')]

        # Gradient pre-processing
        self._init_gradients(intg)

        # Save a reference to the physical solution point locations
        self.plocs = intg.system.ele_ploc_upts

        # Element info and backend data type
        einfo = zip(intg.system.ele_types, intg.system.ele_shapes)
        fpdtype = intg.backend.fpdtype

        # Output metadata
        mdata = [(f'tavg_{etype}', (nupts, len(self.exprs), neles), fpdtype)
                 for etype, (nupts, _, neles) in einfo]

        # Output base directory and name
        basedir = self.cfg.getpath(cfgsect, 'basedir', '.', abs=True)
        basename = self.cfg.get(cfgsect, 'basename')

        self._writer = NativeWriter(intg, mdata, basedir, basename)

        # Time averaging parameters
        self.dtout = self.cfg.getfloat(cfgsect, 'dt-out')
        self.nsteps = self.cfg.getint(cfgsect, 'nsteps')
        self.tout_last = intg.tcurr

        # Register our output times with the integrator
        intg.call_plugin_dt(self.dtout)

        # Time averaging state
        self.prevt = intg.tcurr
        self.prevex = self._eval_exprs(intg)
        self.accmex = [np.zeros_like(p) for p in self.prevex]
示例#10
0
    def save_solution(self, savedir, basename, t=0):
        ndims = self.solver.system.ndims
        nvars = self.solver.system.nvars
        writer = NativeWriter(self.solver,
                              nvars,
                              savedir,
                              basename,
                              prefix='soln')
        fields = self.solver.system.elementscls.convarmap[ndims]
        stats = Inifile()
        stats.set('data', 'fields', ','.join(fields))
        stats.set('data', 'prefix', 'soln')
        self.solver.collect_stats(stats)
        stats.set('solver-time-integrator', 'tcurr', str(t))

        metadata = dict(self.solver.cfgmeta,
                        stats=stats.tostr(),
                        mesh_uuid=self.solver.mesh_uuid)
        writer.write(self.solver.soln, metadata, t)
示例#11
0
文件: tavg.py 项目: vavrines/PyFR
    def __init__(self, intg, cfgsect, suffix=None):
        super().__init__(intg, cfgsect, suffix)

        # Underlying elements class
        self.elementscls = intg.system.elementscls

        # Averaging mode
        self.mode = self.cfg.get(cfgsect, 'mode', 'windowed')
        if self.mode not in {'continuous', 'windowed'}:
            raise ValueError('Invalid averaging mode')

        # Expressions pre-processing
        self._prepare_exprs()

        # Output data type
        fpdtype = self.cfg.get(cfgsect, 'precision', 'single')
        if fpdtype == 'single':
            self.fpdtype = np.float32
        elif fpdtype == 'double':
            self.fpdtype = np.float64
        else:
            raise ValueError('Invalid floating point data type')

        # Base output directory and file name
        basedir = self.cfg.getpath(self.cfgsect, 'basedir', '.', abs=True)
        basename = self.cfg.get(self.cfgsect, 'basename')

        # Construct the file writer
        self._writer = NativeWriter(intg, basedir, basename, 'tavg')

        # Gradient pre-processing
        self._init_gradients(intg)

        # Time averaging parameters
        self.tstart = self.cfg.getfloat(cfgsect, 'tstart', 0.0)
        self.dtout = self.cfg.getfloat(cfgsect, 'dt-out')
        self.nsteps = self.cfg.getint(cfgsect, 'nsteps')

        # Register our output times with the integrator
        intg.call_plugin_dt(self.dtout)

        # Mark ourselves as not currently averaging
        self._started = False
示例#12
0
文件: writer.py 项目: pv101/PyFR
class WriterPlugin(BasePlugin):
    name = 'writer'
    systems = ['*']
    formulations = ['dual', 'std']

    def __init__(self, intg, cfgsect, suffix=None):
        super().__init__(intg, cfgsect, suffix)

        # Construct the solution writer
        basedir = self.cfg.getpath(cfgsect, 'basedir', '.', abs=True)
        basename = self.cfg.get(cfgsect, 'basename')
        self._writer = NativeWriter(intg, self.nvars, basedir, basename,
                                    prefix='soln')

        # Output time step and next output time
        self.dt_out = self.cfg.getfloat(cfgsect, 'dt-out')
        self.tout_next = intg.tcurr

        # Output field names
        self.fields = intg.system.elementscls.convarmap[self.ndims]

        # Register our output times with the integrator
        intg.call_plugin_dt(self.dt_out)

        # If we're not restarting then write out the initial solution
        if not intg.isrestart:
            self(intg)
        else:
            self.tout_next += self.dt_out

    def __call__(self, intg):
        if abs(self.tout_next - intg.tcurr) > self.tol:
            return

        stats = Inifile()
        stats.set('data', 'fields', ','.join(self.fields))
        stats.set('data', 'prefix', 'soln')
        intg.collect_stats(stats)

        # Prepare the metadata
        metadata = dict(intg.cfgmeta,
                        stats=stats.tostr(),
                        mesh_uuid=intg.mesh_uuid)

        # Write out the file
        solnfname = self._writer.write(intg.soln, metadata, intg.tcurr)

        # If a post-action has been registered then invoke it
        self._invoke_postaction(mesh=intg.system.mesh.fname, soln=solnfname,
                                t=intg.tcurr)

        # Compute the next output time
        self.tout_next = intg.tcurr + self.dt_out
示例#13
0
    def __init__(self, intg, cfgsect, suffix=None):
        super().__init__(intg, cfgsect, suffix)

        # Output region
        region = self.cfg.get(cfgsect, 'region', '*')

        # All elements
        if region == '*':
            mdata = self._prepare_mdata_all(intg)
            self._prepare_data = self._prepare_data_all
        # All elements inside a box
        elif ',' in region:
            box = self.cfg.getliteral(cfgsect, 'region')
            mdata = self._prepare_mdata_box(intg, *box)
            self._prepare_data = self._prepare_data_subset
        # All elements on a boundary
        else:
            mdata = self._prepare_mdata_bcs(intg, region)
            self._prepare_data = self._prepare_data_subset

        # Construct the solution writer
        basedir = self.cfg.getpath(cfgsect, 'basedir', '.', abs=True)
        basename = self.cfg.get(cfgsect, 'basename')
        self._writer = NativeWriter(intg, mdata, basedir, basename)

        # Output time step and last output time
        self.dt_out = self.cfg.getfloat(cfgsect, 'dt-out')
        self.tout_last = intg.tcurr

        # Output field names
        self.fields = intg.system.elementscls.convarmap[self.ndims]

        # Register our output times with the integrator
        intg.call_plugin_dt(self.dt_out)

        # If we're not restarting then write out the initial solution
        if not intg.isrestart:
            self.tout_last -= self.dt_out
            self(intg)
示例#14
0
    def __init__(self, intg, cfgsect, suffix=None):
        super().__init__(intg, cfgsect, suffix)

        # Construct the solution writer
        basedir = self.cfg.getpath(cfgsect, 'basedir', '.')
        basename = self.cfg.get(cfgsect, 'basename')
        self._writer = NativeWriter(intg, self.nvars, basedir, basename,
                                    prefix='soln')

        # Output time step and next output time
        self.dt_out = self.cfg.getfloat(cfgsect, 'dt-out')
        self.tout_next = intg.tcurr

        # Output field names
        self.fields = intg.system.elementscls.convarmap[self.ndims]

        # Register our output times with the integrator
        intg.call_plugin_dt(self.dt_out)

        # If we're not restarting then write out the initial solution
        if not intg.isrestart:
            self(intg)
        else:
            self.tout_next += self.dt_out
示例#15
0
class WriterPlugin(BasePlugin):
    name = 'writer'
    systems = ['*']
    formulations = ['dual', 'std']

    def __init__(self, intg, cfgsect, suffix=None):
        super().__init__(intg, cfgsect, suffix)

        # Output region
        region = self.cfg.get(cfgsect, 'region', '*')

        # All elements
        if region == '*':
            mdata = self._prepare_mdata_all(intg)
            self._prepare_data = self._prepare_data_all
        # All elements inside a box
        elif ',' in region:
            box = self.cfg.getliteral(cfgsect, 'region')
            mdata = self._prepare_mdata_box(intg, *box)
            self._prepare_data = self._prepare_data_subset
        # All elements on a boundary
        else:
            mdata = self._prepare_mdata_bcs(intg, region)
            self._prepare_data = self._prepare_data_subset

        # Construct the solution writer
        basedir = self.cfg.getpath(cfgsect, 'basedir', '.', abs=True)
        basename = self.cfg.get(cfgsect, 'basename')
        self._writer = NativeWriter(intg, mdata, basedir, basename)

        # Output time step and last output time
        self.dt_out = self.cfg.getfloat(cfgsect, 'dt-out')
        self.tout_last = intg.tcurr

        # Output field names
        self.fields = intg.system.elementscls.convarmap[self.ndims]

        # Register our output times with the integrator
        intg.call_plugin_dt(self.dt_out)

        # If we're not restarting then write out the initial solution
        if not intg.isrestart:
            self.tout_last -= self.dt_out
            self(intg)

    def _prepare_mdata_all(self, intg):
        # Element info and backend data type
        einfo = zip(intg.system.ele_types, intg.system.ele_shapes)
        fpdtype = intg.backend.fpdtype

        # Output metadata
        return [(f'soln_{etype}', shape, fpdtype) for etype, shape in einfo]

    def _prepare_mdata_box(self, intg, x0, x1):
        eset = {}

        for etype in intg.system.ele_types:
            pts = intg.system.mesh[f'spt_{etype}_p{intg.rallocs.prank}']
            pts = np.moveaxis(pts, 2, 0)

            # Determine which points are inside the box
            inside = np.ones(pts.shape[1:], dtype=np.bool)
            for l, p, u in zip(x0, pts, x1):
                inside &= (l <= p) & (p <= u)

            if np.sum(inside):
                eset[etype] = np.any(inside, axis=0).nonzero()[0]

        return self._prepare_eset(intg, eset)

    def _prepare_mdata_bcs(self, intg, bcname):
        comm, rank, root = get_comm_rank_root()

        # Get the mesh and prepare the element set dict
        mesh = intg.system.mesh
        eset = defaultdict(list)

        # Boundary of interest
        bc = f'bcon_{bcname}_p{intg.rallocs.prank}'

        # Ensure the boundary exists
        bcranks = comm.gather(bc in mesh, root=root)
        if rank == root and not any(bcranks):
            raise ValueError(f'Boundary {bcname} does not exist')

        if bc in mesh:
            # Determine which of our elements are on the boundary
            for etype, eidx in mesh[bc][['f0', 'f1']].astype('U4,i4'):
                eset[etype].append(eidx)

        return self._prepare_eset(intg, eset)

    def _prepare_eset(self, intg, eset):
        elemap = intg.system.ele_map

        mdata, ddata = [], []
        for etype, eidxs in sorted(eset.items()):
            neidx = len(eidxs)
            shape = (elemap[etype].nupts, elemap[etype].nvars, neidx)

            mdata.append((f'soln_{etype}', shape, intg.backend.fpdtype))
            mdata.append((f'soln_{etype}_idxs', (neidx, ), np.int32))

            doff = intg.system.ele_types.index(etype)
            darr = np.unique(eidxs).astype(np.int32)

            ddata.append((doff, darr))

        # Save ddata for later use
        self._ddata = ddata

        return mdata

    def _prepare_data_all(self, intg):
        return intg.soln

    def _prepare_data_subset(self, intg):
        data = []

        for doff, darr in self._ddata:
            data.append(intg.soln[doff][..., darr])
            data.append(darr)

        return data

    def __call__(self, intg):
        if intg.tcurr - self.tout_last < self.dt_out - self.tol:
            return

        stats = Inifile()
        stats.set('data', 'fields', ','.join(self.fields))
        stats.set('data', 'prefix', 'soln')
        intg.collect_stats(stats)

        # Prepare the metadata
        metadata = dict(intg.cfgmeta,
                        stats=stats.tostr(),
                        mesh_uuid=intg.mesh_uuid)

        # Prepare the data itself
        data = self._prepare_data(intg)

        # Write out the file
        solnfname = self._writer.write(data, metadata, intg.tcurr)

        # If a post-action has been registered then invoke it
        self._invoke_postaction(mesh=intg.system.mesh.fname,
                                soln=solnfname,
                                t=intg.tcurr)

        # Update the last output time
        self.tout_last = intg.tcurr
示例#16
0
class TavgPlugin(BasePlugin):
    name = 'tavg'
    systems = ['*']

    def __init__(self, intg, cfgsect, suffix=None):
        super().__init__(intg, cfgsect, suffix)

        # Underlying elements class
        self.elementscls = intg.system.elementscls

        # Expressions to time average
        c = self.cfg.items_as('constants', float)
        self.exprs = [(k, self.cfg.getexpr(cfgsect, k, subs=c))
                      for k in self.cfg.items(cfgsect)
                      if k.startswith('avg-')]

        # Save a reference to the physical solution point locations
        self.plocs = intg.system.ele_ploc_upts

        # Output file directory, base name, and writer
        basedir = self.cfg.getpath(cfgsect, 'basedir', '.')
        basename = self.cfg.get(cfgsect, 'basename')
        self._writer = NativeWriter(intg, len(self.exprs), basedir, basename,
                                    prefix='tavg')

        # Time averaging parameters
        self.dtout = self.cfg.getfloat(cfgsect, 'dt-out')
        self.nsteps = self.cfg.getint(cfgsect, 'nsteps')
        self.tout = intg.tcurr + self.dtout

        # Register our output times with the integrator
        intg.call_plugin_dt(self.dtout)

        # Time averaging state
        self.prevt = intg.tcurr
        self.prevex = self._eval_exprs(intg)
        self.accmex = [np.zeros_like(p) for p in self.prevex]

    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 __call__(self, intg):
        dowrite = abs(self.tout - intg.tcurr) < self.tol
        doaccum = intg.nacptsteps % self.nsteps == 0

        if dowrite or doaccum:
            # Evaluate the time averaging expressions
            currex = self._eval_exprs(intg)

            # Accumulate them; always do this even when just writing
            for a, p, c in zip(self.accmex, self.prevex, currex):
                a += 0.5*(intg.tcurr - self.prevt)*(p + c)

            # Save the time and solution
            self.prevt = intg.tcurr
            self.prevex = currex

            if dowrite:
                # Normalise
                accmex = [a / self.dtout for a in self.accmex]

                stats = Inifile()
                stats.set('data', 'prefix', 'tavg')
                stats.set('data', 'fields',
                          ','.join(k for k, v in self.exprs))
                stats.set('tavg', 'tstart', intg.tcurr - self.dtout)
                stats.set('tavg', 'tend', intg.tcurr)
                intg.collect_stats(stats)

                metadata = dict(intg.cfgmeta,
                                stats=stats.tostr(),
                                mesh_uuid=intg.mesh_uuid)

                self._writer.write(accmex, metadata, intg.tcurr)

                self.tout = intg.tcurr + self.dtout
                self.accmex = [np.zeros_like(a) for a in accmex]
示例#17
0
文件: tavg.py 项目: xgarnaud/PyFR
class TavgPlugin(BasePlugin):
    name = 'tavg'
    systems = ['*']
    formulations = ['dual', 'std']

    def __init__(self, intg, cfgsect, suffix=None):
        super().__init__(intg, cfgsect, suffix)

        # Underlying elements class
        self.elementscls = intg.system.elementscls

        # Expressions to time average
        c = self.cfg.items_as('constants', float)
        self.exprs = [(k, self.cfg.getexpr(cfgsect, k, subs=c))
                      for k in self.cfg.items(cfgsect) if k.startswith('avg-')]

        # Gradient pre-processing
        self._init_gradients(intg)

        # Save a reference to the physical solution point locations
        self.plocs = intg.system.ele_ploc_upts

        # Output file directory, base name, and writer
        basedir = self.cfg.getpath(cfgsect, 'basedir', '.', abs=True)
        basename = self.cfg.get(cfgsect, 'basename')
        self._writer = NativeWriter(intg,
                                    len(self.exprs),
                                    basedir,
                                    basename,
                                    prefix='tavg')

        # Time averaging parameters
        self.dtout = self.cfg.getfloat(cfgsect, 'dt-out')
        self.nsteps = self.cfg.getint(cfgsect, 'nsteps')
        self.tout_last = intg.tcurr

        # Register our output times with the integrator
        intg.call_plugin_dt(self.dtout)

        # Time averaging state
        self.prevt = intg.tcurr
        self.prevex = self._eval_exprs(intg)
        self.accmex = [np.zeros_like(p) for p in self.prevex]

    def _init_gradients(self, intg):
        # Determine what gradients, if any, are required
        self._gradpnames = gradpnames = set()
        for k, ex in self.exprs:
            gradpnames.update(re.findall(r'\bgrad_(.+?)_[xyz]\b', ex))

        # If gradients are required then form the relevant operators
        if gradpnames:
            self._gradop, self._rcpjact = [], []

            for eles in intg.system.ele_map.values():
                self._gradop.append(eles.basis.m4)

                # Get the smats at the solution points
                smat = eles.smat_at_np('upts').transpose(2, 0, 1, 3)

                # Get |J|^-1 at the solution points
                rcpdjac = eles.rcpdjac_at_np('upts')

                # Product to give J^-T at the solution points
                self._rcpjact.append(smat * rcpdjac)

    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 __call__(self, intg):
        tdiff = intg.tcurr - self.tout_last
        dowrite = tdiff >= self.dtout - self.tol
        doaccum = intg.nacptsteps % self.nsteps == 0

        if dowrite or doaccum:
            # Evaluate the time averaging expressions
            currex = self._eval_exprs(intg)

            # Accumulate them; always do this even when just writing
            for a, p, c in zip(self.accmex, self.prevex, currex):
                a += 0.5 * (intg.tcurr - self.prevt) * (p + c)

            # Save the time and solution
            self.prevt = intg.tcurr
            self.prevex = currex

            if dowrite:
                # Normalise
                accmex = [a / tdiff for a in self.accmex]

                stats = Inifile()
                stats.set('data', 'prefix', 'tavg')
                stats.set('data', 'fields', ','.join(k for k, v in self.exprs))
                stats.set('tavg', 'tstart', self.tout_last)
                stats.set('tavg', 'tend', intg.tcurr)
                intg.collect_stats(stats)

                metadata = dict(intg.cfgmeta,
                                stats=stats.tostr(),
                                mesh_uuid=intg.mesh_uuid)

                self._writer.write(accmex, metadata, intg.tcurr)

                self.tout_last = intg.tcurr
                self.accmex = [np.zeros_like(a) for a in accmex]
示例#18
0
文件: writer.py 项目: vavrines/PyFR
class WriterPlugin(PostactionMixin, RegionMixin, BasePlugin):
    name = 'writer'
    systems = ['*']
    formulations = ['dual', 'std']

    def __init__(self, intg, cfgsect, suffix=None):
        super().__init__(intg, cfgsect, suffix)

        # Base output directory and file name
        basedir = self.cfg.getpath(self.cfgsect, 'basedir', '.', abs=True)
        basename = self.cfg.get(self.cfgsect, 'basename')

        # Construct the solution writer
        self._writer = NativeWriter(intg, basedir, basename, 'soln')

        # Output time step and last output time
        self.dt_out = self.cfg.getfloat(cfgsect, 'dt-out')
        self.tout_last = intg.tcurr

        # Output field names
        self.fields = intg.system.elementscls.convarmap[self.ndims]

        # Output data type
        self.fpdtype = intg.backend.fpdtype

        # Register our output times with the integrator
        intg.call_plugin_dt(self.dt_out)

        # If we're not restarting then make sure we write out the initial
        # solution when we are called for the first time
        if not intg.isrestart:
            self.tout_last -= self.dt_out

    def __call__(self, intg):
        if intg.tcurr - self.tout_last < self.dt_out - self.tol:
            return

        comm, rank, root = get_comm_rank_root()

        # If we are the root rank then prepare the metadata
        if rank == root:
            stats = Inifile()
            stats.set('data', 'fields', ','.join(self.fields))
            stats.set('data', 'prefix', 'soln')
            intg.collect_stats(stats)

            metadata = dict(intg.cfgmeta,
                            stats=stats.tostr(),
                            mesh_uuid=intg.mesh_uuid)
        else:
            metadata = None

        # Fetch data from other plugins and add it to metadata with ad-hoc keys
        for csh in intg.completed_step_handlers:
            try:
                prefix = intg.get_plugin_data_prefix(csh.name, csh.suffix)
                pdata = csh.serialise(intg)
            except AttributeError:
                pdata = {}

            if rank == root:
                metadata |= {f'{prefix}/{k}': v for k, v in pdata.items()}

        # Fetch and (if necessary) subset the solution
        data = dict(self._ele_region_data)
        for idx, etype, rgn in self._ele_regions:
            data[etype] = intg.soln[idx][..., rgn].astype(self.fpdtype)

        # Write out the file
        solnfname = self._writer.write(data, intg.tcurr, metadata)

        # If a post-action has been registered then invoke it
        self._invoke_postaction(intg=intg,
                                mesh=intg.system.mesh.fname,
                                soln=solnfname,
                                t=intg.tcurr)

        # Update the last output time
        self.tout_last = intg.tcurr
示例#19
0
文件: tavg.py 项目: vavrines/PyFR
class TavgPlugin(PostactionMixin, RegionMixin, BasePlugin):
    name = 'tavg'
    systems = ['*']
    formulations = ['dual', 'std']

    def __init__(self, intg, cfgsect, suffix=None):
        super().__init__(intg, cfgsect, suffix)

        # Underlying elements class
        self.elementscls = intg.system.elementscls

        # Averaging mode
        self.mode = self.cfg.get(cfgsect, 'mode', 'windowed')
        if self.mode not in {'continuous', 'windowed'}:
            raise ValueError('Invalid averaging mode')

        # Expressions pre-processing
        self._prepare_exprs()

        # Output data type
        fpdtype = self.cfg.get(cfgsect, 'precision', 'single')
        if fpdtype == 'single':
            self.fpdtype = np.float32
        elif fpdtype == 'double':
            self.fpdtype = np.float64
        else:
            raise ValueError('Invalid floating point data type')

        # Base output directory and file name
        basedir = self.cfg.getpath(self.cfgsect, 'basedir', '.', abs=True)
        basename = self.cfg.get(self.cfgsect, 'basename')

        # Construct the file writer
        self._writer = NativeWriter(intg, basedir, basename, 'tavg')

        # Gradient pre-processing
        self._init_gradients(intg)

        # Time averaging parameters
        self.tstart = self.cfg.getfloat(cfgsect, 'tstart', 0.0)
        self.dtout = self.cfg.getfloat(cfgsect, 'dt-out')
        self.nsteps = self.cfg.getint(cfgsect, 'nsteps')

        # Register our output times with the integrator
        intg.call_plugin_dt(self.dtout)

        # Mark ourselves as not currently averaging
        self._started = False

    def _prepare_exprs(self):
        cfg, cfgsect = self.cfg, self.cfgsect
        c = self.cfg.items_as('constants', float)
        self.anames, self.aexprs = [], []
        self.outfields, self.fexprs = [], []

        # Iterate over accumulation expressions first
        for k in cfg.items(cfgsect):
            if k.startswith('avg-'):
                self.anames.append(k[4:])
                self.aexprs.append(cfg.getexpr(cfgsect, k, subs=c))
                self.outfields.append(k)

        # Followed by any functional expressions
        for k in cfg.items(cfgsect):
            if k.startswith('fun-avg-'):
                self.fexprs.append(cfg.getexpr(cfgsect, k, subs=c))
                self.outfields.append(k)

    def _init_gradients(self, intg):
        # Determine what gradients, if any, are required
        gradpnames = set()
        for ex in self.aexprs:
            gradpnames.update(re.findall(r'\bgrad_(.+?)_[xyz]\b', ex))

        privarmap = self.elementscls.privarmap[self.ndims]
        self._gradpinfo = [(pname, privarmap.index(pname))
                           for pname in gradpnames]

    def _init_accumex(self, intg):
        self.prevt = self.tout_last = intg.tcurr
        self.prevex = self._eval_acc_exprs(intg)
        self.accex = [np.zeros_like(p, dtype=np.float64) for p in self.prevex]

        # Extra state for continuous accumulation
        if self.mode == 'continuous':
            self.caccex = [np.zeros_like(a) for a in self.accex]
            self.tstart_actual = intg.tcurr

    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 _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 __call__(self, intg):
        # If we are not supposed to be averaging yet then return
        if intg.tcurr < self.tstart:
            return

        # If necessary, run the start-up routines
        if not self._started:
            self._init_accumex(intg)
            self._started = True

        # See if we are due to write and/or accumulate this step
        dowrite = intg.tcurr - self.tout_last >= self.dtout - self.tol
        doaccum = intg.nacptsteps % self.nsteps == 0

        if dowrite or doaccum:
            # Evaluate the time averaging expressions
            currex = self._eval_acc_exprs(intg)

            # Accumulate them; always do this even when just writing
            for a, p, c in zip(self.accex, self.prevex, currex):
                a += 0.5*(intg.tcurr - self.prevt)*(p + c)

            # Save the time and solution
            self.prevt = intg.tcurr
            self.prevex = currex

            if dowrite:
                comm, rank, root = get_comm_rank_root()

                if self.mode == 'windowed':
                    accex = self.accex
                    tstart = self.tout_last
                else:
                    for a, c in zip(self.accex, self.caccex):
                        c += a

                    accex = self.caccex
                    tstart = self.tstart_actual

                # Normalise the accumulated expressions
                tavg = [a / (intg.tcurr - tstart) for a in accex]

                # Evaluate any functional expressions
                if self.fexprs:
                    funex = self._eval_fun_exprs(intg, tavg)
                    tavg = [np.hstack([a, f]) for a, f in zip(tavg, funex)]

                # Form the output records to be written to disk
                data = dict(self._ele_region_data)
                for (idx, etype, rgn), d in zip(self._ele_regions, tavg):
                    data[etype] = d.astype(self.fpdtype)

                # If we are the root rank then prepare the metadata
                if rank == root:
                    stats = Inifile()
                    stats.set('data', 'prefix', 'tavg')
                    stats.set('data', 'fields', ','.join(self.outfields))
                    stats.set('tavg', 'tstart', tstart)
                    stats.set('tavg', 'tend', intg.tcurr)
                    intg.collect_stats(stats)

                    metadata = dict(intg.cfgmeta,
                                    stats=stats.tostr(),
                                    mesh_uuid=intg.mesh_uuid)
                else:
                    metadata = None

                # Write to disk
                solnfname = self._writer.write(data, intg.tcurr, metadata)

                # If a post-action has been registered then invoke it
                self._invoke_postaction(intg=intg, mesh=intg.system.mesh.fname,
                                        soln=solnfname, t=intg.tcurr)

                # Reset the accumulators
                for a in self.accex:
                    a.fill(0)

                self.tout_last = intg.tcurr
示例#20
0
class TavgPlugin(BasePlugin):
    name = 'tavg'
    systems = ['*']

    def __init__(self, intg, cfgsect, suffix=None):
        super().__init__(intg, cfgsect, suffix)

        # Underlying elements class
        self.elementscls = intg.system.elementscls

        # Expressions to time average
        c = self.cfg.items_as('constants', float)
        self.exprs = [(k, self.cfg.getexpr(cfgsect, k, subs=c))
                      for k in self.cfg.items(cfgsect)
                      if k.startswith('avg-')]

        # Save a reference to the physical solution point locations
        self.plocs = intg.system.ele_ploc_upts

        # Output file directory, base name, and writer
        basedir = self.cfg.getpath(cfgsect, 'basedir', '.')
        basename = self.cfg.get(cfgsect, 'basename')
        self._writer = NativeWriter(intg, len(self.exprs), basedir, basename,
                                    prefix='tavg')

        # Time averaging parameters
        self.dtout = self.cfg.getfloat(cfgsect, 'dt-out')
        self.nsteps = self.cfg.getint(cfgsect, 'nsteps')
        self.tout = intg.tcurr + self.dtout

        # Register our output times with the integrator
        intg.call_plugin_dt(self.dtout)

        # Time averaging state
        self.prevt = intg.tcurr
        self.prevex = self._eval_exprs(intg)
        self.accmex = [np.zeros_like(p) for p in self.prevex]

    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.conv_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 __call__(self, intg):
        dowrite = abs(self.tout - intg.tcurr) < intg.dtmin
        doaccum = intg.nacptsteps % self.nsteps == 0

        if dowrite or doaccum:
            # Evaluate the time averaging expressions
            currex = self._eval_exprs(intg)

            # Accumulate them; always do this even when just writing
            for a, p, c in zip(self.accmex, self.prevex, currex):
                a += 0.5*(intg.tcurr - self.prevt)*(p + c)

            # Save the time and solution
            self.prevt = intg.tcurr
            self.prevex = currex

            if dowrite:
                # Normalise
                accmex = [a / self.dtout for a in self.accmex]

                stats = Inifile()
                stats.set('data', 'prefix', 'tavg')
                stats.set('data', 'fields',
                          ','.join(k for k, v in self.exprs))
                stats.set('tavg', 'tstart', intg.tcurr - self.dtout)
                stats.set('tavg', 'tend', intg.tcurr)
                intg.collect_stats(stats)

                metadata = dict(config=self.cfg.tostr(),
                                stats=stats.tostr(),
                                mesh_uuid=intg.mesh_uuid)

                self._writer.write(accmex, metadata, intg.tcurr)

                self.tout += self.dtout
                self.accmex = [np.zeros_like(a) for a in accmex]