class SolverPreferenceGroup(BasePreferenceGroup):
    """ Storage for solver related preferences.
    """
    #: Path (or name) to the solver executable to use
    solver_binary_path = File

    # Folder containing the solver input files
    input_file_location = Directory

    #: Number of max worker processes to run simulation grids on. 0=all CPUs.
    executor_num_worker = Int

    #: Clean up solver input files when exiting?
    auto_delete_solver_files_on_exit = Bool(True)

    #: CADET allows to run 1 simulation using multiple openMP threads
    cadet_num_threads = PositiveInt(1, exclude_low=True)

    #: Wrap solver execution with SLURM scheduling?
    use_slurm_scheduler = Bool

    #: Slurm scheduler batch run command
    slurm_binary = File("sbatch")

    #: SLURM Partition to run the solver on
    slurm_partition = Str

    #: Name of the SLURM jobs submitted when running the solver
    slurm_job_name = Str("slurm_chrom_solver")

    def _attrs_to_store_default(self):
        return [
            "input_file_location", "auto_delete_solver_files_on_exit",
            "executor_num_worker", "cadet_num_threads", "solver_binary_path",
            "use_slurm_scheduler", "slurm_partition", "slurm_job_name"
        ]

    def _input_file_location_default(self):
        """ Returns the directory to create datasource files in.
        """
        return join(get_app_folder(), CADET_INPUT_DIRNAME)

    def _solver_binary_path_default(self):
        if IS_WINDOWS:
            return 'cadet-cs.exe'
        elif IS_OSX or IS_LINUX:
            return 'cadet-cs'
        else:
            msg = "Platform {} currently not supported.".format(sys.platform)
            raise NotImplementedError(msg)

    def _executor_num_worker_default(self):
        return multiprocessing.cpu_count()
Exemplo n.º 2
0
class Discretization(HasStrictTraits):
    """ Discretization parameters.
    """
    # -------------------------------------------------------------------------
    # Discretization traits
    # -------------------------------------------------------------------------

    #: Number of column (axial) discretization cells
    #: (Default: 50) [Range: >=1]
    ncol = PositiveInt(50, exclude_low=True)

    #: Number of particle (radial) discretization cells
    #: (Default: 5) [Range: >=1]
    npar = PositiveInt(5, exclude_low=True)

    #: Specifies the discretization scheme inside the particles
    #: (default: EQUIDISTANT_PAR)
    #: [Range: EQUIDISTANT_PAR, EQUIVOLUME_PAR, USER_DEFINED_PAR]
    par_disc_type = Enum(['EQUIDISTANT_PAR', 'EQUIVOLUME_PAR',
                          'USER_DEFINED_PAR'])

    #: Type of reconstruction method for fluxes
    #: (default: WENO) [Range: WENO]
    reconstruction = Enum(['WENO'])

    #: A vector with node coordinates for the cell boundaries
    #: (default: NA) [Range: 0-1] [Length: NPAR+1]
    par_disc_vector = Array(dtype=float, shape=(None,))

    #: Weno class instance
    weno = Instance(Weno, args=())

    # -------------------------------------------------------------------------
    # Private methods
    # -------------------------------------------------------------------------

    def _par_disc_vector_default(self):
        return np.zeros(self.npar+1, dtype='float64')
Exemplo n.º 3
0
class Sensitivity(HasStrictTraits):
    """ Sensitivities to be computed by solver.
    """
    # -------------------------------------------------------------------------
    # Sensitivity traits
    # -------------------------------------------------------------------------

    #: Number of sensitivities to be computed
    #: (Default: 0) [Range: >=0]
    nsens = PositiveInt(0)

    #: Method used for computation of sensitivities; algorithmic
    #: differentiation (ad1) or
    #: finite difference of order 1-4 (fd1, fd2, fd3, fd4)
    #: (Default: ad1) [Range: ad1, fd1, fd2, fd3, fd4]
    sens_method = Enum(["ad1", "fd1", "fd2", "fd3", "fd4"])
Exemplo n.º 4
0
class TimeIntegrator(HasStrictTraits):
    """ Represents the properties associated with the time integrator.
    """
    # -------------------------------------------------------------------------
    # Time Integrator traits
    # -------------------------------------------------------------------------

    #: Absolute tolerance in the solution of the original system
    abstol = PositiveFloat(1.0e-8, exclude_low=True)

    #: Factor which is multiplied by the section length to get initial
    #: integrator stepsize (0.0:IDAS default value), see IDAS guide 4.5, 36f.
    init_step_size = PositiveFloat(1.0e-6)

    #: Maximum number of timesteps taken by IDAS (0: IDAS default = 500),
    #: see IDAS guide 4.5, 36
    max_steps = PositiveInt(10000)

    #: Relative tolerance in the solution of the original system
    reltol = PositiveFloat(0.0)
Exemplo n.º 5
0
class Inlet(HasStrictTraits):
    """ Inlet information for the simulation
    """
    # -------------------------------------------------------------------------
    # Section traits
    # -------------------------------------------------------------------------

    #: Number of sections in the simulation
    #: (Default: NA) [Range >= 1]
    nsec = PositiveInt()

    #: A vector with simulation times at which inlet function is discontinous;
    #: including start and end times (units = seconds)
    #: (Default: Vector of length nsec + 1 containing zeros) [Range >= 0.0]
    section_times = Array(dtype=float, shape=(None, ))

    #: A vector indicating continuity of each section transition
    #: 0 (discontinuous) or 1 (continuous)
    #: (Default: Vector of length nsec-1 containing zeros) [Range: 0 or 1]
    section_continuity = Array(dtype=int, shape=(None, ))

    #: A vector containing nsec Section class objects
    #: (Default: Empty Vector ) [Range: NA]
    section = List(Instance(Section))

    # -------------------------------------------------------------------------
    # Private methods
    # -------------------------------------------------------------------------

    def __init__(self, num_components, num_sections, **traits):
        traits['nsec'] = num_sections
        traits.setdefault('section_times', np.zeros(num_sections + 1))
        traits.setdefault('section_continuity', np.zeros(num_sections - 1))
        # Create a distinct Section object for each section:
        traits.setdefault(
            'section', [Section(num_components) for _ in range(num_sections)])
        super(Inlet, self).__init__(**traits)
class SchurSolver(HasStrictTraits):
    """ Schur Solver parameters.
    """
    # -------------------------------------------------------------------------
    # Schur Solver traits
    # -------------------------------------------------------------------------

    #: Type of Gram-Schmidt orthogonalization (1-Classical GS (default),
    #: 2-Modified GS)
    gs_type = Enum([1, 2])

    #: Defines the size of the iterative linear SPGMR solver
    #: (Default: 0) [Range: 0-NCOL]
    max_krylov = Int(0)

    #: Maximum number of restarts in the GMRES algorithm. If lack of memory
    #: is not an issue, better use a larger Krylov space than restarts
    #: (default: 0) [Range: >=0]
    max_restarts = PositiveInt(0)

    #: Schur safety factor; Influences the tradeof between linear iterations
    #: and nonlinear error control; see IDAS guide 2.1, 5 (default: 1.0e-8)
    #: [Range: >=0]
    schur_safety = PositiveFloat(1.0e-8)
 class TestObject(HasTraits):
     int_attr = PositiveInt()
     int_attr_with_default = PositiveInt(value=5)
     int_attr_with_float_default = PositiveInt(value=5)
     int_attr_exclude_low = PositiveInt(value=5, exclude_low=True)
Exemplo n.º 8
0
class Solver(HasStrictTraits):
    """ Solver parameters.
    """
    # -------------------------------------------------------------------------
    # Solver traits
    # -------------------------------------------------------------------------

    #: Number of used OpenMP threads
    nthreads = PositiveInt(exclude_low=True)

    #: Specifies the verbosity of the logging output (Only errors; warning
    #: and errors; info and warnings and errors, etc.)
    log_level = Enum(
        ['INFO', 'WARNING', 'ERROR', 'DEBUG1', 'DEBUG2', 'TRACE1', 'TRACE2'])

    #: Print configuration message before simulation
    print_config = Enum([1, 0])

    #: Print list of parameters before simulation
    print_paramlist = Enum([0, 1])

    #: Print current state of simulation
    print_progress = Enum([1, 0])

    #: Print integrator statistics after each section
    print_statistics = Enum([1, 0])

    #: Print timing information after simulation
    print_timing = Enum([1, 0])

    #: Use analytically computed jacobian matrix (faster) instead of jacobian
    #: generated by algorithmic differentiation (slower)
    use_analytic_jacobian = Enum([1, 0])

    #: A integer with the number of time-points at which a solution is desired
    number_user_solution_points = Int(DEFAULT_NUM_TIMES)

    #: A vector with timepoints at which a solution is desired
    user_solution_times = Array(dtype=float, shape=(None, ))

    #: Write solutions at times specified by USER_SOLUTION_TIMES
    #: (write integration timepoints otherwise)
    write_at_user_times = Enum([0, 1])

    #: Write times at which a solution was produced
    write_solution_times = Enum([1, 0])

    #: Write solutions at column inlet (boundary condition)
    write_solution_column_inlet = Enum([1, 0])

    #: Write solutions at column outlet (chromatograms)
    write_solution_column_outlet = Enum([1, 0])

    #: Write all (intermediate) solutions
    write_solution_all = Enum([1, 0])

    #: Write full solution state vector at last time point
    write_solution_last = Enum([0, 1])

    #: Write sensitivity data at column outlet
    write_sens_column_outlet = Enum([0, 1])

    #: Write all (intermediate) sensitivity data
    write_sens_all = Enum([0, 1])

    #: Write sensitivity data at column outlet
    write_sens_last = Enum([0, 1])

    #: Print current state of simulation
    schur_solver = Instance(SchurSolver, args=())

    #: Print current state of simulation
    time_integrator = Instance(TimeIntegrator, args=())

    # -------------------------------------------------------------------------
    # Methods
    # -------------------------------------------------------------------------

    def calculate_user_solution_times(self, end_time, start_time=0.0):
        self.user_solution_times = \
            numpy.linspace(start_time, float(end_time),
                           self.number_user_solution_points)
        self.write_at_user_times = 1

    def _nthreads_default(self):
        from kromatography.utils.app_utils import get_preferences
        prefs = get_preferences()
        return prefs.solver_preferences.cadet_num_threads
