Exemplo n.º 1
0
def compute_fluid_elevation(particles):
    one_time_equations = [
            Group(
                equations=[
                    FluidBottomElevation(dest='fluid', sources=['bed'])
                    ]
                ),
            Group(
                equations=[
                    GradientCorrectionPreStep(dest='bed', sources=['bed'])
                    ]
                ),
            Group(
                equations=[
                    GradientCorrection(dest='bed', sources=['bed'])
                    ]
                ),
            Group(
                equations=[
                    BedGradient(dest='bed', sources=['bed']),
                    ]
                ),
            Group(
                equations=[
                    BedCurvature(dest='bed', sources=['bed']),
                    ]
                ),
        ]
    kernel = CubicSpline(dim=2)
    sph_eval = SPHEvaluator(particles, one_time_equations, dim=2,
                            kernel=kernel)
    sph_eval.evaluate()
def compute_initial_props(particles):
    one_time_equations = [Group(equations=[SWEOS(dest='fluid')], )]
    kernel = CubicSpline(dim=1)
    sph_eval = SPHEvaluator(particles,
                            one_time_equations,
                            dim=1,
                            kernel=kernel)
    sph_eval.evaluate()
Exemplo n.º 3
0
def remove_repeated_points(x, y, z, dx_triangle):
    EPS = np.finfo(float).eps
    pa_mesh = ParticleArray(name='mesh', x=x, y=y, z=z, h=EPS)
    pa_grid = ParticleArray(name='grid', x=x, y=y, z=z, h=EPS)
    pa_mesh.add_property(name='min_idx')

    equation = [FindRepeatedPoints(dest='mesh', sources=['grid'])]
    sph_eval = SPHEvaluator([pa_mesh, pa_grid], equation, dim=3)
    sph_eval.evaluate()

    idx = list(set(pa_mesh.min_idx))
    idx = np.array(idx, dtype=int)
    return pa_mesh.x[idx], pa_mesh.y[idx], pa_mesh.z[idx]
Exemplo n.º 4
0
    def post_step(self, solver):
        from pysph.tools.sph_evaluator import SPHEvaluator
        if self._sph_eval is None:
            equations = [
                UpdateTangentialContacts(dest='sand', sources=['sand', 'wall'])
            ]

            self._sph_eval = SPHEvaluator(arrays=self.particles,
                                          equations=equations,
                                          dim=2,
                                          kernel=CubicSpline(dim=2))

        self._sph_eval.evaluate()
Exemplo n.º 5
0
    def test_evaluation(self):
        # Given
        xd = [0.5]
        hd = self.src.h[:1]
        dest = get_particle_array(name='dest', x=xd, h=hd)
        sph_eval = SPHEvaluator(arrays=[dest, self.src],
                                equations=self.equations,
                                dim=1)

        # When.
        sph_eval.evaluate()

        # Then.
        self.assertAlmostEqual(dest.rho[0], 9.0, places=2)
Exemplo n.º 6
0
def compute_initial_props(particles):
    one_time_equations = [
        Group(equations=[
            CorrectionFactorVariableSmoothingLength(dest='fluid',
                                                    sources=['fluid'])
        ]),
        Group(equations=[SWEOS(dest='fluid')], )
    ]
    kernel = CubicSpline(dim=2)
    sph_eval = SPHEvaluator(particles,
                            one_time_equations,
                            dim=2,
                            kernel=kernel)
    sph_eval.evaluate()
Exemplo n.º 7
0
    def _get_sph_eval(self, kind):
        from pysph.tools.sph_evaluator import SPHEvaluator
        from pysph.sph.equation import Group
        if self._sph_eval is None:
            arr = self.array
            eqns = []
            name = arr.name
            if 'vmax' not in arr.constants.keys():
                arr.add_constant('vmax', [0.0])
            if 'dpos' not in arr.properties.keys():
                arr.add_property('dpos', stride=3)
            if kind == 'simple':
                const = 0.04 if not self.parameter else self.parameter
                eqns.append(
                    Group(equations=[SimpleShift(name, [name], const=const)],
                          update_nnps=True))
            elif kind == 'fickian':
                const = 4 if not self.parameter else self.parameter
                eqns.append(
                    Group(equations=[
                        FickianShift(name, [name], fickian_const=const)
                    ],
                          update_nnps=True))
            if self.correct_velocity:
                if 'gradv' not in arr.properties.keys():
                    arr.add_property('gradv', stride=9)
                eqns.append(Group(equations=[CorrectVelocities(name, [name])]))

            sph_eval = SPHEvaluator(arrays=[arr],
                                    equations=eqns,
                                    dim=self.dim,
                                    kernel=self.kernel)
            return sph_eval
        else:
            return self._sph_eval
