def test_physics_recovery_kernels(boundary): m = IntervalMesh(3, 3) mesh = ExtrudedMesh(m, layers=3, layer_height=1.0) cell = m.ufl_cell().cellname() hori_elt = FiniteElement("DG", cell, 0) vert_elt = FiniteElement("CG", interval, 1) theta_elt = TensorProductElement(hori_elt, vert_elt) Vt = FunctionSpace(mesh, theta_elt) Vt_brok = FunctionSpace(mesh, BrokenElement(theta_elt)) initial_field = Function(Vt) true_field = Function(Vt_brok) new_field = Function(Vt_brok) initial_field, true_field = setup_values(boundary, initial_field, true_field) kernel = kernels.PhysicsRecoveryTop( ) if boundary == "top" else kernels.PhysicsRecoveryBottom() kernel.apply(new_field, initial_field) tolerance = 1e-12 index = 11 if boundary == "top" else 6 assert abs(true_field.dat.data[index] - new_field.dat.data[index]) < tolerance, \ "Value at %s from physics recovery is not correct" % boundary
def mesh(geometry): L = 3.0 n = 3 if geometry == "1D": m = IntervalMesh(n, L) elif geometry == "2D": m = RectangleMesh(n, n, L, L, quadrilateral=True) return m
def setup_form(): # Create mesh and function space L = 3.0 n = 3 mesh = IntervalMesh(n, L) V = FunctionSpace(mesh, "DG", 0) f = Function(V) g = TestFunction(V) form = f * g * dx return f, form
def mesh(geometry): Lx = 100. deltax = Lx / 5. ncolumnsx = int(Lx/deltax) if geometry == "periodic": m = PeriodicIntervalMesh(ncolumnsx, Lx) elif geometry == "non-periodic": m = IntervalMesh(ncolumnsx, Lx) return m
def mesh(geometry): L = 100. H = 100. deltax = L / 5. deltaz = H / 5. nlayers = int(H / deltaz) ncolumns = int(L / deltax) if geometry == "periodic": m = PeriodicIntervalMesh(ncolumns, L) elif geometry == "non-periodic": m = IntervalMesh(ncolumns, L) extruded_mesh = ExtrudedMesh(m, layers=nlayers, layer_height=deltaz) return extruded_mesh
if '--running-tests' in sys.argv: deltax = 1000. tmax = 5. else: deltax = 100. tmax = 1000. degree = 0 dirname = 'dry_bryan_fritsch' # make mesh L = 10000. H = 10000. nlayers = int(H / deltax) ncolumns = int(L / deltax) m = IntervalMesh(ncolumns, L) mesh = ExtrudedMesh(m, layers=nlayers, layer_height=H / nlayers) output = OutputParameters(dirname=dirname, dumpfreq=int(tmax / (5 * dt)), dumplist=['u'], perturbation_fields=['theta'], log_level='INFO') params = CompressibleParameters() state = State(mesh, dt=dt, output=output, parameters=params) u_transport_option = "vector_advection_form" eqns = CompressibleEulerEquations(state,
def test_label_map(): # ------------------------------------------------------------------------ # # Set up labelled forms # ------------------------------------------------------------------------ # # Some basic labels foo_label = Label("foo") bar_label = Label("bar", validator=lambda value: type(value) == int) # Create mesh, function space and forms L = 3.0 n = 3 mesh = IntervalMesh(n, L) V = FunctionSpace(mesh, "DG", 0) f = Function(V) g = Function(V) test = TestFunction(V) form_1 = f * test * dx form_2 = g * test * dx term_1 = foo_label(Term(form_1)) term_2 = bar_label(Term(form_2), 5) labelled_form = term_1 + term_2 # ------------------------------------------------------------------------ # # Test all_terms # ------------------------------------------------------------------------ # # Passing all_terms should return the same labelled form new_labelled_form = labelled_form.label_map(all_terms) assert len(new_labelled_form) == len(labelled_form), \ 'new_labelled_form should be the same as labelled_form' for new_term, term in zip(new_labelled_form.terms, labelled_form.terms): assert new_term == term, 'terms in new_labelled_form should be the ' + \ 'same as those in labelled_form' # ------------------------------------------------------------------------ # # Test identity and drop # ------------------------------------------------------------------------ # # Get just the first term, which has the foo label new_labelled_form = labelled_form.label_map( lambda t: t.has_label(foo_label), map_if_true=identity, map_if_false=drop) assert len(new_labelled_form) == 1, 'new_labelled_form should be length 1' for new_term in new_labelled_form.terms: assert new_term.has_label(foo_label), 'All terms in ' + \ 'new_labelled_form should have foo_label' # Give term_1 the bar label new_labelled_form = labelled_form.label_map( lambda t: t.has_label(bar_label), map_if_true=identity, map_if_false=lambda t: bar_label(t, 0)) assert len(new_labelled_form) == 2, 'new_labelled_form should be length 2' for new_term in new_labelled_form.terms: assert new_term.has_label(bar_label), 'All terms in ' + \ 'new_labelled_form should have bar_label' # Test with a more complex filter, which should give an empty labelled_form new_labelled_form = labelled_form.label_map( lambda t: (t.has_label(bar_label) and t.get(bar_label) > 10), map_if_true=identity, map_if_false=drop) assert len(new_labelled_form) == 0, 'new_labelled_form should be length 0'
def test_labelled_form(): # ------------------------------------------------------------------------ # # Set up labelled forms # ------------------------------------------------------------------------ # # Some basic labels lorem_label = Label("lorem", validator=lambda value: type(value) == str) ipsum_label = Label("ipsum", validator=lambda value: type(value) == int) # Create mesh, function space and forms L = 3.0 n = 3 mesh = IntervalMesh(n, L) V = FunctionSpace(mesh, "DG", 0) f = Function(V) g = Function(V) test = TestFunction(V) form_1 = f * test * dx form_2 = g * test * dx term_1 = lorem_label(Term(form_1), 'i_have_lorem') term_2 = ipsum_label(Term(form_2), 5) # ------------------------------------------------------------------------ # # Test labelled forms have the correct number of terms # ------------------------------------------------------------------------ # # Create from a single term labelled_form_1 = LabelledForm(term_1) assert len(labelled_form_1) == 1, 'LabelledForm should have 1 term' # Create from multiple terms labelled_form_2 = LabelledForm(*[term_1, term_2]) assert len(labelled_form_2) == 2, 'LabelledForm should have 2 terms' # Trying to create from two LabelledForms should give an error try: labelled_form_3 = LabelledForm(labelled_form_1, labelled_form_2) # If we get here something has gone wrong assert False, 'We should not be able to create LabelledForm ' + \ 'from two LabelledForms' except TypeError: pass # Create from a single LabelledForm labelled_form_3 = LabelledForm(labelled_form_1) assert len(labelled_form_3) == 1, 'LabelledForm should have 1 term' # ------------------------------------------------------------------------ # # Test getting form # ------------------------------------------------------------------------ # assert type(labelled_form_1.form) is Form, 'The form belonging to the ' + \ f'LabelledForm must be a Form, and not {type(labelled_form_1.form)}' assert type(labelled_form_2.form) is Form, 'The form belonging to the ' + \ f'LabelledForm must be a Form, and not {type(labelled_form_2.form)}' assert type(labelled_form_3.form) is Form, 'The form belonging to the ' + \ f'LabelledForm must be a Form, and not {type(labelled_form_3.form)}' # ------------------------------------------------------------------------ # # Test addition and subtraction of labelled forms # ------------------------------------------------------------------------ # # Add a Form to a LabelledForm new_labelled_form = labelled_form_1 + form_2 assert len(new_labelled_form) == 2, 'LabelledForm should have 2 terms' # Add a Term to a LabelledForm new_labelled_form = labelled_form_1 + term_2 assert len(new_labelled_form) == 2, 'LabelledForm should have 2 terms' # Add a LabelledForm to a LabelledForm new_labelled_form = labelled_form_1 + labelled_form_2 assert len(new_labelled_form) == 3, 'LabelledForm should have 3 terms' # Adding None to a LabelledForm should give the same LabelledForm new_labelled_form = labelled_form_1 + None assert new_labelled_form == labelled_form_1, 'Two LabelledForms should be equal' # Subtract a Form from a LabelledForm new_labelled_form = labelled_form_1 - form_2 assert len(new_labelled_form) == 2, 'LabelledForm should have 2 terms' # Subtract a Term from a LabelledForm new_labelled_form = labelled_form_1 - term_2 assert len(new_labelled_form) == 2, 'LabelledForm should have 2 terms' # Subtract a LabelledForm from a LabelledForm new_labelled_form = labelled_form_1 - labelled_form_2 assert len(new_labelled_form) == 3, 'LabelledForm should have 3 terms' # Subtracting None from a LabelledForm should give the same LabelledForm new_labelled_form = labelled_form_1 - None assert new_labelled_form == labelled_form_1, 'Two LabelledForms should be equal' # ------------------------------------------------------------------------ # # Test multiplication and division of labelled forms # ------------------------------------------------------------------------ # # Multiply by integer new_labelled_form = labelled_form_1 * -4 assert len(new_labelled_form) == 1, 'LabelledForm should have 1 term' # Multiply by float new_labelled_form = labelled_form_1 * 12.4 assert len(new_labelled_form) == 1, 'LabelledForm should have 1 term' # Multiply by Constant new_labelled_form = labelled_form_1 * Constant(5.0) assert len(new_labelled_form) == 1, 'LabelledForm should have 1 term' # Divide by integer new_labelled_form = labelled_form_1 / (-8) assert len(new_labelled_form) == 1, 'LabelledForm should have 1 term' # Divide by float new_labelled_form = labelled_form_1 / (-6.2) assert len(new_labelled_form) == 1, 'LabelledForm should have 1 term' # Divide by Constant new_labelled_form = labelled_form_1 / Constant(0.01) assert len(new_labelled_form) == 1, 'LabelledForm should have 1 term'
def test_limit_midpoints(profile): # ------------------------------------------------------------------------ # # Set up meshes and spaces # ------------------------------------------------------------------------ # m = IntervalMesh(3, 3) mesh = ExtrudedMesh(m, layers=1, layer_height=3.0) cell = m.ufl_cell().cellname() DG_hori_elt = FiniteElement("DG", cell, 1, variant='equispaced') DG_vert_elt = FiniteElement("DG", interval, 1, variant='equispaced') Vt_vert_elt = FiniteElement("CG", interval, 2) DG_elt = TensorProductElement(DG_hori_elt, DG_vert_elt) theta_elt = TensorProductElement(DG_hori_elt, Vt_vert_elt) Vt_brok = FunctionSpace(mesh, BrokenElement(theta_elt)) DG1 = FunctionSpace(mesh, DG_elt) new_field = Function(Vt_brok) init_field = Function(Vt_brok) DG1_field = Function(DG1) # ------------------------------------------------------------------------ # # Initial conditions # ------------------------------------------------------------------------ # _, z = SpatialCoordinate(mesh) if profile == 'undershoot': # A quadratic whose midpoint is lower than the top and bottom values init_expr = (80. / 9.) * z**2 - 20. * z + 300. elif profile == 'overshoot': # A quadratic whose midpoint is higher than the top and bottom values init_expr = (-80. / 9.) * z**2 + (100. / 3) * z + 300. elif profile == 'linear': # Linear profile which must be unchanged init_expr = (20. / 3.) * z + 300. else: raise NotImplementedError # Linear DG field has the same values at top and bottom as quadratic DG_expr = (20. / 3.) * z + 300. init_field.interpolate(init_expr) DG1_field.interpolate(DG_expr) # ------------------------------------------------------------------------ # # Apply kernel # ------------------------------------------------------------------------ # kernel = kernels.LimitMidpoints(Vt_brok) kernel.apply(new_field, DG1_field, init_field) # ------------------------------------------------------------------------ # # Check values # ------------------------------------------------------------------------ # tol = 1e-12 assert np.max(new_field.dat.data) <= np.max(init_field.dat.data) + tol, \ 'LimitMidpoints kernel is giving an overshoot' assert np.min(new_field.dat.data) >= np.min(init_field.dat.data) - tol, \ 'LimitMidpoints kernel is giving an undershoot' if profile == 'linear': assert np.allclose(init_field.dat.data, new_field.dat.data), \ 'For a profile with no maxima or minima, the LimitMidpoints ' + \ 'kernel should leave the field unchanged'
def setup_2d_recovery(dirname): L = 5. H = 5. deltax = L / 5. deltay = H / 5. nlayers = int(H / deltay) ncolumns = int(L / deltax) m = IntervalMesh(ncolumns, L) mesh = ExtrudedMesh(m, layers=nlayers, layer_height=H / nlayers) x, y = SpatialCoordinate(mesh) # horizontal base spaces cell = mesh._base_mesh.ufl_cell().cellname() u_hori = FiniteElement("CG", cell, 1) w_hori = FiniteElement("DG", cell, 0) # vertical base spaces u_vert = FiniteElement("DG", interval, 0) w_vert = FiniteElement("CG", interval, 1) # build elements u_element = HDiv(TensorProductElement(u_hori, u_vert)) w_element = HDiv(TensorProductElement(w_hori, w_vert)) theta_element = TensorProductElement(w_hori, w_vert) v_element = u_element + w_element # spaces VDG0 = FunctionSpace(mesh, "DG", 0) VCG1 = FunctionSpace(mesh, "CG", 1) VDG1 = FunctionSpace(mesh, "DG", 1) Vt = FunctionSpace(mesh, theta_element) Vt_brok = FunctionSpace(mesh, BrokenElement(theta_element)) Vu = FunctionSpace(mesh, v_element) VuCG1 = VectorFunctionSpace(mesh, "CG", 1) VuDG1 = VectorFunctionSpace(mesh, "DG", 1) # set up initial conditions np.random.seed(0) expr = np.random.randn() + np.random.randn() * x + np.random.randn( ) * y + np.random.randn() * x * y # our actual theta and rho and v rho_CG1_true = Function(VCG1).interpolate(expr) theta_CG1_true = Function(VCG1).interpolate(expr) v_CG1_true = Function(VuCG1).interpolate(as_vector([expr, expr])) rho_Vt_true = Function(Vt).interpolate(expr) # make the initial fields by projecting expressions into the lowest order spaces rho_DG0 = Function(VDG0).interpolate(expr) rho_CG1 = Function(VCG1) theta_Vt = Function(Vt).interpolate(expr) theta_CG1 = Function(VCG1) v_Vu = Function(Vu).project(as_vector([expr, expr])) v_CG1 = Function(VuCG1) rho_Vt = Function(Vt) # make the recoverers and do the recovery rho_recoverer = Recoverer(rho_DG0, rho_CG1, VDG=VDG1, boundary_method=Boundary_Method.dynamics) theta_recoverer = Recoverer(theta_Vt, theta_CG1, VDG=VDG1, boundary_method=Boundary_Method.dynamics) v_recoverer = Recoverer(v_Vu, v_CG1, VDG=VuDG1, boundary_method=Boundary_Method.dynamics) rho_Vt_recoverer = Recoverer(rho_DG0, rho_Vt, VDG=Vt_brok, boundary_method=Boundary_Method.physics) rho_recoverer.project() theta_recoverer.project() v_recoverer.project() rho_Vt_recoverer.project() rho_diff = errornorm(rho_CG1, rho_CG1_true) / norm(rho_CG1_true) theta_diff = errornorm(theta_CG1, theta_CG1_true) / norm(theta_CG1_true) v_diff = errornorm(v_CG1, v_CG1_true) / norm(v_CG1_true) rho_Vt_diff = errornorm(rho_Vt, rho_Vt_true) / norm(rho_Vt_true) return (rho_diff, theta_diff, v_diff, rho_Vt_diff)
def test_term(initialise): # ------------------------------------------------------------------------ # # Set up terms # ------------------------------------------------------------------------ # # Some basic labels foo_label = Label("foo", validator=lambda value: type(value) == bool) lorem_label = Label("lorem", validator=lambda value: type(value) == str) ipsum_label = Label("ipsum", validator=lambda value: type(value) == int) # Dict for matching the label names to the label objects all_labels = [foo_label, lorem_label, ipsum_label] all_label_dict = {label.label: label for label in all_labels} # Create mesh, function space and forms L = 3.0 n = 3 mesh = IntervalMesh(n, L) V = FunctionSpace(mesh, "DG", 0) f = Function(V) g = Function(V) h = Function(V) test = TestFunction(V) form = f*test*dx # Declare what the labels will be label_dict = {'foo': True, 'lorem': 'etc', 'ipsum': 1} # Make terms if initialise == "from_dicts": term = Term(form, label_dict) else: term = Term(form) # Apply labels for label_name, value in label_dict.items(): term = all_label_dict[label_name](term, value) # ------------------------------------------------------------------------ # # Test Term.get routine # ------------------------------------------------------------------------ # for label in all_labels: if label.label in label_dict.keys(): # Check if label is attached to Term and it has correct value assert term.get(label) == label_dict[label.label], \ f'term should have label {label.label} with value equal ' + \ f'to {label_dict[label.label]} and not {term.get(label)}' else: # Labelled shouldn't be attached to Term so this should return None assert term.get(label) is None, 'term should not have ' + \ f'label {label.label} but term.get(label) returns ' + \ f'{term.get(label)}' # ------------------------------------------------------------------------ # # Test Term.has_label routine # ------------------------------------------------------------------------ # # Test has_label for each label one by one for label in all_labels: assert term.has_label(label) == (label.label in label_dict.keys()), \ f'term.has_label giving incorrect value for {label.label}' # Test has_labels by passing all labels at once has_labels = term.has_label(*all_labels, return_tuple=True) for i, label in enumerate(all_labels): assert has_labels[i] == (label.label in label_dict.keys()), \ f'has_label for label {label.label} returning wrong value' # Check the return_tuple option is correct when only one label is passed has_labels = term.has_label(*[foo_label], return_tuple=True) assert len(has_labels) == 1, 'Length returned by has_label is ' + \ f'incorrect, it is {len(has_labels)} but should be 1' assert has_labels[0] == (label.label in label_dict.keys()), \ f'has_label for label {label.label} returning wrong value' # ------------------------------------------------------------------------ # # Test Term addition and subtraction # ------------------------------------------------------------------------ # form_2 = g*test*dx term_2 = ipsum_label(Term(form_2), 2) labelled_form_1 = term_2 + term labelled_form_2 = term + term_2 # Adding two Terms should return a LabelledForm containing the Terms assert type(labelled_form_1) is LabelledForm, 'The sum of two Terms ' + \ f'should be a LabelledForm, not {type(labelled_form_1)}' assert type(labelled_form_2) is LabelledForm, 'The sum of two Terms ' + \ f'should be a LabelledForm, not {type(labelled_form_1)}' # Adding a LabelledForm to a Term should return a LabelledForm labelled_form_3 = term + labelled_form_2 assert type(labelled_form_3) is LabelledForm, 'The sum of a Term and ' + \ f'Labelled Form should be a LabelledForm, not {type(labelled_form_3)}' labelled_form_1 = term_2 - term labelled_form_2 = term - term_2 # Subtracting two Terms should return a LabelledForm containing the Terms assert type(labelled_form_1) is LabelledForm, 'The difference of two ' + \ f'Terms should be a LabelledForm, not {type(labelled_form_1)}' assert type(labelled_form_2) is LabelledForm, 'The difference of two ' + \ f'Terms should be a LabelledForm, not {type(labelled_form_1)}' # Subtracting a LabelledForm from a Term should return a LabelledForm labelled_form_3 = term - labelled_form_2 assert type(labelled_form_3) is LabelledForm, 'The differnce of a Term ' + \ f'and a Labelled Form should be a LabelledForm, not {type(labelled_form_3)}' # Adding None to a Term should return the Term new_term = term + None assert term == new_term, 'Adding None to a Term should give the same Term' # ------------------------------------------------------------------------ # # Test Term multiplication and division # ------------------------------------------------------------------------ # # Multiplying a term by an integer should give a Term new_term = term*3 assert type(new_term) is Term, 'Multiplying a Term by an integer ' + \ f'give a Term, not a {type(new_term)}' # Multiplying a term by a float should give a Term new_term = term*19.0 assert type(new_term) is Term, 'Multiplying a Term by a float ' + \ f'give a Term, not a {type(new_term)}' # Multiplying a term by a Constant should give a Term new_term = term*Constant(-4.0) assert type(new_term) is Term, 'Multiplying a Term by a Constant ' + \ f'give a Term, not a {type(new_term)}' # Dividing a term by an integer should give a Term new_term = term/3 assert type(new_term) is Term, 'Dividing a Term by an integer ' + \ f'give a Term, not a {type(new_term)}' # Dividing a term by a float should give a Term new_term = term/19.0 assert type(new_term) is Term, 'Dividing a Term by a float ' + \ f'give a Term, not a {type(new_term)}' # Dividing a term by a Constant should give a Term new_term = term/Constant(-4.0) assert type(new_term) is Term, 'Dividing a Term by a Constant ' + \ f'give a Term, not a {type(new_term)}' # Multiplying a term by a Function should fail try: new_term = term*h # If we get here we have failed assert False, 'Multiplying a Term by a Function should fail' except TypeError: pass
# The boundary surfaces are numbered as follows: (except for Periodic Mesh) # * 1: plane x == 0 # * 2: plane x == Lx # * 3: plane y == 0 # * 4: plane y == Ly # * 5: plane z == 0 # * 6: plane z == Lz # OneDimensional Meshes # -> IntervalMesh # --------------- # 1D mesh support ncells, Length (left coords), right coords (opt.) # m= IntervalMesh(nx,-L,L) m = IntervalMesh(nx, L) xIM = m.coordinates.dat.data # -> UnitIntervalMesh # ------------------- m = UnitIntervalMesh(nx) xUIM = m.coordinates.dat.data # -> PeriodicInternalMesh # ----------------------- m = PeriodicIntervalMesh(nx, L) xPIM = m.coordinates.dat.data y = np.ones([nx+1, ])