diff --git a/conmech/dynamics/contact/damped_normal_compliance.py b/conmech/dynamics/contact/damped_normal_compliance.py index 995308ee..de25c502 100644 --- a/conmech/dynamics/contact/damped_normal_compliance.py +++ b/conmech/dynamics/contact/damped_normal_compliance.py @@ -24,6 +24,18 @@ def make_damped_norm_compl(obstacle_level: float, kappa: float, beta: float, int superclass = InteriorContactLaw if interior else PotentialOfContactLaw class DampedNormalCompliance(superclass): + @property + def kappa(self): + return kappa + + @property + def beta(self): + return beta + + @property + def obstacle_level(self): + return obstacle_level + @staticmethod def normal_bound(var_nu: float, static_displacement_nu: float, dt: float) -> float: """ diff --git a/examples/BOSK_2024.py b/examples/BOSK_2024.py new file mode 100644 index 00000000..259a1692 --- /dev/null +++ b/examples/BOSK_2024.py @@ -0,0 +1,277 @@ +from dataclasses import dataclass +from typing import Optional + +import numpy as np + +from conmech.dynamics.contact.damped_normal_compliance import make_damped_norm_compl +from conmech.helpers.config import Config +from conmech.mesh.boundaries_description import BoundariesDescription +from conmech.plotting.membrane import plot_in_columns, plot_limit_points +from conmech.scenarios.problems import ContactWaveProblem, InteriorContactWaveProblem +from conmech.simulations.problem_solver import WaveSolver +from conmech.properties.mesh_description import CrossMeshDescription +from conmech.state.products.verticalintersection import VerticalIntersection +from conmech.state.products.intersection_contact_limit_points import ( + VerticalIntersectionContactLimitPoints, +) +from conmech.state.state import State + + +@dataclass() +class BoundaryContactMembrane(ContactWaveProblem): + time_step: ... = 1 / 64 + propagation: ... = np.sqrt(4.0) + contact_law: ... = make_damped_norm_compl(obstacle_level=1.0, kappa=10.0, beta=0.1)() + + @staticmethod + def inner_forces(x: np.ndarray, t: Optional[float] = None) -> np.ndarray: + return np.array([100]) + + @staticmethod + def outer_forces( + x: np.ndarray, v: Optional[np.ndarray] = None, t: Optional[float] = None + ) -> np.ndarray: + return np.array([0.0]) + + boundaries: ... = BoundariesDescription( + dirichlet=lambda x: x[0] in (0,) or x[1] in (0, 1), + contact=lambda x: x[0] == 1, + ) + + +@dataclass() +class InteriorContactMembrane(InteriorContactWaveProblem): + time_step: ... = 1 / 512 + propagation: ... = np.sqrt(100.00) + contact_law: ... = make_damped_norm_compl( + obstacle_level=1.0, kappa=10.0, beta=100.0, interior=True + )() + + @staticmethod + def inner_forces(x: np.ndarray, t: Optional[float] = None) -> np.ndarray: + return np.array([2500]) + + @staticmethod + def outer_forces( + x: np.ndarray, v: Optional[np.ndarray] = None, t: Optional[float] = None + ) -> np.ndarray: + return np.array([0.0]) + + boundaries: ... = BoundariesDescription(dirichlet=lambda x: x[0] in (0, 1) or x[1] in (0, 1)) + + +def runner(config: Config, setup, name, steps, intersect, continuing, solving_method): + print(name) + output_step = ( + int(steps * 0.25), + int(steps * 0.5), + int(steps * 0.75), + steps, + ) + + to_simulate = False + if config.force: + to_simulate = True + else: + for step in output_step: + try: + State.load(f"{config.path}/{name}_step_{step}") + except IOError: + to_simulate = True + + if to_simulate: + runner = WaveSolver(setup, solving_method) + + if continuing: + path = f"{config.path}/{continuing}" + print("Loading:", path) + state = State.load(path) + state.products = {} + else: + state = None + + states = runner.solve( + n_steps=steps, + output_step=output_step, + products=[ + VerticalIntersectionContactLimitPoints( + obstacle_level=setup.contact_law.obstacle_level, x=intersect + ), + VerticalIntersection(x=intersect), + ], + initial_displacement=setup.initial_displacement, + initial_velocity=setup.initial_velocity, + state=state, + verbose=True, + ) + for step, state in enumerate(states): + state.save(f"{config.path}/{name}_step_{step}") + else: + states = [] + for step in output_step: + states.append(State.load(f"{config.path}/{name}_step_{step}")) + + if continuing: + path = f"{config.path}/{continuing}" + print("Loading:", path) + state = State.load(path) + plot_limit_points( + state.products[f"limit points at {intersect:.2f}"], + title=rf"$\kappa={setup.contact_law.kappa}$ " rf"$\beta={setup.contact_law.beta}$", + finish=False, + ) + plot_limit_points( + states[-1].products[f"limit points at {intersect:.2f}"], + title=rf"$\kappa={setup.contact_law.kappa}$, $\beta={setup.contact_law.beta}$", + ) + + states_ids = list(range(len(states))) + to_plot = states_ids + vmin = np.inf + vmax = -np.inf + field = "velocity" + zmin = np.inf + zmax = -np.inf + zfield = "displacement" + for i, state in enumerate(states): + if i not in to_plot: + continue + vmax = max(max(getattr(state, field)[:, 0]), vmax) + vmin = min(min(getattr(state, field)[:, 0]), vmin) + zmax = max(max(getattr(state, zfield)[:, 0]), zmax) + zmin = min(min(getattr(state, zfield)[:, 0]), zmin) + prec = 1 + zmax = round(zmax + 0.05 * prec, prec) + zmin = round(zmin - 0.05 * prec, prec) + states_ = [] + for i, state in enumerate(states): + if i not in to_plot: + continue + states_.append(state) + plot_in_columns( + states_, + field=field, + vmin=vmin, + vmax=vmax, + zmin=zmin, + zmax=zmax, + x=intersect, + title=f"intersection at {intersect:.2f}", + ) + plot_in_columns( + states_, + field=field, + vmin=vmin, + vmax=vmax, + zmin=zmin, + zmax=zmax, + in3d=True, + title=f"velocity", + ) + + +def boundary_contact(config: Config): + precision = 16 if not config.test else 3 + mesh_descr = CrossMeshDescription( + initial_position=None, max_element_perimeter=1 / precision, scale=[1, 1] + ) + default = BoundaryContactMembrane(mesh_descr) + T = 4.0 if not config.test else default.time_step * 2 + + setups = dict() + to_simulate = [ + "no contact", + "plain", + "beta=0.00", + ] + + setup = default + setups["plain"] = setup + + setup = BoundaryContactMembrane(mesh_descr) + setup.contact_law = make_damped_norm_compl( + obstacle_level=default.contact_law.obstacle_level, kappa=0.00, beta=0.0, interior=False + )() + setups["no contact"] = setup + + setup = BoundaryContactMembrane(mesh_descr) + setup.contact_law = make_damped_norm_compl( + obstacle_level=default.contact_law.obstacle_level, + kappa=default.contact_law.kappa, + beta=0.0, + interior=False, + )() + setups["beta=0.00"] = setup + + for name in to_simulate: + runner( + Config(output_dir="BOSK_case_2_bdry", force=True).init(), + setups[name], + name=name, + steps=int(T / setups[name].time_step) + 1, + intersect=1.00, + continuing=None, + solving_method="schur", + ) + + +def interior_contact(config: Config): + precision = 4 if not config.test else 3 + mesh_descr = CrossMeshDescription( + initial_position=None, max_element_perimeter=1 / precision, scale=[1, 1] + ) + default = InteriorContactMembrane(mesh_descr) + T = 0.5 if not config.test else default.time_step * 2 + + setups = dict() + to_simulate = [ + "plain", + "beta=0.00", + "beta=1000.0", + ] + + setup = default + setups["plain"] = setup + + setup = InteriorContactMembrane(mesh_descr) + setup.contact_law = make_damped_norm_compl( + obstacle_level=default.contact_law.obstacle_level, + kappa=default.contact_law.kappa, + beta=0.0, + interior=True, + )() + setups["beta=0.00"] = setup + + setup = InteriorContactMembrane(mesh_descr) + setup.contact_law = make_damped_norm_compl( + obstacle_level=default.contact_law.obstacle_level, + kappa=default.contact_law.kappa, + beta=1000.0, + interior=True, + )() + setups["beta=1000.0"] = setup + + for name in to_simulate: + runner( + Config(output_dir="BOSK_case_1_int").init(), + setups[name], + name=name, + steps=int(T / setups[name].time_step) + 1, + intersect=0.50, + continuing=None, + solving_method="global", + ) + + +def main(config: Config): + """ + Entrypoint to example. + + To see result of simulation you need to call from python `main(Config().init())`. + """ + boundary_contact(config) + interior_contact(config) + + +if __name__ == "__main__": + main(Config().init()) diff --git a/examples/BOSK_2024_example_1.py b/examples/BOSK_2024_example_1.py deleted file mode 100644 index c0032f8a..00000000 --- a/examples/BOSK_2024_example_1.py +++ /dev/null @@ -1,205 +0,0 @@ -from dataclasses import dataclass -from typing import Optional - -import numpy as np - -from conmech.dynamics.contact.damped_normal_compliance import make_damped_norm_compl -from conmech.helpers.config import Config -from conmech.mesh.boundaries_description import BoundariesDescription -from conmech.plotting.membrane import plot_in_columns, plot_limit_points -from conmech.scenarios.problems import ContactWaveProblem -from conmech.simulations.problem_solver import WaveSolver -from conmech.properties.mesh_description import CrossMeshDescription -from conmech.state.products.verticalintersection import VerticalIntersection -from conmech.state.products.intersection_contact_limit_points import ( - VerticalIntersectionContactLimitPoints, -) -from conmech.state.state import State - -TESTING = False -FORCE_SIMULATION = True -FULL = False -PRECISION = 16 if not TESTING else 3 -OBSTACLE_LEVEL = 0.01 -T = 4.0 - - -@dataclass() -class MembraneSetup(ContactWaveProblem): - time_step: ... = 1 / 512 - propagation: ... = np.sqrt(4.0) - contact_law: ... = make_damped_norm_compl(OBSTACLE_LEVEL, kappa=10.0, beta=0.5)() - - @staticmethod - def inner_forces(x: np.ndarray, t: Optional[float] = None) -> np.ndarray: - return np.array([100]) - - @staticmethod - def outer_forces( - x: np.ndarray, v: Optional[np.ndarray] = None, t: Optional[float] = None - ) -> np.ndarray: - return np.array([0.0]) - - boundaries: ... = BoundariesDescription( - # dirichlet=lambda x: x[0] in (0, 1) or x[1] in (0, 1) - dirichlet=lambda x: x[0] in (0,) or x[1] in (0, 1), - contact=lambda x: x[0] == 1, - ) - - -def main(config: Config, setup, name, steps): - """ - Entrypoint to example. - - To see result of simulation you need to call from python `main(Config().init())`. - """ - print(name) - output_step = (steps,) - to_simulate = False - if config.force: - to_simulate = True - else: - for step in output_step: - try: - State.load(f"{config.path}/{name}_step_{step}") - except IOError: - to_simulate = True - - if to_simulate: - runner = WaveSolver(setup, "schur") - - states = runner.solve( - n_steps=steps, - output_step=output_step, - products=[ - VerticalIntersectionContactLimitPoints(obstacle_level=OBSTACLE_LEVEL, x=1.0), - VerticalIntersection(x=1.0), - ], - initial_displacement=setup.initial_displacement, - initial_velocity=setup.initial_velocity, - verbose=True, - method="Powell", - ) - for step, state in enumerate(states): - state.save(f"{config.path}/{name}_step_{step}") - else: - states = [] - for step in output_step: - states.append(State.load(f"{config.path}/{name}_step_{step}")) - - plot_limit_points(states[-1].products["limit points at 1.00"]) - # intersect = states[-1].products['intersection at 1.00'] - # for t, v in intersect.data.items(): - # if t in (s / 2 for s in range(int(2 * T) + 1)): - # plt.title(f'{t:.2f}') - # plt.plot(*v) - # plt.show() - if not FULL: - return - - states_ids = list(range(len(states))) - to_plot = [ - 10, - 30, - 50, - 210, - 320, - 430, - 540, - 600, - ] # states_ids[1:4] #+ states_ids[::4][1:] - vmin = np.inf - vmax = -np.inf - field = "velocity" - zmin = np.inf - zmax = -np.inf - zfield = "displacement" - for i, state in enumerate(states): - if i not in to_plot: - continue - state["velocity"][:] = np.abs(state["velocity"])[:] - vmax = max(max(getattr(state, field)[:, 0]), vmax) - vmin = min(min(getattr(state, field)[:, 0]), vmin) - zmax = max(max(getattr(state, zfield)[:, 0]), zmax) - zmin = min(min(getattr(state, zfield)[:, 0]), zmin) - prec = 1 - zmax = round(zmax + 0.05 * prec, prec) - zmin = round(zmin - 0.05 * prec, prec) - states_ = [] - for i, state in enumerate(states): - if i not in to_plot: - continue - states_.append(state) - plot_in_columns( - states_, - field=field, - vmin=vmin, - vmax=vmax, - zmin=zmin, - zmax=zmax, - title=f"velocity", #: {i * setup.time_step:.2f}s" - ) - plot_in_columns( - states_, - field=field, - vmin=vmin, - vmax=vmax, - zmin=zmin, - zmax=zmax, - in3d=True, - title=f"velocity", #: {i * setup.time_step:.2f}s" - ) - - -if __name__ == "__main__": - mesh_descr = CrossMeshDescription( - initial_position=None, max_element_perimeter=1 / PRECISION, scale=[1, 1] - ) - setups = dict() - - # kappas = (0.0, 0.5, 1.0, 5.0, 10.0, 100.0)[-2:] - # betas = (0.0, 0.25, 0.5, 0.75, 1.0, 1.5)[1:-1] - # to_simulate = [] - # for kappa in kappas: - # for beta in betas: - # label = f"kappa={kappa:.2f};beta={beta:.2f}" - # to_simulate.append(label) - # setup = MembraneSetup(mesh_descr) - # setup.contact_law = make_DNC(OBSTACLE_LEVEL, kappa=kappa, beta=beta)() - # setups[label] = setup - to_simulate = [ - "no contact", - # "plain", - # "force" - # "beta=0.00", - # "beta=0.25", - # "beta=0.50", - # "beta=0.75", - # "beta=1.00", - ] - - setup = MembraneSetup(mesh_descr) - setups["plain"] = setup - - setup = MembraneSetup(mesh_descr) - setup.contact_law = make_damped_norm_compl(OBSTACLE_LEVEL, kappa=0.0, beta=0.0)() - setups["no contact"] = setup - - def inner_forces(x: np.ndarray, t: Optional[float] = None) -> np.ndarray: - return np.array([max(100 * (1 - t), 0)]) - - setup = MembraneSetup(mesh_descr) - setup.inner_forces = inner_forces - setups["force"] = setup - - setup = MembraneSetup(mesh_descr) - setup.contact_law = make_damped_norm_compl(OBSTACLE_LEVEL, kappa=10.0, beta=0.0)() - setups["beta=0"] = setup - - for name in to_simulate: - main( - Config(output_dir="BOSK.1", force=FORCE_SIMULATION).init(), - setups[name], - name=name, - steps=int(T / setups[name].time_step) + 1, - ) diff --git a/examples/BOSK_2024_example_2.py b/examples/BOSK_2024_example_2.py deleted file mode 100644 index 400bca66..00000000 --- a/examples/BOSK_2024_example_2.py +++ /dev/null @@ -1,266 +0,0 @@ -import time -from dataclasses import dataclass -from typing import Optional - -import numpy as np -from matplotlib import pyplot as plt - -from conmech.dynamics.contact.damped_normal_compliance import make_damped_norm_compl -from conmech.helpers.config import Config -from conmech.mesh.boundaries_description import BoundariesDescription -from conmech.plotting.membrane import ( - plot as membrane_plot, - plot_in_columns, - plot_limit_points, -) -from conmech.scenarios.problems import InteriorContactWaveProblem -from conmech.simulations.problem_solver import WaveSolver -from conmech.properties.mesh_description import CrossMeshDescription -from conmech.state.products.verticalintersection import VerticalIntersection -from conmech.state.products.intersection_contact_limit_points import ( - VerticalIntersectionContactLimitPoints, -) -from conmech.state.state import State - -TESTING = False -FORCE_SIMULATION = True -PRECISION = 8 if not TESTING else 3 -OBSTACLE_LEVEL = 1.0 -KAPPA = 10.0 -BETA = 0.0 -FORCE = 250.0 -PROPAGATION = 2.5 -TIMESTEP = 1 / 1024 -# TIMESTEP = 1/4096 -CONTINUING = None #'beta=100.0_step_32769' - -FULL = False -END = (0.9, 1) - - -def make_DNC(obstacle_level: float, kappa: float, beta: float): - return make_damped_norm_compl(obstacle_level, kappa, beta, interior=True) - - -@dataclass() -class MembraneSetup(InteriorContactWaveProblem): - time_step: ... = TIMESTEP - propagation: ... = PROPAGATION - contact_law: ... = make_DNC(OBSTACLE_LEVEL, kappa=KAPPA, beta=BETA)() - - @staticmethod - def inner_forces(x: np.ndarray, t: Optional[float] = None) -> np.ndarray: - return np.array([FORCE]) - - @staticmethod - def outer_forces( - x: np.ndarray, v: Optional[np.ndarray] = None, t: Optional[float] = None - ) -> np.ndarray: - return np.array([0.0]) - - boundaries: ... = BoundariesDescription(dirichlet=lambda x: x[0] in (0, 1) or x[1] in (0, 1)) - - -def main(config: Config, setup, name, steps): - """ - Entrypoint to example. - - To see result of simulation you need to call from python `main(Config().init())`. - """ - print(name) - output_step = (steps,) - to_simulate = False - if config.force: - to_simulate = True - else: - for step in output_step: - try: - State.load(f"{config.path}/{name}_step_{step}") - except IOError: - to_simulate = True - - if to_simulate: - runner = WaveSolver(setup, "global") - - if CONTINUING: - path = f"{config.path}/{CONTINUING}" - print("Loading:", path) - state = State.load(path) - state.products = {} - else: - state = None - - states = runner.solve( - n_steps=steps, - output_step=output_step, - products=[ - VerticalIntersectionContactLimitPoints(obstacle_level=OBSTACLE_LEVEL, x=0.50), - VerticalIntersection(x=0.50), - ], - initial_displacement=setup.initial_displacement, - initial_velocity=setup.initial_velocity, - state=state, - verbose=True, - # method="Powell", - ) - for step, state in enumerate(states): - state.save(f"{config.path}/{name}_step_{int(state.time / setup.time_step)}") - print(f"{config.path}/{name}_step_{int(state.time / setup.time_step)}") - else: - states = [] - for step in output_step: - states.append(State.load(f"{config.path}/{name}_step_{step}")) - - start = time.time() - if CONTINUING: - path = f"{config.path}/{CONTINUING}" - print("Loading:", path) - state = State.load(path) - plot_limit_points( - state.products["limit points at 0.50"], - title=rf"$\kappa={setup.contact_law.KAPPA}$ " rf"$\beta={setup.contact_law.BETA}$", - finish=False, - ) - plot_limit_points( - states[-1].products["limit points at 0.50"], - title=rf"$\kappa={setup.contact_law.KAPPA}$ " rf"$\beta={setup.contact_law.BETA}$", - finish=False, - ) - print(time.time() - start) - plt.grid() - plt.show() - # intersect = states[-1].products['intersection at 0.50'] - # results = tuple(intersect.data.items()) - # T = results[-1][0] - # num = len(results) - # i = 0 - # for t, v in intersect.data.items(): - # i += 1 - # # if t in (s / 2 for s in range(int(2 * T) + 1)): - # plt.plot(*v, color=f'{1 - t / T:.3f}') - # if num * END[0] < i < num * END[1]: - # break - # plt.title(f'{t:.2f}') - # plt.show() - if not FULL: - return - - states_ids = list(range(len(states))) - to_plot = states_ids[:64:4] # [2, 4, 8, 11, 13, 15, 17, 20] #states_ids[1:4] + states_ids[-1:] - vmin = np.inf - vmax = -np.inf - field = "velocity" - zmin = np.inf - zmax = -np.inf - zfield = "displacement" - for i, state in enumerate(states): - if i not in to_plot: - continue - vmax = max(max(getattr(state, field)[:, 0]), vmax) - vmin = min(min(getattr(state, field)[:, 0]), vmin) - zmax = max(max(getattr(state, zfield)[:, 0]), zmax) - zmin = min(min(getattr(state, zfield)[:, 0]), zmin) - # vmax = min(vmax, 1) - # vmin = max(vmin, -1) - prec = 1 - zmax = round(zmax + 0.05 * prec, prec) - zmin = round(zmin - 0.05 * prec, prec) - states_ = [] - for i, state in enumerate(states): - if i not in to_plot: - continue - states_.append(state) - plot_in_columns( - states_, - field=field, - vmin=vmin, - vmax=vmax, - zmin=zmin, - zmax=zmax, - x=0.5, - title=f"velocity", #: {i * setup.time_step:.2f}s" - ) - # plot_in_columns( - # states_, field=field, vmin=vmin, vmax=vmax, zmin=zmin, zmax=zmax, - # in3d=True, - # title=f"velocity" #: {i * setup.time_step:.2f}s" - # ) - - -if __name__ == "__main__": - mesh_descr = CrossMeshDescription( - initial_position=None, max_element_perimeter=1 / PRECISION, scale=[1, 1] - ) - T = 2.0 if not TESTING else MembraneSetup(None).time_step * 2 - setups = dict() - to_simulate = [ - "plain", - # "nonzero", - # "velocity", - # "force", - # "beta=0", - # "beta=0.5", - # "beta=1.0", - # "beta=10.0", - # "beta=100.0", - # "beta=200.0", - ] - - setup = MembraneSetup(mesh_descr) - setups["plain"] = setup - - def initial_displacement(x: np.ndarray) -> np.ndarray: - a = (x[:, 1] - 1) * 4 * (x[:, 0] * (x[:, 0] - 1)) - b = np.zeros(x.shape[0]) - c = np.stack((a, b), axis=1) - return c - - setup = MembraneSetup(mesh_descr) - setup.initial_displacement = initial_displacement - setups["nonzero"] = setup - - setup = MembraneSetup(mesh_descr) - setup.contact_law = make_DNC(OBSTACLE_LEVEL, kappa=KAPPA, beta=0.5)() - setups["beta=0.5"] = setup - - setup = MembraneSetup(mesh_descr) - setup.contact_law = make_DNC(OBSTACLE_LEVEL, kappa=KAPPA, beta=1.0)() - setups["beta=1.0"] = setup - - setup = MembraneSetup(mesh_descr) - setup.contact_law = make_DNC(OBSTACLE_LEVEL, kappa=KAPPA, beta=10.0)() - setups["beta=10.0"] = setup - - setup = MembraneSetup(mesh_descr) - setup.contact_law = make_DNC(OBSTACLE_LEVEL, kappa=KAPPA, beta=100.0)() - setups["beta=100.0"] = setup - - setup = MembraneSetup(mesh_descr) - setup.contact_law = make_DNC(OBSTACLE_LEVEL, kappa=KAPPA, beta=200.0)() - setups["beta=200.0"] = setup - - def initial_velocity(x: np.ndarray) -> np.ndarray: - return np.ones_like(x) * 10 - - setup = MembraneSetup(mesh_descr) - setup.initial_velocity = initial_velocity - setups["velocity"] = setup - - def inner_forces(x: np.ndarray, t: Optional[float] = None) -> np.ndarray: - return np.array([max(15 * (1 - t), 0)]) - - setup = MembraneSetup(mesh_descr) - setup.inner_forces = inner_forces - setups["force"] = setup - - setup = MembraneSetup(mesh_descr) - setup.contact_law = make_DNC(OBSTACLE_LEVEL, kappa=KAPPA, beta=0.0)() - setups["beta=0"] = setup - - for name in to_simulate: - main( - Config(output_dir="BOSK.2", force=FORCE_SIMULATION).init(), - setups[name], - name=name, - steps=int(T / setups[name].time_step) + 1, - ) diff --git a/tests/test_conmech/regression/test_membrane_DNC.py b/tests/test_conmech/regression/test_membrane_DNC.py index b26d04c2..07337052 100644 --- a/tests/test_conmech/regression/test_membrane_DNC.py +++ b/tests/test_conmech/regression/test_membrane_DNC.py @@ -22,11 +22,11 @@ import numpy as np import pytest +from conmech.dynamics.contact.damped_normal_compliance import make_damped_norm_compl from conmech.mesh.boundaries_description import BoundariesDescription from conmech.scenarios.problems import InteriorContactWaveProblem from conmech.simulations.problem_solver import WaveSolver from conmech.properties.mesh_description import CrossMeshDescription -from examples.BOSK_2024_example_2 import make_DNC @pytest.fixture(params=["global"]) @@ -41,7 +41,9 @@ def generate_test_suits(): class MembraneSetup(InteriorContactWaveProblem): time_step: ... = 0.1 propagation: ... = 1.0 - contact_law: ... = make_DNC(0.01, kappa=1.0, beta=0.5)() + contact_law: ... = make_damped_norm_compl( + obstacle_level=0.01, kappa=1.0, beta=0.5, interior=True + )() @staticmethod def inner_forces(x: np.ndarray, t: Optional[float] = None) -> np.ndarray: @@ -114,7 +116,9 @@ def outer_forces( class MembraneSetup(InteriorContactWaveProblem): time_step: ... = 0.1 propagation: ... = 1.0 - contact_law: ... = make_DNC(0.01, kappa=10.0, beta=0.5)() + contact_law: ... = make_damped_norm_compl( + obstacle_level=0.01, kappa=1.0, beta=0.5, interior=True + )() @staticmethod def inner_forces(x: np.ndarray, t: Optional[float] = None) -> np.ndarray: diff --git a/tests/test_conmech/smoke/test_examples.py b/tests/test_conmech/smoke/test_examples.py index 06ec2470..e88c3a49 100644 --- a/tests/test_conmech/smoke/test_examples.py +++ b/tests/test_conmech/smoke/test_examples.py @@ -18,6 +18,7 @@ from examples.Jureczka_Ochal_Bartman_2023 import main as Jureczka_Ochal_Bartman_2023 from examples.Sofonea_Ochal_Bartman_2023 import main as Sofonea_Ochal_Bartman_2023 from examples.BOST_2024 import main as BOST_2024 +from examples.BOSK_2024 import main as BOSK_2024 from examples.example_Tarzia_problem import main as Tarzia_problem from examples.example_poisson import main as poisson from examples.example_nonhomogenous_density import main as nonhomogenous_density @@ -44,6 +45,7 @@ Config(outputs_path="./output/SOB2023", **default_args).init() ), "BOST_2024": lambda: BOST_2024(Config(outputs_path="./output/BOST2024", **default_args).init()), + "BOSK_2024": lambda: BOSK_2024(Config(outputs_path="./output/BOSK2024", **default_args).init()), "Tarzia_problem": lambda: Tarzia_problem( Config(outputs_path="./output/BOST2024", **default_args).init() ),