Exemplo n.º 8
0
    def _create_io_eval(self):
        if self.io_eval is None:
            from pysph.sph.equation import Group
            from pysph.tools.sph_evaluator import SPHEvaluator
            o_name = self.outlet_pa.name
            f_name = self.source_pa.name
            eqns = []

            eqns.append(Group(equations=[
                IOEvaluate(
                    o_name, [], x=self.x, y=self.y, z=self.z, xn=self.xn,
                    yn=self.yn, zn=self.zn, maxdist=self.length)],
                real=False, update_nnps=False))

            eqns.append(Group(equations=[
                IOEvaluate(
                    f_name, [], x=self.x, y=self.y, z=self.z, xn=self.xn,
                    yn=self.yn, zn=self.zn,)], real=False, update_nnps=False))

            arrays = [self.outlet_pa] + [self.source_pa]
            io_eval = SPHEvaluator(arrays=arrays, equations=eqns, dim=self.dim,
                                   kernel=self.kernel)
            return io_eval
        else:
            return self.io_eval
Exemplo n.º 9
0
def compute_initial_props(particles):
    one_time_equations = [
        Group(equations=[
            FluidBottomElevation(dest='fluid', sources=['bed']),
            BedGradient(dest='bed', sources=['bed']),
            CorrectionFactorVariableSmoothingLength(dest='fluid',
                                                    sources=['fluid']),
            SWEOS(dest='fluid')
        ]),
    ]
    kernel = CubicSpline(dim=2)
    sph_eval = SPHEvaluator(particles,
                            one_time_equations,
                            dim=2,
                            kernel=kernel)
    sph_eval.evaluate()
Exemplo n.º 10
0
 def _make_accel_eval(self, equations):
     kernel = CubicSpline(dim=self.dim)
     seval = SPHEvaluator(
         arrays=[self.pa], equations=equations,
         dim=self.dim, kernel=kernel
     )
     return seval
Exemplo n.º 11
0
def compute_initial_props(particles):
    one_time_equations = [
        Group(equations=[
            CheckForParticlesToSplit(dest='fluid',
                                     A_max=2900,
                                     x_min=300,
                                     x_max=1100,
                                     y_min=300,
                                     y_max=1100)
        ], )
    ]
    kernel = CubicSpline(dim=2)
    sph_eval = SPHEvaluator(particles,
                            one_time_equations,
                            dim=2,
                            kernel=kernel)
    sph_eval.evaluate()
Exemplo n.º 12
0
    def _get_normals(self, pa):
        from pysph.tools.sph_evaluator import SPHEvaluator
        from pysph.sph.isph.wall_normal import ComputeNormals, SmoothNormals

        pa.add_property('normal', stride=3)
        pa.add_property('normal_tmp', stride=3)

        name = pa.name

        seval = SPHEvaluator(
            arrays=[pa],
            equations=[
                Group(equations=[ComputeNormals(dest=name, sources=[name])]),
                Group(equations=[SmoothNormals(dest=name, sources=[name])]),
            ],
            dim=self.dim)
        seval.evaluate()
Exemplo n.º 13
0
    def test_evaluation_with_domain_manager(self):
        # Given
        xd = [0.0]
        hd = self.src.h[:1]
        dest = get_particle_array(name='dest', x=xd, h=hd)
        dx = self.dx
        dm = DomainManager(xmin=-dx / 2, xmax=1.0 + dx / 2, periodic_in_x=True)
        sph_eval = SPHEvaluator(arrays=[dest, self.src],
                                equations=self.equations,
                                dim=1,
                                domain_manager=dm)

        # When.
        sph_eval.evaluate()

        # Then.
        self.assertAlmostEqual(dest.rho[0], 9.0, places=2)
def compute_initial_props(particles):
    one_time_equations = [
        Group(equations=[
            InitialTimeGatherSummationDensity(dest='fluid',
                                              sources=[
                                                  'fluid',
                                              ]),
            CheckForParticlesToSplit(dest='fluid', h_max=h_max, A_max=2900)
        ],
              update_nnps=False)
    ]
    kernel = CubicSpline(dim=2)
    sph_eval = SPHEvaluator(particles,
                            one_time_equations,
                            dim=2,
                            kernel=kernel)
    sph_eval.evaluate()
Exemplo n.º 15
0
    def test_tangential_contacts(self):
        # before updating the  contact information lets check
        # tangential properties

        # number of contacts of each individual particles
        for i in range(len(self.pa.x)):
            self.assertAlmostEqual(self.pa.total_tng_contacts[i], 0.)

        for i in range(self.pa.total_dem_entities[0]):
            self.assertAlmostEqual(self.pa.tng_idx[i], -1)
            self.assertAlmostEqual(self.pa.tng_x[i], 0.)
            self.assertAlmostEqual(self.pa.tng_y[i], 0.)
            self.assertAlmostEqual(self.pa.tng_z[i], 0.)

        # ------------------------------
        # execute the interparticle force equation
        # ------------------------------
        # Given
        eqs = [
            Group(equations=[
                LinearSpringForceParticleParticle(dest='sand',
                                                  sources=['sand'])
            ])
        ]

        kernel = CubicSpline(dim=2)
        sph_eval = SPHEvaluator(arrays=[self.pa],
                                equations=eqs,
                                dim=2,
                                kernel=kernel)

        # When
        sph_eval.evaluate(0.0, 0.1)

        # check the tangential contacts indices and displacements
        # number of contacts of each individual particles
        for i in range(len(self.pa.x)):
            self.assertAlmostEqual(self.pa.total_tng_contacts[i], 0)

        for i in range(self.pa.total_dem_entities[0]):
            self.assertAlmostEqual(self.pa.tng_idx[i], -1)
            self.assertAlmostEqual(self.pa.tng_x[i], 0.)
            self.assertAlmostEqual(self.pa.tng_y[i], 0.)
            self.assertAlmostEqual(self.pa.tng_z[i], 0.)
Exemplo n.º 16
0
    def _create_io_eval(self):
        """Evaluator to assign ioid to particles leaving a domain"""
        if self.io_eval is None:
            from pysph.sph.equation import Group
            from pysph.tools.sph_evaluator import SPHEvaluator
            o_name = self.outlet_pa.name
            f_name = self.source_pa.name
            eqns = []
            if self.gpu:
                from pysph.base.gpu_nnps import ZOrderGPUNNPS as NNPS
            else:
                from pysph.base.nnps import LinkedListNNPS as NNPS

            eqns.append(
                Group(equations=[
                    IOEvaluate(o_name, [],
                               x=self.x,
                               y=self.y,
                               z=self.z,
                               xn=self.xn,
                               yn=self.yn,
                               zn=self.zn,
                               maxdist=self.length)
                ],
                      real=False,
                      update_nnps=False))

            eqns.append(
                Group(equations=[
                    IOEvaluate(
                        f_name,
                        [],
                        x=self.x,
                        y=self.y,
                        z=self.z,
                        xn=self.xn,
                        yn=self.yn,
                        zn=self.zn,
                    )
                ],
                      real=False,
                      update_nnps=False))

            arrays = [self.outlet_pa] + [self.source_pa]
            io_eval = SPHEvaluator(arrays=arrays,
                                   equations=eqns,
                                   dim=self.dim,
                                   kernel=self.kernel,
                                   nnps_factory=NNPS)
            return io_eval
        else:
            return self.io_eval
Exemplo n.º 17
0
 def _get_sph_evaluator(self, array):
     if not hasattr(self, '_sph_eval'):
         from pysph.tools.sph_evaluator import SPHEvaluator
         equations = [
             ComputeAveragePressure(dest='fluid', sources=['fluid'])
         ]
         dm = self.create_domain()
         sph_eval = SPHEvaluator(
             arrays=[array], equations=equations, dim=2,
             kernel=QuinticSpline(dim=2), domain_manager=dm
         )
         self._sph_eval = sph_eval
     return self._sph_eval
Exemplo n.º 18
0
def compute_initial_props(particles):
    one_time_equations = [
        Group(equations=[
            SWEOS(dest='fluid'),
        ]),
        Group(equations=[
            BoundaryInnerReimannStateEval(dest='inlet', sources=['fluid']),
            BoundaryInnerReimannStateEval(dest='outlet', sources=['fluid'])
        ]),
        Group(equations=[
            SubCriticalInFlow(dest='inlet'),
            SubCriticalOutFlow(dest='outlet')
        ]),
        Group(equations=[
            CorrectionFactorVariableSmoothingLength(
                dest='fluid', sources=['fluid', 'inlet', 'outlet', 'boundary'])
        ]),
    ]
    kernel = CubicSpline(dim=2)
    sph_eval = SPHEvaluator(particles,
                            one_time_equations,
                            dim=2,
                            kernel=kernel)
    sph_eval.evaluate()
