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

Add potential interactions in 4C #74

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions meshpy/FourC/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
# -----------------------------------------------------------------------------
# MeshPy: A beam finite element input generator
#
# MIT License
#
# Copyright (c) 2018-2024
# Ivo Steinbrecher
# Institute for Mathematics and Computer-Based Simulation
# Universitaet der Bundeswehr Muenchen
# https://www.unibw.de/imcs-en
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# -----------------------------------------------------------------------------
"""
This module defines classes and functions to create a 4C beam input file.
"""

from .beam_potential import BeamPotential

# Define the items that will be exported by default.
__all__ = ["BeamPotential"]
256 changes: 256 additions & 0 deletions meshpy/FourC/beam_potential.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
# -*- coding: utf-8 -*-
# -----------------------------------------------------------------------------
# MeshPy: A beam finite element input generator
#
# MIT License
#
# Copyright (c) 2018-2024
# Ivo Steinbrecher
# Institute for Mathematics and Computer-Based Simulation
# Universitaet der Bundeswehr Muenchen
# https://www.unibw.de/imcs-en
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# -----------------------------------------------------------------------------
"""
This file includes functions to ease the creation of input files using beam
interaction potentials.
"""


# Python modules
import numpy as np

# MeshPy modules
from ..inputfile import InputSection
from ..header_functions import get_yes_no
from ..boundary_condition import BoundaryCondition


class BeamPotential:

def __init__(
self,
input_file,
*,
pot_law_prefactor=None,
pot_law_exponent=None,
pot_law_line_charge_density=None,
pot_law_line_charge_density_funcs=None,
):
"""Initialize object to enable beam potential interactions.

Args
----
input_file:
Input file of current problem setup.
pot_law_prefactors: float, int, np.array, list
Prefactors of a potential law in form of a power law. Same number
of prefactors and exponents/line charge densities/functions must be
provided!
pot_law_exponent: float, int, np.array, list
Exponents of a potential law in form of a power law. Same number
of exponents and prefactors/line charge densities/functions must be
provided!
pot_law_line_charge_density: float, int, np.array, list
Line charge densities of a potential law in form of a power law.
Same number of line charge densities and prefactors/exponents/functions
must be provided!
pot_law_line_charge_density_funcs:
Functions for line charge densities of a potential law in form of a
power law. Same number of functions and prefactors/exponents/line
charge densities must be provided!
"""

self.input_file = input_file

# if only one potential law prefactor/exponent is present, convert it
# into a list for simplified usage
if isinstance(pot_law_prefactor, (float, int)):
pot_law_prefactor = [pot_law_prefactor]
if isinstance(pot_law_exponent, (float, int)):
pot_law_exponent = [pot_law_exponent]
if isinstance(pot_law_line_charge_density, (float, int)):
pot_law_line_charge_density = [pot_law_line_charge_density]

# check if same number of prefactors and exponents are provided
if (
not len(pot_law_prefactor)
== len(pot_law_exponent)
== len(pot_law_line_charge_density)
):
raise ValueError(
"Number of potential law prefactors do not match potential law exponents!"
)

self.pot_law_prefactor = pot_law_prefactor
self.pot_law_exponent = pot_law_exponent
self.pot_law_line_charge_density = pot_law_line_charge_density
self.pot_law_line_charge_density_funcs = pot_law_line_charge_density_funcs

def add_header(
self,
*,
potential_type="Volume",
cutoff_radius=None,
evaluation_strategy=None,
regularization_type=None,
regularization_separation=None,
integration_segments=1,
gauss_points=10,
potential_reduction_length=-1,
automatic_differentiation=False,
choice_master_slave=None,
option_overwrite=False,
):
"""
Set the basic header options for beam potential interactions.

Args
----
potential_type: string
Type of applied potential (volume, surface).
cutoff_radius: float
Neglect all contributions at separation larger than this cutoff
radius.
evaluation_strategy: string
Strategy to evaluate interaction potential.
regularization_type: string
Type of regularization to use for force law at separations below
specified separation (constant_extrapolation, linear_extrapolation).
regularization_separation: float
Use specified regularization type for separations smaller than
this value.
integration_segments: int
Number of integration segments to be used per beam element.
gauss_points: int
Number of Gauss points to be used per integration segment.
potential_reduction_length: float
Potential is smoothly decreased within this length when using the
singlelengthsspecific approach to enable an axial pull off force.
automatic_differentiation: bool
Use automatic differentiation via FAD.
choice_master_slave: string
Rule how to assign the role of master and slave to beam elements (if
applicable) (lower_eleGID_is_slave, higher_eleGID_is_slave).
option_overwrite: bool
If existing options should be overwritten. If this is false and an
option is already defined, and error will be thrown.
"""

