Ejemplo n.º 1
0
def test_sharp_field_dg0():
    sim = Simulation()
    sim.input.read_yaml(yaml_string=INP)
    mesh = dolfin.UnitCubeMesh(2, 2, 2)
    sim.set_mesh(mesh)

    # Sharp jump at the cell boundaries
    field_inp = sim.input.get_value('fields/0', required_type='Input')
    f = SharpField(sim, field_inp).get_variable('rho')
    check_vector_value_histogram(f.vector(), {1: 24, 1000: 24}, round_digits=6)

    # Sharp jump in the middle of the cells
    field_inp['z'] = 0.25
    f = SharpField(sim, field_inp).get_variable('rho')
    hist = get_vector_value_histogram(f.vector())
    assert len(hist) == 4
    for k, v in hist.items():
        if round(k, 6) != 1:
            assert v == 8
        else:
            assert v == 24

    # Non-projected sharp jump between cells
    field_inp['local_projection'] = False
    field_inp['z'] = 0.50
    f = SharpField(sim, field_inp).get_variable('rho')
    check_vector_value_histogram(f.vector(), {1: 24, 1000: 24}, round_digits=6)

    # Non-projected sharp jump the middle of the cells
    field_inp['z'] = 0.25
    f = SharpField(sim, field_inp).get_variable('rho')
    hist = get_vector_value_histogram(f.vector())
    check_vector_value_histogram(f.vector(), {1: 40, 1000: 8}, round_digits=6)
Ejemplo n.º 2
0
def test_get_dof_region_marks():
    sim = Simulation()
    sim.input.read_yaml(yaml_string=BASE_INPUT)
    setup_simulation(sim)
    Vp = sim.data['Vp']
    dofs_x = Vp.tabulate_dof_coordinates().reshape((-1, 2))

    drm = get_dof_region_marks(sim, Vp)
    num_in_region = [0, 0]
    ok = True
    for dof, marks in drm.items():
        x, y = dofs_x[dof]
        if not (x == 0 or x == 1 or y == 0 or y == 1):
            mpi_print('Got unexpected dof coords', x, y)
            ok = False
        if (0 in marks) != (x == 1 or y == 0 or y == 1):
            mpi_print('Got unexpected dof coords in region 0', x, y)
            ok = False
        if (1 in marks) != (x == 0):
            mpi_print('Got unexpected dof coords in region 0', x, y)
            ok = False
        for mark in marks:
            num_in_region[mark] += 1

    assert all_ok(ok)
    assert mpi_int_sum(num_in_region[0]) == 30 + 29 * 2
    assert mpi_int_sum(num_in_region[1]) == 30
Ejemplo n.º 3
0
def test_user_constants():
    sim = Simulation()
    sim.input.read_yaml(yaml_string=INPUT_USER_CONSTANTS)
    success = setup_simulation(sim)
    assert success

    assert sim.input.get_value('ref') == 42.0
Ejemplo n.º 4
0
def test_bdm_identity_transform(gdim):
    N = 5
    k = 2

    # Create mesh and define a divergence free field
    if gdim == 2:
        mesh = dolfin.UnitSquareMesh(N, N)
        field = ['-sin(pi*x[1])*cos(pi*x[0])', 'sin(pi*x[0])*cos(pi*x[1])']
    elif gdim == 3:
        mesh = dolfin.UnitCubeMesh(N, N, N)
        field = [
            '-sin(pi*x[0])*cos(pi*x[1])*sin(pi*x[2])',
            'sin(pi*x[0])*cos(pi*x[1])*sin(pi*x[2])',
            '-cos(pi*x[2])*cos(pi*(x[0]-x[1]))',
        ]

    V = dolfin.FunctionSpace(mesh, 'DG', k)
    u = dolfin.as_vector([dolfin.Function(V) for _ in range(gdim)])
    a = dolfin.as_vector([dolfin.Function(V) for _ in range(gdim)])

    # Make a divergence free field
    for i, cpp in enumerate(field):
        ei = dolfin.Expression(cpp, degree=k)
        u[i].interpolate(ei)
        a[i].assign(u[i])

    # Run the projection into BDM and then assign this to u
    bdm = VelocityBDMProjection(simulation=Simulation(), w=u, use_bcs=False)
    bdm.run()

    # Check the changes made
    for ui, ai in zip(u, a):
        error = dolfin.errornorm(ai, ui, degree_rise=0)
        assert error < 1e-15
Ejemplo n.º 5
0
def test_dirichlet_bcs_scalar_constant_value(method):
    "Test inhomogenous Dirichlet BCs using a Poisson solver"
    sim = Simulation()
    sim.input.read_yaml(yaml_string=BASE_INPUT)
    sim.input.set_value('boundary_conditions', [{}])
    sim.input.set_value('boundary_conditions/0/name', 'all walls')
    sim.input.set_value('boundary_conditions/0/selector', 'code')
    sim.input.set_value('boundary_conditions/0/inside_code', 'on_boundary')

    if method == 'const':
        sim.input.set_value('boundary_conditions/0/phi/type', 'ConstantValue')
        sim.input.set_value('boundary_conditions/0/phi/value', 1.0)
    elif method == 'py_eval':
        sim.input.set_value('boundary_conditions/0/phi/type', 'CodedValue')
        sim.input.set_value('boundary_conditions/0/phi/code', '1.0')
    elif method == 'py_exec':
        sim.input.set_value('boundary_conditions/0/phi/type', 'CodedValue')
        sim.input.set_value('boundary_conditions/0/phi/code', 'value[0] = 1.0')
    elif method == 'cpp':
        sim.input.set_value('boundary_conditions/0/phi/type', 'CppCodedValue')
        sim.input.set_value('boundary_conditions/0/phi/cpp_code', '1.0')

    setup_simulation(sim)
    run_simulation(sim)

    p = sim.data['phi'].vector().get_local()
    assert numpy.linalg.norm(p - 1.0) < 1e-8
Ejemplo n.º 6
0
def test_has_path():
    fn = get_test_file_name('base.inp')
    sim = Simulation()
    sim.input.read_yaml(fn)

    assert sim.input.has_path('ocellaris') is True
    assert sim.input.has_path('ocellaris/type') is True
    assert sim.input.has_path('ocellaris222') is False
    assert sim.input.has_path('ocellaris222/type') is False
    assert sim.input.has_path('ocellaris/type222') is False
Ejemplo n.º 7
0
def test_use_code():
    dummy_mod = '__DUMMY__'
    assert dummy_mod not in sys.modules

    sim = Simulation()
    sim.input.read_yaml(yaml_string=INPUT_USER_CODE)
    success = setup_simulation(sim)
    assert success

    assert dummy_mod in sys.modules
    sys.modules.pop(dummy_mod)
Ejemplo n.º 8
0
def test_child_input():
    fn = get_test_file_name('child.inp')
    sim = Simulation()
    sim.input.read_yaml(fn)

    gv = lambda k, t: sim.input.get_value(k, required_type=t)
    assert gv('metadata/author', 'string') == 'Tormod Landet'
    # assert gv('metadata/date', 'date') == '2018-04-03'
    assert gv('metadata/description', 'string') == 'ThisIsTheDescription'

    assert gv('some_vals/computed', 'float') == 2.0
    assert gv('test_py_val/C', 'float') == 8.0
Ejemplo n.º 9
0
def test_base_input():
    fn = get_test_file_name('base.inp')
    sim = Simulation()
    sim.input.read_yaml(fn)

    gv = lambda k, t: sim.input.get_value(k, required_type=t)
    assert gv('metadata/author', 'string') == 'Tormod Landet'
    assert gv('metadata/description', 'string') == 'NoDescription'

    assert tuple(gv('some_vals/bools', 'list(int)')) == (1, 1, 0, 0)
    assert tuple(gv('some_vals/floats', 'list(float)')) == (1.1, 2, 3.0e3)
    assert gv('some_vals/computed', 'float') == 2.0
Ejemplo n.º 10
0
def mk_scheme(N, Vname, Vorder, cpp_expr, expr_args, convection_inp, dim=2, comm=None):
    if comm is None:
        comm = MPI.comm_world

    parameters['ghost_mode'] = 'shared_vertex'
    if dim == 2:
        mesh = UnitSquareMesh(comm, N, N)
    else:
        mesh = UnitCubeMesh(comm, N, N, N)

    V = FunctionSpace(mesh, Vname, Vorder)
    C = Function(V)
    e = Expression(cpp_expr, element=V.ufl_element(), **expr_args)
    C.interpolate(e)

    D = Function(V)
    D.assign(C)

    sim = Simulation()
    sim.set_mesh(mesh)
    sim.data['constrained_domain'] = None
    sim.data['C'] = C
    for key, value in convection_inp.items():
        sim.input.set_value('convection/C/%s' % key, value)

    scheme_name = convection_inp['convection_scheme']
    return get_convection_scheme(scheme_name)(sim, 'C')