Exemplo n.º 19
0
def compute_initial_props(particles):
    one_time_equations = [
                Group(
                    equations=[
                        InitialTimeScatterSummationDensity(dest='fluid',
                                                           sources=['fluid',]),
                        ]
                    ),
                Group(
                    equations=[
                        SWEOS(dest='fluid'),
                        ]
                    ),
                Group(
                    equations=[
                        CheckForParticlesToSplit(dest='fluid', h_max=h_max,
                                                 A_max=A_max),
                            ]
                    )
            ]
    kernel = CubicSpline(dim=2)
    sph_eval = SPHEvaluator(particles, one_time_equations, dim=2,
                            kernel=kernel)
    sph_eval.evaluate()
Exemplo n.º 20
0
    def _get_force_evaluator(self):
        from pysph.solver.utils import load
        from pysph.base.kernels import QuinticSpline
        from pysph.tools.sph_evaluator import SPHEvaluator
        from pysph.sph.equation import Group
        from pysph.sph.wc.transport_velocity import (
            SetWallVelocity, MomentumEquationPressureGradient,
            SolidWallNoSlipBC, VolumeSummation, MomentumEquationViscosity)
        data = load(self.output_files[0])
        solid = data['arrays']['solid']
        fluid = data['arrays']['fluid']

        prop = [
            'awhat', 'auhat', 'avhat', 'wg', 'vg', 'ug', 'V', 'uf', 'vf', 'wf',
            'wij', 'vmag'
        ]
        for p in prop:
            solid.add_property(p)
            fluid.add_property(p)
        equations = [
            Group(equations=[
                SetWallVelocity(dest='fluid', sources=['solid']),
                VolumeSummation(dest='fluid', sources=['fluid', 'solid']),
                VolumeSummation(dest='solid', sources=['fluid', 'solid']),
            ],
                  real=False),
            Group(
                equations=[
                    # Pressure gradient terms
                    MomentumEquationPressureGradient(
                        dest='solid', sources=['fluid', 'solid'], pb=p0),
                    MomentumEquationViscosity(dest='solid',
                                              sources=['fluid', 'solid'],
                                              nu=self.nu),
                    SolidWallNoSlipBC(dest='solid',
                                      sources=['fluid'],
                                      nu=self.nu),
                ],
                real=True),
        ]
        sph_eval = SPHEvaluator(arrays=[solid, fluid],
                                equations=equations,
                                dim=2,
                                kernel=QuinticSpline(dim=2))

        return sph_eval
Exemplo n.º 21
0
    def test_updating_particle_arrays(self):
        # Given
        xd = [0.5]
        hd = self.src.h[:1]
        dest = get_particle_array(name='dest', x=xd, h=hd)
        sph_eval = SPHEvaluator([dest, self.src],
                                equations=self.equations,
                                dim=1)
        sph_eval.evaluate()
        rho0 = dest.rho[0]

        # When.
        dest.x[0] = 0.0
        sph_eval.update_particle_arrays([dest, self.src])
        sph_eval.evaluate()

        # Then.
        self.assertNotEqual(rho0, dest.rho[0])
        self.assertAlmostEqual(dest.rho[0], 7.0, places=1)
Exemplo n.º 22
0
 def _get_sph_eval_mls3d_1(self):
     from pysph.sph.wc.density_correction import MLSFirstOrder3D
     from pysph.tools.sph_evaluator import SPHEvaluator
     from pysph.sph.equation import Group
     if self._sph_eval is None:
         arrs = self.arrs
         eqns = []
         for arr in arrs:
             name = arr.name
             arr.add_property('rhotmp')
             eqns.append(Group(equations=[
                         MLSFirstOrder3D(name, [name])], real=False))
         sph_eval = SPHEvaluator(
             arrays=arrs, equations=eqns, dim=self.dim,
             kernel=self.kernel(dim=self.dim))
         return sph_eval
     else:
         return self._sph_eval
