Source code for geometry_initialization

# Copyright (c) 2025 ONERA and MINES Paris, France 
#
# All rights reserved.
#
# This file is part of OptiCut.
#
# Author(s)     : Amina El Bachari 

import numpy as np
import math
import ufl


###################################
####  Level set's definition   ####
###################################
[docs] def circle(x): r"""Computes the signed distance from a point to a circle. This function calculates the signed distance from a point `x = (x_0, x_1)` to a circle centered at `(1, 0.5)` with radius `0.3`. The function returns a negative value if the point is inside the circle and a positive value if it is outside. .. math:: \text{distance}(x) = -\left(\sqrt{(x_0 - 1)^2 + (x_1 - 0.5)^2} - 0.3\right) :param tuple x: A tuple representing the point coordinates (x_0, x_1). :returns: The signed distance from the point to the circle. :rtype: float """ return -(np.sqrt((x[0]- 1)**2 + (x[1] - 0.5)**2) - 0.3)
[docs] def level_set(x, parameters): r"""Computes a 2D level set function based on cosine functions. This function returns a level set value based on a combination of cosine functions depending on the coordinates of the input point `x = (x_0, x_1)` and a parameter `lx`. .. math:: \text{level set}(x) = -\cos\left(\frac{6\pi x_0}{l_x}\right)\cos(4\pi x_1) - 0.6 :param tuple x: A tuple representing the point coordinates (x_0, x_1). :param parameters: The parameters object containing the domain length `lx`. :type parameters: object with attribute `lx`. :returns: The computed level set value. :rtype: float """ res = -2*ufl.cos(6.0/parameters.lx*math.pi*x[0]) * ufl.cos(4.0*math.pi*x[1]) -0.6 return res/2
[docs] def level_set_3D(x, parameters): r"""Computes a 3D level set function based on cosine functions. This function returns a level set value based on a combination of cosine functions depending on the coordinates of the input point `x = (x_0, x_1, x_2)` and a parameter `lx`, 'ly' and 'lz', the dimensions of the box containing :math:`\Omega`. .. math:: \text{level set}(x) = -\cos\left(\frac{6\pi x_0}{l_x}\right)\cos(4\pi x_1)\cos(4\pi x_2) - 0.6 :param tuple x: A tuple representing the point coordinates (x_0, x_1, x_2). :param parameters: The parameters object containing the domain length `lx`, 'ly' and 'lz'. :type parameters: object with attribute `lx`. :returns: The computed level set value. :rtype: float """ res = -2*ufl.cos(6.0/parameters.lx*math.pi*x[0]) * ufl.cos(4.0*math.pi*x[1]) -0.6 return res/2
def level_set_L_shape(x): """ Calculate the level set for an L-shaped domain. This function computes the level set for a geometric shape consisting of a series of overlapping circles. The L-shape is represented by a set of level sets for these circles, and the function uses the `ufl.max_value` and `ufl.sqrt` functions to compute the level set values for a given point `x` in the domain. Parameters ---------- x : tuple of float A tuple containing the coordinates (x[0], x[1]) of the point where the level set is evaluated. The point is expected to be in 2D space. Returns ------- float The computed level set value at the point `x`. The value represents the distance from the point `x` to the nearest boundary of the L-shaped domain formed by the overlapping circles. A negative value indicates the point is inside the domain, and a positive value indicates the point is outside the domain. Notes ----- The function uses a series of circles with radius `r_cercle` and an adjusted radius `r_cercle_modif` to form the shape. The level set is computed by iteratively taking the maximum of the distances to the circle boundaries. The function is designed to work with the `ufl` module, typically used in finite element methods for computational geometry and simulations. Example ------- >>> x = (1.0, 2.0) >>> level_set_L_shape(x) -0.0037388523762586055 See Also -------- ufl.max_value, ufl.sqrt """ r_cercle = 0.05 r_cercle_modif = 0.06 d0 = ufl.max_value(-(ufl.sqrt((x[0]- 0)**2 + (x[1] - 0)**2) - r_cercle_modif),-(ufl.sqrt((x[0]- 4*r_cercle)**2 + (x[1] - 0)**2) - r_cercle_modif)) d1 = ufl.max_value(-(ufl.sqrt((x[0]- 8*r_cercle)**2 + (x[1] - 0.0)**2) - r_cercle_modif),d0) d2 = ufl.max_value(d1,-(ufl.sqrt((x[0]- 12*r_cercle)**2 + (x[1] - 0.)**2) - r_cercle_modif)) d3 = ufl.max_value(d2,-(ufl.sqrt((x[0]- 1)**2 + (x[1] - 0.0)**2) - r_cercle_modif)) d4 = ufl.max_value(d3,-(ufl.sqrt((x[0]- 0.)**2 + (x[1] - 4*r_cercle)**2) - r_cercle_modif)) d5 = ufl.max_value(d4,-(ufl.sqrt((x[0]- 4*r_cercle)**2 + (x[1] - 4*r_cercle)**2) - r_cercle_modif)) d7 = ufl.max_value(d5,-(ufl.sqrt((x[0]- 8*r_cercle)**2 + (x[1] - 4*r_cercle)**2) - r_cercle_modif)) d8 = ufl.max_value(d7,-(ufl.sqrt((x[0]- 12*r_cercle)**2 + (x[1] - 4*r_cercle)**2) - r_cercle_modif)) d9 = ufl.max_value(d8,-(ufl.sqrt((x[0]- 16*r_cercle)**2 + (x[1] - 4*r_cercle)**2) - r_cercle_modif)) d10 = ufl.max_value(d9,-(ufl.sqrt((x[0]- 0.)**2 + (x[1] - 8*r_cercle)**2) - r_cercle_modif)) #d11 = ufl.max_value(d10,-(ufl.sqrt((x[0]- 4*r_cercle)**2 + (x[1] - 8*r_cercle)**2) - r_cercle_modif)) d12 = ufl.max_value(d10,-(ufl.sqrt((x[0]- 8*r_cercle)**2 + (x[1] - 8*r_cercle)**2) - r_cercle_modif)) d13 = ufl.max_value(d12,-(ufl.sqrt((x[0]- 12*r_cercle)**2 + (x[1] - 8*r_cercle)**2) - r_cercle_modif)) d14 = ufl.max_value(d13,-(ufl.sqrt((x[0]- 1.)**2 + (x[1] - 4*r_cercle)**2) - r_cercle_modif)) d15 = ufl.max_value(d14,-(ufl.sqrt((x[0]- 0.)**2 + (x[1] - 12*r_cercle)**2) - r_cercle_modif)) d16 = ufl.max_value(d15,-(ufl.sqrt((x[0]- 4*r_cercle)**2 + (x[1] - 12*r_cercle)**2) - r_cercle_modif)) d17 = ufl.max_value(d16,-(ufl.sqrt((x[0]- 8*r_cercle)**2 + (x[1] - 12*r_cercle)**2) - r_cercle_modif)) d18 = ufl.max_value(d17,-(ufl.sqrt((x[0]- 4*r_cercle)**2 + (x[1] - 1.)**2) - r_cercle_modif)) d19 = ufl.max_value(d18,-(ufl.sqrt((x[0]- 8*r_cercle)**2 + (x[1] - 1.)**2) - r_cercle_modif)) d20 = ufl.max_value(d19,-(ufl.sqrt((x[0]- 16*r_cercle)**2 + (x[1] - 8*r_cercle)**2) - r_cercle_modif)) d21 = ufl.max_value(d20,-(ufl.sqrt((x[0]- 16*r_cercle)**2 + (x[1] - 0*r_cercle)**2) - r_cercle_modif)) d22 = ufl.max_value(d21,-(ufl.sqrt((x[0]- 4*r_cercle)**2 + (x[1] - 16*r_cercle)**2) - r_cercle_modif)) d23 = ufl.max_value(d22,-(ufl.sqrt((x[0]- 8*r_cercle)**2 + (x[1] - 16*r_cercle)**2) - r_cercle_modif)) d24 = ufl.max_value(d23,-(ufl.sqrt((x[0]- 0.*r_cercle)**2 + (x[1] - 16*r_cercle)**2) - r_cercle_modif)) return d24