class CADETModel(HasStrictTraits):
    """ The CADET model parameters to be stored in the HDF5 input file.

    NOTES
    -----
    Keep in mind:

        * This class is primarily used for creating the input parameters to the
          CADET simulator.
        * The attributes here correspond to the H5 nodes under `/input/model`.
        * The units have to be in SI units. For more details, see the CADET
          documentation.
    """
    # -------------------------------------------------------------------------
    # CADETModel traits
    # -------------------------------------------------------------------------

    #: Specifies the type of binding model
    adsorption_type = Enum(ALL_CADET_TYPES.values())

    #: Axial dispersion coefficient(m2/s)
    #: [Range: >=0]
    col_dispersion = PositiveFloat(6e-8)

    #: Column length (m)
    #: (default: 0.20) [Range: > 0]
    col_length = PositiveFloat(0.20, exclude_low=True)

    #: Column porosity
    #: [Range: > 0]
    col_porosity = PositiveFloat(0.35)

    #: Number of chemical components in the chromatographic media
    #: [Range: > 0]
    ncomp = PositiveInt(exclude_low=True)

    #: A vector with film diffusion coefficients (m/2) [len(ncomp)]
    #: (Default:N/A) [Range: >=0]
    film_diffusion = Array(dtype=float, shape=(None, ))

    #: A vector with initial concentrations for each comp. in the bulk mobile
    #: phase (mmol/m3)[len(ncomp)]
    #: (Default:N/A) [Range: >=0]
    init_c = Array(dtype=float, shape=(None, ))

    #: Same as INIT_C but for the bead liquid phase (optional, INIT_C is used
    #: if left out). (mmol/m3) [len(ncomp)]
    #: (Default:N/A) [Range: >=0]
    init_cp = Array(dtype=float, shape=(None, ))

    #: Same as INIT_C but for the bound phase (mmol/m3) [len(ncomp)]
    #: (Default:N/A) [Range: >=0]
    init_q = Array(dtype=float, shape=(None, ))

    #: A vector with particle di usion coefficients (m2/s) [len(ncomp)]
    #: (Default: NA) [Range: >=0]
    par_diffusion = Array(dtype=float, shape=(None, ))

    #: A vector with particle surface diffusion cofficients (m2/s)
    #: [len(ncomp)]
    #: (Default: NA) [Range: >=0]
    par_surfdiffusion = Array(dtype=float, shape=(None, ))

    #: Particle porosity
    #: (Default: 0.5) [Range: > 0]
    par_porosity = PositiveFloat(0.5, exclude_low=True)

    #: Particle Radius
    #: (Default: 4.5e-5) [Range: > 0]
    par_radius = PositiveFloat(4.5e-5, exclude_low=True)

    #: A vector of Interstitial velocity of the mobile phase (m/2)
    #: [len(nsec)]
    #: (Default: NA) [Range: >=0]
    velocity = Array(dtype=float, shape=(None, ))

    #: Binding Model
    adsorption = Instance(BindingModel)

    #: Inlet
    inlet = Instance(Inlet)

    #: External pH dependence profile
    external = Instance(CADETPhExternalProfile)

    def __init__(self, num_components, num_sections, **traits):
        # Initialize any array traits that are not explicitly passed to the
        # constructor
        self.ncomp = num_components
        ncomp_arr_traits = [
            'film_diffusion', 'init_c', 'init_cp', 'init_q', 'par_diffusion',
            'par_surfdiffusion'
        ]
        for name in ncomp_arr_traits:
            traits.setdefault(name, np.zeros(num_components))

        nsec_arr_traits = ['velocity']
        for name in nsec_arr_traits:
            traits.setdefault(name, np.zeros(num_sections))

        # Initialize the Inlet object if not explicitly passed.
        traits.setdefault('inlet', Inlet(num_components, num_sections))

        super(CADETModel, self).__init__(**traits)