Exemplo n.º 23
0
    def _plot_cd_vs_t(self):
        from pysph.solver.utils import iter_output, load
        from pysph.tools.sph_evaluator import SPHEvaluator
        from pysph.sph.equation import Group
        from pysph.sph.wc.transport_velocity import (SetWallVelocity,
            MomentumEquationPressureGradient, SolidWallNoSlipBC,
            SolidWallPressureBC, VolumeSummation)

        data = load(self.output_files[0])
        solid = data['arrays']['solid']
        fluid = data['arrays']['fluid']
        x, y = solid.x.copy(), solid.y.copy()
        cx = 0.5 * L; cy = 0.5 * H
        inside = np.sqrt((x-cx)**2 + (y-cy)**2) <= a
        dest = solid.extract_particles(inside.nonzero()[0])
        # We use the same equations for this as the simulation, except that we
        # do not include the acceleration terms as these are externally
        # imposed.  The goal of these is to find the force of the fluid on the
        # cylinder, thus, gx=0.0 is used in the following.
        equations = [
            Group(
                equations=[
                    VolumeSummation(
                        dest='fluid', sources=['fluid', 'solid']
                    ),
                    VolumeSummation(
                        dest='solid', sources=['fluid', 'solid']
                    ),
                    ], real=False),

            Group(
                equations=[
                    SetWallVelocity(dest='solid', sources=['fluid']),
                    ], real=False),

            Group(
                equations=[
                    SolidWallPressureBC(dest='solid', sources=['fluid'],
                                        gx=0.0, b=1.0, rho0=rho0, p0=p0),
                    ], real=False),

            Group(
                equations=[
                    # Pressure gradient terms
                    MomentumEquationPressureGradient(
                        dest='fluid', sources=['solid'], gx=0.0, pb=pb),
                    SolidWallNoSlipBC(
                        dest='fluid', sources=['solid'], nu=nu),
                    ], real=True),
        ]

        sph_eval = SPHEvaluator(
            arrays=[dest, fluid], equations=equations, dim=2,
            kernel=QuinticSpline(dim=2)
        )

        t, cd = [], []
        for sd, fluid in iter_output(self.output_files, 'fluid'):
            fluid.remove_property('vmag2')
            t.append(sd['t'])
            sph_eval.update_particle_arrays([dest, fluid])
            sph_eval.evaluate()
            Fx = np.sum(-fluid.au*fluid.m)
            cd.append(Fx/(nu*rho0*Umax))

        t, cd = list(map(np.asarray, (t, cd)))

        # Now plot the results.
        import matplotlib
        matplotlib.use('Agg')

        from matplotlib import pyplot as plt
        f = plt.figure()
        plt.plot(t, cd)
        plt.xlabel('$t$'); plt.ylabel(r'$C_D$')
        fig = os.path.join(self.output_dir, "cd_vs_t.png")
        plt.savefig(fig, dpi=300)
        plt.close()

        return t, cd
Exemplo n.º 24
0
class HopperFlow(Application):
    def initialize(self):
        self._sph_eval = None
        self.dx = 1

    def create_particles(self):
        x = np.linspace(-0.5, 0.5, 10)
        y = np.linspace(0.77, 1.77, 10)
        r = (x[1] - x[0]) / 2.
        x, y = np.meshgrid(x, y)
        x, y = x.ravel(), y.ravel()
        R = np.ones_like(x) * r
        _m = np.pi * 2 * r * 2 * r
        m = np.ones_like(x) * _m
        m_inverse = np.ones_like(x) * 1. / _m
        _I = 2. / 5. * _m * r**2
        I_inverse = np.ones_like(x) * 1. / _I
        h = np.ones_like(x) * r
        sand = get_particle_array_dem(x=x,
                                      y=y,
                                      m=m,
                                      m_inverse=m_inverse,
                                      R=R,
                                      h=h,
                                      I_inverse=I_inverse,
                                      name="sand",
                                      dem_id=0,
                                      dim=2,
                                      total_dem_entities=2)

        x, y = create_hopper(r)
        m = np.ones_like(x) * _m
        m_inverse = np.ones_like(x) * 1. / _m
        R = np.ones_like(x) * r
        h = np.ones_like(x) * r
        _I = 2. / 5. * _m * r**2
        I_inverse = np.ones_like(x) * 1. / _I
        wall = get_particle_array_dem(x=x,
                                      y=y,
                                      m=m,
                                      m_inverse=m_inverse,
                                      R=R,
                                      h=h,
                                      I_inverse=I_inverse,
                                      name="wall",
                                      dem_id=1,
                                      dim=2,
                                      total_dem_entities=2)
        return [sand, wall]

    def create_solver(self):
        kernel = CubicSpline(dim=2)

        integrator = EulerIntegrator(sand=EulerDEMStep())

        dt = 5e-5
        print("DT: %s" % dt)
        tf = 2
        solver = Solver(kernel=kernel,
                        dim=2,
                        integrator=integrator,
                        dt=dt,
                        tf=tf,
                        adaptive_timestep=False)

        return solver

    def create_equations(self):
        equations = [
            Group(equations=[
                BodyForce(dest='sand', sources=None, gy=-9.81),
                LinearSpringForceParticleParticle(
                    dest='sand', sources=['sand', 'wall'], kn=1e3),
            ]),
        ]
        return equations

    def post_step(self, solver):
        from pysph.tools.sph_evaluator import SPHEvaluator
        if self._sph_eval is None:
            equations = [
                UpdateTangentialContacts(dest='sand', sources=['sand', 'wall'])
            ]

            self._sph_eval = SPHEvaluator(arrays=self.particles,
                                          equations=equations,
                                          dim=2,
                                          kernel=CubicSpline(dim=2))

        self._sph_eval.evaluate()
