Ejemplo n.º 1
0
def _toc_tree(obj, prefix=""):
    ret = colorize(obj.__str__(), "blue")
    prefix = prefix + 4*" "
    for key in sorted(obj.__dict__.keys(), key=str.casefold):
        if key.startswith("_"):
            continue
        val = obj.__dict__[key]
        ret += "\n{}- {}: ".format(
            prefix, colorize(key, "blue"))
        if isinstance(val, Group):
            ret += _toc_tree(val, prefix=prefix)
        else:
            ret += val.__str__()
    return ret
Ejemplo n.º 2
0
 def __repr__(self):
     ret = self.__str__() + "\n"
     ret += "-" * (len(ret) - 1) + "\n"
     ret += "    Data directory : {}\n".format(self.datadir)
     ret += "    File names     : {}\n".format(self._getfilename(0))
     ret += "    Overwrite      : {}\n".format(
         colorize(self.overwrite, "yellow") if self.overwrite else self.
         overwrite)
     ret += "    Dumping        : {}\n".format(
         colorize(self.dumping, "yellow") if not self.dumping else self.
         dumping)
     ret += "    Options        : {}\n".format(self.options)
     ret += "    Verbosity      : {}".format(self.verbosity)
     return ret
Ejemplo n.º 3
0
    def write(self, owner, i, forceoverwrite, filename=""):
        """Writes output to file

        Parameters
        ----------
        owner : Frame
            Parent ``Frame`` object
        i : int
            Number of output
        forceoverwrite : boolean
            If ``True`` it will forces and overwrite of the file if it exists independent of the writer attribute
        filename : string
            If this is not "" the writer will use this filename instead of the standard scheme"""

        if filename == "":
            filename = self._getfilename(i)
        self.checkdatadir(createdir=True)
        if not forceoverwrite:
            if not self.overwrite:
                if os.path.isfile(filename):
                    raise RuntimeError(
                        "File {} already exists.".format(filename))
        self._func(owner, filename, **self.options)
        if self.verbosity > 0:
            msg = "Writing file {}".format(colorize(filename, "blue"))
            print(msg)
        if self.dumping:
            self.writedump(owner)
Ejemplo n.º 4
0
 def __repr__(self):
     ret = self.__str__() + "\n"
     ret += "-" * (len(ret) - 1) + "\n"
     ret += "    Data directory : {}\n".format(self.datadir)
     ret += "    Dumping        : {}\n".format(
         colorize(self.dumping, "yellow") if not self.dumping else self.
         dumping)
     ret += "    Verbosity      : {}".format(self.verbosity)
     return ret
Ejemplo n.º 5
0
    def writedump(self, frame, filename=""):
        """Writes the ``Frame`` to dump file

        Parameters
        ----------
        frame : object
            object to be written to file
        filename : str, optional, default : ""
            path to file to be written
            if not set, filename will be <writer.datadir>/frame.dmp."""

        filename = os.path.join(self.datadir,
                                "frame.dmp") if filename == "" else filename
        self.checkdatadir(createdir=True)

        if self.verbosity > 0:
            msg = "Writing dump file {}".format(colorize(filename, "blue"))
            print(msg)

        writedump(frame, filename)
Ejemplo n.º 6
0
 def run(self):
     """This functions runs the simulation."""
     # Print welcome message
     if self.verbosity > 0:
         msg = ""
         msg += "\nDustPy v{}".format(self.__version__)
         msg += "\n"
         msg += "\nDocumentation: {}".format(
             "https://stammler.github.io/dustpy/")
         msg += "\nPyPI:          {}".format(
             "https://pypi.org/project/dustpy/")
         msg += "\nGitHub:        {}".format(
             "https://github.com/stammler/dustpy/")
         msg += "\n"
         msg += colorize("\nPlease cite Stammler & Birnstiel (2022).", "blue")
         print(msg)
     # Check for mass conserbation
     self.checkmassconservation()
     # Actually run the simulation
     super().run()
Ejemplo n.º 7
0
 def condition(self, val):
     msg = "{} Use <Boundary>.setcondition() to set boundary condition.".format(
         colorize("Warning:", color="yellow"))
     print(msg)
Ejemplo n.º 8
0
 def __str__(self):
     ret = AbstractGroup.__str__(self)
     if self.constant:
         ret += ", {}".format(colorize("constant", "purple"))
     return ret
