Ejemplo n.º 1
0
def checkmissing(itemlist, listname, field, identifybyfield):
    missing = set()
    for record in itemlist:
        if field not in record:
            missing.add(record[identifybyfield])
    if missing:
        warn(listname, f"missing {field} for: {', '.join(sorted(missing))}")
Ejemplo n.º 2
0
def run(conf_path, output_path, definitions):
    try:
        print "configuring"
        if conf_path is not None:
            conf = cfg.load_conf(params.__dict__, conf_path)
            params.__dict__.update(conf)
        if definitions is not None:
            cfg.update_conf(params.__dict__, params.__dict__, definitions)
        
        if params.verbose:
            print "verbose output enabled"
        
        if params.lower_process_priority:
            if params.verbose:
                print "reducing process priority"
            warning = svc.reduce_process_priority()
            if warning:
                output.warn(warning)
        
        if params.graphs:
            if not output_path:
                raise InvocationError("no output directory")
            output_path = os.path.normpath(output_path)
            if params.verbose:
                print "graphs will be written to:", output_path
        output.output_dir = output_path
        
        print "validating"
        cfg.validate()
        
        with mp.TaskPool(params.num_tasks, params.extended_mode, params.__dict__) as task_pool:
            print "executing"
            
            if params.verbose:
                print "number of parallel tasks:", task_pool.num_tasks
            
            start_time = time.time()
            execute(task_pool)
            end_time = time.time()
            elapsed_time = end_time - start_time
            
            print output.div_line
            print "done"
            
            if params.verbose:
                print "finished in %.2f s" % elapsed_time
    except (cfg.ConfigurationError, core.ComputationError, model.exc.ModelError) as exc:
        output.print_error(str(exc))
        sys.exit(1)
    except MemoryError:
        output.print_error("out of memory")
        sys.exit(1)
    except:
        if not debug_mode:
            output.print_exception()
            sys.exit(1)
        else:
            raise
Ejemplo n.º 3
0
def compute_inversion(dirname):
    print output.div_line
    print "computing population inversion"
    
    active_medium = create_medium(None)
    pump_system = model.pump.PumpSystem(params.pump_wavelen, params.pump_duration, params.pump_power, params.pump_efficiency)
    depop_model = create_depop_model(active_medium, params.depop_model_class)
    inv = params.inverter_class(active_medium, pump_system, depop_model)
    
    ref_inversion = inv.invert(params.inversion_rtol, params.inversion_min_count_t)
    rate_evals = (len(inv.inversion) - 1) * inv.evals_per_step
    pump_energy = params.pump_duration * params.pump_power
    stored_energy = model.energy.energy(params.lasing_wavelen, ref_inversion * active_medium.volume)
    
    if params.verbose:
        print "count_t:", len(inv.T)
        print "depopulation rate evaluation count:", rate_evals
    
    if params.inversion_validate:
        print "validating uniform ASE-induced depopulation rate approximation"
        ross_num_model = depop_model if isinstance(depop_model, model.depop.RossNumericalASEModel) else model.depop.RossNumericalASEModel(active_medium, params.depop_rate_rtol, params.depop_rate_min_samples)
        rate_rel_stddev = ross_num_model.rate_rel_stddev(ref_inversion)
        unitconv.print_result("depopulation rate rel. std. deviation [{}]: {}", ("%",), (rate_rel_stddev,))
        if rate_rel_stddev > 10.0e-2:
            output.warn("uniform ASE-induced depopulation rate approximation is invalid")
    
    if isinstance(depop_model, model.depop.NumericalDepopulationModel):
        print "perturbing population inversion"
        perturb_depop_model = model.depop.PerturbedDepopulationModel(depop_model)
        perturb_inv = params.inverter_class(active_medium, pump_system, perturb_depop_model)
        perturb_ref_inversion = perturb_inv.invert(params.inversion_rtol, params.inversion_min_count_t)
        rel_error = model.error.perturbed_inversion_rel_error(ref_inversion, perturb_ref_inversion, params.inversion_rtol)
    else:
        rel_error = params.inversion_rtol
    
    gain_coef = ref_inversion * active_medium.doping_agent.xsection
    gain = math.exp(gain_coef * active_medium.length)
    
    ref_inversion_atol = ref_inversion * rel_error
    gain_atol = gain * (math.exp(ref_inversion_atol * active_medium.doping_agent.xsection * active_medium.length) - 1.0)
    stored_energy_atol = stored_energy * rel_error
    
    unitconv.print_result("pump energy [{}]: {}", ("mJ",), (pump_energy,))
    unitconv.print_result("population inversion [{}]: {} ~ {}", ("cm^-3",), (ref_inversion, ref_inversion_atol))
    unitconv.print_result("small signal gain: {} ~ {}", (), (gain, gain_atol))
    unitconv.print_result("stored energy [{}]: {} ~ {}", ("mJ",), (stored_energy, stored_energy_atol))
    
    if params.graphs:
        print output.status_writing
        dirname = output.init_dir(dirname)
        output.plot_inversion(dirname, inv)
    
    return ref_inversion, rel_error
