Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

143 fenics version 0.7.0 --- Hackathon #150

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
8 changes: 4 additions & 4 deletions src/fenicsxconcrete/boundary_conditions/bcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from fenicsxconcrete.util import LogMixin


def get_boundary_dofs(V: dolfinx.fem.FunctionSpace, marker: Callable) -> np.ndarray:
def get_boundary_dofs(V: dolfinx.fem.FunctionSpaceBase, marker: Callable) -> np.ndarray:
"""Returns dofs on the boundary specified by geometrical `marker`.

Args:
Expand Down Expand Up @@ -78,7 +78,7 @@ def __init__(
def add_dirichlet_bc(
self,
value: (
dolfinx.fem.Function | dolfinx.fem.Constant | dolfinx.fem.DirichletBCMetaClass | np.ndarray | Callable
dolfinx.fem.Function | dolfinx.fem.Constant | dolfinx.fem.DirichletBC | np.ndarray | Callable
),
boundary: int | np.ndarray | Callable | None = None,
sub: int = None,
Expand All @@ -103,7 +103,7 @@ def add_dirichlet_bc(
topologically. Note that `entity_dim` is required if `sub`
is not None and `method=geometrical`.
"""
if isinstance(value, dolfinx.fem.DirichletBCMetaClass):
if isinstance(value, dolfinx.fem.DirichletBC):
self._bcs.append(value)
else:
assert method in ("topological", "geometrical")
Expand Down Expand Up @@ -180,7 +180,7 @@ def has_dirichlet(self) -> bool:
return len(self._bcs) > 0

@property
def bcs(self) -> list[dolfinx.fem.DirichletBCMetaClass]:
def bcs(self) -> list[dolfinx.fem.DirichletBC]:
"""returns the list of Dirichlet BCs

Returns:
Expand Down
2 changes: 1 addition & 1 deletion src/fenicsxconcrete/boundary_conditions/boundary.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def _show_marked(
if tdim in (1, 3):
raise NotImplementedError(f"Not implemented for mesh of topological dimension {tdim=}.")

V = dolfinx.fem.FunctionSpace(domain, ("Lagrange", 1))
V = dolfinx.fem.functionspace(domain, ("Lagrange", 1))
dofs = dolfinx.fem.locate_dofs_geometrical(V, marker)
u = dolfinx.fem.Function(V)
bc = dolfinx.fem.dirichletbc(u, dofs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def setup(self) -> None:
else:
raise ValueError(f'wrong dimension: {self.p["dim"]} is not implemented for problem setup')

def create_displacement_boundary(self, V: df.fem.FunctionSpace) -> list[df.fem.bcs.DirichletBCMetaClass]:
def create_displacement_boundary(self, V: df.fem.FunctionSpaceBase) -> list[df.fem.bcs.DirichletBC]:
"""defines displacement boundary as fixed at bottom

Args:
Expand Down
6 changes: 3 additions & 3 deletions src/fenicsxconcrete/experimental_setup/base_experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
import pint
import ufl

from fenicsxconcrete.boundary_conditions.boundary import plane_at, point_at
from fenicsxconcrete.util import LogMixin, Parameters, QuadratureRule, ureg
from fenicsxconcrete.boundary_conditions.boundary import plane_at
from fenicsxconcrete.util import LogMixin, Parameters, QuadratureRule


class Experiment(ABC, LogMixin):
Expand Down Expand Up @@ -81,7 +81,7 @@ def default_parameters() -> dict[str, pint.Quantity]:
pass

@abstractmethod
def create_displacement_boundary(self, V: df.fem.FunctionSpace) -> list[df.fem.bcs.DirichletBCMetaClass] | None:
def create_displacement_boundary(self, V: df.fem.FunctionSpaceBase) -> list[df.fem.bcs.DirichletBC] | None:
"""defines empty displacement boundary conditions (to be done in child)

this function is abstract until there is a need for a material that does not need a displacement boundary
Expand Down
4 changes: 2 additions & 2 deletions src/fenicsxconcrete/experimental_setup/cantilever_beam.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from petsc4py.PETSc import ScalarType

from fenicsxconcrete.experimental_setup.base_experiment import Experiment
from fenicsxconcrete.util import Parameters, ureg
from fenicsxconcrete.util import ureg


class CantileverBeam(Experiment):
Expand Down Expand Up @@ -81,7 +81,7 @@ def default_parameters() -> dict[str, pint.Quantity]:

return setup_parameters

def create_displacement_boundary(self, V) -> list:
def create_displacement_boundary(self, V: df.fem.FunctionSpaceBase) -> list:
"""defines displacement boundary as fixed at bottom

