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

Dynamically updating Neumann load boundary conditions for Incremental Loading #52

Open
RayKruger opened this issue Feb 5, 2025 · 1 comment

Comments

@RayKruger
Copy link

I am modeling large-strain linear elasticity for a cantilever beam using JAX-FEM. In this simulation, I need to dynamically update the Neumann boundary conditions (applied loads) over multiple load steps, incrementally increasing the applied force.

In the plasticity example, I see that Dirichlet displacement boundary conditions can easily be updated dynamically in multiple steps using:

problem.fe.update_Dirichlet_boundary_conditions(dirichlet_bc_info)

where dirichlet_bc_info is structured as:

dirichlet_bc_info = [location_fns, vecs, value_fns]

However, the Neumann bc in the problem class currently only accepts location_fns (position functions) and does not support value functions, making dynamic load updates a little harder.

I implemented a workaround by using the problem.get_surface_maps with the optional argument cell_internal_vars_surface and providing a custom problem.update_load method:

def get_surface_maps(self):
    def surface_map(u, x, cell_internal_vars_surface):
        return np.array([0.0, cell_internal_vars_surface])
    return [surface_map]
                
def update_load(self, new_load):
    for i in range(len(self.internal_vars_surfaces)):
        num_face_quads = self.physical_surface_quad_points[i].shape[0]
        # Create an array of shape (num_face_quads,) filled with new_load
        self.internal_vars_surfaces[i] = (np.full((num_face_quads,), new_load),)

Example of the multi-step Neumann bc I got working:

Image

I also had to adjust the internal JAX-FEM surface_kernel’s jnp.vmap call to match dimensions. This solution is rather hacky and requires digging deep into the internals.

Is there a better way to do this? Could the problem class be extended to support dynamic Neumann bc function updates similar to the Dirichlet boundary condition?

@xwpken
Copy link
Collaborator

xwpken commented Feb 23, 2025

Hi, it seems that you want to change the magnitude of the applied forces, right? If so, your implementation is correct. But you don't need to change the internal codes, for we have already defined the same variable internal_vars_surfaces, see

self.internal_vars_surfaces = [() for _ in range(len(self.boundary_inds_list))]

You only need to set up the internal_vars_surfaces with the correct format (corresponding to each get_surface_map), and the surface_kernel will get the input.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants