-
Notifications
You must be signed in to change notification settings - Fork 139
Adding new example : dynamic simulation of PCB #938
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
Merged
Merged
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
d6c3f16
adding new example from manual
pmaroneh 484fe28
Adapting to PEP8 and commenting use of DPF
pmaroneh 4045064
Spell check
pmaroneh cd78d58
Correcting formatting issues
pmaroneh c982722
Minor corrections
pmaroneh e482831
Adding ReadMe
pmaroneh 145060f
Changing file reference and Modification of description to indicate u…
pmaroneh e8c82fb
Corrected path to download cdb
pmaroneh cd607b4
Correction for importing cdb file
pmaroneh 5b92ad8
Correction for cdb path
pmaroneh f7009c3
Correcting path for dowloading pcb
pmaroneh f26ba92
Correct modules to import
pmaroneh 094f15e
Correction on upload file
pmaroneh 4b96077
Modified path
pmaroneh 3011e98
Editing path to grab cdb file
pmaroneh f53f060
Correction to file path
pmaroneh aa0df8a
Change running directory
pmaroneh ddd8881
Using a lower number of modes for CI/CD and using longer title underl…
pmaroneh 0ec1211
cleanup example
akaszynski 5842648
merge main
akaszynski File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
278 changes: 278 additions & 0 deletions
278
.../07-technology-showcase-examples/20-example-technology-showcase-dynamic-simulation-PCB.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,278 @@ | ||
| """.. _ref_dynamic_simulation_printed_circuit_board: | ||
|
|
||
| Dynamic simulation of a printed circuit board assembly | ||
| ------------------------------------------------------ | ||
|
|
||
| This examples shows how to use PyMAPDL to import an existing FE model and to | ||
| run a modal and PSD analysis. PyDPF modules are also used for post-processing. | ||
|
|
||
| This example is inspired from the model and analysis defined in Chapter 20 of | ||
| the Mechanical APDL Technology Showcase Manual. | ||
|
|
||
| Additional Packages Used | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| * `Matplotlib <https://matplotlib.org>`_ is used for plotting purposes. | ||
|
|
||
| """ | ||
|
|
||
| ############################################################################### | ||
| # Starting MAPDL as a service and importing an external model | ||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| # The original FE model is given in the Ansys Mechanical APDL Technology Showcase Manual. | ||
| # The .cdb contains a FE model of a single circuit board. The model is meshed | ||
| # with SOLID186, SHELL181 and BEAM188 elements. All components of the PCB | ||
| # model is assigned with linear elastic isotropic materials. Bonded and | ||
| # flexible surface-to-surface contact pairs are used to define the contact | ||
| # between the IC packages and the circuit board. | ||
|
|
||
|
|
||
| import matplotlib.pyplot as plt | ||
|
|
||
| from ansys.mapdl.core import launch_mapdl | ||
| from ansys.mapdl.core.examples import download_tech_demo_data | ||
|
|
||
| # start MAPDL as a service | ||
| mapdl = launch_mapdl() | ||
| print(mapdl) | ||
|
|
||
| # read model of single circuit board | ||
| # download the cdb file | ||
| pcb_mesh_file = download_tech_demo_data("td-20", "pcb_mesh_file.cdb") | ||
|
|
||
| # enter preprocessor and read in cdb | ||
| mapdl.prep7() | ||
| mapdl.cdread("COMB", pcb_mesh_file) | ||
| mapdl.allsel() | ||
| mapdl.eplot(background="w") | ||
| mapdl.cmsel("all") | ||
|
|
||
| ############################################################################### | ||
| # Creating the complete layered model | ||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| # The original model will be duplicated to create a layered PCB of three layers | ||
| # that are binded together | ||
|
|
||
| # duplicate single PCB to get three layers | ||
| # get the maximum node number for the single layers PCB in the input file | ||
| max_nodenum = mapdl.get("max_nodenum", "node", " ", "num", "max") | ||
|
|
||
| # generate additional PCBs offset by 20 mm in the -y direction | ||
| mapdl.egen("3", max_nodenum, "all", dy="-20") | ||
|
|
||
|
|
||
| # bind the three layers together | ||
| # select components of interest | ||
| mapdl.cmsel("s", "N_JOINT_BOARD") | ||
| mapdl.cmsel("a", "N_JOINT_LEGS") | ||
| mapdl.cmsel("a", "N_BASE") | ||
|
|
||
| # get number of currently selected nodes | ||
| nb_selected_nodes = mapdl.mesh.n_node | ||
| current_node = 0 | ||
| queries = mapdl.queries | ||
|
|
||
| # also select similar nodes for copies of the single PCB | ||
| # and couple all dofs at the interface | ||
| for node_id in range(1, nb_selected_nodes + 1): | ||
| current_node = queries.ndnext(current_node) | ||
| mapdl.nsel("a", "node", " ", current_node + max_nodenum) | ||
| mapdl.nsel("a", "node", " ", current_node + 2 * max_nodenum) | ||
| mapdl.cpintf("all") | ||
|
|
||
| # define fixed support boundary condition | ||
| # get max coupled set number | ||
| cp_max = mapdl.get("cp_max", "cp", "0", "max") | ||
|
|
||
| # unselect nodes scoped in CP equations | ||
| mapdl.nsel("u", "cp", " ", "1", "cp_max") | ||
|
|
||
| # create named selection for base excitation | ||
| mapdl.cm("n_base_excite", "node") | ||
|
|
||
| # fix displacement for base excitation nodes | ||
| mapdl.d("all", "all") | ||
|
|
||
| # select all and plot the model using MAPDL's plotter and VTK's | ||
| mapdl.allsel("all") | ||
| mapdl.cmsel("all") | ||
| mapdl.graphics("power") | ||
| mapdl.rgb("index", "100", "100", "100", "0") | ||
| mapdl.rgb("index", "80", "80", "80", "13") | ||
| mapdl.rgb("index", "60", "60", "60", "14") | ||
| mapdl.rgb("index", "0", "0", "0", "15") | ||
| mapdl.triad("rbot") | ||
| mapdl.pnum("type", "1") | ||
| mapdl.number("1") | ||
| mapdl.hbc("1", "on") | ||
| mapdl.pbc("all", " ", "1") | ||
| mapdl.view(1, 1, 1, 1) | ||
| mapdl.eplot(vtk=False) | ||
| mapdl.eplot(vtk=True) | ||
|
|
||
| ############################################################################### | ||
| # Run a modal analysis | ||
| # ~~~~~~~~~~~~~~~~~~~~~~~ | ||
| # | ||
|
|
||
| # enter solution processor and define analysis settings | ||
| mapdl.slashsolu() | ||
| mapdl.antype("modal") | ||
| # set number of modes to extract | ||
| # using a higher number of modes is recommended | ||
| nb_modes = 10 | ||
| # use Block Lanzos to extract specified number of modes | ||
| mapdl.modopt("lanb", nb_modes) | ||
| mapdl.mxpand(nb_modes) | ||
| output = mapdl.solve() | ||
| print(output) | ||
|
|
||
|
|
||
| ############################################################################### | ||
| # Post-processing the modal results | ||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| # This sections illustrates different methods to post-process the results of the | ||
| # modal analysis : PyMAPDL method, PyMAPDL result reader, PyDPF-Post | ||
| # and PyDPF-Core. All methods lead to the same result and are just given as an | ||
| # example of how each module can be used. | ||
|
|
||
| # using MAPDL methods | ||
| mapdl.post1() | ||
| mapdl.set(1, 1) | ||
| mapdl.plnsol("u", "sum") | ||
|
|
||
| # using PyMAPDL result reader | ||
| mapdl_result = mapdl.result | ||
| mapdl_result.plot_nodal_displacement(0) | ||
|
|
||
| ############################################################################### | ||
| # Using DPF-Post | ||
| # ~~~~~~~~~~~~~~ | ||
| # from ansys.dpf import post | ||
| # solution_path = 'file.rst' | ||
| # solution = post.load_solution(solution_path) | ||
| # print(solution) | ||
| # displacement = solution.displacement(time_scoping=1) | ||
| # total_deformation = displacement.norm | ||
| # total_deformation.plot_contour(show_edges=True) | ||
|
|
||
| # using DPF-Core | ||
| # from ansys.dpf import core | ||
| # model = core.Model(solution_path) | ||
| # results = model.results | ||
| # print(results) | ||
| # displacements = results.displacement() | ||
| # total_def = core.operators.math.norm_fc(displacements) | ||
| # total_def_container = total_def.outputs.fields_container() | ||
| # mesh = model.metadata.meshed_region | ||
| # mesh.plot(total_def_container.get_field_by_time_id(1)) | ||
|
|
||
| ############################################################################### | ||
| # PSD analysis | ||
| # ~~~~~~~~~~~~~ | ||
| # The response spectrum analysis is defined, solved and post-processed | ||
|
|
||
| # define PSD analysis with input spectrum | ||
| mapdl.slashsolu() | ||
| mapdl.antype("spectr") | ||
|
|
||
| # power spectral density | ||
| mapdl.spopt("psd") | ||
|
|
||
| # use input table 1 with acceleration spectrum in terms of acceleration due to gravity | ||
| mapdl.psdunit(1, "accg", 9.81 * 1000) | ||
|
|
||
| # define the frequency points in the input table 1 | ||
| mapdl.psdfrq(1, " ", 1, 40, 50, 70.71678, 100, 700, 900) | ||
|
|
||
| # define the PSD values in the input table 1 | ||
| mapdl.psdval(1, 0.01, 0.01, 0.1, 1, 10, 10, 1) | ||
|
|
||
| # set the damping ratio as 5% | ||
| mapdl.dmprat(0.05) | ||
|
|
||
| # apply base excitation on the set of nodes N_BASE_EXCITE in the y-direction from table 1 | ||
| mapdl.d("N_BASE_EXCITE", "uy", 1) | ||
|
|
||
| # calculate the participation factor for PSD with base excitation from input table 1 | ||
| mapdl.pfact(1, "base") | ||
|
|
||
| # write the displacent solution relative to the base excitation to the results file from the PSD analysis | ||
| mapdl.psdres("disp", "rel") | ||
|
|
||
| # write the absolute velocity solution to the results file from the PSD analysis | ||
| mapdl.psdres("velo", "abs") | ||
|
|
||
| # write the absolute acceleration solution to the results file from the PSD analysis | ||
| mapdl.psdres("acel", "abs") | ||
|
|
||
| # combine only those modes whose significance level exceeds 0.0001 | ||
| mapdl.psdcom() | ||
| output = mapdl.solve() | ||
| print(output) | ||
|
|
||
| ############################################################################### | ||
| # Post-process PSD analysis | ||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| # Using MAPDL methods in POST1 | ||
| mapdl.post1() | ||
| mapdl.set(1, 1) | ||
| mapdl.plnsol("u", "sum") | ||
| mapdl.set("last") | ||
| mapdl.plnsol("u", "sum") | ||
|
|
||
| # Using MAPDL methods in POST26 (time-history post-processing) | ||
| mapdl.post26() | ||
|
|
||
| # allow storage for 200 variables | ||
| mapdl.numvar(200) | ||
| mapdl.cmsel("s", "MY_MONITOR") | ||
| monitored_node = mapdl.queries.ndnext(0) | ||
| mapdl.store("psd") | ||
|
|
||
| # store the psd analysis u_y data for the node MYMONITOR as the reference no 2 | ||
| mapdl.nsol(2, monitored_node, "u", "y") | ||
|
|
||
| # compute the response power spectral density for displacement associated with variable 2 | ||
| mapdl.rpsd(3, 2) | ||
| mapdl.show("png") | ||
|
|
||
| # plot the variable 3 | ||
| mapdl.plvar(3) | ||
|
|
||
| # print the variable 3 | ||
| mapdl.prvar(3) | ||
|
|
||
| # x-axis is set for Log X scale | ||
| mapdl.gropt("logx", 1) | ||
|
|
||
| # y-axis is set for Log X scale | ||
| mapdl.gropt("logy", 1) | ||
|
|
||
| # plot the variable 3 | ||
| mapdl.plvar(3) | ||
| mapdl.show("close") | ||
|
|
||
| ############################################################################### | ||
| # Plot using python libraries | ||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| # store MAPDL results to python variables | ||
| mapdl.dim("frequencies", "array", 4000, 1) | ||
| mapdl.dim("response", "array", 4000, 1) | ||
| mapdl.vget("frequencies(1)", 1) | ||
| mapdl.vget("response(1)", 3) | ||
| frequencies = mapdl.parameters["frequencies"] | ||
| response = mapdl.parameters["response"] | ||
|
|
||
| # use Matplotlib to create graph | ||
|
|
||
| fig = plt.figure() | ||
| ax = fig.add_subplot(111) | ||
| plt.xscale("log") | ||
| plt.yscale("log") | ||
| ax.plot(frequencies, response) | ||
| ax.set_xlabel("Frequencies") | ||
| ax.set_ylabel("Response power spectral density") | ||
|
|
||
| ############################################################################### | ||
| # Exit MAPDL | ||
| mapdl.exit() | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| Technology Showcase Manual Examples | ||
| ==================================== | ||
| This section demonstrates the broad simulation capabilities | ||
| of Ansys Mechanical APDL. The problems demonstrate how | ||
| to use PyMAPDL to effectively and accurately | ||
| solve interdisciplinary problems | ||
| from a variety of industries and engineering fields. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.