Example #1
0
def main():
    parser = ArgumentParser()
    genfmtx_parser = genfmtx_args(parser)
    genfmtx_parser.add_argument('-v',
                                '--verbose',
                                action='count',
                                default=0,
                                help='verbose mode')
    args = genfmtx_parser.parse_args()
    logger = logging.getLogger('frads')
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    console_handler = logging.StreamHandler()
    _level = args.verbose * 10
    logger.setLevel(_level)
    console_handler.setLevel(_level)
    console_handler.setFormatter(formatter)
    logger.addHandler(console_handler)
    raw_wndw_prims = radutil.unpack_primitives(args.window)
    ncp_prims = radutil.unpack_primitives(args.ncp)
    wndw_prims = [p for p in raw_wndw_prims if p.ptype == 'polygon']
    port_prims = fcd.genport(wpolys=wndw_prims,
                             npolys=ncp_prims,
                             depth=None,
                             scale=None)
    wndw_polygon = [
        radutil.parse_polygon(p.real_arg) for p in wndw_prims
        if p.ptype == 'polygon'
    ]
    args.env.append(args.ncp)
    all_prims = []
    for env in args.env:
        all_prims.extend(radutil.unpack_primitives(env))
    ncp_mod = [prim.modifier for prim in ncp_prims
               if prim.ptype == 'polygon'][0]
    ncp_mat: radutil.Primitive
    ncp_type: str = ''
    for prim in all_prims:
        if prim.identifier == ncp_mod:
            ncp_mat = prim
            ncp_type = prim.ptype
            break
    if ncp_type == '':
        raise ValueError("Unknown NCP material")
    wrap2xml = args.wrap
    dirname = os.path.dirname(args.o)
    dirname = '.' if dirname == '' else dirname
    if args.solar and ncp_type == 'BSDF':
        logger.info('Computing for solar and visible spectrum...')
        wrap2xml = False
        xmlpath = ncp_mat.str_arg.split()[2]
        td = tf.mkdtemp()
        with open(xmlpath) as rdr:
            raw = rdr.read()
        raw = raw.replace('<Wavelength unit="Integral">Visible</Wavelength>',
                          '<Wavelength unit="Integral">Visible2</Wavelength>')
        raw = raw.replace('<Wavelength unit="Integral">Solar</Wavelength>',
                          '<Wavelength unit="Integral">Visible</Wavelength>')
        raw = raw.replace('<Wavelength unit="Integral">Visible2</Wavelength>',
                          '<Wavelength unit="Integral">Solar</Wavelength>')
        solar_xml_path = os.path.join(td, 'solar.xml')
        with open(solar_xml_path, 'w') as wtr:
            wtr.write(raw)
        _strarg = ncp_mat.str_arg.split()
        _strarg[2] = solar_xml_path
        solar_ncp_mat = radutil.Primitive(ncp_mat.modifier, ncp_mat.ptype,
                                          ncp_mat.identifier + ".solar",
                                          ' '.join(_strarg), '0')

        _env_path = os.path.join(td, 'env_solar.rad')
        with open(_env_path, 'w') as wtr:
            for prim in all_prims:
                wtr.write(str(prim))
        outsolar = os.path.join(dirname, '_solar_' + util.basename(args.o))
        process_thread = Thread(target=fcd.Genfmtx,
                                kwargs={
                                    'win_polygons': wndw_polygon,
                                    'port_prim': port_prims,
                                    'out': outsolar,
                                    'env': [_env_path],
                                    'sbasis': args.ss,
                                    'rbasis': args.rs,
                                    'opt': args.opt,
                                    'refl': args.refl,
                                    'forw': args.forw,
                                    'wrap': wrap2xml
                                })
        process_thread.start()
        #fcd.Genfmtx(win_polygons=wndw_polygon, port_prim=port_prims, out=outsolar,
        #            env=[_env_path], sbasis=args['ss'], rbasis=args['rs'],
        #            opt=args['opt'], refl=args['refl'], forw=args['forw'], wrap=wrap2xml)

    fcd.Genfmtx(win_polygons=wndw_polygon,
                port_prim=port_prims,
                out=args.o,
                env=args.env,
                sbasis=args.ss,
                rbasis=args.rs,
                opt=args.opt,
                refl=args.refl,
                forw=args.forw,
                wrap=wrap2xml)
    if args.solar and ncp_type == 'BSDF':
        process_thread.join()
        vis_dict = {}
        sol_dict = {}
        oname = util.basename(args['o'])
        mtxs = [
            os.path.join(dirname, mtx) for mtx in os.listdir(dirname)
            if mtx.endswith('.mtx')
        ]
        for mtx in mtxs:
            _direc = util.basename(mtx).split('_')[-1][:2]
            mtxname = util.basename(mtx)
            if mtxname.startswith(oname):
                #vis_dict[_direc] = os.path.join(dirname, f"_vis_{_direc}")
                vis_dict[_direc] = os.path.join(td, f"vis_{_direc}")
                out2 = os.path.join(dirname, f"vis_{_direc}")
                klems_wrap(vis_dict[_direc], out2, mtx, args.ss)
            if mtxname.startswith('_solar_'):
                sol_dict[_direc] = os.path.join(td, f"sol_{_direc}")
                out2 = os.path.join(dirname, f"sol_{_direc}")
                klems_wrap(sol_dict[_direc], out2, mtx, args.ss)
        cmd = f"wrapBSDF -a {args.ss} -c -s Visible "
        cmd += ' '.join([f"-{key} {vis_dict[key]}" for key in vis_dict])
        cmd += ' -s Solar '
        cmd += ' '.join([f"-{key} {sol_dict[key]}" for key in sol_dict])
        cmd += f" > {os.path.join(dirname, oname)}.xml"
        os.system(cmd)
        shutil.rmtree(td)
        [os.remove(mtx) for mtx in mtxs]