Exemplo n.º 25
0
    def _plot_force_vs_t(self):
        from pysph.solver.utils import iter_output, load
        from pysph.tools.sph_evaluator import SPHEvaluator
        from pysph.sph.equation import Group
        from pysph.base.kernels import QuinticSpline
        from pysph.sph.wc.transport_velocity import (
            MomentumEquationPressureGradient, SummationDensity,
            SetWallVelocity)

        data = load(self.output_files[0])
        solid = data['arrays']['solid']
        fluid = data['arrays']['fluid']

        prop = [
            'awhat', 'auhat', 'avhat', 'wg', 'vg', 'ug', 'V', 'uf', 'vf', 'wf',
            'wij', 'vmag', 'pavg', 'nnbr', 'auf', 'avf', 'awf'
        ]
        for p in prop:
            solid.add_property(p)
            fluid.add_property(p)

        # We find the force of the solid on the fluid and the opposite of that
        # is the force on the solid. Note that the assumption is that the solid
        # is far from the inlet and outlet so those are ignored.
        print(self.nu, p0, self.dc, rho)
        equations = [
            Group(equations=[
                SummationDensity(dest='fluid', sources=['fluid', 'solid']),
                SummationDensity(dest='solid', sources=['fluid', 'solid']),
                SetWallVelocity(dest='solid', sources=['fluid']),
            ],
                  real=False),
            Group(
                equations=[
                    # Pressure gradient terms
                    MomentumEquationPressureGradient(dest='solid',
                                                     sources=['fluid'],
                                                     pb=p0),
                    SolidWallNoSlipBCReverse(dest='solid',
                                             sources=['fluid'],
                                             nu=self.nu),
                ],
                real=True),
        ]
        sph_eval = SPHEvaluator(arrays=[solid, fluid],
                                equations=equations,
                                dim=2,
                                kernel=QuinticSpline(dim=2))
        t, cd, cl = [], [], []
        import gc
        print(self.dc, self.dx, self.nu)
        print('fxf', 'fxp', 'fyf', 'fyp', 'cd', 'cl', 't')
        for sd, arrays in iter_output(self.output_files[:]):
            fluid = arrays['fluid']
            solid = arrays['solid']
            for p in prop:
                solid.add_property(p)
                fluid.add_property(p)
            t.append(sd['t'])
            sph_eval.update_particle_arrays([solid, fluid])
            sph_eval.evaluate()
            fxp = sum(solid.m * solid.au)
            fyp = sum(solid.m * solid.av)
            fxf = sum(solid.m * solid.auf)
            fyf = sum(solid.m * solid.avf)
            fx = fxf + fxp
            fy = fyf + fyp
            cd.append(fx / (0.5 * rho * umax**2 * self.dc))
            cl.append(fy / (0.5 * rho * umax**2 * self.dc))
            print(fxf, fxp, fyf, fyp, cd[-1], cl[-1], t[-1])
            gc.collect()
        t, cd, cl = list(map(np.asarray, (t, cd, cl)))
        # Now plot the results.
        import matplotlib
        matplotlib.use('Agg')
        from matplotlib import pyplot as plt
        plt.figure()
        plt.plot(t, cd, label=r'$C_d$')
        plt.plot(t, cl, label=r'$C_l$')
        plt.xlabel(r'$t$')
        plt.ylabel('cd/cl')
        plt.legend()
        plt.grid()
        fig = os.path.join(self.output_dir, "force_vs_t.png")
        plt.savefig(fig, dpi=300)
        plt.close()
        return t, cd, cl