Skip to content

Commit

Permalink
122 make sure that parameter have correct units (#141)
Browse files Browse the repository at this point in the history
* set default parameters in base experiment instead of in each child once, move all parameter decleration into default_parameters function

* add dimensionaly test of eyperiment parameters

* add parameter dimensionalty test in material problems

* fixed thix test missing default parameter

* add set to default parameters in doc examples

* add test for dimensionality check and exclude old default_parameter test

* add default parameter test

* changed degree in cylinder example to element_order

* Update src/fenicsxconcrete/finite_element_problem/concrete_thermo_mechanical.py

Co-authored-by: Sjard Mathis Rosenbusch <[email protected]>

* Update src/fenicsxconcrete/finite_element_problem/concrete_thermo_mechanical.py

Co-authored-by: Sjard Mathis Rosenbusch <[email protected]>

* Update src/fenicsxconcrete/finite_element_problem/concrete_thermo_mechanical.py

Co-authored-by: Sjard Mathis Rosenbusch <[email protected]>

* add Sjards comments

* add Sjards comments

---------

Co-authored-by: aradermacher <[email protected]>
Co-authored-by: Sjard Mathis Rosenbusch <[email protected]>
  • Loading branch information
3 people authored Oct 5, 2023
1 parent 304d2b9 commit 624caee
Show file tree
Hide file tree
Showing 20 changed files with 254 additions and 141 deletions.
3 changes: 2 additions & 1 deletion docs/examples/3_point_bending.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# Setting up the Beam
# -------------------
# First, initialize the setup for the simply supported beam with a distributed load.
# Define the geometry, the mesh, and the load.
# Define the geometry, the mesh, and the load. Not defined parameters are set to default values (from class function default_parameters).
# Note, all parameters must be pint objects:

parameters = {}
Expand All @@ -36,6 +36,7 @@
# Initializing the Linear Elasticity Problem
# ------------------------------------------
# Second, initialize the linear elastic problem using the setup object and further material parameters:
# Again not defined parameters are set to default values (from class function default_parameters).

parameters["rho"] = 7750 * ureg("kg/m^3")
parameters["E"] = 210e9 * ureg("N/m^2")
Expand Down
1 change: 1 addition & 0 deletions docs/examples/cylinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
# * `mesh_density` (mesh density) in 1/m
#
# The parameters must be defined as `pint` objects
# Parameters required but not defined are set to default values (from class function default_parameters).
#
# Example code
# ------------
Expand Down
9 changes: 2 additions & 7 deletions src/fenicsxconcrete/experimental_setup/am_multiple_layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,7 @@ def __init__(self, parameters: dict[str, pint.Quantity]):
"""

# initialize default parameters for the setup
default_p = Parameters()
# default_p['dummy'] = 'example' * ureg('') # example default parameter for this class

# updating parameters, overriding defaults
default_p.update(parameters)
super().__init__(default_p)
super().__init__(parameters)

@staticmethod
def default_parameters() -> dict[str, pint.Quantity]:
Expand All @@ -52,6 +46,7 @@ def default_parameters() -> dict[str, pint.Quantity]:
"""

setup_parameters = {}
setup_parameters["degree"] = 2 * ureg("") # polynomial degree
# geometry
setup_parameters["dim"] = 2 * ureg("")
setup_parameters["num_layers"] = 10 * ureg("") # number of layers in y
Expand Down
31 changes: 26 additions & 5 deletions src/fenicsxconcrete/experimental_setup/base_experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,33 @@ def __init__(self, parameters: dict[str, pint.Quantity]) -> None:
"""

# initialize parameter attributes
default_setup_parameters = Parameters()
# setting up default setup parameters
default_setup_parameters["degree"] = 2 * ureg("") # polynomial degree
setup_parameters = Parameters()

# setting up default setup parameters defined in each child
default_p = self.default_parameters()
setup_parameters.update(default_p)
# update with input parameters
default_setup_parameters.update(parameters)
setup_parameters.update(parameters)

# get logger info which parameters are set to default values
# plus check dimensionality of input parameters
keys_set_default = []
for key in dict(default_p):
if key not in parameters:
keys_set_default.append(key)
else:
# check if units are compatible
dim_given = parameters[key].dimensionality
dim_default = default_p[key].dimensionality
if dim_given != dim_default:
raise ValueError(
f"given units for {key} are not compatible with default units: {dim_given} != {dim_default}"
)
self.logger.info(f"for the following parameters, the default values are used: {keys_set_default}")

# as attribute
self.parameters = default_setup_parameters
self.parameters = setup_parameters

# remove units for use in fem model
self.p = self.parameters.to_magnitude()

Expand All @@ -59,6 +78,8 @@ def default_parameters() -> dict[str, pint.Quantity]:
"""

pass

@abstractmethod
def create_displacement_boundary(self, V: df.fem.FunctionSpace) -> list[df.fem.bcs.DirichletBCMetaClass] | None:
"""defines empty displacement boundary conditions (to be done in child)
Expand Down
10 changes: 2 additions & 8 deletions src/fenicsxconcrete/experimental_setup/cantilever_beam.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,7 @@ def __init__(self, parameters: dict[str, pint.Quantity] | None = None):
"""

# initialize default parameters for the setup
default_p = Parameters()
# default_p['dummy'] = 'example' * ureg('') # example default parameter for this class

# updating parameters, overriding defaults
default_p.update(parameters)

super().__init__(default_p)
super().__init__(parameters)

def setup(self) -> None:
"""defines the mesh for 2D or 3D
Expand Down Expand Up @@ -77,6 +70,7 @@ def default_parameters() -> dict[str, pint.Quantity]:
"""

setup_parameters = {}

setup_parameters["length"] = 1 * ureg("m")
setup_parameters["height"] = 0.3 * ureg("m")
setup_parameters["width"] = 0.3 * ureg("m") # only relevant for 3D case
Expand Down
10 changes: 3 additions & 7 deletions src/fenicsxconcrete/experimental_setup/compression_cylinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,7 @@ def __init__(self, parameters: dict[str, pint.Quantity] | None = None) -> None:
"""

# initialize a set of default parameters
p = Parameters()

p.update(parameters)

super().__init__(p)
super().__init__(parameters)

# initialize variable top_displacement
self.top_displacement = df.fem.Constant(domain=self.mesh, c=0.0) # applied via fkt: apply_displ_load(...)
Expand Down Expand Up @@ -127,7 +122,7 @@ def setup(self) -> None:
# until the bottom surface area matches that of a circle with the initially defined radius
def create_cylinder_mesh(radius, p):
# generate cylinder mesh using gmsh
mesh = generate_cylinder_mesh(radius, p["height"], p["mesh_density"], p["degree"])
mesh = generate_cylinder_mesh(radius, p["height"], p["mesh_density"], p["element_order"])
facets = df.mesh.locate_entities_boundary(mesh, 2, plane_at(0.0, 2))
tdim = mesh.topology.dim
f_v = mesh.topology.connectivity(tdim - 1, 0).array.reshape(-1, 3)
Expand Down Expand Up @@ -169,6 +164,7 @@ def default_parameters() -> dict[str, pint.Quantity]:
"""

default_parameters = {}
default_parameters["element_order"] = 2 * ureg("") # polynomial degree

# boundary setting
default_parameters["bc_setting"] = "free" * ureg("") # boundary setting, two options available: fixed and free
Expand Down
10 changes: 2 additions & 8 deletions src/fenicsxconcrete/experimental_setup/simple_beam.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,7 @@ def __init__(self, parameters: dict[str, pint.Quantity]) -> None:
"""

# initialize default parameters for the setup
default_p = Parameters()
default_p["degree"] = 2 * ureg("") # polynomial degree

# updating parameters, overriding defaults
default_p.update(parameters)

super().__init__(default_p)
super().__init__(parameters)

def setup(self):
"""defines the mesh for 2D or 3D
Expand Down Expand Up @@ -81,6 +74,7 @@ def default_parameters() -> dict[str, pint.Quantity]:
"""

setup_parameters = {}

setup_parameters["load"] = 10000 * ureg("N/m^2")
setup_parameters["length"] = 1 * ureg("m")
setup_parameters["height"] = 0.3 * ureg("m")
Expand Down
19 changes: 7 additions & 12 deletions src/fenicsxconcrete/experimental_setup/simple_cube.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from fenicsxconcrete.boundary_conditions.bcs import BoundaryConditions
from fenicsxconcrete.experimental_setup.base_experiment import Experiment
from fenicsxconcrete.util import Parameters, ureg
from fenicsxconcrete.util import LogMixin, Parameters, ureg


class SimpleCube(Experiment):
Expand All @@ -33,17 +33,7 @@ def __init__(self, parameters: dict[str, pint.Quantity] | None = None) -> None:
see default_parameters for a first guess
"""

# initialize a set of default parameters
default_p = Parameters()
default_p["height"] = 1 * ureg("m")
default_p["width"] = 1 * ureg("m")
default_p["length"] = 1 * ureg("m")
default_p["T_0"] = ureg.Quantity(20.0, ureg.degC)
default_p["T_bc"] = ureg.Quantity(20.0, ureg.degC)

default_p.update(parameters)

super().__init__(default_p)
super().__init__(parameters)

@staticmethod
def default_parameters() -> dict[str, pint.Quantity]:
Expand All @@ -56,6 +46,11 @@ def default_parameters() -> dict[str, pint.Quantity]:

setup_parameters = {}

setup_parameters["height"] = 1 * ureg("m")
setup_parameters["width"] = 1 * ureg("m")
setup_parameters["length"] = 1 * ureg("m")
setup_parameters["T_0"] = ureg.Quantity(20.0, ureg.degC)
setup_parameters["T_bc"] = ureg.Quantity(20.0, ureg.degC)
setup_parameters["dim"] = 3 * ureg("")
setup_parameters["num_elements_length"] = 2 * ureg("")
setup_parameters["num_elements_width"] = 2 * ureg("")
Expand Down
9 changes: 2 additions & 7 deletions src/fenicsxconcrete/experimental_setup/tensile_beam.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,8 @@ def __init__(self, parameters: dict[str, pint.Quantity] | None = None) -> None:
see default_parameters for a first guess
"""
# initialize a set of "basic parameters"
default_p = Parameters()
# default_p['dummy'] = 'example' * ureg('') # example default parameter for this class

# updating parameters, overriding defaults
default_p.update(parameters)

super().__init__(default_p)
super().__init__(parameters)

def setup(self) -> None:
"""defines the mesh for 2D or 3D
Expand Down Expand Up @@ -76,6 +70,7 @@ def default_parameters() -> dict[str, pint.Quantity]:
"""

setup_parameters = {}

setup_parameters["length"] = 1 * ureg("m")
setup_parameters["height"] = 0.3 * ureg("m")
setup_parameters["width"] = 0.3 * ureg("m") # only relevant for 3D case
Expand Down
38 changes: 29 additions & 9 deletions src/fenicsxconcrete/finite_element_problem/base_material.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,34 @@ def __init__(
self.experiment = experiment
self.mesh = self.experiment.mesh

# setting up default material parameters
default_fem_parameters = Parameters()
default_fem_parameters["g"] = 9.81 * ureg("m/s^2")
default_fem_parameters["dt"] = 1.0 * ureg("s")

# adding experimental parameters to dictionary to combine to one
default_fem_parameters.update(self.experiment.parameters)
# initialize parameter attributes
setup_parameters = Parameters()
# setting up default setup parameters defined in each child
_, default_p = self.default_parameters()
setup_parameters.update(default_p)
# update with experiment parameters
setup_parameters.update(self.experiment.parameters)
# update with input parameters
default_fem_parameters.update(parameters)
self.parameters = default_fem_parameters
setup_parameters.update(parameters)

# get logger info which input parameters are set to default values
# plus check dimensionality of input parameters
keys_set_default = []
for key in dict(default_p):
if key not in parameters:
keys_set_default.append(key)
else:
# check if units are compatible
dim_given = parameters[key].dimensionality
dim_default = default_p[key].dimensionality
if dim_given != dim_default:
raise ValueError(
f"given units for {key} are not compatible with default units: {dim_given} != {dim_default}"
)
self.logger.info(f"for the following parameters, the default values are used: {keys_set_default}")

# set parameters as attribute
self.parameters = setup_parameters
# remove units for use in fem model
self.p = self.parameters.to_magnitude()
self.experiment.p = self.p # update experimental parameter list for use in e.g. boundary definition
Expand Down Expand Up @@ -135,6 +153,8 @@ def default_parameters() -> tuple[Experiment, dict[str, pint.Quantity]]:
"""returns a dictionary with required parameters and a set of working values as example"""
# this must de defined in each setup class

pass

@abstractmethod
def setup(self) -> None:
# initialization of this specific problem
Expand Down
22 changes: 13 additions & 9 deletions src/fenicsxconcrete/finite_element_problem/concrete_am.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,19 @@ def __init__(
"""

# adding default material parameter, will be overridden by outside input
default_p = Parameters()
default_p["stress_state"] = "plane_strain" * ureg("") # default stress state for 2D optional "plane_stress"

# updating parameters, overriding defaults
default_p.update(parameters)
# # adding default material parameter, will be overridden by outside input
# default_p = Parameters()
# # default stress state for 2D optional "plane_stress"
#
# # updating parameters, overriding defaults
# default_p.update(parameters)

if nonlinear_problem:
self.nonlinear_problem = nonlinear_problem
else:
self.nonlinear_problem = ConcreteThixElasticModel # default material

super().__init__(experiment, default_p, pv_name, pv_path)
super().__init__(experiment, parameters, pv_name, pv_path)

@staticmethod
def parameter_description() -> dict[str, str]:
Expand All @@ -73,12 +73,13 @@ def parameter_description() -> dict[str, str]:
description = {
"general parameters": {
"rho": "density of fresh concrete",
"g": "gravity",
"nu": "Poissons Ratio",
"degree": "Polynomial degree for the FEM model",
"q_degree": "Polynomial degree for which the quadrature rule integrates correctly",
"load_time": "time in which the load is applied",
"stress_state": "for 2D plain stress or plane strain",
"dt": "time step", # default set in material base class
"dt": "time step",
},
"ThixElasticModel": {
"E_0": "Youngs Modulus at age=0",
Expand Down Expand Up @@ -112,10 +113,13 @@ def default_parameters(
joined_parameters = {
# Material parameter for concrete model with structural build-up
"rho": 2070 * ureg("kg/m^3"), # density of fresh concrete
"g": 9.81 * ureg("m/s^2"), # gravity
"nu": 0.3 * ureg(""), # Poissons Ratio
# other model parameters
# "degree": 2 * ureg(""), # polynomial degree --> default defined in base_experiment!!
"degree": 2 * ureg(""), # polynomial degree
"q_degree": 2 * ureg(""), # quadrature rule
"stress_state": "plane_strain" * ureg(""), # for 2D stress state
"dt": 1.0 * ureg("s"), # time step
"load_time": 60 * ureg("s"), # body force load applied in s
}
if not non_linear_problem or non_linear_problem == ConcreteThixElasticModel:
Expand Down
Loading

0 comments on commit 624caee

Please sign in to comment.