Args:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ def default_parameters() -> dict[str, pint.Quantity]:

return default_parameters

def create_displacement_boundary(self, V: df.fem.FunctionSpace) -> list[df.fem.bcs.DirichletBCMetaClass]:
def create_displacement_boundary(self, V: df.fem.FunctionSpaceBase) -> list[df.fem.bcs.DirichletBC]:
"""Defines the displacement boundary conditions

Args:
Expand Down
2 changes: 1 addition & 1 deletion src/fenicsxconcrete/experimental_setup/simple_beam.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def default_parameters() -> dict[str, pint.Quantity]:

return setup_parameters

def create_displacement_boundary(self, V) -> list:
def create_displacement_boundary(self, V: df.fem.FunctionSpaceBase) -> list[df.fem.bcs.DirichletBC]:
"""defines displacement boundary as fixed at bottom

Args:
Expand Down
4 changes: 2 additions & 2 deletions src/fenicsxconcrete/experimental_setup/simple_cube.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def setup(self) -> None:
self.use_body_force = False
self.temperature_bc = df.fem.Constant(domain=self.mesh, c=self.p["T_bc"])

def create_displacement_boundary(self, V: df.fem.FunctionSpace) -> list[df.fem.bcs.DirichletBCMetaClass]:
def create_displacement_boundary(self, V: df.fem.FunctionSpaceBase) -> list[df.fem.bcs.DirichletBC]:
"""Defines the displacement boundary conditions

Args:
Expand Down Expand Up @@ -192,7 +192,7 @@ def apply_temp_bc(self, T_bc: pint.Quantity | float) -> None:
def apply_body_force(self) -> None:
self.use_body_force = True

def create_temperature_bcs(self, V: df.fem.FunctionSpace) -> list[df.fem.bcs.DirichletBCMetaClass]:
def create_temperature_bcs(self, V: df.fem.FunctionSpaceBase) -> list[df.fem.bcs.DirichletBC]:
"""defines empty temperature boundary conditions (to be done in child)

this function is abstract until there is a need for a material that does need a temperature boundary
Expand Down
2 changes: 1 addition & 1 deletion src/fenicsxconcrete/experimental_setup/tensile_beam.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def default_parameters() -> dict[str, pint.Quantity]:

return setup_parameters

