From 2b03f5f73b6ef49ac3c4e5f07820df9bab50ced3 Mon Sep 17 00:00:00 2001 From: Roman Ilchenko <44849889+RomanIlchenko1308@users.noreply.github.com> Date: Wed, 26 Jan 2022 19:07:36 +0100 Subject: [PATCH] Add Verification Manual VM8 (#820) * VM8 almost finishe code, idea how to modify NDIST * check kp distances and use updates of kdist * vm8 check * almost all code without comments * deleted unnecessary files * deleted old file without ndist and kdist functionality * removed old file and created new one to check kdist functionality * Full script without comments * extra modifications * check vm8 * updated and simplified pandas dataframe with output results * Modified Output dataframe and added comments * Modified LaTex style at the Check Output * add numbers of the kps and nodes * Added f-string properties to the print outputs * Added vtk and numbering to the kps and nodes plotting * adding description * chaged a style inside of the keypoint and node topic * fixed some mistakes of the description * fixing style of script for pandas data frame settings * check unit testing * added Analysis Assumptions description * VM is ready to review * VM is ready to review * VM is ready to review1 * VM8 is ready to review * VM8 changed name of the class block * Delete misc.xml * Delete pymapdl.iml * removed idea files * changed names of the methods * VM8 is ready to be merged, almost all suggestions were added * VM8 is rebuilt with decorator property and ready to review * Removed styling setting, left just format style for decimals * Unit test check * Unit test check2 * VM8 Last update, ready to be merged * VM8 check * VM10 check test Co-authored-by: German <28149841+germa89@users.noreply.github.com> --- .idea/.gitignore | 3 - .../inspectionProfiles/profiles_settings.xml | 6 - .idea/misc.xml | 4 - .idea/modules.xml | 8 - .idea/pymapdl.iml | 17 -- .idea/vcs.xml | 6 - doc/source/_static/vm8_setup.png | Bin 0 -> 7688 bytes .../vm-008-parametric_calculation.py | 232 ++++++++++++++++++ 8 files changed, 232 insertions(+), 44 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/inspectionProfiles/profiles_settings.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/pymapdl.iml delete mode 100644 .idea/vcs.xml create mode 100644 doc/source/_static/vm8_setup.png create mode 100644 examples/06-verif-manual/vm-008-parametric_calculation.py diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d33521af..0000000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 105ce2da2d..0000000000 --- a/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 1d209eafc7..0000000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 62f867e629..0000000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/pymapdl.iml b/.idea/pymapdl.iml deleted file mode 100644 index 5195124935..0000000000 --- a/.idea/pymapdl.iml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7f4c..0000000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/doc/source/_static/vm8_setup.png b/doc/source/_static/vm8_setup.png new file mode 100644 index 0000000000000000000000000000000000000000..d3087b477b4e50af37ff9594f151b847099c7bea GIT binary patch literal 7688 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 b9WLU>Fpra&FG9etw~+a18{=X_eB}QEXkPo9 literal 0 HcmV?d00001 diff --git a/examples/06-verif-manual/vm-008-parametric_calculation.py b/examples/06-verif-manual/vm-008-parametric_calculation.py new file mode 100644 index 0000000000..f83219551a --- /dev/null +++ b/examples/06-verif-manual/vm-008-parametric_calculation.py @@ -0,0 +1,232 @@ +r""" +.. _ref_vm8_example: + +Parametric Calculation +---------------------- +Problem Description: + - Write a user file macro to calculate the distance ``d`` between either nodes + or keypoints in ``PREP7``. Define abbreviations for calling the macro and + verify the parametric expressions by using the macro to calculate + the distance between nodes :math:`N_1` and :math:`N_2` and + between keypoints :math:`K_3` and :math:`K_4`. + +Reference: + - None. + +Analysis Type(s): + - Parametric Arithmetic. + +Element Type: + - None. + +Geometric Properties(Coordinates): + - :math:`N_{\mathrm{1(x,y,z)}} = 1.5, 2.5, 3.5` + - :math:`N_{\mathrm{2(x,y,z)}} = -3.7, 4.6, -3` + - :math:`K_{\mathrm{3(x,y,z)}} = 100, 0, 30` + - :math:`K_{\mathrm{4(x,y,z)}} = -200,25,80` + +.. image:: ../../_static/vm8_setup.png + :width: 300 + :alt: VM8 Problem Sketch + +Analysis Assumptions and Modeling Notes: + - Instead of ``*CREATE``, ``*USE``, etc., we have created a class + ``Create`` with methods that correspond to each type of simulation. + This class gives a possibility to change coordinates and reuse it. + The simulation can be checked not just by target values, but also + with the simple distances' formula between keypoints as: + + * Calculate distance between two keypoints in the Cartesian coordinate system: + :math:`D = \sqrt[2]{(x_2 - x_1)^2 + (y_2 - y_1)^2 + (z_2 - z_1)^2}` + * Python representation of the distance formula: + .. doctest:: + + import math + # Define coordinates for keypoints K3 and K4. + x1, y1, z1 = 100, 0, 30 + x2, y2, z2 = -200, 25, 80 + dist_kp = math.sqrt((x2 - x1)**2 + (y2 - y1)**2 + (z2 - z1)**2) + print(dist_kp) + +""" + +############################################################################### +# Start MAPDL +# ~~~~~~~~~~~ +# Start MAPDL and import Numpy and Pandas libraries. + +# sphinx_gallery_thumbnail_path = '_static/vm8_setup.png' + +import numpy as np +import pandas as pd + +from ansys.mapdl.core import launch_mapdl + +# Start MAPDL. +mapdl = launch_mapdl() + + +############################################################################### +# Pre-Processing +# ~~~~~~~~~~~~~~ +# Enter verification example mode and the pre-processing routine. + +mapdl.clear() +mapdl.verify() +mapdl.prep7(mute=True) + + +############################################################################### +# Define Class +# ~~~~~~~~~~~~ +# Identifying the class ``create`` with methods ``create_kp_method`` and +# ``create_node_method`` to calculate and plot the distances between keypoints +# and nodes. + +class Create: + def __init__(self, p1, p2): + # Points Attributes. + self.p1 = p1 + self.p2 = p2 + + def kp_distances(self): + + # Define keypoints by coordinates. + kp1 = mapdl.k(npt=3, x=self.p1[0], y=self.p1[1], z=self.p1[2]) + kp2 = mapdl.k(npt=4, x=self.p2[0], y=self.p2[1], z=self.p2[2]) + + # Get the distance between keypoints. + dist_kp, kx, ky, kz = mapdl.kdist(kp1, kp2) + + # Plot keypoints. + mapdl.kplot(show_keypoint_numbering=True, + vtk=True, + background="grey", + show_bounds=True, + font_size=26) + return dist_kp + + def node_distances(self): + + # Define nodes by coordinates. + node1 = mapdl.n(node=1, x=self.p1[0], y=self.p1[1], z=self.p1[2]) + node2 = mapdl.n(node=2, x=self.p2[0], y=self.p2[1], z=self.p2[2]) + + # Get the distance between nodes. + dist_node, node_x, node_y, node_z = mapdl.ndist(node1, node2) + + # Plot nodes. + mapdl.nplot(nnum=True, + vtk=True, + color="grey", + show_bounds=True, + font_size=26) + return dist_node + + @property + def p1(self): + # Getting value + return self._p1 + + @p1.setter + def p1(self, new_value): + # Check the data type: + if not isinstance(new_value, list): + raise ValueError("The coordinates should be implemented by the list!") + # Check the quantity of items: + if len(new_value) != 3: + raise ValueError("The coordinates should have three items in the list as [X, Y, Z]") + self._p1 = new_value + + @property + def p2(self): + return self._p2 + + @p2.setter + def p2(self, new_value): + # Check the data type: + if not isinstance(new_value, list): + raise ValueError("The coordinates should be implemented by the list!") + # Check the quantity of items: + if len(new_value) != 3: + raise ValueError("The coordinates should have three items in the list as [X, Y, Z]") + self._p2 = new_value + + +############################################################################### +# Distance between keypoints +# ~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Using already created method for keypoints to get the distance between them +# and print out an output. The keypoints have got next coordinates: +# +# * :math:`K_{\mathrm{3(x,y,z)}} = 100, 0, 30` +# * :math:`K_{\mathrm{4(x,y,z)}} = -200, 25,80` + +kp1 = [100, 0, 30] +kp2 = [-200, 25, 80] +kp = Create(kp1, kp2) +kp_dist = kp.kp_distances() +print(f"Distance between keypoint is: {kp_dist:.2f}\n\n") + +# Print the list of keypoints. +print(mapdl.klist()) + + +############################################################################### +# Distance between nodes. +# ~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Using already created method for nodes to get the distance between them and +# print out an output. The nodes have got next coordinates: +# +# * :math:`N_{\mathrm{1(x,y,z)}} = 1.5, 2.5, 3.5` +# * :math:`N_{\mathrm{2(x,y,z)}} = -3.7, 4.6, -3` + +node1 = [1.5, 2.5, 3.5] +node2 = [-3.7, 4.6, -3] +nodes = Create(node1, node2) +node_dist = nodes.node_distances() +print(f"Distance between nodes is: {node_dist:.2f}\n\n") + +# Print the list of nodes. +print(mapdl.nlist()) + + +############################################################################### +# Check Results +# ~~~~~~~~~~~~~ +# Finally we have the results of the distances for both simulations, +# which can be compared with expected target values: +# +# - 1st simulation to get the distance between keypoints :math:`K_3` and :math:`K_4`, where :math:`LEN_1 = 305.16\,(in)` +# - 2nd simulation to get the distance between nodes :math:`N_1` and :math:`N_2`, where :math:`LEN_2 = 8.58\,(in)` +# +# For better representation of the results we can use ``pandas`` dataframe +# with following settings below: + +# Define the names of the rows. +row_names = ["N1 - N2 distance (LEN2)", + "K3 - K4 distance (LEN1)"] + +# Define the names of the columns. +col_names = ['Target', + 'Mechanical APDL', + 'RATIO'] + +# Define the values of the target results. +target_res = np.asarray([8.5849, 305.16]) + +# Create an array with outputs of the simulations. +simulation_res = np.asarray([node_dist, kp_dist]) + +# Identifying and filling corresponding columns. +main_columns = { + "Target": target_res, + "Mechanical APDL": simulation_res, + "Ratio": list(np.divide(simulation_res, target_res)) +} + +# Create and fill the output dataframe with pandas. +df2 = pd.DataFrame(main_columns, index=row_names).round(2) + +# Apply settings for the dataframe. +df2.head()