settings = f"""
POT_LAW_PREFACTOR {' '.join(map(str, self.pot_law_prefactor))}
POT_LAW_EXPONENT {' '.join(map(str, self.pot_law_exponent))}
BEAMPOTENTIAL_TYPE {potential_type}
CUTOFF_RADIUS {cutoff_radius}
STRATEGY {evaluation_strategy}
NUM_INTEGRATION_SEGMENTS {integration_segments}
NUM_GAUSSPOINTS {gauss_points}
POTENTIAL_REDUCTION_LENGTH {potential_reduction_length}
AUTOMATIC_DIFFERENTIATION {automatic_differentiation}"""

if regularization_type is not None:
settings.append(
f"""
REGULARIZATION_TYPE {regularization_type}
REGULARIZATION_SEPARATION {regularization_separation}"""
)
if choice_master_slave is not None:
settings.append(f"\nCHOICE_MASTER_SLAVE {choice_master_slave}")

self.input_file.add(
InputSection(
"BEAM POTENTIAL",
settings,
option_overwrite=option_overwrite,
)
)

def add_runtime_output(
self,
*,
output_beam_potential=True,
interval_steps=1,
every_iteration=False,
forces=True,
moments=True,
per_ele_pair=True,
option_overwrite=False,
):
"""
Set the basic runtime output options for beam potential interactions.

Args
----
output_beam_potential: bool
If the output for beam potential should be written.
interval_steps: int
Interval at which output is written.
every_iteration: bool
If output at every Newton iteration should be written.
forces: bool
If the forces should be written.
moments: bool
If the moments should be written.
per_ele_pair: bool
If the forces/moments should be written per element pair.
option_overwrite: bool
If existing options should be overwritten. If this is false and an
option is already defined, and error will be thrown.
"""

self.input_file.add(
InputSection(
"BEAM POTENTIAL/RUNTIME VTK OUTPUT",
f"""
VTK_OUTPUT_BEAM_POTENTIAL {get_yes_no(output_beam_potential)}
INTERVAL_STEPS {get_yes_no(interval_steps)}
EVERY_ITERATION {get_yes_no(every_iteration)}
FORCES {get_yes_no(forces)}
MOMENTS {get_yes_no(moments)}
WRITE_FORCE_MOMENT_PER_ELEMENTPAIR {get_yes_no(per_ele_pair)}""",
option_overwrite=option_overwrite,
)
)

def add_potential_charge_condition(self, *, geometry_set=None):
"""Add potential charge condition to geometry.

Args
----
geometry_set:
Add potential charge condition to this set.
"""

for i, (line_charge, func) in enumerate(
zip(
self.pot_law_line_charge_density, self.pot_law_line_charge_density_funcs
)
):

if func != "none":
self.input_file.add(func)

bc = BoundaryCondition(
geometry_set,
f"POTLAW {i+1} VAL {line_charge} FUNCT {str(func)}",
bc_type="DESIGN LINE BEAM POTENTIAL CHARGE CONDITIONS",
)

self.input_file.add(bc)
20 changes: 20 additions & 0 deletions meshpy/utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,3 +328,23 @@ def get_min_max_nodes(nodes, *, middle_nodes=False):
min_max_nodes.append(node_list[index])
geometry[f"{direction}_{text}"] = GeometrySet(min_max_nodes)
return geometry


def find_node_on_plane(node, *, normal=None, origin_distance=None, tol=mpy.eps_pos):
"""
Return the nodes lie on the plane defined by normal and origin_distance.
Args
----
node:
Check if this node coincides with the defined plane.
normal: np.array, list
Normal vector of defined plane.
origin_distance: float
Distance between origin and defined plane.
tol: float
Tolerance of evaluation if point coincides with plane
"""
projection = np.dot(node.coordinates, normal) / np.linalg.norm(normal)

return np.abs(projection - origin_distance) < tol
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ requires = ["setuptools", "Cython", "numpy", "wheel"]
[tool.setuptools]
packages = [
"meshpy",
"meshpy.FourC",
"meshpy.abaqus",
"meshpy.geometric_search",
"meshpy.mesh_creation_functions",
Expand Down
Loading