def create_displacement_boundary(self, V) -> list:
def create_displacement_boundary(self, V: df.fem.FunctionSpaceBase) -> list[df.fem.bcs.DirichletBC]:
"""Defines the displacement boundary conditions

Args:
Expand Down
8 changes: 5 additions & 3 deletions src/fenicsxconcrete/finite_element_problem/concrete_am.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def setup(self) -> None:

self.rule = QuadratureRule(cell_type=self.mesh.ufl_cell(), degree=self.p["q_degree"])
# displacement space (name V required for sensors!)
self.V = df.fem.VectorFunctionSpace(self.mesh, ("CG", self.p["degree"]))
self.V = df.fem.functionspace(self.mesh, ("CG", self.p["degree"], (self.mesh.geometry.dim,)))
self.strain_stress_space = self.rule.create_quadrature_tensor_space(self.mesh, (self.p["dim"], self.p["dim"]))

# global variables for all AM problems relevant
Expand Down Expand Up @@ -243,12 +243,14 @@ def pv_plot(self) -> None:
# write further fields
sigma_plot = project(
self.mechanics_problem.sigma(self.fields.displacement),
df.fem.TensorFunctionSpace(self.mesh, self.q_fields.plot_space_type),
df.fem.functionspace(
self.mesh, self.q_fields.plot_space_type + (self.q_fields.stress.ufl_element().value_shape(), True)
),
self.rule.dx,
)

E_plot = project(
self.mechanics_problem.q_E, df.fem.FunctionSpace(self.mesh, self.q_fields.plot_space_type), self.rule.dx
self.mechanics_problem.q_E, df.fem.functionspace(self.mesh, self.q_fields.plot_space_type), self.rule.dx
)

E_plot.name = "Youngs_Modulus"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from fenicsxconcrete.experimental_setup import CantileverBeam, Experiment
from fenicsxconcrete.finite_element_problem.base_material import MaterialProblem, QuadratureFields, SolutionFields
from fenicsxconcrete.util import Parameters, ureg
from fenicsxconcrete.util import ureg


class LinearElasticity(MaterialProblem):
Expand Down Expand Up @@ -44,8 +44,8 @@ def setup(self) -> None:
)

# define function space ets.
self.V = df.fem.VectorFunctionSpace(self.mesh, ("Lagrange", self.p["degree"])) # 2 for quadratic elements
self.V_scalar = df.fem.FunctionSpace(self.mesh, ("Lagrange", self.p["degree"]))
self.V = df.fem.functionspace(self.mesh, ("Lagrange", self.p["degree"], (self.mesh.geometry.dim,))) # 2 for quadratic elements
self.V_scalar = df.fem.functionspace(self.mesh, ("Lagrange", self.p["degree"], (1,)))

# Define variational problem
self.u_trial = ufl.TrialFunction(self.V)
Expand Down Expand Up @@ -100,7 +100,6 @@ def parameter_description() -> dict[str, str]:
"nu": "Poissons Ratio",
"stress_state": "for 2D plain stress or plane strain",
"degree": "Polynomial degree for the FEM model",
"dt": "time step",
}

return description
Expand Down Expand Up @@ -134,7 +133,7 @@ def sigma(self, u: ufl.argument.Argument) -> ufl.core.expr.Expr:

def solve(self) -> None:
self.update_time()
self.logger.info(f"solving t={self.time}")
self.logger.info("solving t=%s", self.time)
self.weak_form_problem.solve()

# TODO Defined as abstractmethod. Should it depend on sensor instead of material?
Expand Down
4 changes: 2 additions & 2 deletions src/fenicsxconcrete/sensor_definition/displacement_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ def measure(self, problem: MaterialProblem) -> None:
t : time of measurement for time dependent problems, default is 1
"""
# get displacements
bb_tree = df.geometry.BoundingBoxTree(problem.experiment.mesh, problem.experiment.mesh.topology.dim)
bb_tree = df.geometry.bb_tree(problem.experiment.mesh, problem.experiment.mesh.topology.dim)
cells = []

# Find cells whose bounding-box collide with the points
cell_candidates = df.geometry.compute_collisions(bb_tree, [self.where])
cell_candidates = df.geometry.compute_collisions_points(bb_tree, [self.where])

# Choose one of the cells that contains the point
colliding_cells = df.geometry.compute_colliding_cells(problem.experiment.mesh, cell_candidates, [self.where])
Expand Down
4 changes: 2 additions & 2 deletions src/fenicsxconcrete/sensor_definition/doh_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ def measure(self, problem: MaterialProblem) -> None:
# project stress onto visualization space

# finding the cells corresponding to the point
bb_tree = df.geometry.BoundingBoxTree(problem.experiment.mesh, problem.experiment.mesh.topology.dim)
bb_tree = df.geometry.bb_tree(problem.experiment.mesh, problem.experiment.mesh.topology.dim)
cells = []

# Find cells whose bounding-box collide with the points
cell_candidates = df.geometry.compute_collisions(bb_tree, [self.where])
cell_candidates = df.geometry.compute_collisions_points(bb_tree, [self.where])

# Choose one of the cells that contains the point
colliding_cells = df.geometry.compute_colliding_cells(problem.experiment.mesh, cell_candidates, [self.where])
Expand Down
6 changes: 3 additions & 3 deletions src/fenicsxconcrete/sensor_definition/strain_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,17 @@ def measure(self, problem: MaterialProblem) -> None:

strain_function = project(
strain, # stress fct from problem
df.fem.TensorFunctionSpace(problem.experiment.mesh, problem.q_fields.plot_space_type), # tensor space
df.fem.functionspace(problem.experiment.mesh, problem.q_fields.plot_space_type), # tensor space
problem.q_fields.measure,
)
# project stress onto visualization space

# finding the cells corresponding to the point
bb_tree = df.geometry.BoundingBoxTree(problem.experiment.mesh, problem.experiment.mesh.topology.dim)
bb_tree = df.geometry.bb_tree(problem.experiment.mesh, problem.experiment.mesh.topology.dim)
cells = []