Ejemplo n.º 4
0
def validate():
    def validate_param_bounds(name, value):
        vtype = type(value)
        if vtype in (int, float):
            if vtype is float and name not in param_nan_allowed:
                if math.isnan(value):
                    raise ConfigurationError("parameter \"%s\" has (or contains) an not-a-number value" % name)
            if vtype is float and name not in param_zero_allowed:
                if value <= 0.0:
                    raise ConfigurationError("parameter \"%s\" has (or contains) a non-positive value" % name)
            elif value < 0.0:
                raise ConfigurationError("parameter \"%s\" has (or contains) a negative value" % name)
            if vtype is float and name not in param_infty_allowed:
                if math.isinf(value):
                    raise ConfigurationError("parameter \"%s\" has (or contains) an infinite value" % name)
            if name in param_bounds:
                min_value, max_value = param_bounds[name]
                if min_value is not None:
                    if value < min_value:
                        raise ConfigurationError("parameter \"%s\" has (or contains) a value less than %s" % (name, min_value))
                if max_value is not None:
                    if value > max_value:
                        raise ConfigurationError("parameter \"%s\" has (or contains) a value greater than %s" % (name, max_value))
        elif vtype in (tuple, list):
            for element in value:
                validate_param_bounds(name, element)
    
    def validate_interval(name, values):
        if values[0] >= values[1]:
            raise ConfigurationError("parameter \"%s\" has an upper bound not greater than its lower bound" % name)
    
    def validate_list_uniques(name, values):
        if len(values) != len(set(values)):
            raise ConfigurationError("parameter \"%s\" contains duplicate values" % name)
    
    param_nan_allowed = set([
    ])
    param_zero_allowed = set([
        "dopant_branching_ratio",
        "dopant_lower_lifetime",
        "initial_inversion",
    ])
    param_infty_allowed = set([
        "dopant_upper_lifetime",
        "dopant_lower_lifetime",
        "ext_opt_inversion_rdiff_max",
        "ext_opt_fluence_max",
    ])
    param_bounds = {
        "train_pulse_count": (1, None),
        "depop_rate_min_samples": (16, None),
        "out_num_markers": (1, None),
        "out_count_rho": (1, None),
        "out_count_phi": (1, None),
        "out_count_z": (1, None),
        "out_count_t": (1, None),
        "ext_opt_pump_resolution": (1, None),
        "ext_opt_geom_resolution": (1, None),
        "dopant_branching_ratio": (None, 1.0),
        "pump_efficiency": (None, 1.0),
    }
    param_intervals = set([
        "ext_opt_pump_duration",
        "ext_opt_pump_power",
        "ext_opt_geom_mediumradius",
        "ext_opt_geom_beamradius",
    ])
    
    conf = copy_conf(params.__dict__)
    
    for parameter, value in conf.items():
        validate_param_bounds(parameter, value)
    
    for parameter in param_intervals:
        values = conf[parameter]
        validate_interval(parameter, values)
    
    active_medium = core.create_medium(None)
    input_beam = core.create_beam()
    ref_pulse = core.create_pulse(active_medium, input_beam, input_beam.rho_ref, input_beam.phi_ref)
    
    if not (params.pump_wavelen < params.lasing_wavelen or params.initial_inversion):
        output.warn("pump wavelength is not less than lasing wavelength")
    
    if not (params.dopant_lower_lifetime <= params.dopant_upper_lifetime / 10.0 or params.initial_inversion):
        output.warn("approximation validity condition violated: lower state lifetime is not much shorter than upper state (fluorescence) lifetime")
    
    transit_time = active_medium.length / active_medium.light_speed
    if not (transit_time <= params.dopant_upper_lifetime / 10.0):
        output.warn("approximation validity condition violated: amplifier transit time is not much shorter than upper state (fluorescence) lifetime")
    
    train_duration = params.pulse_duration + (params.train_pulse_count - 1) * params.train_pulse_period
    if not (train_duration <= params.dopant_upper_lifetime / 10.0 or not params.amplification):
        output.warn("approximation validity condition violated: signal duration is not much shorter than upper state (fluorescence) lifetime")
    
    if not (params.train_pulse_period >= ref_pulse.duration or params.train_pulse_count == 1 or not params.amplification):
        raise ConfigurationError("invalid parameters: pulse repetition period is less than (extended) pulse duration")
Ejemplo n.º 5
0
def extraneousfields(itemlist, listname, knownfields):
    for record in itemlist:
        for key in record:
            if key not in knownfields:
                warn(listname, f"found extraneous field '{key}', typo?")