예제 #1
0
class SIMRA3DMeshReader(SIMRAMeshReader):

    reader_name = "SIMRA-3D"

    filename: Path
    mesh: FortranFile
    nodeshape: Shape

    @classmethod
    def applicable(cls, filename: Path) -> bool:
        _, u4_type = dtypes(config.input_endianness)
        try:
            with FortranFile(filename, 'r', header_dtype=u4_type) as f:
                assert f._read_size() == 6 * 4
            return True
        except:
            return False

    def __init__(self, filename: Path):
        super().__init__()
        self.filename = filename

    def __enter__(self):
        self.mesh = FortranFile(self.filename, 'r', header_dtype=self.u4_type).__enter__()
        with save_excursion(self.mesh._fp):
            _, _, imax, jmax, kmax, _ = self.mesh.read_ints(self.u4_type)
        if config.fix_orientation:
            self.nodeshape = (jmax, imax, kmax)
        else:
            self.nodeshape = (imax, jmax, kmax)
        return self

    def __exit__(self, *args):
        self.mesh.__exit__(*args)

    @cache(1)
    def patch(self) -> Patch:
        i, j, k = self.nodeshape
        return Patch(('geometry',), StructuredTopology((j-1, i-1, k-1), celltype=Hex()))

    @cache(1)
    def nodes(self) -> Array2D:
        with save_excursion(self.mesh._fp):
            fortran_skip_record(self.mesh)
            nodes = transpose(self.mesh.read_reals(self.f4_type), self.nodeshape)
        nodes = ensure_native(nodes)
        return translate(self.filename.parent, nodes)
예제 #2
0
class SIMRADataReader(SIMRAReader):

    result_fn: Path
    mesh_fn: Path
    input_fn: Path

    result: FortranFile
    mesh: SIMRA3DMeshReader
    input_data: Dict[str, Any]

    f4_type: np.dtype
    u4_type: np.dtype

    def __enter__(self):
        self.result = FortranFile(self.result_fn, 'r', header_dtype=self.u4_type).__enter__()
        self.mesh = SIMRA3DMeshReader(self.mesh_fn).__enter__()
        return self

    def __exit__(self, *args):
        self.mesh.__exit__(*args)
        self.result.__exit__(*args)

    def __init__(self, result_fn: Path):
        super().__init__()
        self.result_fn = Path(result_fn)
        self.mesh_fn = Path(config.mesh_file) if config.mesh_file else self.result_fn.with_name('mesh.dat')
        self.input_fn = self.result_fn.with_name('simra.in')

        if not self.mesh_fn.is_file():
            raise IOError(f"Unable to find mesh file: {self.mesh_fn}")

        if self.input_fn.is_file():
            self.input_data = f90nml.read(self.input_fn)
        else:
            self.input_data = {}
            log.warning(f"SIMRA input file not found, scales will be missing")

    def patch(self) -> Patch:
        return self.mesh.patch()

    def nodes(self) -> Array2D:
        return self.mesh.nodes()

    def scale(self, name: str) -> float:
        return self.input_data.get('param_data', {}).get(name, 1.0)

    def fields(self, apply_scales: bool = True) -> Iterable[Field]:
        yield from self.mesh.fields()

        uref = self.scale('uref') if apply_scales else 1.0
        lref = self.scale('lenref') if apply_scales else 1.0
        yield SIMRAField('u', 0, 3, self, scale=uref)
        yield SIMRAField('ps', 3, 1, self, scale=uref**2)
        yield SIMRAField('tk', 4, 1, self, scale=uref**2)
        yield SIMRAField('td', 5, 1, self, scale=uref**3/lref)
        yield SIMRAField('vtef', 6, 1, self, scale=uref*lref)
        yield SIMRAField('pt', 7, 1, self)
        yield SIMRAField('pts', 8, 1, self)
        yield SIMRAField('rho', 9, 1, self)
        yield SIMRAField('rhos', 10, 1, self)

        # yield SIMRAField('pressure', 0, 1, self, cells=True)

    @abstractmethod
    def data(self, stepid: int) -> Tuple[Array2D, Array2D]:
        pass