# Find cells whose bounding-box collide with the points
cell_candidates = df.geometry.compute_collisions(bb_tree, [self.where])
cell_candidates = df.geometry.compute_collisions_points(bb_tree, [self.where])

# Choose one of the cells that contains the point
colliding_cells = df.geometry.compute_colliding_cells(problem.experiment.mesh, cell_candidates, [self.where])
Expand Down
6 changes: 3 additions & 3 deletions src/fenicsxconcrete/sensor_definition/stress_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,16 @@ def measure(self, problem: MaterialProblem) -> None:

stress_function = project(
stress, # stress fct from problem
df.fem.TensorFunctionSpace(problem.experiment.mesh, problem.q_fields.plot_space_type), # tensor space
df.fem.functionspace(problem.experiment.mesh, problem.q_fields.plot_space_type), # tensor space
problem.q_fields.measure,
)

# finding the cells corresponding to the point
bb_tree = df.geometry.BoundingBoxTree(problem.experiment.mesh, problem.experiment.mesh.topology.dim)
bb_tree = df.geometry.bb_tree(problem.experiment.mesh, problem.experiment.mesh.topology.dim)
cells = []

# Find cells whose bounding-box collide with the points
cell_candidates = df.geometry.compute_collisions(bb_tree, [self.where])
cell_candidates = df.geometry.compute_collisions_points(bb_tree, [self.where])