Ejemplo n.º 11
0
def test_vector_field():
    sim = Simulation()
    sim.input.read_yaml(yaml_string=INP)
    mesh = dolfin.UnitCubeMesh(2, 2, 2)
    sim.set_mesh(mesh)

    field_inp = sim.input.get_value('fields/0', required_type='Input')
    field = VectorField(sim, field_inp)

    def verify(f, t, A):
        print(t, A)
        check_vector_value_histogram(f[0].vector(), {t + A: 125})
        check_vector_value_histogram(f[1].vector(), {t * A: 125})
        check_vector_value_histogram(f[2].vector(), {t * A + A: 125})

    # t = 0
    t, A = 0, 1
    f = field.get_variable('u')
    verify(f, t, A)

    # t = 1
    t, A = 1, 1
    sim.time = t
    sim.input.set_value('user_code/constants/A', A)
    field.update(1, t, 1.0)
    verify(f, t, A)

    # t = 2
    t, A = 2, 10
    sim.time = t
    sim.input.set_value('user_code/constants/A', A)
    field.update(2, t, 1.0)
    verify(f, t, A)
Ejemplo n.º 12
0
def test_scalar_field():
    sim = Simulation()
    sim.input.read_yaml(yaml_string=INP)
    mesh = dolfin.UnitCubeMesh(2, 2, 2)
    sim.set_mesh(mesh)

    field_inp = sim.input.get_value('fields/1', required_type='Input')
    field = ScalarField(sim, field_inp)

    # t = 0
    t, A = 0, 1
    f = field.get_variable('rho')
    check_vector_value_histogram(f.vector(), {t * A + A: 125})

    # t = 1
    t, A = 1, 1
    sim.time = t
    field.update(1, t, 1.0)
    check_vector_value_histogram(f.vector(), {t * A + A: 125})

    # t = 2
    t, A = 2, 10
    sim.time = t
    sim.input.set_value('user_code/constants/A', A)
    field.update(2, t, 1.0)
    check_vector_value_histogram(f.vector(), {t * A + A: 125})
Ejemplo n.º 13
0
def test_restart_file_io(tmpdir_factory):
    dir_name = mpi_tmpdir(tmpdir_factory, 'test_restart_file_io')
    prefix = os.path.join(dir_name, 'ocellaris')

    sim = Simulation()
    sim.input.read_yaml(yaml_string=BASE_INPUT_PHI)
    sim.input.set_value('output/prefix', prefix)
    sim.input.set_value('time/tstart', 42.0)
    sim.input.set_value('time/dt', 1.0)
    setup_simulation(sim)

    # Fill in the phi function
    phi = sim.data['phi']
    phi_arr = phi.vector().get_local()
    phi_arr[:] = numpy.random.rand(*phi_arr.shape)
    phi.vector().set_local(phi_arr)
    phi.vector().apply('insert')

    # Save restart file
    file_name = sim.io.write_restart_file()
    assert file_name.startswith(prefix)

    # Load input from restart file
    sim2 = Simulation()
    sim2.io.load_restart_file_input(file_name)
    assert sim2.input.get_value('time/tstart') == 42.0
    assert str(sim.input) == str(sim2.input)

    # Load phi from restart file
    setup_simulation(sim2)
    sim2.io.load_restart_file_results(file_name)
    phi2 = sim2.data['phi']
    phi2_arr = phi2.vector().get_local()

    # FIXME: make tests work in parallel
    if sim2.data['mesh'].mpi_comm().size == 1:
        assert all(phi_arr == phi2_arr)
        assert sim.data['mesh'].hash() == sim2.data['mesh'].hash()
Ejemplo n.º 14
0
def mk_limiter(degree, dim, use_cpp, comm_self=False):
    dolfin.parameters['ghost_mode'] = 'shared_vertex'

    sim = Simulation()
    sim.input.read_yaml(yaml_string=BASE_INPUT)

    if dim == 2:
        sim.input.set_value('mesh/type', 'Rectangle')
        sim.input.set_value('mesh/Nx', 10)
        sim.input.set_value('mesh/Ny', 10)
        cpp = 'A + A*sin(B*pi*x[0])*sin(B*pi*x[1])'
    else:
        sim.input.set_value('mesh/type', 'Box')
        sim.input.set_value('mesh/Nx', 5)
        sim.input.set_value('mesh/Ny', 5)
        sim.input.set_value('mesh/Nz', 5)
        cpp = 'A + A*sin(B*pi*x[0])*sin(B*pi*x[1])*sin(B*pi*x[2])'

    # Create simulation with mesh and the phi function
    sim.input.set_value('mesh/mpi_comm', 'SELF' if comm_self else 'WORLD')
    sim.input.set_value('solver/polynomial_degree', degree)
    sim.input.set_value('output/stdout_enabled', False)
    setup_simulation(sim)
    phi = sim.data['phi']
    V = phi.function_space()

    # Create a phi field with some jumps
    e = dolfin.Expression(cpp, element=V.ufl_element(), A=0.5, B=2.0)
    phi.interpolate(e)
    arr = phi.vector().get_local()
    arr[arr > 0.8] = 2 * 0.8 - arr[arr > 0.8]
    arr[arr < 0.2] = 0.5
    phi.vector().set_local(arr)
    phi.vector().apply('insert')

    # Create slope limiter
    sim.input.set_value('slope_limiter/phi/method', 'HierarchicalTaylor')
    sim.input.set_value('slope_limiter/phi/use_cpp', use_cpp)
    sim.input.set_value('slope_limiter/phi/skip_boundaries', [])
    lim = SlopeLimiter(sim, 'phi', phi)

    if True:
        from matplotlib import pyplot

        pyplot.figure()
        patches = dolfin.plot(phi)
        pyplot.colorbar(patches)
        pyplot.savefig('ht_lim_phi.png')

    return phi, lim
Ejemplo n.º 15
0
def test_ensure_path():
    fn = get_test_file_name('base.inp')
    sim = Simulation()
    sim.input.read_yaml(fn)

    a = sim.input.ensure_path('user_code/constants')
    assert 'A' in a

    b = sim.input.ensure_path('does_not_exist')
    assert len(b) == 0
    assert 'does_not_exist' in sim.input

    c = sim.input.ensure_path('does_not_exist/c')
    assert len(c) == 0
    assert len(sim.input.get_value('does_not_exist')) == 1
Ejemplo n.º 16
0
def test_import_module():
    # A randomly selected script that does nothing at import time
    dummy_mod = 'plot_reports'
    assert dummy_mod not in sys.modules

    # Account for current working directory
    inp = INPUT_MODULE_IMPORT % os.path.join(TEST_DIR, '..')

    sim = Simulation()
    sim.input.read_yaml(yaml_string=inp)
    success = setup_simulation(sim)
    assert success

    assert dummy_mod in sys.modules
    sys.modules.pop(dummy_mod)
Ejemplo n.º 17
0
def test_isoline_circle(degree):
    sim = Simulation()
    sim.input.read_yaml(yaml_string=ISO_INPUT)
    sim.input.set_value('multiphase_solver/polynomial_degree_colour', degree)
    sim.input.set_value('mesh/Nx', 10)
    sim.input.set_value('mesh/Ny', 10)
    sim.input.set_value(
        'initial_conditions/cp/cpp_code', '1.1*pow(pow(x[0] - 0.5, 2) + pow(x[1] - 0.5, 2), 0.5)'
    )
    setup_simulation(sim)

    sim.data['c'].assign(sim.data['cp'])
    probe = sim.probes['free_surface']
    lines = probe.run(force_active=True)

    if False:
        from matplotlib import pyplot

        c = dolfin.plot(sim.data['c'])
        pyplot.colorbar(c)
        for x, y in lines:
            pyplot.plot(x, y)
        pyplot.savefig('test_isoline_circle_%d.png' % degree)
        pyplot.close()

    print(probe.name, probe.field_name, probe.value)
    print(len(lines))
    for x, y in lines:
        # Check that the radius is constant
        r = ((x - 0.5) ** 2 + (y - 0.5) ** 2) ** 0.5
        print('x', x)
        print('y', y)
        print('dr', r - 0.5 / 1.1)
        assert all(abs(r - 0.5 / 1.1) < 5e-3)

        # Check that the line is clockwise or counter clockwise
        # for all segments, no going back and forth
        theta = numpy.arctan2(y - 0.5, x - 0.5) * 180 / numpy.pi
        theta[theta < 0] += 360
        tdt = numpy.diff(theta)
        tdt2 = tdt[abs(tdt) < 340]
        print('dt', tdt)
        assert all(tdt2 > 0) or all(tdt2 < 0)

    if sim.ncpu == 1:
        # The iso surface code is not written for full parallel support
        assert len(lines) == 1
        assert x[0] == x[-1] and y[0] == y[-1], "The loop should be closed"