Ejemplo n.º 9
0
    def setdustintegrator(self, scheme="explicit", method="cash-karp"):
        """Function sets the dust integrator.

        Parameters
        ----------
        scheme : string, optional, default : "explicit"
            Possible values
                {"explicit", "implicit"}
        method : string, optional, default : "cash-karp"
            Possible values for explicit integration
                {"cash-karp"}
            Possible values for implicit integration
                {"direct", "gmres", "bicgstab}"""

        if not isinstance(self.grid.Nm, Field) or not isinstance(self.grid.Nr, Field):
            raise RuntimeError(
                "The simulation frame has to be initialized before calling setdustimplicit().")

        # Get index of dust instruction
        for i, inst in enumerate(self.integrator.instructions):
            if inst.Y is self.dust.Sigma:
                break

        if scheme == "implicit":

            shape2ravel = (int(self.grid.Nr*self.grid.Nm))

            # Hidden fields
            # We store the old values of the surface density in a hidden field
            # to calculate the fluxes through the boundaries in case of implicit integration.
            self.dust._SigmaOld = Field(
                self, self.dust.Sigma, description="Previous value of surface density [g/cm²]")
            # The right-hand side of the matrix equation is stored in a hidden field
            self.dust._rhs = Field(self, np.zeros(
                shape2ravel), description="Right-hand side of matrix equation [g/cm²]")

            # Setting the Jacobinator
            self.dust.Sigma.jacobinator = std.dust.jacobian

            # Time step routine
            self.t.updater = std.sim.dt

            # Updaters
            self.dust.v.updater = ["frag", "driftmax", "rel"]
            self.dust.updater = ["delta", "rhos", "fill", "a", "St", "H",
                                 "rho", "backreaction", "v", "D", "eps", "kernel", "p", "S"]
            self.dust.S.updater = ["ext", "tot"]

            # Preparation/Finalization
            self.integrator.preparator = std.sim.prepare_implicit_dust
            self.integrator.finalizer = std.sim.finalize_implicit_dust

            # Integrator
            if method == "direct":

                inst = Instruction(std.dust.impl_1_direct,
                                   self.dust.Sigma,
                                   controller={"rhs": self.dust._rhs
                                               },
                                   description="Dust: implicit 1st-order direct solver"
                                   )
                self.integrator.instructions[i] = inst

            elif method == "gmres":
                raise NotImplementedError(
                    "GMRES method is not implemented, yet.")
            elif method == "bicgstab":
                raise NotImplementedError("BiCGSTAB is not implemented, yet.")
            else:
                raise RuntimeError("Invalid method for implicit integration.")
        elif scheme == "explicit":

            # Remove hidden fields if they exist
            if hasattr(self.dust, "_SigmaOld"):
                del self.dust._SigmaOld
            if hasattr(self.dust, "_rhs"):
                del self.dust._rhs

            # Unset Jacobian
            self.dust.Sigma.jacobinator = None

            # Updaters
            self.dust.v.updater = ["frag", "driftmax", "rad", "rel"]
            self.dust.updater = ["delta", "rhos", "fill", "a", "St", "H",
                                 "rho", "backreaction", "v", "D", "eps", "Fi", "kernel", "p", "S"]
            self.dust.S.updater = ["coag", "hyd", "ext", "tot"]

            # Preparation/Finalization
            self.integrator.preparator = std.sim.prepare_explicit_dust
            self.integrator.finalizer = std.sim.finalize_explicit_dust

            if method == "cash-karp":

                # Adaptive time step routine
                self.t.updater = std.sim.dt_adaptive

                # Instruction
                inst = Instruction(schemes.expl_5_cash_karp_adptv,
                                   self.dust.Sigma,
                                   controller={"dYdx": self.dust.S.tot,
                                               "eps": 0.1,
                                               "S": 0.9,
                                               },
                                   description="Dust: explicit 5th-order adaptive Cash-Karp method"
                                   )
                self.integrator.instructions[i] = inst
                self.t.suggest(1.*c.year)

            else:
                raise RuntimeError("Invalid method for explicit integration.")
        else:
            raise RuntimeError("Unknown integration scheme.")

        self.integrator._finalize()
        self.update()

        if self.verbosity > 0:
            msg = "Setting dust integrator\n    scheme: {}\n    method: {}".format(
                colorize(scheme, "blue"), colorize(method, "blue"))
            print(msg)