# Choose one of the cells that contains the point
colliding_cells = df.geometry.compute_colliding_cells(problem.experiment.mesh, cell_candidates, [self.where])
Expand Down
4 changes: 2 additions & 2 deletions src/fenicsxconcrete/sensor_definition/temperature_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ def measure(self, problem: MaterialProblem) -> None:
t : time of measurement for time dependent problems, default is 1
"""
# get displacements
bb_tree = df.geometry.BoundingBoxTree(problem.experiment.mesh, problem.experiment.mesh.topology.dim)
bb_tree = df.geometry.bb_tree(problem.experiment.mesh, problem.experiment.mesh.topology.dim)
cells = []

# Find cells whose bounding-box collide with the points
cell_candidates = df.geometry.compute_collisions(bb_tree, [self.where])
cell_candidates = df.geometry.compute_collisions_points(bb_tree, [self.where])

# Choose one of the cells that contains the point
colliding_cells = df.geometry.compute_colliding_cells(problem.experiment.mesh, cell_candidates, [self.where])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ def measure(self, problem: MaterialProblem) -> None:
# project stress onto visualization space

# finding the cells corresponding to the point
bb_tree = df.geometry.BoundingBoxTree(problem.experiment.mesh, problem.experiment.mesh.topology.dim)
bb_tree = df.geometry.bb_tree(problem.experiment.mesh, problem.experiment.mesh.topology.dim)
cells = []

# Find cells whose bounding-box collide with the points
cell_candidates = df.geometry.compute_collisions(bb_tree, [self.where])
cell_candidates = df.geometry.compute_collisions_points(bb_tree, [self.where])

# Choose one of the cells that contains the point
colliding_cells = df.geometry.compute_colliding_cells(problem.experiment.mesh, cell_candidates, [self.where])
Expand Down
7 changes: 5 additions & 2 deletions tests/boundary_conditions/test_bcs_get_boundary_dofs.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import dolfinx
import numpy as np
from mpi4py import MPI
from basix.ufl import element

from fenicsxconcrete.boundary_conditions.bcs import BoundaryConditions, get_boundary_dofs
from fenicsxconcrete.boundary_conditions.boundary import plane_at
Expand Down Expand Up @@ -44,7 +45,8 @@ def test_whole_boundary() -> None:
dim = 2

domain = dolfinx.mesh.create_unit_square(MPI.COMM_WORLD, n, n, dolfinx.mesh.CellType.quadrilateral)
V = dolfinx.fem.VectorFunctionSpace(domain, ("Lagrange", degree), dim=dim)
el = element("Lagrange", domain.basix_cell(), degree, shape=(dim,))
V = dolfinx.fem.functionspace(domain, el)

# option (a)
bc_handler = BoundaryConditions(domain, V)
Expand All @@ -70,7 +72,8 @@ def test_xy_plane() -> None:
dim = 3

domain = dolfinx.mesh.create_unit_cube(MPI.COMM_WORLD, n, n, n, dolfinx.mesh.CellType.hexahedron)
V = dolfinx.fem.VectorFunctionSpace(domain, ("Lagrange", degree), dim=dim)
el = element("Lagrange", domain.basix_cell(), degree, shape=(dim,))
V = dolfinx.fem.functionspace(domain, el)
xy_plane = plane_at(0.0, "z")

# option (a)
Expand Down
2 changes: 1 addition & 1 deletion tests/boundary_conditions/test_boundary_line_at.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
def test_cube() -> None:
n = 4
domain = dolfinx.mesh.create_unit_cube(MPI.COMM_WORLD, n, n, n, dolfinx.mesh.CellType.hexahedron)
V = dolfinx.fem.FunctionSpace(domain, ("Lagrange", 1))
V = dolfinx.fem.functionspace(domain, ("Lagrange", 1))

x_axis = line_at([0, 0], ["z", "y"])
y_axis = line_at([0, 0], ["z", "x"])
Expand Down
4 changes: 2 additions & 2 deletions tests/boundary_conditions/test_boundary_plane_at.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

def test_square() -> None:
domain = dolfinx.mesh.create_unit_square(MPI.COMM_WORLD, 8, 8, dolfinx.mesh.CellType.quadrilateral)
V = dolfinx.fem.FunctionSpace(domain, ("Lagrange", 1))
V = dolfinx.fem.functionspace(domain, ("Lagrange", 1))

bottom = plane_at(0.0, "y")
top = plane_at(1.0, "y")
Expand Down Expand Up @@ -56,7 +56,7 @@ def l_shaped_boundary(x):
def test_cube() -> None:
nx, ny, nz = 4, 4, 4
domain = dolfinx.mesh.create_unit_cube(MPI.COMM_WORLD, nx, ny, nz, dolfinx.mesh.CellType.hexahedron)
V = dolfinx.fem.FunctionSpace(domain, ("Lagrange", 1))
V = dolfinx.fem.functionspace(domain, ("Lagrange", 1))

xy_plane = plane_at(0.0, "z")
dofs = dolfinx.fem.locate_dofs_geometrical(V, xy_plane)
Expand Down
9 changes: 6 additions & 3 deletions tests/boundary_conditions/test_boundary_point_at.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import numpy as np
from mpi4py import MPI
from petsc4py.PETSc import ScalarType
from basix.ufl import element

from fenicsxconcrete.boundary_conditions.boundary import point_at

Expand All @@ -12,7 +13,7 @@ def test_type_error() -> None:
"""test TypeError in conversion to float"""
n = 10
domain = dolfinx.mesh.create_interval(MPI.COMM_WORLD, n, [0.0, 10.0])
V = dolfinx.fem.FunctionSpace(domain, ("Lagrange", 1))
V = dolfinx.fem.functionspace(domain, ("Lagrange", 1))
x = point_at(5)
dofs = dolfinx.fem.locate_dofs_geometrical(V, x)
nodal_value = 42
Expand All @@ -25,7 +26,7 @@ def test_type_error() -> None:
def test_function_space() -> None:
n = 101
domain = dolfinx.mesh.create_unit_square(MPI.COMM_WORLD, n, n, dolfinx.mesh.CellType.quadrilateral)
V = dolfinx.fem.FunctionSpace(domain, ("Lagrange", 2))
V = dolfinx.fem.functionspace(domain, ("Lagrange", 2))

h = 1.0 / n
my_point = point_at(np.array([h * 2, h * 5]))
Expand All @@ -40,7 +41,9 @@ def test_function_space() -> None:
def test_vector_function_space() -> None:
n = 101
domain = dolfinx.mesh.create_unit_square(MPI.COMM_WORLD, n, n, dolfinx.mesh.CellType.quadrilateral)
V = dolfinx.fem.VectorFunctionSpace(domain, ("Lagrange", 2))
degree = 2
ve = element("Lagrange", domain.basix_cell(), degree, shape=(2,))
V = dolfinx.fem.functionspace(domain, ve)

# note the inconsistency in specifying the coordinates
# this is handled by `to_floats`
Expand Down
Loading
Loading