Ejemplo n.º 18
0
def test_plot_io_3D(iotype, tmpdir_factory):
    dir_name = mpi_tmpdir(tmpdir_factory, 'test_plot_io_3D')
    prefix = os.path.join(dir_name, 'ocellaris')
    N = 4

    sim = Simulation()
    sim.input.read_yaml(yaml_string=BASE_INPUT_VELPRES)
    sim.input.set_value('output/prefix', prefix)
    sim.input.set_value('user_code/constants/N', N)
    setup_simulation(sim)
    sim.io.setup()  # Normally called in sim._at_start_of_simulation()

    for d in range(3):
        sim.data['u%d' % d].assign(sim.data['up%d' % d])

    ncell = N**3 * 6
    npoint = ncell * 10

    if iotype == 'vtk':
        file_name = sim.io.lvtk.write()
        assert file_name.startswith(prefix)
        assert file_name.endswith('.vtk')
        assert os.path.isfile(file_name)

        with open(file_name, 'rt') as f:
            for line in f:
                if line.startswith('POINTS'):
                    pline = line
                elif line.startswith('CELLS'):
                    cline = line
                elif line.startswith('CELL_TYPES'):
                    tline = line
                elif line.startswith('POINT_DATA'):
                    dline = line
        assert pline.strip() == 'POINTS %d float' % npoint
        assert cline.strip() == 'CELLS %d %d' % (ncell, ncell * 11)
        assert tline.strip() == 'CELL_TYPES %d' % ncell
        assert dline.strip() == 'POINT_DATA %d' % (ncell * 10)

    elif iotype == 'xdmf':
        file_name = sim.io.xdmf.write()
        assert file_name.startswith(prefix)
        assert file_name.endswith('.xdmf')
        assert os.path.isfile(file_name)
Ejemplo n.º 19
0
def test_mark_cell_layers():
    sim = Simulation()
    sim.input.read_yaml(yaml_string=BASE_INPUT)
    setup_simulation(sim)
    mesh = sim.data['mesh']
    Vp = sim.data['Vp']

    # No named == all
    cells = mark_cell_layers(sim, Vp)
    for cid in cells:
        cell = dolfin.Cell(mesh, cid)
        mp = cell.midpoint()[:]
        assert mp[0] < 0.1 or mp[0] > 0.9 or mp[1] < 0.1 or mp[1] > 0.9
    assert mpi_int_sum(len(cells)) == 20 * 2 + 16 * 2

    # Test all
    cells = mark_cell_layers(sim, Vp, named_boundaries=['all'])
    for cid in cells:
        cell = dolfin.Cell(mesh, cid)
        mp = cell.midpoint()[:]
        assert mp[0] < 0.1 or mp[0] > 0.9 or mp[1] < 0.1 or mp[1] > 0.9
    assert mpi_int_sum(len(cells)) * 2 + 16 * 2

    # Test only left side
    cells = mark_cell_layers(sim, Vp, named_boundaries=['left'])
    for cid in cells:
        cell = dolfin.Cell(mesh, cid)
        mp = cell.midpoint()[:]
        assert mp[0] < 0.1
    assert mpi_int_sum(len(cells)) == 20

    cells = mark_cell_layers(sim, Vp, named_boundaries=['not left'])
    for cid in cells:
        cell = dolfin.Cell(mesh, cid)
        mp = cell.midpoint()[:]
        assert mp[0] > 0.9 or mp[1] < 0.1 or mp[1] > 0.9
    assert mpi_int_sum(len(cells)) == 20 * 1 + 18 * 2

    cells = mark_cell_layers(sim, Vp, named_boundaries=['left', 'not left'])
    assert mpi_int_sum(len(cells)) == 20 * 2 + 16 * 2
Ejemplo n.º 20
0
def test_dirichlet_bcs_scalar_mms(method):
    "Test inhomogenous coded Dirichlet BCs using a Poisson solver"
    sim = Simulation()
    sim.input.read_yaml(yaml_string=BASE_INPUT)
    sim.input.set_value('boundary_conditions', [{}])
    sim.input.set_value('boundary_conditions/0/name', 'all walls')
    sim.input.set_value('boundary_conditions/0/selector', 'code')
    sim.input.set_value('boundary_conditions/0/inside_code', 'on_boundary')

    # Get analytical expressions
    cphi, _, _, cf = mms_case()
    sim.input.set_value('solver/source', cf)

    # Setup the boundary conditions to test
    if method == 'py_eval':
        sim.input.set_value('boundary_conditions/0/phi/type', 'CodedValue')
        sim.input.set_value('boundary_conditions/0/phi/code', cphi)
    elif method == 'py_exec':
        sim.input.set_value('boundary_conditions/0/phi/type', 'CodedValue')
        sim.input.set_value('boundary_conditions/0/phi/code', 'value[0] = ' + cphi)
    elif method == 'cpp':
        sim.input.set_value('boundary_conditions/0/phi/type', 'CppCodedValue')
        sim.input.set_value('boundary_conditions/0/phi/cpp_code', cphi)

    # Run Ocellaris
    setup_simulation(sim)
    run_simulation(sim)

    # The numeric (phih) and analytic (phia) solution functions
    Vphi = sim.data['Vphi']
    phi = dolfin.Expression(cphi, degree=5)
    phih = sim.data['phi']
    phia = dolfin.interpolate(phi, Vphi)

    # Compute relative error and check that it is reasonable
    phidiff = dolfin.errornorm(phi, phih)
    analytical = dolfin.norm(phia)
    relative_error = phidiff / analytical
    print('RELATIVE ERROR IS %.3f' % relative_error)
    assert relative_error < 0.074
Ejemplo n.º 21
0
def test_isoline_horizontal(degree):
    sim = Simulation()
    sim.input.read_yaml(yaml_string=ISO_INPUT)
    sim.input.set_value('multiphase_solver/polynomial_degree_colour', degree)
    setup_simulation(sim)
    probe = sim.probes['free_surface']

    # Initial value with sharp interface at x[1] == 0.5
    Vc = sim.data['Vc']
    c = sim.data['c']
    dm = Vc.dofmap()
    arr = c.vector().get_local()
    for cell in dolfin.cells(sim.data['mesh']):
        cell_value = 1 if cell.midpoint().y() < 0.5 else 0
        for dof in dm.cell_dofs(cell.index()):
            arr[dof] = cell_value
    c.vector().set_local(arr)
    c.vector().apply('insert')

    lines = probe.run(force_active=True)
    print('\nDegree:', degree, 'Vcdim:', Vc.dim())
    print(probe.name, probe.field_name, probe.value)
    print(len(lines))

    if sim.ncpu > 1:
        raise pytest.skip()

    for x, y in lines:
        print('x', x, '\ny', y)
        assert all(abs(y - 0.5) < 1e-12)

        # Results should be in sorted order
        xdx = numpy.diff(x)
        assert all(xdx > 0) or all(xdx < 0)

    assert len(lines) == 1