Example #2
0
def main():
    """Generate a matrix."""
    description = 'Generate flux transport matrix'
    parser = argparse.ArgumentParser(prog='genmtx', description=description)
    genmtx_r = genmtx_args(parser)
    args = genmtx_r.parse_args()
    logger = logging.getLogger('frads')
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    console_handler = logging.StreamHandler()
    _level = args.verbose * 10
    logger.setLevel(_level)
    console_handler.setLevel(_level)
    console_handler.setFormatter(formatter)
    logger.addHandler(console_handler)
    assert len(args.receiver) == len(args.outpath)
    env = args.env
    sender = None
    outpath = None
    if args.octree is not None:
        env.extend(['-i', args.octree])
    # what's the sender
    with open(args.sender) as rdr:
        sndrlines = rdr.readlines()
    if args.sender_type == 's':
        prim_list = radutil.parse_primitive(sndrlines)
        sender = rm.Sender.as_surface(prim_list=prim_list,
                                      basis=args.sender_basis,
                                      offset=args.sender_offset)
    elif args.sender_type == 'v':
        vudict = util.parse_vu(sndrlines[-1])  # use the last view
        sender = rm.Sender.as_view(vu_dict=vudict,
                                   ray_cnt=args.ray_count,
                                   xres=args.resolu[0],
                                   yres=args.resolu[1])
    elif args.sender_type == 'p':
        pts_list = [line.split() for line in sndrlines]
        sender = rm.Sender.as_pts(pts_list=pts_list, ray_cnt=args.ray_count)
    # figure out receiver
    if args.receiver[0] == 'sky':
        logger.info('Sky is the receiver')
        receiver = rm.Receiver.as_sky(args.receiver_basis)
        outpath = args.outpath[0]
        if args.sender_type == 'v':
            util.mkdir_p(outpath)
    elif args.receiver[0] == 'sun':
        full_modifier = False
        if args.sender_type != 'v':
            full_modifier = True
        window_normals: Union[None, Set[radgeom.Vector]] = None
        if args.wpths is not None:
            window_normals = radutil.primitive_normal(args.wpths)
        receiver = rm.Receiver.as_sun(basis=args.receiver_basis,
                                      smx_path=args.smx,
                                      window_normals=window_normals,
                                      full_mod=full_modifier)
    else:  # assuming multiple receivers
        rcvr_prims = []
        for path in args.receiver:
            rcvr_prims.extend(radutil.unpack_primitives(path))
        modifiers = set([prim.modifier for prim in rcvr_prims])
        receiver = rm.Receiver(receiver='',
                               basis=args.receiver_basis,
                               modifier=None)
        for mod, op in zip(modifiers, args.outpath):
            _receiver = [
                prim for prim in rcvr_prims
                if prim.modifier == mod and prim.ptype in ('polygon', 'ring')
            ]
            if _receiver != []:
                if args.sender_type == 'v':
                    _outpath = os.path.join(op, '%04d.hdr')
                else:
                    _outpath = op
                receiver += rm.Receiver.as_surface(prim_list=_receiver,
                                                   basis=args.receiver_basis,
                                                   offset=args.receiver_offset,
                                                   left=None,
                                                   source='glow',
                                                   out=_outpath)
        outpath = None
    # generate matrices
    if args.receiver[0] == 'sun':
        logger.info('Suns are the receivers.')
        outpath = os.path.join(os.getcwd(), args.outpath[0])
        sun_oct = 'sun.oct'
        rm.rcvr_oct(receiver, env, sun_oct)
        with tf.TemporaryDirectory(dir=os.getcwd()) as tempd:
            mod_names = [
                "%04d" % (int(l[3:]) - 1)
                for l in receiver.modifier.splitlines()
            ]
            rm.rcontrib(sender=sender,
                        modifier=receiver.modifier,
                        octree=sun_oct,
                        out=tempd,
                        opt=args.option)
            _files = [
                os.path.join(tempd, f) for f in sorted(os.listdir(tempd))
                if f.endswith('.hdr')
            ]
            util.mkdir_p(outpath)
            for idx, val in enumerate(_files):
                os.rename(val, os.path.join(outpath, mod_names[idx] + '.hdr'))

    else:
        res = rm.rfluxmtx(sender=sender,
                          receiver=receiver,
                          env=env,
                          opt=args.option,
                          out=outpath)
        if (outpath is not None) and (args.sender_type != 'v'):
            with open(outpath, 'wb') as wtr:
                wtr.write(res)