Ejemplo n.º 10
0
    def checkmassconservation(self):
        """Function checks for mass conservation and prints the maximum relative mass error."""

        # Check if required fields are present
        if self.dust.coagulation.stick is None:
            raise RuntimeError(
                "'Simulation.dust.coagulation.stick' is not set.")
        if self.dust.coagulation.stick_ind is None:
            raise RuntimeError(
                "'Simulation.dust.coagulation.stick_ind' is not set.")
        if self.dust.coagulation.A is None:
            raise RuntimeError(
                "'Simulation.dust.coagulation.A' is not set.")
        if self.dust.coagulation.eps is None:
            raise RuntimeError(
                "'Simulation.dust.coagulation.eps' is not set.")
        if self.dust.coagulation.lf_ind is None:
            raise RuntimeError(
                "'Simulation.dust.coagulation.lf_ind' is not set.")
        if self.dust.coagulation.rm_ind is None:
            raise RuntimeError(
                "'Simulation.dust.coagulation.rm_ind' is not set.")
        if self.dust.coagulation.phi is None:
            raise RuntimeError(
                "'Simulation.dust.coagulation.phi' is not set.")
        if self.grid.m is None:
            raise RuntimeError("'sim.grid.m' is not set.")

        if self.verbosity > 0:

            # Maximum acceptable error
            erracc = 1.e-13

            # Checking for sticking error
            msg = "\n"
            msg += colorize("Checking for mass conservation...\n",
                            color="yellow")
            print(msg)
            msg = colorize("    - Sticking:", color="yellow")
            print(msg)
            errmax, i, j = std.dust_f.check_mass_conservation_sticking(
                self.dust.coagulation.stick, self.dust.coagulation.stick_ind, self.grid.m)
            tup = (j, i)
            color = "red"
            if(errmax < erracc):
                color = "green"
            error = "{:9.2e}".format(errmax)
            msg = "        max. rel. error: {:}\n".format(
                colorize(error, color=color))
            msg += "        for particle collision\n"
            msg += "            m[{:d}] = {:9.2e} g    with\n".format(
                tup[0], self.grid.m[tup[0]])
            msg += "            m[{:d}] = {:9.2e} g".format(
                tup[1], self.grid.m[tup[1]])
            msg = colorize(msg)
            print(msg)

            # Checking for full fragmentation error
            msg = colorize("    - Full fragmentation:", color="yellow")
            print(msg)
            A = self.dust.coagulation.A
            eps = self.dust.coagulation.eps
            klf = self.dust.coagulation.lf_ind
            krm = self.dust.coagulation.rm_ind
            m = self.grid.m
            phi = self.dust.coagulation.phi
            errmax, i, j = std.dust_f.check_mass_conservation_full_fragmentation(
                A, klf, m, phi)
            tup = (j, i)
            color = "red"
            if(errmax < erracc):
                color = "green"
            error = "{:9.2e}".format(errmax)
            msg = "        max. rel. error: {:}\n".format(
                colorize(error, color=color))
            msg += "        for particle collision\n"
            msg += "            m[{:d}] = {:9.2e} g    with\n".format(
                tup[0], self.grid.m[tup[0]])
            msg += "            m[{:d}] = {:9.2e} g".format(
                tup[1], self.grid.m[tup[1]])
            msg = colorize(msg)
            print(msg)

            # Checking for erosion error
            msg = colorize("    - Erosion:", color="yellow")
            print(msg)
            errmax, i, j = std.dust_f.check_mass_conservation_erosion(
                A, eps, klf, krm, m, phi)
            tup = (j, i)
            color = "red"
            if(errmax < erracc):
                color = "green"
            error = "{:9.2e}".format(errmax)
            msg = "        max. rel. error: {:}\n".format(
                colorize(error, color=color))
            msg += "        for particle collision\n"
            msg += "            m[{:d}] = {:9.2e} g    with\n".format(
                tup[0], self.grid.m[tup[0]])
            msg += "            m[{:d}] = {:9.2e} g\n".format(
                tup[1], self.grid.m[tup[1]])
            msg = colorize(msg)
            print(msg)
