Basics

This tutorial assumes that you’ve already read the Basic tutorial. We will use a common model of a fish with an object near the head. The details are not important as all Model descendants will behave similarly.

The solution object is actually a plotting data structure. All plotting functions will require this along with some configuration settings. We’ll cover the two basic plots in this section: solutions and outlines.

Plots are broken into 2D and 1D plots. 2D plots describe a function over the space: for example the EOD, the model conductance as a function of position, or the domains. 1D plots describe a function on the boundaries - the simplest on is the outline which is outline = 1 if an edge describes the geometry outline and outline = 0 otherwise.

The solution object has several fields corresponding to different properties they are

  • 2D properties
    • solution

    • active (only present if image computed)

    • domain

    • sigma

  • 1D properties
    • boundary

    • outline

  • Misc properties
    • SkinStructure

    • ElectricImage

Plot Solution

The solution field contains the “most resent” simulation result. I.e. the voltage from the EOD (note however that if the field perturbation is computed to compute the electric image them solution is the field perturbation and an additional variable active is created which contains the “raw EOD”.

from fish2eod import BaseFishModel, Circle, plotting

"""
Boilerplate to solve the model
"""


class PreyClass(BaseFishModel):
    def add_geometry(self, **kwargs):
        prey = Circle((3, 2), 0.5)

        self.model_geometry.add_domain("prey", prey, sigma=1)


model = PreyClass()
parameters = {"fish_x": [-15, 15], "fish_y": [0, 0]}
model.compile(**parameters)
model.solve(**parameters)

"""
Extract the solution object

Plot the "FEM solution"
"""

model_solution = model.solution  # pull solution
plotting.mesh_plot_2d(model_solution, "solution")  # plot the result named solution

(Source code, png, hires.png, pdf)

../../_images/basic_solution_plot.png

Here where we specify the “solution” variable we could have used any valid 2D function.

Plot Outline

Technically the outline can be computed from a 1D plot - however we’ve provided a helper function to do so. All thats needed is to call the plot_outline function.

from fish2eod import BaseFishModel, Circle, plotting

"""
Boilerplate to solve the model
"""


class PreyClass(BaseFishModel):
    def add_geometry(self, **kwargs):
        prey = Circle((3, 2), 0.5)

        self.model_geometry.add_domain("prey", prey, sigma=1)


model = PreyClass()
parameters = {"fish_x": [-15, 15], "fish_y": [0, 0]}
model.compile(**parameters)
model.solve(**parameters)

"""
Extract the solution object

Plot the "FEM solution"
"""

model_solution = model.solution  # pull solution
plotting.plot_outline(model_solution)  # plot the result named solution

(Source code, png, hires.png, pdf)

../../_images/basic_outline_plot.png

Masking

In many cases some information is included in the plot that you don’t want. For example inside the fish is usually “not interesting” so this can be masked out.

import matplotlib.pyplot as plt

from fish2eod import BaseFishModel, Circle, plotting

"""
Boilerplate to solve the model
"""


class PreyClass(BaseFishModel):
    def add_geometry(self, **kwargs):
        prey = Circle((3, 2), 0.5)

        self.model_geometry.add_domain("prey", prey, sigma=1)


model = PreyClass()
parameters = {"fish_x": [-15, 15], "fish_y": [0, 0]}
model.compile(**parameters)
model.solve(**parameters)

"""
Extract the solution object

Plot the "FEM solution"
Mask only the water (outside fish)
"""

model_solution = model.solution  # pull solution
mask = plotting.generate_mask(model.solution, include_domains=("water",))
plotting.mesh_plot_2d(model_solution, "solution", mask=mask)  # plot the result named solution

# For convenience you can also exclude a domain by setting include=False
plt.figure()
mask = plotting.generate_mask(model.solution, include_domains=("water",), include=False)
plotting.mesh_plot_2d(model_solution, "solution", mask=mask)  # plot the result named solution

(Source code)

../../_images/basic_mask_00.png

(png, hires.png, pdf)

../../_images/basic_mask_01.png

(png, hires.png, pdf)

Additionally it may be more convenient to set a certain domain to be ommitted rather than have a long list of included domains. For this reason we provide an include flag to set whether the mask is inclusive or exclusive.

Sweeps

Plotting during sweeps is almost the same as for regular plotting. You just need to specify the sweep parameter values

Note that because of the way matplotlib works we cannot pass properties as prop_0 = 0 but we need to specify the properties argument. This is necessary to provide the flexibility of passing arbitrary matplotlib settings.

Not that setting the properties argument does not influence any other settings and this can be used in concert with all other flags and settings.

from itertools import product
from tempfile import TemporaryDirectory

import matplotlib.pyplot as plt

from fish2eod import (
    BaseFishModel,
    Circle,
    IterativeSolver,
    ParameterSet,
    ParameterSweep,
    load_from_file,
    plotting,
)

"""
Boilerplate to solve the model
"""


class PreyClass(BaseFishModel):
    def add_geometry(self, prey_x, prey_y, **kwargs):
        prey = Circle((prey_x, prey_y), 0.5)

        self.model_geometry.add_domain("prey", prey, sigma=1)


d = TemporaryDirectory()

prey_x = ParameterSet("prey_x", prey_x=[3, 6], rebuild_mesh=True)
prey_y = ParameterSet("prey_y", prey_y=[2, 4], rebuild_mesh=True)

parameter_sweep = ParameterSweep(prey_x, prey_y)
it = IterativeSolver("temp", d.name, PreyClass, parameter_sweep, fish_x=[-15, 15], fish_y=[0, 0])
it.run()

"""
Extract the solution object

Plot the "FEM solution"
"""

loaded_solution = load_from_file(d.name + "/temp")
prey_x_values = loaded_solution.parameter_levels["prey_x"]
prey_y_values = loaded_solution.parameter_levels["prey_y"]
for prey_x, prey_y in product(prey_x_values, prey_y_values):
    plt.figure()

    # pass the solution parameters in an additional dictionary.
    # all other arguments can be used as normal
    plotting.mesh_plot_2d(loaded_solution, "solution", prey_x=prey_x, prey_y=prey_y)
    plotting.plot_outline(loaded_solution, prey_x=prey_x, prey_y=prey_y)

(Source code)

../../_images/basic_sweep_plot_00.png

(png, hires.png, pdf)

../../_images/basic_sweep_plot_01.png

(png, hires.png, pdf)

../../_images/basic_sweep_plot_02.png

(png, hires.png, pdf)

../../_images/basic_sweep_plot_03.png

(png, hires.png, pdf)