Example #3
0
def main():
    """Generate a BSDF for macroscopic systems."""
    parser = argparse.ArgumentParser()
    parser.add_argument('-blinds',
                        nargs=3,
                        type=float,
                        metavar=('depth', 'spacing', 'angle'))
    parser.add_argument('-curve', default='')
    parser.add_argument('-custom', nargs=3)
    parser.add_argument('-section', nargs=2)
    parser.add_argument('-gap', type=float, default=0.0)
    parser.add_argument('-ext', action='store_true')
    parser.add_argument('-m',
                        nargs=3,
                        type=float,
                        required=True,
                        metavar=('refl', 'spec', 'rough'))
    parser.add_argument('-g', type=float)
    parser.add_argument('-window')
    parser.add_argument('-env')
    parser.add_argument('-o', default='default_blinds.rad')
    args = parser.parse_args()
    mat_prim = radutil.neutral_plastic_prim('void', 'blindmaterial', *args.m)
    mat_prim_str = radutil.put_primitive(mat_prim)
    if args.custom:
        # Custom periodic geometry
        pass
    elif args.section:
        # Custom section drawing
        pass
    elif args.window:
        primitves = radutil.unpack_primitives(args.window)
        env_primitives = radutil.unpack_primitives(args.env)
        env_identifier = [prim['identifier'] for prim in env_primitives]
        windows = [
            p for p in primitves if p['identifier'].startswith('window')
        ]
        window = windows[0]  # only take the first window primitive
        depth, spacing, angle = args.blinds
        movedown = depth * math.cos(math.radians(float(angle)))
        window_movedown = 0 if args.ext else movedown + args.gap
        # window_polygon = radutil.parse_polygon(window.real_args)
        height, width, angle2negY, translate = radutil.analyze_window(
            window, window_movedown)
        xform_cmd = f'!xform -rz {math.degrees(angle2negY)} -rx -90 -t {translate.x} {translate.y} {translate.z} {args.env}\n'
        xform_cmd += f'!xform -rz {math.degrees(angle2negY)} -rx -90 -t {translate.x} {translate.y} {translate.z} {args.window}\n'
        print(xform_cmd)
        slat_cmd = radutil.gen_blinds(depth, width, height, spacing, angle,
                                      args.curve, movedown)
        print(slat_cmd)
        lower_bound = max(movedown, window_movedown)
        with open("tmp_blinds.rad", 'w') as wtr:
            wtr.write(mat_prim_str)
            wtr.write(xform_cmd)
            wtr.write(slat_cmd)
        cmd = f"genBSDF -n 4 -f +b -c 500 +geom meter -dim {-width/2} {width/2} {-height/2} {height/2} -{lower_bound} 0 tmp_blinds.rad"
        print(cmd)
        _stdout = sp.run(cmd.split(), check=True,
                         stdout=sp.PIPE).stdout.decode()
        xml_name = "{}_blinds_{}_{}_{}.xml".format(window['identifier'], depth,
                                                   spacing, angle)
        with open(xml_name, 'w') as wtr:
            wtr.write(_stdout)
        #move back
        pkgbsdf_cmd = ["pkgBSDF", "-s", xml_name]
        xform_back_cmd = [
            "xform", "-t",
            str(-translate.x),
            str(-translate.y),
            str(-translate.z)
        ]
        xform_back_cmd += ["-rx", "90", "-rz", str(-math.degrees(angle2negY))]
        ps1 = sp.Popen(pkgbsdf_cmd, stdout=sp.PIPE)
        ps2 = sp.Popen(xform_back_cmd, stdin=ps1.stdout, stdout=sp.PIPE)
        ps1.stdout.close()
        _stdout, _ = ps2.communicate()
        result_primitives = radutil.parse_primitive(
            _stdout.decode().splitlines())
        result_primitives = [
            prim for prim in result_primitives
            if prim['identifier'] not in env_identifier
        ]
        with open(args.o, 'w') as wtr:
            [
                wtr.write(radutil.put_primitive(prim))
                for prim in result_primitives
            ]
    else:
        width = 10  # default blinds width
        height = 0.096  # default blinds height
        depth, spacing, angle = args.blinds
        if args.ext:
            glass_z = 0
            movedown = args.gap + depth * math.cos(math.radians(angle))
        else:
            glass_z = args.gap + depth * math.cos(math.radians(angle))
            movedown = depth * math.cos(math.radians(angle))
        lower_bound = min(-glass_z, -movedown)
        genblinds_cmd = radutil.gen_blinds(depth, width, height, spacing,
                                           angle, args.curve, movedown)
        pt1 = radgeom.Vector(-width / 2, height / 2, -glass_z)
        pt2 = radgeom.Vector(-width / 2, -height / 2, -glass_z)
        pt3 = radgeom.Vector(width / 2, -height / 2, -glass_z)
        tmis = util.tmit2tmis(.38)
        glass_prim = radutil.glass_prim('void', 'glass1', tmis, tmis, tmis)
        glazing_polygon = radgeom.Polygon.rectangle3pts(pt1, pt2, pt3)
        glazing_prim_str = radutil.put_primitive(glass_prim)
        glazing_prim_str += radutil.put_primitive(
            radutil.polygon2prim(glazing_polygon, 'glass1', 'window'))
        with open("tmp_blinds.rad", 'w') as wtr:
            wtr.write(mat_prim_str)
            wtr.write(glazing_prim_str)
            wtr.write(genblinds_cmd)
        cmd = f"genBSDF -n 4 +f +b -c 500 -geom meter -dim -0.025 0.025 -0.012 0.012 {lower_bound} 0 tmp_blinds.rad"
        _stdout = sp.run(cmd.split(), check=True,
                         stdout=sp.PIPE).stdout.decode()
        xml_name = "blinds_{}_{}_{}.xml".format(depth, spacing, angle)
        with open(xml_name, 'w') as wtr:
            wtr.write(_stdout)
    os.remove("tmp_blinds.rad")