Ejemplo n.º 11
0
    def __repr__(self):
        """Function to have good looking overview of the members of the group."""

        fields = {}
        groups = {}
        misc = {}

        # return value
        ret = ""

        for key, val in self.__dict__.items():
            # Don't show private attributes
            if key.startswith("_"):
                continue

            # Sort attributes by group, field and else
            if isinstance(val, Field):
                fields[key] = val
            elif isinstance(val, Group):
                groups[key] = val
            else:
                misc[key] = val

        # Underlined headline. The length of the underline is off if there are hidden characters, like color.
        ret += self.__str__() + "\n"
        ret += "-" * (len(ret) - 1) + "\n"

        # Printing all groups alphanumerically sorted by name
        if len(groups) > 0:
            for key in sorted(groups.keys(), key=str.casefold):
                if len(key) > 12:
                    name = key[:9] + "..."
                else:
                    name = key
                ret += "    {:12s} : {}\n".format(name, groups[key])
            ret += "  -----\n"

        # Printing all fields alphanumerically sorted by name
        if len(fields) > 0:
            for key in sorted(fields.keys(), key=str.casefold):
                if len(key) > 12:
                    name = key[:9] + "..."
                else:
                    name = key
                ret += "    {:12s} : {}\n".format(name, fields[key].__str__())
            ret += "  -----\n"

        # Printing everything else alphanumerically sorted
        if len(misc) > 0:
            for key in sorted(misc.keys(), key=str.casefold):
                if len(key) > 12:
                    name = key[:9] + "..."
                else:
                    name = key
                ret += "    {:12s} : {}\n".format(name,
                                                  type(misc[key]).__name__)
            ret += "  -----\n"

        # The Frame object should have an integrator and writer which are displayed separately.
        # If the object has an integrator
        if "_integrator" in self.__dict__.keys():
            integrator = self.__dict__["_integrator"]
            # If not set, print warning
            txt = colorize("not specified", "yellow")
            if integrator is not None:
                txt = integrator.__str__()
            ret += "    {:12s} : {}".format("Integrator", txt)
            ret += "\n"

        # If the object has a writer
        if "_writer" in self.__dict__.keys():
            writer = self.__dict__["_writer"]
            # If not set print warning
            txt = colorize("not specified", "yellow")
            if writer is not None:
                txt = writer.__str__()
            ret += "    {:12s} : {}".format("Writer", txt)
            ret += "\n"

        return ret
Ejemplo n.º 12
0
    def run(self):
        """This method starts the simulation. An ``Integrator`` has to be set beforehand."""

        if not isinstance(self.integrator, Integrator):
            raise RuntimeError("No integrator set.")

        # Check if integration variable is set
        if not isinstance(self.integrator.var, IntVar):
            raise RuntimeError(
                "No integration variable assigned to integrator.")

        # If there are no snapshots set
        if not len(self.integrator.var.snapshots):
            raise RuntimeError(
                "No snapshots set. At least one snapshot has to be given.")

        # If integration variable passed maximum value of snapshots
        if self.integrator.var >= self.integrator.var.snapshots[-1]:
            raise RuntimeError(
                "Integration variable already passed the largest snapshot.")

        # Timekeeping
        tini = monotonic()

        # Write initial conditions
        if self.integrator.var < self.integrator.var.snapshots[0]:
            self.writeoutput(0)

        # Staring index of snapshots
        starting_index = np.argmin(
            self.integrator.var >= self.integrator.var.snapshots)
        # Starting value of integration variable
        startingvalue = self.integrator.var.copy()
        for i in range(starting_index, len(self.integrator.var.snapshots)):

            # Nextsnapshot cannot be referenced directly, because it dynamically changes.
            nextsnapshot = self.integrator.var.nextsnapshot
            prevsnapshot = self.integrator.var.prevsnapshot if self.integrator.var.prevsnapshot is not None else startingvalue

            while self.integrator.var < nextsnapshot:

                if self.verbosity > 1:
                    self.progressbar(self.integrator.var, prevsnapshot,
                                     nextsnapshot, startingvalue,
                                     self.integrator.var.snapshots[-1])

                self.integrator.integrate()
                self.integrator.var += self.integrator.var._prevstepsize

                self.update()

            if self.verbosity > 1:
                self.progressbar._reset()

            self.writeoutput(i + 1)

        # Timekeeping
        tfin = monotonic()
        t_exec = timedelta(seconds=int(tfin - tini))
        if self.verbosity > 0:
            msg = "Execution time: {}".format(colorize(t_exec, color="blue"))
            print(msg)
Ejemplo n.º 13
0
 def update(self):
     """Not used for ``IntVar``."""
     msg = "{}: {}".format(
         colorize("Warning", "yellow"),
         "Do not update the integration variable by hand.")
     print(msg)
Ejemplo n.º 14
0
 def __str__(self):
     ret = "{}".format(str(self.__name__))
     ret = super().__str__()
     ret += ", {}".format(colorize("Integration variable", "purple"))
     return ret