Ejemplo n.º 22
0
def run_and_calculate_error(N, dt, tmax, polydeg_rho, last=False):
    """
    Run Ocellaris and return L2 & H1 errors in the last time step
    """
    say(N, dt, tmax, polydeg_rho)

    # Setup and run simulation
    sim = Simulation()
    sim.input.read_yaml('transport.inp')

    mesh_type = sim.input.get_value('mesh/type')
    if mesh_type == 'XML':
        # Create unstructured mesh with gmsh
        cmd1 = [
            'gmsh', '-string',
            'lc = %f;' % (3.14 / N), '-o',
            'disc_%d.msh' % N, '-2',
            '../convergence-variable-density-disk/disc.geo'
        ]
        cmd2 = ['dolfin-convert', 'disc_%d.msh' % N, 'disc.xml']
        with open('/dev/null', 'w') as devnull:
            for cmd in (cmd1, cmd2):
                say(' '.join(cmd))
                if ISROOT:
                    subprocess.call(cmd, stdout=devnull, stderr=devnull)
    elif mesh_type == 'UnitDisc':
        sim.input.set_value('mesh/N', N // 2)
    else:
        sim.input.set_value('mesh/Nx', N)
        sim.input.set_value('mesh/Ny', N)

    sim.input.set_value('time/dt', dt)
    sim.input.set_value('time/tmax', tmax)
    sim.input.set_value('multiphase_solver/polynomial_degree_rho', polydeg_rho)
    sim.input.set_value('output/stdout_enabled', False)

    say('Running with multiphase solver %s ...' %
        (sim.input.get_value('multiphase_solver/type')))
    t1 = time.time()
    setup_simulation(sim)
    run_simulation(sim)
    duration = time.time() - t1
    say('DONE')

    # Interpolate the analytical solution to the same function space
    Vu = sim.data['Vu']
    Vp = sim.data['Vp']
    Vr = sim.data['Vrho']
    polydeg_r = Vr.ufl_element().degree()
    vals = dict(t=sim.time, dt=sim.dt)
    rho_e = dolfin.Expression(
        sim.input.get_value('initial_conditions/rho_p/cpp_code'),
        degree=polydeg_r,
        **vals)
    rho_a = dolfin.project(rho_e, Vr)

    rho_e.t = 0
    rho_0 = dolfin.project(rho_e, Vr)

    # Calculate L2 errors
    err_rho = calc_err(sim.data['rho'], rho_a)

    # Calculate H1 errors
    err_rho_H1 = calc_err(sim.data['rho'], rho_a, 'H1')

    mesh = sim.data['mesh']
    n = dolfin.FacetNormal(mesh)

    reports = sim.reporting.timestep_xy_reports
    say('Num time steps:', sim.timestep)
    say('Num cells:', mesh.num_cells())
    say('Co_max:', numpy.max(reports['Co']))
    say('rho_min went from %r to %r' %
        (reports['min(rho)'][0], reports['min(rho)'][-1]))
    say('rho_max went from %r to %r' %
        (reports['max(rho)'][0], reports['max(rho)'][-1]))
    m0, m1 = reports['mass'][0], reports['mass'][-1]
    say('mass error %.3e (%.3e)' % (m1 - m0, (m1 - m0) / m0))
    say('vel compat error %.3e' %
        dolfin.assemble(dolfin.dot(sim.data['u'], n) * dolfin.ds))
    int_p = dolfin.assemble(sim.data['p'] * dolfin.dx)
    say('p*dx', int_p)
    div_u_Vp = abs(
        dolfin.project(dolfin.div(sim.data['u']),
                       Vp).vector().get_local()).max()
    say('div(u)|Vp', div_u_Vp)
    div_u_Vu = abs(
        dolfin.project(dolfin.div(sim.data['u']),
                       Vu).vector().get_local()).max()
    say('div(u)|Vu', div_u_Vu)
    Vdg0 = dolfin.FunctionSpace(mesh, "DG", 0)
    div_u_DG0 = abs(
        dolfin.project(dolfin.div(sim.data['u']),
                       Vdg0).vector().get_local()).max()
    say('div(u)|DG0', div_u_DG0)
    Vdg1 = dolfin.FunctionSpace(mesh, "DG", 1)
    div_u_DG1 = abs(
        dolfin.project(dolfin.div(sim.data['u']),
                       Vdg1).vector().get_local()).max()
    say('div(u)|DG1', div_u_DG1)

    isoparam = mesh.ufl_coordinate_element().degree() > 1
    if last and (not isoparam
                 or sim.input.get_value('mesh/type') == 'UnitDisc'):
        # Plot the results
        for fa, name in ((rho_a, 'rho'), ):
            fh = sim.data[name]
            if isoparam:
                # Bug in matplotlib plotting for isoparametric elements
                mesh2 = dolfin.UnitDiscMesh(dolfin.MPI.comm_world, N // 2, 1,
                                            2)
                ue = fa.function_space().ufl_element()
                V2 = dolfin.FunctionSpace(mesh2, ue.family(), ue.degree())
                fa2, fh2 = dolfin.Function(V2), dolfin.Function(V2)
                fa2.vector().set_local(fa.vector().get_local())
                fh2.vector().set_local(fh.vector().get_local())
                fa, fh = fa2, fh2
            plot(fh - fa, name + ' diff', '%g_%g_%s_diff' % (N, dt, name))
            plot(fa, name + ' analytical',
                 '%g_%g_%s_analytical' % (N, dt, name))
            plot(fh, name + ' numerical', '%g_%g_%s_numerical' % (N, dt, name))
            plot(rho_0, name + ' initial', '%g_%g_%s_initial' % (N, dt, name))

    hmin = mesh.hmin()
    return err_rho, err_rho_H1, hmin, dt, duration
Ejemplo n.º 23
0
def plot_backward_facing_step(res):
    u = df.as_vector([res['u0'], res['u1']])
    V = u[0].function_space()
    mesh = V.mesh()

    ############################################################################
    # Get some meta data
    sim = Simulation()
    sim.input.read_yaml(yaml_string=res['input'])
    Re = sim.input.get_value('user_code/constants/Re', required_type='float')
    time = res['time']

    ############################################################################
    # Find the length X1 of primary recirculating bubble

    x1_ypos = -0.99 * H2
    xf, _, _, f = get_probe_values(u[0], [0, x1_ypos, 0], [L2, x1_ypos, 0], 200)
    x1_c0 = get_zero_crossings(xf, f)
    print(x1_c0)

    ############################################################################
    # Find the inflow profile

    x_inflow = -1.5 * H1
    _, y_inflow, _, u0_inflow = get_probe_values(
        u[0], [x_inflow, 0, 0], [x_inflow, H1, 0], 20
    )

    ############################################################################
    # Refine the mesh and get a triangluated stream function
    for _ in range(2):
        old = mesh, V
        mesh = df.refine(mesh)
        V = df.FunctionSpace(mesh, V.ufl_element())
        df.parameters['allow_extrapolation'] = True
        try:
            u0 = df.interpolate(u[0], V)
            u1 = df.interpolate(u[1], V)
            u = df.as_vector([u0, u1])
        except Exception:
            mesh, V = old
            u0, u1 = u[0], u[1]
            print('Refining failed ------------------------------')
            break
        df.parameters['allow_extrapolation'] = False

    sf = StreamFunction(u, degree=V.ufl_element().degree())
    sf.compute()

    levels = get_probe_values(
        sf.psi, [1.5 * H2, -0.5 * H2, 0], [H2, H1 * 0.99, 0], N_levels
    )[-1]
    levels2 = []
    for xi, _idx, _upcrossing in x1_c0:
        # Add stream function values at upcrossing locations
        if xi - 0.3 > 0:
            levels2.append(get_probe_value(sf.psi, (xi - 0.3, x1_ypos, 0)))
        if xi + 0.1 < L2:
            levels2.append(get_probe_value(sf.psi, (xi + 0.1, x1_ypos, 0)))
    if levels2:
        levels = numpy.concatenate((levels, levels2))
    levels.sort()

    coords = mesh.coordinates()
    triangles = []
    for cell in df.cells(mesh):
        cell_vertices = cell.entities(0)
        triangles.append(cell_vertices)
    triangulation = Triangulation(coords[:, 0], coords[:, 1], triangles)
    Z = sf.psi.compute_vertex_values()

    ############################################################################
    # Plot streamlines and velocity distributions

    fig = pyplot.figure(figsize=(15, 2.5))
    ax = fig.add_subplot(111)
    ax.plot([-L1, -L1, 0, 0, L2, L2, -L1], [H1, 0, 0, -H2, -H2, H1, H1], 'k')

    # ax.triplot(triangulation, color='#000000', alpha=0.5, lw=0.25)
    ax.tricontour(
        triangulation, Z, levels, linestyles='solid', colors='#0000AA', linewidths=0.5
    )
    ax.plot(x_inflow + u0_inflow, y_inflow, 'm')
    ax.plot(x_inflow - 6 * (y_inflow - 1) * y_inflow, y_inflow, 'k.', ms=4)

    # ax2 = fig.add_subplot(212)
    # ax2.plot(xf, f)
    # ax2.set_xlim(-L1, L2)

    for xi, _idx, _upcrossing in x1_c0:
        ax.plot(xi, x1_ypos, 'rx')
        # ax.text(xi, x1_ypos+0.1, 'X1=%.3f' % x1, backgroundcolor='white')

    ax.set_title(
        'Re = %g, t = %g, xi = %s' % (Re, time, ', '.join('%.3f' % e[0] for e in x1_c0))
    )
    fig.tight_layout()
Ejemplo n.º 24
0
def test_robin_bcs_scalar_mms(bcs, b):
    """
    Test Robin BCs using a Poisson solver to solve

      -∇⋅∇φ = f

    where φ = 1 + x and hence f = 0. We use Neumann
    BCs n⋅∇φ = 0 on the horizontal walls and Robin
    BCs on the vertical walls
    """
    sim = Simulation()
    sim.input.read_yaml(yaml_string=BASE_INPUT)

    # Create boundary regions
    sim.input.set_value('boundary_conditions', [{}, {}, {}])
    sim.input.set_value('boundary_conditions/0/name', 'vertical wall x=0')
    sim.input.set_value('boundary_conditions/0/selector', 'code')
    sim.input.set_value(
        'boundary_conditions/0/inside_code', 'on_boundary and (x[0] < 1e-6 or x[0] > 1 - 1e-6)'
    )
    sim.input.set_value('boundary_conditions/1/name', 'vertical walls x=1')
    sim.input.set_value('boundary_conditions/1/selector', 'code')
    sim.input.set_value('boundary_conditions/1/inside_code', 'on_boundary and x[0] > 1 - 1e-6')
    sim.input.set_value('boundary_conditions/2/name', 'horizontal walls')
    sim.input.set_value('boundary_conditions/2/selector', 'code')
    sim.input.set_value(
        'boundary_conditions/2/inside_code', 'on_boundary and (x[1] < 1e-6 or x[1] > 1 - 1e-6)'
    )

    # Setup the boundary conditions to test
    if bcs == 'robin':
        sim.input.set_value('boundary_conditions/0/phi/type', 'ConstantRobin')
        sim.input.set_value('boundary_conditions/0/phi/blend', b)
        sim.input.set_value('boundary_conditions/0/phi/dval', 1.0)
        sim.input.set_value('boundary_conditions/0/phi/nval', -1.0)
        sim.input.set_value('boundary_conditions/1/phi/type', 'ConstantRobin')
        sim.input.set_value('boundary_conditions/1/phi/blend', b)
        sim.input.set_value('boundary_conditions/1/phi/dval', 2.0)
        sim.input.set_value('boundary_conditions/1/phi/nval', 1.0)
        sim.input.set_value('boundary_conditions/2/phi/type', 'ConstantGradient')
        sim.input.set_value('boundary_conditions/2/phi/value', 0.0)
    elif bcs == 'neumann':
        sim.input.set_value('boundary_conditions/0/phi/type', 'ConstantGradient')
        sim.input.set_value('boundary_conditions/0/phi/value', -1.0)
        sim.input.set_value('boundary_conditions/1/phi/type', 'ConstantGradient')
        sim.input.set_value('boundary_conditions/1/phi/value', 1.0)

    # RHS
    sim.input.set_value('solver/source', '2*pi*pi*(pow(sin(x[0]*pi), 2) - pow(cos(x[0]*pi), 2))')

    # Run Ocellaris
    setup_simulation(sim)
    run_simulation(sim)

    # The numeric (phih) and analytic (phia) solution functions
    cphi = '1.0 + x[0] + pow(sin(x[0]*pi), 2)'
    Vphi = sim.data['Vphi']
    phi = dolfin.Expression(cphi, degree=5)
    phih = sim.data['phi']
    phia = dolfin.interpolate(phi, Vphi)

    # Correct the constant offset due to how the null space is handledFalse
    if bcs == 'neumann':
        correct_constant_offset(sim, phih, phia)

    # Plot to file for debugging
    # debug_phi_plot(phia, phih, 'test_robin_bcs_scalar_mms_%s.png' % bcs)

    # Compute relative error and check that it is reasonable
    phidiff = dolfin.errornorm(phi, phih)
    analytical = dolfin.norm(phia)
    relative_error = phidiff / analytical
    print('RELATIVE ERROR IS %.3f' % relative_error)
    assert relative_error < 0.015  # Expect 0.0139 with Robin
Ejemplo n.º 25
0
def run_and_calculate_error(N, dt, tmax, polydeg_u, polydeg_p, modifier=None):
    """
    Run Ocellaris and return L2 & H1 errors in the last time step
    """
    say(N, dt, tmax, polydeg_u, polydeg_p)

    # Setup and run simulation
    sim = Simulation()
    sim.input.read_yaml('kovasznay.inp')

    sim.input.set_value('mesh/Nx', N)
    sim.input.set_value('mesh/Ny', N)
    sim.input.set_value('time/dt', dt)
    sim.input.set_value('time/tmax', tmax)
    sim.input.set_value('solver/polynomial_degree_velocity', polydeg_u)
    sim.input.set_value('solver/polynomial_degree_pressure', polydeg_p)
    sim.input.set_value('output/stdout_enabled', False)

    if modifier:
        modifier(sim)  # Running regression tests, modify some input params

    say('Running ...')
    try:
        t1 = time.time()
        setup_simulation(sim)
        run_simulation(sim)
        duration = time.time() - t1
    except KeyboardInterrupt:
        raise
    except BaseException as e:
        raise
        import traceback

        traceback.print_exc()
        return [1e10] * 6 + [1, dt, time.time() - t1]
    say('DONE')
    tmax_warning = ' <------ NON CONVERGENCE!!' if sim.time > tmax - dt / 2 else ''

    # Interpolate the analytical solution to the same function space
    Vu = sim.data['Vu']
    Vp = sim.data['Vp']
    lambda_ = sim.input.get_value('user_code/constants/LAMBDA',
                                  required_type='float')
    u0e = dolfin.Expression(
        sim.input.get_value('boundary_conditions/0/u/cpp_code/0'),
        LAMBDA=lambda_,
        degree=polydeg_u)
    u1e = dolfin.Expression(
        sim.input.get_value('boundary_conditions/0/u/cpp_code/1'),
        LAMBDA=lambda_,
        degree=polydeg_u)
    pe = dolfin.Expression(
        '-0.5*exp(LAMBDA*2*x[0]) + 1/(4*LAMBDA)*(exp(2*LAMBDA) - 1.0)',
        LAMBDA=lambda_,
        degree=polydeg_p,
    )
    u0a = dolfin.project(u0e, Vu)
    u1a = dolfin.project(u1e, Vu)
    pa = dolfin.project(pe, Vp)

    # Correct pa (we want to be spot on, not close)
    int_pa = dolfin.assemble(pa * dolfin.dx)
    vol = dolfin.assemble(dolfin.Constant(1.0) * dolfin.dx(domain=Vp.mesh()))
    pa.vector()[:] -= int_pa / vol

    # Calculate L2 errors
    err_u0 = calc_err(sim.data['u0'], u0a)
    err_u1 = calc_err(sim.data['u1'], u1a)
    err_p = calc_err(sim.data['p'], pa)

    # Calculate H1 errors
    err_u0_H1 = calc_err(sim.data['u0'], u0a, 'H1')
    err_u1_H1 = calc_err(sim.data['u1'], u1a, 'H1')
    err_p_H1 = calc_err(sim.data['p'], pa, 'H1')

    say('Number of time steps:', sim.timestep, tmax_warning)
    loglines = sim.log.get_full_log().split('\n')
    say('Num inner iterations:',
        sum(1 if 'Inner iteration' in line else 0 for line in loglines))
    say('max(ui_new-ui_prev)',
        sim.reporting.get_report('max(ui_new-ui_prev)')[1][-1])
    int_p = dolfin.assemble(sim.data['p'] * dolfin.dx)
    say('p*dx', int_p)
    say('pa*dx', dolfin.assemble(pa * dolfin.dx(domain=Vp.mesh())))
    div_u_Vp = abs(
        dolfin.project(dolfin.div(sim.data['u']),
                       Vp).vector().get_local()).max()
    say('div(u)|Vp', div_u_Vp)
    div_u_Vu = abs(
        dolfin.project(dolfin.div(sim.data['u']),
                       Vu).vector().get_local()).max()
    say('div(u)|Vu', div_u_Vu)
    Vdg0 = dolfin.FunctionSpace(sim.data['mesh'], "DG", 0)
    div_u_DG0 = abs(
        dolfin.project(dolfin.div(sim.data['u']),
                       Vdg0).vector().get_local()).max()
    say('div(u)|DG0', div_u_DG0)
    Vdg1 = dolfin.FunctionSpace(sim.data['mesh'], "DG", 1)
    div_u_DG1 = abs(
        dolfin.project(dolfin.div(sim.data['u']),
                       Vdg1).vector().get_local()).max()
    say('div(u)|DG1', div_u_DG1)

    if False:
        # Plot the results
        for fa, name in ((u0a, 'u0'), (u1a, 'u1'), (pa, 'p')):
            p1 = dolfin.plot(sim.data[name] - fa,
                             title='%s_diff' % name,
                             key='%s_diff' % name)
            p2 = dolfin.plot(fa, title=name + ' analytical', key=name)
            p1.write_png('%g_%g_%s_diff' % (N, dt, name))
            p2.write_png('%g_%g_%s' % (N, dt, name))
        dolfin.interactive()

    from numpy import argmax

    for d in range(2):
        up = sim.data['up%d' % d]
        upp = sim.data['upp%d' % d]

        V = up.function_space()
        coords = V.tabulate_dof_coordinates().reshape((-1, 2))

        up.vector()[:] -= upp.vector()
        diff = abs(up.vector().get_local())
        i = argmax(diff)
        say('Max difference in %d direction is %.4e at %r' %
            (d, diff[i], coords[i]))

        if 'uppp%d' % d in sim.data:
            uppp = sim.data['uppp%d' % d]
            upp.vector()[:] -= uppp.vector()
            diffp = abs(upp.vector().get_local())
            ip = argmax(diffp)
            say('Prev max diff. in %d direction is %.4e at %r' %
                (d, diffp[ip], coords[ip]))

    if False and N == 24:
        # dolfin.plot(sim.data['u0'], title='u0')
        # dolfin.plot(sim.data['u1'], title='u1')
        # dolfin.plot(sim.data['p'], title='p')
        # dolfin.plot(u0a, title='u0a')
        # dolfin.plot(u1a, title='u1a')
        # dolfin.plot(pa, title='pa')
        plot_err(sim.data['u0'], u0a, title='u0a - u0')
        plot_err(sim.data['u1'], u1a, title='u1a - u1')
        plot_err(sim.data['p'], pa, 'pa - p')

        # plot_err(sim.data['u0'], u0a, title='u0a - u0')
        dolfin.plot(sim.data['up0'], title='up0 - upp0')
        dolfin.plot(sim.data['upp0'], title='upp0 - uppp0')

        # plot_err(sim.data['u1'], u1a, title='u1a - u1')
        dolfin.plot(sim.data['up1'], title='up1 - upp1')
        # dolfin.plot(sim.data['upp1'], title='upp1 - uppp1')

    hmin = sim.data['mesh'].hmin()
    return err_u0, err_u1, err_p, err_u0_H1, err_u1_H1, err_p_H1, hmin, dt, duration
Ejemplo n.º 26
0
def test_slip_length_robin_bcs_scalar_mms(slip_length, method):
    """
    Test slip length Robin BCs using a Poisson solver to solve

      -∇⋅∇φ = f

    where φ = (-6x² + 6x + 6𝛿)/(6𝛿  - 1) and hence f = 12/(6𝛿  - 1). 

    We use Neumann BCs n⋅∇φ = 0 on the horizontal walls and Navier's
    slip length boundary condition on the vertical walls. The selected
    analytical solution is such that for any slip length 𝛿 the average
    value of φ is 1.0

    This mimics a flow profile going vertically in a 1.0 wide channel
    """
    sim = Simulation()
    sim.input.read_yaml(yaml_string=BASE_INPUT)

    # Create boundary regions
    sim.input.set_value('boundary_conditions', [{}, {}])
    sim.input.set_value('boundary_conditions/0/name', 'vertical walls')
    sim.input.set_value('boundary_conditions/0/selector', 'code')
    sim.input.set_value(
        'boundary_conditions/0/inside_code', 'on_boundary and (x[0] < 1e-6 or x[0] > 1 - 1e-6)'
    )
    sim.input.set_value('boundary_conditions/1/name', 'horizontal walls')
    sim.input.set_value('boundary_conditions/1/selector', 'code')
    sim.input.set_value(
        'boundary_conditions/1/inside_code', 'on_boundary and (x[1] < 1e-6 or x[1] > 1 - 1e-6)'
    )

    # Vertical wall BCs
    if method == 'Constant':
        sim.input.set_value('boundary_conditions/0/phi/type', 'SlipLength')
        sim.input.set_value('boundary_conditions/0/phi/slip_length', slip_length)
    elif method == 'C++':
        sim.input.set_value('boundary_conditions/0/phi/type', 'SlipLength')
        sim.input.set_value('boundary_conditions/0/phi/slip_length', repr(slip_length))
    else:
        sim.input.set_value('boundary_conditions/0/phi/type', 'InterfaceSlipLength')
        sim.input.set_value('boundary_conditions/0/phi/slip_length', slip_length)
        sim.input.set_value('boundary_conditions/0/phi/slip_factor_function', 'fs_zone/phi')

        sim.input.set_value('fields', [{}])
        sim.input.set_value('fields/0/name', 'fs_zone')
        sim.input.set_value('fields/0/type', 'FreeSurfaceZone')
        sim.input.set_value('fields/0/radius', 0.5)

        # Create dummy scalar field
        sim.input.set_value('multiphase_solver/type', 'BlendedAlgebraicVOF')
        sim.input.set_value('multiphase_solver/function_space_colour', 'DG')
        sim.input.set_value('multiphase_solver/polynomial_degree_colour', 0)
        sim.input.set_value('initial_conditions/cp/cpp_code', 'x[1] < 0.5 ? 1.0 : 0.0')

        sim.input.set_value('physical_properties/rho0', 1.0)
        sim.input.set_value('physical_properties/rho1', 1.0)
        sim.input.set_value('physical_properties/nu0', 1.0)
        sim.input.set_value('physical_properties/nu1', 1.0)

        sim.input.set_value('multiphase_solver/project_uconv_dgt0', False)
        sim.data['u_conv'] = dolfin.as_vector([0, 0])
        sim.data['dt'] = dolfin.Constant(1.0)

    # Horizontal wall BCs
    sim.input.set_value('boundary_conditions/1/phi/type', 'ConstantGradient')
    sim.input.set_value('boundary_conditions/1/phi/value', 0.0)

    # RHS
    sim.input.set_value('solver/source', '12/(6*𝛿  - 1.0)'.replace('𝛿', repr(slip_length)))

    # Run Ocellaris
    setup_simulation(sim)
    run_simulation(sim)

    # The numeric (phih) and analytic (phia) solution functions
    cphi = '(-6*x[0]*x[0] + 6*x[0] + 6*𝛿)/(6*𝛿  - 1.0)'.replace('𝛿', repr(slip_length))
    Vphi = sim.data['Vphi']
    phi = dolfin.Expression(cphi, degree=5)
    phih = sim.data['phi']
    phia = dolfin.interpolate(phi, Vphi)

    # Plot to file for debugging
    # debug_phi_plot(phi, phia, phih, 'test_slip_length_bcs_scalar_mms_%g.png' % slip_length)

    # Compute relative error and check that it is reasonable
    phidiff = dolfin.errornorm(phi, phih)
    analytical = dolfin.norm(phia)
    relative_error = phidiff / analytical
    print('RELATIVE ERROR IS %.4f for 𝛿=%r' % (relative_error, slip_length))

    if method == 'Interface' and False:
        from matplotlib import pyplot

        fig = pyplot.figure(figsize=(8, 15))
        fig.add_subplot(311)
        c = dolfin.plot(sim.data['c'])
        pyplot.colorbar(c)
        fig.add_subplot(312)
        c = dolfin.plot(sim.data['ls_c_0_5'])
        pyplot.colorbar(c)
        fig.add_subplot(313)
        c = dolfin.plot(sim.fields['fs_zone'].get_variable('phi'))
        pyplot.colorbar(c)
        fig.tight_layout()
        fig.savefig('AAAAAAAAAAAaaaa.png')

    assert relative_error < 0.0099  # Expect 0.0097 for 𝛿=0.001
Ejemplo n.º 27
0
def main(inputfile, input_override):
    """
    Run Ocellaris
    """
    if os.environ.get('OCELLARIS_SUPER_DEBUG', False):
        print('FOUND OCELLARIS_SUPER_DEBUG in environment')
        from ocellaris.utils.debug import enable_super_debug

        enable_super_debug()

    sim = Simulation()

    # Read input
    if sim.io.is_restart_file(inputfile):
        sim.io.load_restart_file_input(inputfile)
    else:
        sim.input.read_yaml(inputfile)

    # Alter input by values given on the command line
    override_input_variables(sim, input_override)

    # Setup logging before we start printing anything
    sim.log.setup()

    # Print banner with Ocellaris version number
    version = get_detailed_version()
    location = os.path.split(os.path.abspath(__file__))[0]
    sim.log.info('=' * 80)
    sim.log.info('                  Ocellaris   %s' % version)
    sim.log.info('=' * 80)
    sim.log.info('Installed at:')
    sim.log.info('    %s' % location)
    sim.log.info('    host: %s' % platform.node())
    sim.log.info()

    # Print some version information
    sim.log.info('Running on Python %s' % sys.version)
    sim.log.info('    Using dolfin %s' % dolfin.__version__)
    sim.log.info('    Using mpi4py %s' % mpi4py.__version__)
    sim.log.info('    Using h5py   %s' % h5py.__version__)
    sim.log.info('    Using meshio %s' % meshio.__version__)
    sim.log.info('    Using PyYAML %s' % yaml.__version__)
    sim.log.info('    Using petsc4py %s' % petsc4py_version)
    sim.log.info('    Using PETSc %d.%d.%d\n' % PETSc.Sys.getVersion())

    # Setup the Ocellaris simulation
    ok = setup_simulation(sim, setup_logging=False, catch_exceptions=True)
    if not ok:
        sim.log.error('Setup did not suceed, exiting')
        sys.exit(1)

    if sim.restarted:
        # Load previous results
        sim.io.load_restart_file_results(inputfile)

    # Run the Ocellaris simulation time loop
    run_simulation(sim, catch_exceptions=True)

    sim.log.info('=' * 80)
    if sim.success:
        sim.log.info('Ocellaris finished successfully')
    else:
        sim.log.info('Ocellaris finished with errors')
Ejemplo n.º 28
0
def run_and_calculate_error(N, dt, tmax, polydeg_u, polydeg_p, nu, last=False):
    """
    Run Ocellaris and return L2 & H1 errors in the last time step
    """
    say(N, dt, tmax, polydeg_u, polydeg_p)

    # Setup and run simulation
    timingtypes = [
        dolfin.TimingType.user, dolfin.TimingType.system,
        dolfin.TimingType.wall
    ]
    dolfin.timings(dolfin.TimingClear_clear, timingtypes)
    sim = Simulation()
    sim.input.read_yaml('disc.inp')

    mesh_type = sim.input.get_value('mesh/type')
    if mesh_type == 'XML':
        # Create unstructured mesh with gmsh
        cmd1 = [
            'gmsh', '-string',
            'lc = %f;' % (3.14 / N), '-o',
            'disc_%d.msh' % N, '-2', 'disc.geo'
        ]
        cmd2 = ['dolfin-convert', 'disc_%d.msh' % N, 'disc.xml']
        with open('/dev/null', 'w') as devnull:
            for cmd in (cmd1, cmd2):
                say(' '.join(cmd))
                subprocess.call(cmd, stdout=devnull, stderr=devnull)
    elif mesh_type == 'UnitDisc':
        sim.input.set_value('mesh/N', N // 2)
    else:
        sim.input.set_value('mesh/Nx', N)
        sim.input.set_value('mesh/Ny', N)

    sim.input.set_value('time/dt', dt)
    sim.input.set_value('time/tmax', tmax)
    sim.input.set_value('solver/polynomial_degree_velocity', polydeg_u)
    sim.input.set_value('solver/polynomial_degree_pressure', polydeg_p)
    sim.input.set_value('physical_properties/nu', nu)
    sim.input.set_value('output/stdout_enabled', False)

    say('Running with %s %s solver ...' %
        (sim.input.get_value('solver/type'),
         sim.input.get_value('solver/function_space_velocity')))
    t1 = time.time()
    setup_simulation(sim)
    run_simulation(sim)
    duration = time.time() - t1
    say('DONE')

    # Interpolate the analytical solution to the same function space
    Vu = sim.data['Vu']
    Vp = sim.data['Vp']
    Vr = sim.data['Vrho']
    polydeg_r = Vr.ufl_element().degree()
    vals = dict(t=sim.time,
                dt=sim.dt,
                Q=sim.input.get_value('user_code/constants/Q'))
    rho_e = dolfin.Expression(
        sim.input.get_value('initial_conditions/rho_p/cpp_code'),
        degree=polydeg_r,
        **vals)
    u0e = dolfin.Expression(
        sim.input.get_value('initial_conditions/up0/cpp_code'),
        degree=polydeg_u,
        **vals)
    u1e = dolfin.Expression(
        sim.input.get_value('initial_conditions/up1/cpp_code'),
        degree=polydeg_u,
        **vals)
    pe = dolfin.Expression(
        sim.input.get_value('initial_conditions/p/cpp_code'),
        degree=polydeg_p,
        **vals)

    rho_a = dolfin.project(rho_e, Vr)
    u0a = dolfin.project(u0e, Vu)
    u1a = dolfin.project(u1e, Vu)
    pa = dolfin.project(pe, Vp)

    mesh = sim.data['mesh']
    n = dolfin.FacetNormal(mesh)

    # Correct for possible non-zero average p
    int_p = dolfin.assemble(sim.data['p'] * dolfin.dx)
    int_pa = dolfin.assemble(pa * dolfin.dx)
    vol = dolfin.assemble(dolfin.Constant(1.0) * dolfin.dx(domain=mesh))
    pa_avg = int_pa / vol
    sim.data['p'].vector()[:] += pa_avg

    # Calculate L2 errors
    err_rho = calc_err(sim.data['rho'], rho_a)
    err_u0 = calc_err(sim.data['u0'], u0a)
    err_u1 = calc_err(sim.data['u1'], u1a)
    err_p = calc_err(sim.data['p'], pa)

    # Calculate H1 errors
    err_rho_H1 = calc_err(sim.data['rho'], rho_a, 'H1')
    err_u0_H1 = calc_err(sim.data['u0'], u0a, 'H1')
    err_u1_H1 = calc_err(sim.data['u1'], u1a, 'H1')
    err_p_H1 = calc_err(sim.data['p'], pa, 'H1')

    reports = sim.reporting.timestep_xy_reports
    say('Num time steps:', sim.timestep)
    say('Num cells:', mesh.num_cells())
    Co_max, Pe_max = numpy.max(reports['Co']), numpy.max(reports['Pe'])
    say('Co_max:', Co_max)
    say('Pe_max:', Pe_max)
    say('rho_min went from %r to %r' %
        (reports['min(rho)'][0], reports['min(rho)'][-1]))
    say('rho_max went from %r to %r' %
        (reports['max(rho)'][0], reports['max(rho)'][-1]))
    m0, m1 = reports['mass'][0], reports['mass'][-1]
    say('mass error %.3e (%.3e)' % (m1 - m0, (m1 - m0) / m0))
    say('vel repr error %.3e' %
        dolfin.assemble(dolfin.dot(sim.data['u'], n) * dolfin.ds))
    say('p*dx', int_p)
    div_u_Vp = abs(
        dolfin.project(dolfin.div(sim.data['u']),
                       Vp).vector().get_local()).max()
    say('div(u)|Vp', div_u_Vp)
    div_u_Vu = abs(
        dolfin.project(dolfin.div(sim.data['u']),
                       Vu).vector().get_local()).max()
    say('div(u)|Vu', div_u_Vu)
    Vdg0 = dolfin.FunctionSpace(mesh, "DG", 0)
    div_u_DG0 = abs(
        dolfin.project(dolfin.div(sim.data['u']),
                       Vdg0).vector().get_local()).max()
    say('div(u)|DG0', div_u_DG0)
    Vdg1 = dolfin.FunctionSpace(mesh, "DG", 1)
    div_u_DG1 = abs(
        dolfin.project(dolfin.div(sim.data['u']),
                       Vdg1).vector().get_local()).max()
    say('div(u)|DG1', div_u_DG1)

    isoparam = mesh.ufl_coordinate_element().degree() > 1
    allways_plot = True
    if (last or allways_plot) and (
            not isoparam or sim.input.get_value('mesh/type') == 'UnitDisc'):
        # Plot the results
        for fa, name in ((u0a, 'u0'), (u1a, 'u1'), (pa, 'p'), (rho_a, 'rho')):
            fh = sim.data[name]
            if isoparam:
                # Bug in matplotlib plotting for isoparametric elements
                mesh2 = dolfin.UnitDiscMesh(dolfin.MPI.comm_world, N // 2, 1,
                                            2)
                ue = fa.function_space().ufl_element()
                V2 = dolfin.FunctionSpace(mesh2, ue.family(), ue.degree())
                fa2, fh2 = dolfin.Function(V2), dolfin.Function(V2)
                fa2.vector().set_local(fa.vector().get_local())
                fh2.vector().set_local(fh.vector().get_local())
                fa, fh = fa2, fh2
            discr = ''  # '%g_%g_' % (N, dt)
            plot(fa, name + ' analytical', '%s%s_1analytical' % (discr, name))
            plot(fh, name + ' numerical', '%s%s_2numerical' % (discr, name))
            plot(fh - fa, name + ' diff', '%s%s_3diff' % (discr, name))

    hmin = mesh.hmin()
    return err_rho, err_u0, err_u1, err_p, err_rho_H1, err_u0_H1, err_u1_H1, err_p_H1, hmin, dt, Co_max, Pe_max, duration
Ejemplo n.º 29
0
def mk_vof_sim(case_name, modifier=None):
    sim = Simulation()
    sim.input.read_yaml(yaml_string=BASE_INPUT)

    cases = {
        'DG0_2D_y': (2, 0, 'y'),
        'DG0_3D_z': (3, 0, 'z'),
        'DG0_2D_x': (2, 0, 'x')
    }
    dim, vof_deg, surf_normal = cases[case_name]

    if dim == 3:
        sim.input.set_value('mesh/type', 'Box')
        sim.input.set_value('mesh/Nz', 2)

    sim.test_name = case_name
    if surf_normal == 'x':
        sim.input.set_value('initial_conditions/cp/cpp_code',
                            'x[0] < 0.5 ? 0.0 : 1.0')
        sim.test_surf_normal = [1, 0, 0]
        sim.test_coord_index = 0
    elif surf_normal == 'y':
        sim.input.set_value('initial_conditions/cp/cpp_code',
                            'x[1] < 0.5 ? 1.0 : 0.0')
        sim.test_surf_normal = [0, -1, 0]
        sim.test_coord_index = 1
    elif surf_normal == 'z':
        sim.input.set_value('initial_conditions/cp/cpp_code',
                            'x[2] < 0.5 ? 1.0 : 0.0')
        sim.test_surf_normal = [0, 0, -1]
        sim.test_coord_index = 2

    sim.input.set_value('multiphase_solver/polynomial_degree_colour', vof_deg)

    # Run any custom code
    if modifier is not None:
        modifier(sim)

    sim.log.setup()
    sim.setup()
    sim.data['c'].assign(sim.data['cp'])
    return sim
Ejemplo n.º 30
0
def run_and_calculate_error(N, dt, tmax, polydeg_u, polydeg_p, modifier=None):
    """
    Run Ocellaris and return L2 & H1 errors in the last time step
    """
    say(N, dt, tmax, polydeg_u, polydeg_p)

    # Setup and run simulation
    sim = Simulation()
    sim.input.read_yaml('taylor-green.inp')

    if sim.input.get_value('mesh/type') == 'Rectangle':
        # Use structured mesh
        sim.input.set_value('mesh/Nx', N)
        sim.input.set_value('mesh/Ny', N)
    else:
        # Create unstructured mesh with gmsh
        cmd1 = [
            'gmsh',
            '-string',
            'lc = %f;' % (2.0 / N),
            '-o',
            'taylor-green_%d.msh' % N,
            '-2',
            'taylor-green.geo',
        ]
        cmd2 = [
            'dolfin-convert',
            'taylor-green_%d.msh' % N, 'taylor-green.xml'
        ]
        with open('/dev/null', 'w') as devnull:
            for cmd in (cmd1, cmd2):
                say(' '.join(cmd))
                subprocess.call(cmd, stdout=devnull, stderr=devnull)

    sim.input.set_value('time/dt', dt)
    sim.input.set_value('time/tmax', tmax)
    sim.input.set_value('solver/polynomial_degree_velocity', polydeg_u)
    sim.input.set_value('solver/polynomial_degree_pressure', polydeg_p)
    sim.input.set_value('output/stdout_enabled', False)

    if sim.input.get_value('solver/timestepping_method', 'BDF') == 'CN':
        sim.input.set_value(
            'initial_conditions/p/cpp_code',
            '-(cos(2*pi*x[0]) + cos(2*pi*x[1])) * exp(-4*pi*pi*nu*(t+dt/2))/4',
        )

    # Turn off BDM
    # sim.input.set_value('solver/velocity_postprocessing', 'None')

    if modifier:
        modifier(sim)  # Running regression tests, modify some input params

    say('Running with %s %s solver ...' % (
        sim.input.get_value('solver/type'),
        sim.input.get_value('solver/function_space_velocity', 'DG'),
    ))
    t1 = time.time()
    setup_simulation(sim)
    if 'Vcoupled' in sim.data:
        say('Num unknowns', sim.data['Vcoupled'].dim())
    run_simulation(sim)
    duration = time.time() - t1
    say('DONE')

    # Interpolate the analytical solution to the same function space
    Vu = sim.data['Vu']
    Vp = sim.data['Vp']
    vals = dict(
        t=sim.time,
        dt=sim.dt,
        nu=sim.input['physical_properties']['nu'],
        rho=sim.input['physical_properties']['rho'],
    )
    u0e = dolfin.Expression(
        sim.input.get_value('initial_conditions/up0/cpp_code'),
        degree=polydeg_u + 3,
        **vals)
    u1e = dolfin.Expression(
        sim.input.get_value('initial_conditions/up1/cpp_code'),
        degree=polydeg_u + 3,
        **vals)
    if sim.input.get_value('solver/timestepping_method', 'BDF') == 'CN':
        vals['t'] = sim.time - sim.dt
    pe = dolfin.Expression(
        sim.input.get_value('initial_conditions/p/cpp_code'),
        degree=polydeg_p + 3,
        **vals)

    u0a = dolfin.project(u0e, Vu)
    u1a = dolfin.project(u1e, Vu)
    pa = dolfin.project(pe, Vp)

    # Calculate L2 errors
    err_u0 = calc_err(sim.data['u0'], u0a)
    err_u1 = calc_err(sim.data['u1'], u1a)
    err_p = calc_err(sim.data['p'], pa)

    # Calculate H1 errors
    err_u0_H1 = calc_err(sim.data['u0'], u0a, 'H1')
    err_u1_H1 = calc_err(sim.data['u1'], u1a, 'H1')
    err_p_H1 = calc_err(sim.data['p'], pa, 'H1')

    say('Number of time steps:', sim.timestep)
    loglines = sim.log.get_full_log().split('\n')
    say('Num inner iterations:',
        sum(1 if 'iteration' in line else 0 for line in loglines))
    int_p = dolfin.assemble(sim.data['p'] * dolfin.dx)
    say('Number of mesh cells:', sim.data['mesh'].num_cells())
    say('p*dx', int_p)
    div_u_Vp = abs(
        dolfin.project(dolfin.div(sim.data['u']),
                       Vp).vector().get_local()).max()
    say('div(u)|Vp', div_u_Vp)
    div_u_Vu = abs(
        dolfin.project(dolfin.div(sim.data['u']),
                       Vu).vector().get_local()).max()
    say('div(u)|Vu', div_u_Vu)
    Vdg0 = dolfin.FunctionSpace(sim.data['mesh'], "DG", 0)
    div_u_DG0 = abs(
        dolfin.project(dolfin.div(sim.data['u']),
                       Vdg0).vector().get_local()).max()
    say('div(u)|DG0', div_u_DG0)
    Vdg1 = dolfin.FunctionSpace(sim.data['mesh'], "DG", 1)
    div_u_DG1 = abs(
        dolfin.project(dolfin.div(sim.data['u']),
                       Vdg1).vector().get_local()).max()
    say('div(u)|DG1', div_u_DG1)

    if 'u_mesh' in sim.data:
        Vmesh = sim.data['Vmesh']
        div_u_mesh_Vmesh = abs(
            dolfin.project(dolfin.div(sim.data['u_mesh']),
                           Vmesh).vector().get_local()).max()
        say('div(u_mesh)|V_mesh', div_u_mesh_Vmesh)
        div_u_mesh_DG0 = abs(
            dolfin.project(dolfin.div(sim.data['u_mesh']),
                           Vdg0).vector().get_local()).max()
        say('div(u_mesh)|DG0', div_u_mesh_DG0)
        div_u_mesh_DG1 = abs(
            dolfin.project(dolfin.div(sim.data['u_mesh']),
                           Vdg1).vector().get_local()).max()
        say('div(u_mesh)|DG1', div_u_mesh_DG1)

    if False:
        # Plot the results
        for fa, name in ((u0a, 'u0'), (u1a, 'u1'), (pa, 'p')):
            p1 = dolfin.plot(sim.data[name] - fa,
                             title='%s_diff' % name,
                             key='%s_diff' % name)
            p2 = dolfin.plot(fa, title=name + ' analytical', key=name)
            p1.write_png('%g_%g_%s_diff' % (N, dt, name))
            p2.write_png('%g_%g_%s' % (N, dt, name))
        dolfin.interactive()

    if N == 40 and False:
        dolfin.plot(sim.data['u0'], title='u0')
        dolfin.plot(sim.data['u1'], title='u1')
        dolfin.plot(sim.data['p'], title='p')
        dolfin.plot(u0a, title='u0a')
        dolfin.plot(u1a, title='u1a')
        dolfin.plot(pa, title='pa')
        plot_err(sim.data['u0'], u0a, 'u0a - u0')
        plot_err(sim.data['u1'], u1a, 'u1a - u1')
        plot_err(sim.data['p'], pa, 'pa - p')

    hmin = sim.data['mesh'].hmin()
    return err_u0, err_u1, err_p, err_u0_H1, err_u1_H1, err_p_H1, hmin, dt, duration