├── LICENSE
├── Pipfile
├── Pipfile.lock
├── PythonReader1.exe
├── README.md
├── abaqusODBProcess.py
├── abaqusPythonScript.py
├── dispForce.gif
├── launcher.bat
├── main_Run.py
├── misesStress.gif
├── postResults
├── PEEQ.txt
├── dispX.txt
├── dispY.txt
├── dispZ.txt
├── elements.txt
├── misesStress.txt
├── nodes.txt
├── refDisp.txt
└── refLoad.txt
├── prePostProcess.py
├── prePostProcess.py.bak
├── requirements.txt
├── runAbaqus.py
└── saveDataToSqlite.py
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/Pipfile:
--------------------------------------------------------------------------------
1 | [[source]]
2 | name = "pypi"
3 | url = "https://pypi.tuna.tsinghua.edu.cn/simple"
4 | verify_ssl = true
5 |
6 | [dev-packages]
7 |
8 | [packages]
9 | pyvista = "==0.25.3"
10 | records = "==0.5.3"
11 | numpy = "==1.19.1"
12 |
13 | [requires]
14 | python_version = "3.6"
15 |
--------------------------------------------------------------------------------
/Pipfile.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_meta": {
3 | "hash": {
4 | "sha256": "196465fa120306f94539a269bf3c9e1e46533d108947ea6a4b1c02e5b8403923"
5 | },
6 | "pipfile-spec": 6,
7 | "requires": {
8 | "python_version": "3.6"
9 | },
10 | "sources": [
11 | {
12 | "name": "pypi",
13 | "url": "https://pypi.tuna.tsinghua.edu.cn/simple",
14 | "verify_ssl": true
15 | }
16 | ]
17 | },
18 | "default": {
19 | "appdirs": {
20 | "hashes": [
21 | "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41",
22 | "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"
23 | ],
24 | "version": "==1.4.4"
25 | },
26 | "docopt": {
27 | "hashes": [
28 | "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"
29 | ],
30 | "version": "==0.6.2"
31 | },
32 | "et-xmlfile": {
33 | "hashes": [
34 | "sha256:614d9722d572f6246302c4491846d2c393c199cfa4edc9af593437691683335b"
35 | ],
36 | "version": "==1.0.1"
37 | },
38 | "imageio": {
39 | "hashes": [
40 | "sha256:3604d751f03002e8e0e7650aa71d8d9148144a87daf17cb1f3228e80747f2e6b",
41 | "sha256:52ddbaeca2dccf53ba2d6dec5676ca7bc3b2403ef8b37f7da78b7654bb3e10f0"
42 | ],
43 | "version": "==2.9.0"
44 | },
45 | "importlib-metadata": {
46 | "hashes": [
47 | "sha256:90bb658cdbbf6d1735b6341ce708fc7024a3e14e99ffdc5783edea9f9b077f83",
48 | "sha256:dc15b2969b4ce36305c51eebe62d418ac7791e9a157911d58bfb1f9ccd8e2070"
49 | ],
50 | "markers": "python_version < '3.8'",
51 | "version": "==1.7.0"
52 | },
53 | "jdcal": {
54 | "hashes": [
55 | "sha256:1abf1305fce18b4e8aa248cf8fe0c56ce2032392bc64bbd61b5dff2a19ec8bba",
56 | "sha256:472872e096eb8df219c23f2689fc336668bdb43d194094b5cc1707e1640acfc8"
57 | ],
58 | "version": "==1.4.1"
59 | },
60 | "meshio": {
61 | "hashes": [
62 | "sha256:33ad81bc91f33983dd58f727b27fa117a7ce49623e11f10a2348204daa317f1e",
63 | "sha256:fed50ad79effc167c36a7ac6a90ce0bf284c3484136414642b803e78080cacac"
64 | ],
65 | "markers": "python_version >= '3.5'",
66 | "version": "==4.1.1"
67 | },
68 | "numpy": {
69 | "hashes": [
70 | "sha256:082f8d4dd69b6b688f64f509b91d482362124986d98dc7dc5f5e9f9b9c3bb983",
71 | "sha256:1bc0145999e8cb8aed9d4e65dd8b139adf1919e521177f198529687dbf613065",
72 | "sha256:309cbcfaa103fc9a33ec16d2d62569d541b79f828c382556ff072442226d1968",
73 | "sha256:3673c8b2b29077f1b7b3a848794f8e11f401ba0b71c49fbd26fb40b71788b132",
74 | "sha256:480fdd4dbda4dd6b638d3863da3be82873bba6d32d1fc12ea1b8486ac7b8d129",
75 | "sha256:56ef7f56470c24bb67fb43dae442e946a6ce172f97c69f8d067ff8550cf782ff",
76 | "sha256:5a936fd51049541d86ccdeef2833cc89a18e4d3808fe58a8abeb802665c5af93",
77 | "sha256:5b6885c12784a27e957294b60f97e8b5b4174c7504665333c5e94fbf41ae5d6a",
78 | "sha256:667c07063940e934287993366ad5f56766bc009017b4a0fe91dbd07960d0aba7",
79 | "sha256:7ed448ff4eaffeb01094959b19cbaf998ecdee9ef9932381420d514e446601cd",
80 | "sha256:8343bf67c72e09cfabfab55ad4a43ce3f6bf6e6ced7acf70f45ded9ebb425055",
81 | "sha256:92feb989b47f83ebef246adabc7ff3b9a59ac30601c3f6819f8913458610bdcc",
82 | "sha256:935c27ae2760c21cd7354402546f6be21d3d0c806fffe967f745d5f2de5005a7",
83 | "sha256:aaf42a04b472d12515debc621c31cf16c215e332242e7a9f56403d814c744624",
84 | "sha256:b12e639378c741add21fbffd16ba5ad25c0a1a17cf2b6fe4288feeb65144f35b",
85 | "sha256:b1cca51512299841bf69add3b75361779962f9cee7d9ee3bb446d5982e925b69",
86 | "sha256:b8456987b637232602ceb4d663cb34106f7eb780e247d51a260b84760fd8f491",
87 | "sha256:b9792b0ac0130b277536ab8944e7b754c69560dac0415dd4b2dbd16b902c8954",
88 | "sha256:c9591886fc9cbe5532d5df85cb8e0cc3b44ba8ce4367bd4cf1b93dc19713da72",
89 | "sha256:cf1347450c0b7644ea142712619533553f02ef23f92f781312f6a3553d031fc7",
90 | "sha256:de8b4a9b56255797cbddb93281ed92acbc510fb7b15df3f01bd28f46ebc4edae",
91 | "sha256:e1b1dc0372f530f26a03578ac75d5e51b3868b9b76cd2facba4c9ee0eb252ab1",
92 | "sha256:e45f8e981a0ab47103181773cc0a54e650b2aef8c7b6cd07405d0fa8d869444a",
93 | "sha256:e4f6d3c53911a9d103d8ec9518190e52a8b945bab021745af4939cfc7c0d4a9e",
94 | "sha256:ed8a311493cf5480a2ebc597d1e177231984c818a86875126cfd004241a73c3e",
95 | "sha256:ef71a1d4fd4858596ae80ad1ec76404ad29701f8ca7cdcebc50300178db14dfc"
96 | ],
97 | "index": "pypi",
98 | "version": "==1.19.1"
99 | },
100 | "openpyxl": {
101 | "hashes": [
102 | "sha256:626d38647c063d55803ef4971c4d43226538d4e95cb6260c094e363ee33e10c7"
103 | ],
104 | "version": "==2.4.11"
105 | },
106 | "pillow": {
107 | "hashes": [
108 | "sha256:0295442429645fa16d05bd567ef5cff178482439c9aad0411d3f0ce9b88b3a6f",
109 | "sha256:06aba4169e78c439d528fdeb34762c3b61a70813527a2c57f0540541e9f433a8",
110 | "sha256:09d7f9e64289cb40c2c8d7ad674b2ed6105f55dc3b09aa8e4918e20a0311e7ad",
111 | "sha256:0a80dd307a5d8440b0a08bd7b81617e04d870e40a3e46a32d9c246e54705e86f",
112 | "sha256:1ca594126d3c4def54babee699c055a913efb01e106c309fa6b04405d474d5ae",
113 | "sha256:25930fadde8019f374400f7986e8404c8b781ce519da27792cbe46eabec00c4d",
114 | "sha256:431b15cffbf949e89df2f7b48528be18b78bfa5177cb3036284a5508159492b5",
115 | "sha256:52125833b070791fcb5710fabc640fc1df07d087fc0c0f02d3661f76c23c5b8b",
116 | "sha256:5e51ee2b8114def244384eda1c82b10e307ad9778dac5c83fb0943775a653cd8",
117 | "sha256:612cfda94e9c8346f239bf1a4b082fdd5c8143cf82d685ba2dba76e7adeeb233",
118 | "sha256:6d7741e65835716ceea0fd13a7d0192961212fd59e741a46bbed7a473c634ed6",
119 | "sha256:6edb5446f44d901e8683ffb25ebdfc26988ee813da3bf91e12252b57ac163727",
120 | "sha256:725aa6cfc66ce2857d585f06e9519a1cc0ef6d13f186ff3447ab6dff0a09bc7f",
121 | "sha256:8dad18b69f710bf3a001d2bf3afab7c432785d94fcf819c16b5207b1cfd17d38",
122 | "sha256:94cf49723928eb6070a892cb39d6c156f7b5a2db4e8971cb958f7b6b104fb4c4",
123 | "sha256:97f9e7953a77d5a70f49b9a48da7776dc51e9b738151b22dacf101641594a626",
124 | "sha256:9ad7f865eebde135d526bb3163d0b23ffff365cf87e767c649550964ad72785d",
125 | "sha256:9c87ef410a58dd54b92424ffd7e28fd2ec65d2f7fc02b76f5e9b2067e355ebf6",
126 | "sha256:a060cf8aa332052df2158e5a119303965be92c3da6f2d93b6878f0ebca80b2f6",
127 | "sha256:c79f9c5fb846285f943aafeafda3358992d64f0ef58566e23484132ecd8d7d63",
128 | "sha256:c92302a33138409e8f1ad16731568c55c9053eee71bb05b6b744067e1b62380f",
129 | "sha256:d08b23fdb388c0715990cbc06866db554e1822c4bdcf6d4166cf30ac82df8c41",
130 | "sha256:d350f0f2c2421e65fbc62690f26b59b0bcda1b614beb318c81e38647e0f673a1",
131 | "sha256:e901964262a56d9ea3c2693df68bc9860b8bdda2b04768821e4c44ae797de117",
132 | "sha256:ec29604081f10f16a7aea809ad42e27764188fc258b02259a03a8ff7ded3808d",
133 | "sha256:edf31f1150778abd4322444c393ab9c7bd2af271dd4dafb4208fb613b1f3cdc9",
134 | "sha256:f7e30c27477dffc3e85c2463b3e649f751789e0f6c8456099eea7ddd53be4a8a",
135 | "sha256:ffe538682dc19cc542ae7c3e504fdf54ca7f86fb8a135e59dd6bc8627eae6cce"
136 | ],
137 | "markers": "python_version >= '3.5'",
138 | "version": "==7.2.0"
139 | },
140 | "pyvista": {
141 | "hashes": [
142 | "sha256:02e916ca94413b8c88c1cd83b37d6ec860bd91f07c70436777208954541d3889",
143 | "sha256:576479045bdee6843f5f50eb4c9844efbf5cd82022c789ce564956a2ea948428"
144 | ],
145 | "index": "pypi",
146 | "version": "==0.25.3"
147 | },
148 | "records": {
149 | "hashes": [
150 | "sha256:47e4874096f4a8f4b5bcad8c7c7cf512be36186e6e263ff3dfd750b05ff0d3c4",
151 | "sha256:cdbacf52c61b4a3bc10fef1286a24a63ae95255a2e7b4e8ccb1e1f96737231ed"
152 | ],
153 | "index": "pypi",
154 | "version": "==0.5.3"
155 | },
156 | "scooby": {
157 | "hashes": [
158 | "sha256:5a194438edb02b18dd49be1e37570735486386413bb9ea0749dbf218a68104ea",
159 | "sha256:eb9f11d2aa281fc672c68e62ac3e7d66db48a07004bdea595e74862c2d361bb3"
160 | ],
161 | "version": "==0.5.6"
162 | },
163 | "sqlalchemy": {
164 | "hashes": [
165 | "sha256:072766c3bd09294d716b2d114d46ffc5ccf8ea0b714a4e1c48253014b771c6bb",
166 | "sha256:107d4af989831d7b091e382d192955679ec07a9209996bf8090f1f539ffc5804",
167 | "sha256:15c0bcd3c14f4086701c33a9e87e2c7ceb3bcb4a246cd88ec54a49cf2a5bd1a6",
168 | "sha256:26c5ca9d09f0e21b8671a32f7d83caad5be1f6ff45eef5ec2f6fd0db85fc5dc0",
169 | "sha256:276936d41111a501cf4a1a0543e25449108d87e9f8c94714f7660eaea89ae5fe",
170 | "sha256:3292a28344922415f939ee7f4fc0c186f3d5a0bf02192ceabd4f1129d71b08de",
171 | "sha256:33d29ae8f1dc7c75b191bb6833f55a19c932514b9b5ce8c3ab9bc3047da5db36",
172 | "sha256:3bba2e9fbedb0511769780fe1d63007081008c5c2d7d715e91858c94dbaa260e",
173 | "sha256:465c999ef30b1c7525f81330184121521418a67189053bcf585824d833c05b66",
174 | "sha256:51064ee7938526bab92acd049d41a1dc797422256086b39c08bafeffb9d304c6",
175 | "sha256:5a49e8473b1ab1228302ed27365ea0fadd4bf44bc0f9e73fe38e10fdd3d6b4fc",
176 | "sha256:618db68745682f64cedc96ca93707805d1f3a031747b5a0d8e150cfd5055ae4d",
177 | "sha256:6547b27698b5b3bbfc5210233bd9523de849b2bb8a0329cd754c9308fc8a05ce",
178 | "sha256:6557af9e0d23f46b8cd56f8af08eaac72d2e3c632ac8d5cf4e20215a8dca7cea",
179 | "sha256:73a40d4fcd35fdedce07b5885905753d5d4edf413fbe53544dd871f27d48bd4f",
180 | "sha256:8280f9dae4adb5889ce0bb3ec6a541bf05434db5f9ab7673078c00713d148365",
181 | "sha256:83469ad15262402b0e0974e612546bc0b05f379b5aa9072ebf66d0f8fef16bea",
182 | "sha256:860d0fe234922fd5552b7f807fbb039e3e7ca58c18c8d38aa0d0a95ddf4f6c23",
183 | "sha256:883c9fb62cebd1e7126dd683222b3b919657590c3e2db33bdc50ebbad53e0338",
184 | "sha256:8afcb6f4064d234a43fea108859942d9795c4060ed0fbd9082b0f280181a15c1",
185 | "sha256:96f51489ac187f4bab588cf51f9ff2d40b6d170ac9a4270ffaed535c8404256b",
186 | "sha256:9e865835e36dfbb1873b65e722ea627c096c11b05f796831e3a9b542926e979e",
187 | "sha256:aa0554495fe06172b550098909be8db79b5accdf6ffb59611900bea345df5eba",
188 | "sha256:b595e71c51657f9ee3235db8b53d0b57c09eee74dfb5b77edff0e46d2218dc02",
189 | "sha256:b6ff91356354b7ff3bd208adcf875056d3d886ed7cef90c571aef2ab8a554b12",
190 | "sha256:b70bad2f1a5bd3460746c3fb3ab69e4e0eb5f59d977a23f9b66e5bdc74d97b86",
191 | "sha256:c7adb1f69a80573698c2def5ead584138ca00fff4ad9785a4b0b2bf927ba308d",
192 | "sha256:c898b3ebcc9eae7b36bd0b4bbbafce2d8076680f6868bcbacee2d39a7a9726a7",
193 | "sha256:e49947d583fe4d29af528677e4f0aa21f5e535ca2ae69c48270ebebd0d8843c0",
194 | "sha256:eb1d71643e4154398b02e88a42fc8b29db8c44ce4134cf0f4474bfc5cb5d4dac",
195 | "sha256:f2e8a9c0c8813a468aa659a01af6592f71cd30237ec27c4cc0683f089f90dcfc",
196 | "sha256:fe7fe11019fc3e6600819775a7d55abc5446dda07e9795f5954fdbf8a49e1c37"
197 | ],
198 | "markers": "python_version >= '3.0'",
199 | "version": "==1.3.19"
200 | },
201 | "tablib": {
202 | "hashes": [
203 | "sha256:8cc2fa10bc37219ac5e76850eb7fbd50de313c7a1a7895c44af2a8dd206b7be7",
204 | "sha256:c5a77c96ad306d5b380def1309d521ad5e98b4f83726f84857ad87e142d13279"
205 | ],
206 | "markers": "python_version >= '3.5'",
207 | "version": "==2.0.0"
208 | },
209 | "vtk": {
210 | "hashes": [
211 | "sha256:11c7b05e2a35ff5724b5c88a90ffaa1de84347ddc8293c1b74158c721db31573",
212 | "sha256:3b0873e79365268b3b7d2acb238d2333f73209c27f54b76dc0cdd85483afa82e",
213 | "sha256:4092bf85e1d02a76ea878bb9b822eb57ec7b73c8826e3ec29f1c8cbddcb312e3",
214 | "sha256:424d7e6f8a216b7af82c672ebae82bc6e268582f802c7b32684ae9a90ef4c19e",
215 | "sha256:b9d3827bf84ca11a669cf798d2a205d4ca19ed66e15e93ab2ab747f9dbe9edbe",
216 | "sha256:bd4a066dbb4fb35d329278538976ad4440aeb0e5c839cc12310567238211971c",
217 | "sha256:bd6efb3d3a6ead36e42ab938806364fa7dc858228a1c81e321556e43ff899d89",
218 | "sha256:cbf17bc5ab7ccbda79458cf241cad8bc790a228dfa15066c50648bfb5d7abeb1",
219 | "sha256:cdc7d6d556cf520e6c3c76299125a71d7be5895744ba949e2560d9332e607b50",
220 | "sha256:e2ce620b2691ee8770bd9bfc0ae2ca99c0263ded20559c389a10b9b78e7750b2",
221 | "sha256:e6bfc40f4cdc02f8b869b0c2023b73c6aad86fdb39fcb1823b1f4f5efd1a0001"
222 | ],
223 | "version": "==9.0.1"
224 | },
225 | "zipp": {
226 | "hashes": [
227 | "sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b",
228 | "sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96"
229 | ],
230 | "markers": "python_version >= '3.6'",
231 | "version": "==3.1.0"
232 | }
233 | },
234 | "develop": {}
235 | }
236 |
--------------------------------------------------------------------------------
/PythonReader1.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Junjun1guo/pythonInteractAbaqus/364cf248b161bbd9760540cc86d4bd06d4eff667/PythonReader1.exe
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ##########################################################################
2 | Author: Junjun Guo([HomePage](https://github.com/Junjun1guo))
3 | E-mail: guojj@tongji.edu.cn/guojj_ce@163.com
4 | Environemet: Successfully excucted in python 3.8
5 | ##########################################################################
6 | ______
7 | A general pre and post process framework for finite element analysis, such as ABAQUS, OpenSees et al.
8 |
9 | 
10 |
11 | ## Usage
12 | 1. __Generate finite element model__. If use commercial software,such as ABAQUS, you can write python script to establish FEM(referring __abaqusPythonScript.py__). If use open source software, such as OpenSees, you can also write python script to generate the input file(referring __abaqusPythonScript.py__). In additon, for two or three dimensional problems, [pygmsh](https://github.com/nschloe/pygmsh) can be used to mesh the model.
13 | 2. __outPut process__. If use commercial software,such as ABAQUS, you can write python script to read the output database(referring __abaqusODBProcess.py__).If use open source software, such as OpenSees, you can process the output files and save data to [pysqlite](https://github.com/ghaering/pysqlite) database(referring __saveDataToSqlite.py__).
14 | 3. __result display__. [pyvista](https://docs.pyvista.org/) is adopted to generate static and dynamic graphs(referring __prePostProcess.py__).
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/abaqusODBProcess.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @File : 234.py
3 | # @Date : 2020-09-02 18:14
4 | # @Email : {guojj@tongji.edu.cn/guojj01@gmail.com}
5 | # @Author : guojj
6 |
7 |
8 | ###导入必要的模块
9 | from odbAccess import *
10 | from abaqusConstants import *
11 | from odbMaterial import *
12 | from odbSection import *
13 | import numpy as np
14 | import os
15 |
16 |
17 |
18 | class abaqusODBProcess(object):
19 | """基于python的Abaqus前后处理程序."""
20 |
21 | def __init__(self,odbPath):
22 | self._odb = openOdb(path=odbPath) #打开结果数据库
23 |
24 | @property
25 | def steps(self):
26 | """返回模型荷载步,编号规则stepName_number,number 从1到N"""
27 | totalSteps=self._odb.steps.keys()
28 | stepName=totalSteps[0].split('_')[0]
29 | numStep=len(totalSteps)
30 | return stepName,numStep
31 |
32 | @property
33 | def instance(self):
34 | """返回装配件实例"""
35 | print(self._odb.rootAssembly.instances.keys())
36 |
37 | return self._odb.rootAssembly.instances.keys()[1]
38 |
39 | @property
40 | def nodes(self):
41 | """返回模型节点列表,[[number1,x1,y1,z1],...]"""
42 | nodes = self._odb.rootAssembly.instances[self.instance].nodes
43 | nodeList=[[each.label]+list(each.coordinates) for each in nodes]
44 | return nodeList
45 |
46 | @property
47 | def elements(self):
48 | """返回模型单元列表,[[eleNum1,node1i,node1j,...],...]"""
49 | elements = self._odb.rootAssembly.instances[self.instance].elements
50 | eleList=[[each.label]+list(each.connectivity) for each in elements]
51 | return eleList
52 |
53 | def rfNodeResponse(self,nodedSetName,component):
54 | """
55 | 返回参考点响应列表[[rx0,ry0,rz0],...]
56 | :param nodedSetName: 节点集名称
57 | :param component:分量名称,如‘U’,‘RF’等
58 | """
59 | endSet=self._odb.rootAssembly.nodeSets[nodedSetName]
60 | returnList = []
61 | stepName,numSteps=self.steps
62 | print(numSteps)
63 | for i1 in range(numSteps):
64 | flag = True
65 | j1 = 0
66 | while (flag):
67 | try:
68 | frame = self._odb.steps[stepName+"_" + str(i1 + 1)].frames[j1]
69 | j1 = j1 + 1
70 | displacement = frame.fieldOutputs[component]
71 | centerDisplacement = displacement.getSubset(region=endSet)
72 | fieldValues = centerDisplacement.values
73 | for v in fieldValues:
74 | returnList.append(v.data)
75 | except:
76 | flag = False
77 | return returnList
78 |
79 | def nodeDisp(self):
80 | """返回节点位移,dispXList,dispYList,dispZList"""
81 | stepName, numSteps = self.steps
82 | returnDict = {}
83 | for i1 in range(numSteps):
84 | flag = True
85 | j1 = 0
86 | while (flag):
87 | try:
88 | frame = self._odb.steps[stepName +"_"+ str(i1 + 1)].frames[j1]
89 | j1 = j1 + 1
90 | displacement = frame.fieldOutputs['U'].values
91 | for each in displacement:
92 | if not returnDict.has_key(each.nodeLabel):
93 | returnDict[each.nodeLabel] = []
94 | returnDict[each.nodeLabel].append(each.data)
95 | else:
96 | returnDict[each.nodeLabel].append(each.data)
97 | except:
98 | flag = False
99 | changeValue = [returnDict[1][i1 * 2] for i1 in range(len(returnDict[1]) / 2)]
100 | returnDict[1] = changeValue
101 | dispXList=[]
102 | dispYList=[]
103 | dispZList=[]
104 | for i1 in range(len(returnDict)):
105 | tempValueX=[each[0] for each in returnDict[i1+1]]
106 | tempValueY = [each[1] for each in returnDict[i1 + 1]]
107 | tempValueZ = [each[2] for each in returnDict[i1 + 1]]
108 | dispXList.append([i1+1]+tempValueX)
109 | dispYList.append([i1 + 1] + tempValueY)
110 | dispZList.append([i1 + 1] + tempValueZ)
111 | return dispXList,dispYList,dispZList
112 |
113 | def intPointResponse(self,responseType):
114 | """
115 | 提取积分点响应
116 | responseType:响应类型
117 | """
118 | stepName, numSteps = self.steps
119 | returnDict = {}
120 | if responseType=='mises':
121 | for i1 in range(numSteps):
122 | flag = True
123 | j1 = 0
124 | while (flag):
125 | try:
126 | frame = self._odb.steps[stepName+"_" + str(i1 + 1)].frames[j1]
127 | j1 = j1 + 1
128 | displacement = frame.fieldOutputs['S'].values
129 | for each in displacement:
130 | if not returnDict.has_key(each.elementLabel):
131 | returnDict[each.elementLabel] = []
132 | returnDict[each.elementLabel].append(each.mises)
133 | else:
134 | returnDict[each.elementLabel].append(each.mises)
135 | except:
136 | flag = False
137 | elif responseType=='PEEQ':
138 | for i1 in range(numSteps):
139 | flag = True
140 | j1 = 0
141 | while (flag):
142 | try:
143 | frame = self._odb.steps[stepName+"_" + str(i1 + 1)].frames[j1]
144 | j1 = j1 + 1
145 | displacement = frame.fieldOutputs['PEEQ'].values
146 | for each in displacement:
147 | if not returnDict.has_key(each.elementLabel):
148 | returnDict[each.elementLabel] = []
149 | returnDict[each.elementLabel].append(each.data)
150 | else:
151 | returnDict[each.elementLabel].append(each.data)
152 | except:
153 | flag = False
154 | else:
155 | raise NameError("Please enter correct name:'mises' or'PEEQ'")
156 | num = len(returnDict)
157 | returnList = []
158 | for i2 in range(num):
159 | numj = len(returnDict[i2 + 1]) / 2
160 | tempj = [returnDict[i2 + 1][2 * each] for each in range(numj)]
161 | returnList.append(([i2 + 1] + tempj))
162 | return returnList
163 | ################################################################################
164 | if __name__ == '__main__':
165 | odbPath = 'E:/abaqusModel/pythonProgramAbaqus/Job-pushOver.odb'
166 | instance=abaqusODBProcess(odbPath)
167 | ##节点及单元信息
168 | nodes=instance.nodes
169 | np.savetxt("postResults/nodes.txt",nodes,fmt='%d %.8f %.8f %.8f')
170 | elements=instance.elements
171 | np.savetxt("postResults/elements.txt", elements, fmt='%d')
172 | ##加载点力与位移时程
173 | nodedSetName = 'ASSEMBLY_CONSTRAINT-UPPERPLATE_REFERENCE_POINT'
174 | compDisp = 'U'
175 | comReactionForce = 'RF'
176 | rfDisp=instance.rfNodeResponse(nodedSetName,compDisp)
177 | np.savetxt('postResults/refDisp.txt',rfDisp,fmt='%f')
178 | rfForce = instance.rfNodeResponse(nodedSetName, comReactionForce)
179 | np.savetxt('postResults/refLoad.txt', rfForce, fmt='%f')
180 | ##节点位移时程
181 | dispXList, dispYList, dispZList = instance.nodeDisp()
182 | np.savetxt("postResults/dispX.txt",dispXList,fmt='%f')
183 | np.savetxt("postResults/dispY.txt",dispYList,fmt='%f')
184 | np.savetxt("postResults/dispZ.txt",dispZList,fmt='%f')
185 | ##单元积分点Mises应力
186 | responseType='mises'
187 | misesStress=instance.intPointResponse(responseType)
188 | np.savetxt("postResults/misesStress.txt", misesStress, fmt="%f")
189 | ##单元积分点等效塑性应变
190 | responseType1 = 'PEEQ'
191 | plasticStrain = instance.intPointResponse(responseType1)
192 | np.savetxt("postResults/PEEQ.txt", plasticStrain, fmt="%f")
193 |
194 |
--------------------------------------------------------------------------------
/abaqusPythonScript.py:
--------------------------------------------------------------------------------
1 | import os
2 | ##########################################################################
3 | ########################---参数设置---####################################
4 | thick=0.03 #弯曲板厚度(m)
5 | upperPlateThick=0.1 #上下固定板厚度
6 | height=1.5 #板高度(m)
7 | width=1.5 #板宽度(m)
8 | tapHeight=0.1 #不变宽度高度(m)
9 | middleHeight=0.3 #中间段高度(m)
10 | middleWidth=0.6 #中间段宽度(m)
11 | numPlate=5 #板个数(m)
12 | distance=0.2 #板间隔距离
13 | numStep=1 #荷载步数
14 | stepDisp=0.6 #每个荷载步位移增量
15 | seedSize=0.03 #网格尺寸
16 | maxInc=0.05 #每个荷载步增量大小
17 | ##########################################################################
18 | ########################---清除历史结果---#################################
19 | import fnmatch
20 | listName=os.listdir(os.getcwd())
21 | for fileName in listName:
22 | try:
23 | if fnmatch.fnmatch(fileName,'Job-pushOver.*'):
24 | os.remove(fileName)
25 | except:
26 | os.system('taskkill /f /t /im '+"Job-pushOver.023")
27 | ##########################################################################
28 | ########################---abaqus脚本文件---##############################
29 |
30 | fileName="runAbaqus.py"
31 | os.remove(fileName)
32 | f= open(fileName, "a+")
33 | #######################################
34 | #########---导入必要的模块---#########
35 |
36 | f.write( "#############################\n")
37 | f.write( "from abaqus import *\n")
38 | f.write( "from abaqusConstants import *\n")
39 | f.write( "from caeModules import *\n")
40 | f.write( "from odbAccess import *\n")
41 | f.write( "import regionToolset\n")
42 | # """
43 | ######################################
44 | #########---初始化---#################
45 | f.write( "#############################\n")
46 | f.write( "session.viewports[\"Viewport: 1\"].setValues(displayedObject=None)\n")
47 | ######################################
48 | #########---建立模型---################
49 | f.write( "#############################\n")
50 | f.write( "mdb.models.changeKey(fromName=\"Model-1\",toName=\"steelPlate Frame\")\n")
51 | f.write( "plateModel=mdb.models[\"steelPlate Frame\"]\n")
52 | ######################################
53 | #########---生成部件---################
54 | f.write( "#############################\n")
55 | f.write( "bendPlateSketch_1=plateModel.ConstrainedSketch(name=\"bendPlateSketch_1\",sheetSize=2)\n")
56 | xyCoords1=[(-0.5*width,tapHeight),(-0.5*width,0),(0.5*width,0),(0.5*width,tapHeight),
57 | (0.5*middleWidth,0.5*height-0.5*middleHeight),(0.5*middleWidth,0.5*height+0.5*middleHeight),
58 | (0.5*width,height-tapHeight),(0.5*width,height),(-0.5*width,height),
59 | (-0.5*width,height-tapHeight),(-0.5*middleWidth,0.5*height+0.5*middleHeight),
60 | (-0.5*middleWidth,0.5*height-0.5*middleHeight),(-0.5*width,tapHeight)]
61 | for j1 in range(len(xyCoords1)-1):
62 | f.write("bendPlateSketch_1.Line(point1="+str(xyCoords1[j1])+",point2="+str(xyCoords1[j1+1])+")\n")
63 |
64 | f.write( "bendPlatePart_1=plateModel.Part(name=\"bendPlatePart_1\",dimensionality=THREE_D,type=DEFORMABLE_BODY)\n")
65 | f.write( "bendPlatePart_1.BaseShell(sketch=bendPlateSketch_1)\n")
66 | for i1 in range(numPlate-1):
67 | f.write("bendPlatePart_"+str(i1+2)+"=plateModel.Part(name=\"bendPlatePart_"+
68 | str(i1+2)+"\",objectToCopy=bendPlatePart_1)\n")
69 | ####################
70 | f.write( "bottomPlateSketch=plateModel.ConstrainedSketch(name=\"bottomPlate\",sheetSize=2)\n")
71 | xyCoords1=[(-0.5*width,0),(0.5*width,0)]
72 | extrudeValue=distance*(numPlate+1)
73 | f.write("bottomPlateSketch.Line(point1="+str(xyCoords1[0])+",point2="+str(xyCoords1[1])+")\n")
74 | f.write( "bottomPlatePart=plateModel.Part(name=\"bottomPlatePart\",dimensionality=THREE_D,type=DEFORMABLE_BODY)\n")
75 | f.write( "bottomPlatePart.BaseShellExtrude(sketch=bottomPlateSketch, depth="+str(extrudeValue)+")\n")
76 | f.write("upperPlatePart=plateModel.Part(name=\"upperPlatePart\",objectToCopy=bottomPlatePart)\n")
77 | ######################################
78 | # """
79 | #########---定义材料---################
80 | f.write( "#############################\n")
81 | f.write( "elasPlasticMaterial=plateModel.Material(name=\"elasPlasticMaterial\")\n")
82 | f.write( "elasPlasticMaterial.Elastic(table=((210000000,0.3),))\n")
83 | stressStrainTable=((345000,0),(471000,0.15),(480000,1))
84 | f.write( "elasPlasticMaterial.Plastic(table="+str(stressStrainTable)+")\n")
85 | #####################################
86 | #########---创建截面---###############
87 | f.write( "#############################\n")
88 | f.write( "bendPlateSection=plateModel.HomogeneousShellSection(name=\"bendPlateSection\","
89 | "material=\"elasPlasticMaterial\",thickness="+str(thick)+")\n")
90 | f.write( "fixPlateSection=plateModel.HomogeneousShellSection(name=\"fixPlateSection\","
91 | "material=\"elasPlasticMaterial\",thickness="+str(upperPlateThick)+")\n")
92 | #####################################
93 | #########---截面指定---###############
94 | f.write( "#############################\n")
95 | for i2 in range(numPlate):
96 | f.write("bendPlateFace_"+str(i2+1)+"=(bendPlatePart_"+str(i2+1)+".faces,)\n")
97 | f.write("bendPlatePart_"+str(i2+1)+".SectionAssignment(region=bendPlateFace_"+str(i2+1)+","
98 | "sectionName=\"bendPlateSection\")\n")
99 | f.write("bottomPlateFaces=(bottomPlatePart.faces,)\n")
100 | f.write("bottomPlatePart.SectionAssignment(region=bottomPlateFaces,sectionName=\"fixPlateSection\")\n")
101 | f.write("upperPlateFaces=(upperPlatePart.faces,)\n")
102 | f.write("upperPlatePart.SectionAssignment(region=upperPlateFaces,sectionName=\"fixPlateSection\")\n")
103 | ######################################
104 | #########---装配部件---###############
105 | f.write( "#############################\n")
106 | f.write("rootAssembly=plateModel.rootAssembly\n")
107 | for i3 in range(numPlate):
108 | f.write("bendInstance_"+str(i3+1)+"=rootAssembly.Instance(name=\"bendPlateAssembly_"+str(i3+1)+"\","
109 | "part=bendPlatePart_"+str(i3+1)+",dependent=ON)\n")
110 | f.write("bottomInstance=rootAssembly.Instance(name=\"bottomPlateAssembly\",part=bottomPlatePart,dependent=ON)\n")
111 | f.write("upperInstance=rootAssembly.Instance(name=\"upperPlateAssembly\",part=upperPlatePart,dependent=ON)\n")
112 | for i4 in range(numPlate):
113 | f.write("rootAssembly.translate(instanceList=('bendPlateAssembly_"+str(i4+1)+"', ),"
114 | " vector=(0.0, 0.0,"+str(distance*(i4+1))+"))\n")
115 | f.write("rootAssembly.translate(instanceList=('upperPlateAssembly', ), vector=(0.0,"+str(height)+",0.0))\n")
116 |
117 | f.write("assemblyPart=rootAssembly.InstanceFromBooleanMerge(name='assemblyPart', instances=(")
118 | for i5 in range(numPlate):
119 | f.write("bendInstance_"+str(i5+1)+",")
120 | f.write("\nbottomInstance,upperInstance,),originalInstances=SUPPRESS,domain=GEOMETRY)\n")
121 | ######################################
122 | #########---荷载步设置---##############
123 | f.write( "#############################\n")
124 | aa="pushOver_"+str(1)
125 | f.write("plateModel.StaticStep(name=\""+aa+"\",previous='Initial', initialInc="+str(maxInc)+","
126 | " maxInc="+str(maxInc)+",nlgeom=ON)\n")
127 | for i6 in range(numStep-1):
128 | previousName="pushOver_"+str(i6+1)
129 | currentName="pushOver_"+str(i6+2)
130 | f.write("plateModel.StaticStep(name=\"" + currentName + "\",previous=\"" + previousName + "\","
131 | " initialInc="+str(maxInc)+", maxInc="+str(maxInc)+",nlgeom=ON)\n")
132 | ######################################
133 | #########---耦合设置--##############
134 | f.write( "#############################\n")
135 | f.write("refPointid=rootAssembly.ReferencePoint(point="+str((0,height,0))+").id\n")
136 | f.write("refPointRegion=rootAssembly.Set(referencePoints=(rootAssembly.referencePoints[refPointid],), name='refPointSet')\n")
137 | points=tuple([((0,height,distance*(i7+0.5)),) for i7 in range(numPlate+1)])
138 | f.write("assemblyTopFaces = assemblyPart.faces.findAt"+str(points)+"\n")
139 | f.write("topFameRegion=regionToolset.Region(faces=assemblyTopFaces)\n")
140 | f.write("plateModel.Coupling(name='Constraint-upperPlate',controlPoint=refPointRegion,"
141 | "surface=topFameRegion,couplingType=KINEMATIC,influenceRadius=WHOLE_SURFACE)\n")
142 | ######################################
143 | #########---边界条件设置--#############
144 | f.write( "#############################\n")
145 | pointsBC=tuple([((0,0,distance*(i7+0.5)),) for i7 in range(numPlate+1)])
146 | f.write("assemblyBottomFaces = assemblyPart.faces.findAt"+str(pointsBC)+"\n")
147 | f.write("bottomFameRegion=regionToolset.Region(faces=assemblyBottomFaces)\n")
148 | f.write("plateModel.DisplacementBC(name='initBC', createStepName='Initial',region=bottomFameRegion,"
149 | "u1=SET, u2=SET, u3=SET, ur1=SET,ur2=SET, ur3=SET)\n")
150 | #############################################
151 | #########---pushOver荷载设置--################
152 | f.write( "#############################\n")
153 | f.write("plateModel.DisplacementBC(name='pushOver',createStepName='pushOver_1',region=refPointRegion,u3="+str(stepDisp)+")\n")
154 | for i8 in range(numStep-1):
155 | stepName="pushOver_"+str(i8+2)
156 | u3=(i8+2)*stepDisp*(-1)**(i8+1)
157 | f.write("plateModel.boundaryConditions['pushOver'].setValuesInStep(stepName=\""+str(stepName)+"\",u3="+str(u3)+")\n")
158 | #############################################
159 | #########---网格划分设置--####################
160 | f.write( "#############################\n")
161 | ######网格尺寸设置
162 | f.write("meshPart=plateModel.parts[\"assemblyPart\"]\n")
163 | f.write("seedEdges=meshPart.edges\n")
164 | f.write("meshPart.seedEdgeBySize(edges=seedEdges,size="+str(seedSize)+")\n")
165 | ######划分控制设置
166 | f.write("assemblyFaces=assemblyPart.faces\n")
167 | f.write("assemblyFaces=meshPart.setMeshControls(regions=assemblyFaces,technique=STRUCTURED)\n")
168 | ######单元类型设置
169 | f.write("eleType1=mesh.ElemType(elemCode=S4R)\n")
170 | f.write("eleType2=mesh.ElemType(elemCode=S3)\n")
171 | f.write("meshRegion=regionToolset.Region(faces=(assemblyPart.faces),)\n")
172 | f.write("meshPart.setElementType(regions=meshRegion, elemTypes=(eleType1, eleType2))\n")
173 | ######网格划分
174 | f.write("meshPart.generateMesh()\n")
175 | #############################################
176 | #########---任务设置--########################
177 | f.write( "#############################\n")
178 | f.write("mdb.Job(name='Job-pushOver', model='steelPlate Frame', multiprocessingMode=DEFAULT, numCpus=4,numDomains=4, numGPUs=1)\n")
179 | f.write( "mdb.jobs['Job-pushOver'].submit(consistencyChecking=OFF)\n")
180 | # """
181 | ######################################
182 | f.close()
183 | #######################################
184 | os.system('abaqus CAE script=runAbaqus.py')
185 | # os.system('abaqus CAE noGUI=runAbaqus.py')
186 | ############################################
187 | ######结果数据库处理
188 | os.system('abaqus CAE noGUI=abaqusODBProcess.py')
189 | ###########################################
190 | ############################################
191 | ######结果后处理
192 |
193 |
--------------------------------------------------------------------------------
/dispForce.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Junjun1guo/pythonInteractAbaqus/364cf248b161bbd9760540cc86d4bd06d4eff667/dispForce.gif
--------------------------------------------------------------------------------
/launcher.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | "C:\SIMULIA\Commands\abq2019.bat" %*
--------------------------------------------------------------------------------
/main_Run.py:
--------------------------------------------------------------------------------
1 | #-*-coding: UTF-8-*-
2 | #########################################################################
3 | # Author: Junjun Guo
4 | # E-mail: guojj@tongji.edu.cn/guojj_ce@163.com/guojj01@gmail.com
5 | # Environemet: Successfully executed in python 3.8
6 | # Date: 2021-09-19
7 | #########################################################################
8 | #import necessary modules
9 | import os
10 | import runpy
11 | #########################################################################
12 | ############---1---基于abaqus环境进行计算----##########################
13 | # os.system('abaqus CAE noGUI=runAbaqus.py') #active abaqus CAE and run the script
14 | os.system('abaqus CAE script=runAbaqus.py') #active abaqus CAE and run the script
15 | # print("Successfully executed runAbaqus.py module!")
16 | ############---2---操作obd文件提取结果----#############################
17 | # os.system('abaqus CAE noGUI=abaqusODBProcess.py')
18 | # os.system('abaqus CAE script=abaqusODBProcess.py')
19 | # print("Successfully executed abaqusODBProcess.py module!")
20 | ############---3---将提取的结果存储于数据库中----########################
21 | # runpy.run_path('saveDataToSqlite.py', run_name='__main__')
22 | # print("Successfully executed saveDataToSqlite.py module!")
23 | ############---4---基于pyvista显示结果动图----########################
24 | # runpy.run_path('resultsDisplayPyvista.py', run_name='__main__')
25 | # print("Successfully executed resultsDisplayPyvista.py module!")
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/misesStress.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Junjun1guo/pythonInteractAbaqus/364cf248b161bbd9760540cc86d4bd06d4eff667/misesStress.gif
--------------------------------------------------------------------------------
/postResults/refDisp.txt:
--------------------------------------------------------------------------------
1 | 0.000000 0.000000 0.000000
2 | 0.000000 -0.000277 0.030000
3 | -0.000000 -0.001285 0.060000
4 | 0.000000 -0.002964 0.090000
5 | 0.000000 -0.005161 0.120000
6 | 0.000000 -0.007837 0.150000
7 | -0.000000 -0.011067 0.180000
8 | 0.000000 -0.014901 0.210000
9 | 0.000000 -0.019351 0.240000
10 | 0.000000 -0.024423 0.270000
11 | -0.000000 -0.030123 0.300000
12 | 0.000000 -0.036452 0.330000
13 | 0.000000 -0.043410 0.360000
14 | -0.000000 -0.050996 0.390000
15 | -0.000000 -0.059210 0.420000
16 | 0.000000 -0.068054 0.450000
17 | 0.000000 -0.070366 0.457500
18 | 0.000000 -0.072717 0.465000
19 | 0.000000 -0.076318 0.476250
20 | 0.000000 -0.081886 0.493125
21 | 0.000000 -0.090611 0.518438
22 | 0.000000 -0.099790 0.543750
23 | 0.000000 -0.109425 0.569062
24 | 0.000000 -0.119517 0.594375
25 | -0.000000 -0.121825 0.600000
26 |
--------------------------------------------------------------------------------
/postResults/refLoad.txt:
--------------------------------------------------------------------------------
1 | 0.000000 0.000000 -0.000000
2 | 0.000000 0.000000 290.094574
3 | 0.000000 0.000000 568.478516
4 | 0.000000 0.000000 747.361511
5 | 0.000000 0.000000 845.071167
6 | 0.000000 0.000000 890.106873
7 | 0.000000 0.000000 912.915588
8 | 0.000000 0.000000 929.463135
9 | 0.000000 0.000000 943.338745
10 | 0.000000 0.000000 955.686157
11 | 0.000000 0.000000 967.042053
12 | 0.000000 0.000000 977.629578
13 | 0.000000 0.000000 987.638184
14 | 0.000000 0.000000 997.175903
15 | 0.000000 0.000000 1006.390808
16 | 0.000000 0.000000 1015.390076
17 | 0.000000 0.000000 1017.660217
18 | 0.000000 0.000000 1019.923645
19 | 0.000000 0.000000 1023.297424
20 | 0.000000 0.000000 1028.319214
21 | 0.000000 0.000000 1035.789917
22 | 0.000000 0.000000 1043.258545
23 | 0.000000 0.000000 1050.716187
24 | 0.000000 0.000000 1058.145996
25 | 0.000000 0.000000 1059.824341
26 |
--------------------------------------------------------------------------------
/prePostProcess.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @File : 234.py
3 | # @Date : 2020-09-02 18:14
4 | # @Email : {guojj@tongji.edu.cn/guojj01@gmail.com}
5 | # @Author : guojj
6 |
7 |
8 | ###导入必要的模块
9 | import numpy as np
10 | import pyvista as pv
11 | import ctypes
12 | import os
13 | import time
14 | import array
15 | import re
16 | from saveDataToSqlite import SaveData
17 |
18 | class prePostPlot(object):
19 | """模型及结果显示类"""
20 | def __init__(self,dbPath):
21 | self.saveInstance = SaveData(dbPath)
22 |
23 | def prePlot(self):
24 | """前处理模型展示"""
25 | nodes=self.saveInstance.getAllNode()
26 | elements=self.saveInstance.getAllEle()
27 | nodesProcess=prePostPlot.strToListConvert(nodes,'coords','float')
28 | elementsProcess=prePostPlot.strToListConvert(elements,'connectivity','int')
29 | prePostPlot.staticPlot(nodesProcess,elementsProcess)
30 |
31 | def postPlot(self,comp,colorValue,saveName,sleepValue):
32 | """后处理结果绘制"""
33 | nodes = self.saveInstance.getAllNode()
34 | elements = self.saveInstance.getAllEle()
35 | nodesProcess = prePostPlot.strToListConvert(nodes, 'coords', 'float')
36 | elementsProcess = prePostPlot.strToListConvert(elements, 'connectivity', 'int')
37 | if comp=="mises":
38 | response=self.saveInstance.getAllMises()
39 | responsePorcess = prePostPlot.strToListConvert(response, 'mises', 'float')
40 | elif comp=="PEEQ":
41 | response = self.saveInstance.getAllPEEQ()
42 | responsePorcess = prePostPlot.strToListConvert(response, 'PEEQ', 'float')
43 | nodeDisp=self.saveInstance.getAllDisp()
44 | dispXProcess=prePostPlot.strToListConvert(nodeDisp, 'dispX', 'float')
45 | dispYProcess=prePostPlot.strToListConvert(nodeDisp, 'dispY', 'float')
46 | dispZProcess = prePostPlot.strToListConvert(nodeDisp, 'dispZ', 'float')
47 | prePostPlot.dynamicPlot(nodesProcess,elementsProcess,dispXProcess,dispYProcess
48 | ,dispZProcess,responsePorcess,colorValue,saveName,sleepValue)
49 |
50 | @staticmethod
51 | def dynamicPlot(nodes,elements,dispX,dispY,dispZ,varValue,colorValue,saveName,sleepValue):
52 | """"""
53 | ##绘图窗口设置
54 | user32 = ctypes.windll.user32
55 | screensizex, screensizey = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)
56 | plotter = pv.Plotter(shape=(1,1), border=True, window_size=[int(screensizex), int(screensizey)])
57 | plotter.set_background(color="white")
58 | ##数据格式处理
59 | vertices=np.array(nodes)
60 | elementProcess = [[len(each)] + list(map(lambda item: item - 1, each)) for each in elements]
61 | faces = np.hstack(elementProcess)
62 | surf = pv.PolyData(vertices, faces)
63 | scales = np.array([varValue[j1][0] for j1 in range(len(varValue))])
64 | ##动态图绘制
65 | plotter.add_mesh(surf, show_edges=False, scalars=scales, edge_color="blue", interpolate_before_map=True,
66 | cmap="jet", clim=[0, colorValue], show_scalar_bar=True)
67 | plotter.show(interactive=False, auto_close=False)
68 | plotter.add_axes()
69 | plotter.camera_position = (2, 2, -2)
70 | plotter.open_gif(saveName+'.gif')
71 | for i1 in range(len(varValue[0]) - 1):
72 | scaless = np.array([varValue[j1][i1] for j1 in range(len(varValue))])
73 | pts = np.array([[dispX[j1][i1] + vertices[j1][0], dispY[j1][i1] + vertices[j1][1], \
74 | dispZ[j1][i1] + vertices[j1][2]] for j1 in range(len(dispX))])
75 | plotter.update_scalars(scaless)
76 | plotter.update_coordinates(pts)
77 | plotter.write_frame()
78 | time.sleep(sleepValue)
79 | plotter.close()
80 |
81 | @staticmethod
82 | def staticPlot(nodes,elements,showNodes=False,showEle=False):
83 | """
84 | 静态图形绘制
85 | """
86 | vertices=np.array(nodes)
87 | elementProcess=[[len(each)]+list(map(lambda item:item-1,each)) for each in elements]
88 | faces=np.hstack(elementProcess)
89 | surf = pv.PolyData(vertices, faces)
90 | ##绘图窗口设置
91 | user32 = ctypes.windll.user32
92 | screensizex, screensizey = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)
93 | plotter = pv.Plotter(shape=(1,1), border=True, window_size=[int(1 * screensizex),
94 | int(1 * screensizey)])
95 | plotter.set_background(color="white")
96 | ##坐标轴绘制
97 | arrowX=pv.Arrow(start=(0,0,0),direction=(1,0,0),tip_length=0.3,tip_radius=0.1,
98 | shaft_radius=0.05,scale=0.1)
99 | arrowY=pv.Arrow(start=(0,0,0),direction=(0,1,0),tip_length=0.3,tip_radius=0.1,
100 | shaft_radius=0.05,scale=0.1)
101 | arrowZ=pv.Arrow(start=(0,0,0),direction=(0,0,1),tip_length=0.3,tip_radius=0.1,
102 | shaft_radius=0.05,scale=0.1)
103 | plotter.add_mesh(arrowX, color="red", show_edges=False)
104 | plotter.add_mesh(arrowY, color="green", show_edges=False)
105 | plotter.add_mesh(arrowZ, color="blue", show_edges=False)
106 | ##图形绘制
107 | plotter.add_mesh(surf, show_edges=True, edge_color="blue",style='surface')
108 | if showNodes==True:
109 | labelRange = [(i1 + 1) for i1 in range(len(vertices))]
110 | plotter.add_point_labels(vertices,labelRange, bold=False, point_size=0,
111 | font_size=16,text_color="red",font_family="times",show_points=False,shape=None,tolerance=1.0)
112 | if showEle==True:
113 | pass
114 | plotter.show(interactive=True, auto_close=False)
115 |
116 | @staticmethod
117 | def strToListConvert(strList,keys,types):
118 | """
119 | pass
120 | 将字符化列表转为数字列表,'[1,2,3]'to [1,2,3]
121 | 其中strList为字典列表,keys为键值,types为转换目标类型
122 | """
123 | temp1=[each[keys][1:-1].split() for each in strList]
124 | returnList=[list(map(float,each)) for each in temp1]
125 | if types=='float':
126 | finalList=returnList
127 | elif types=='int':
128 | finalList=[list(map(eval(types),each)) for each in returnList]
129 | else:
130 | print("types must be float or int!")
131 | return finalList
132 |
133 | @staticmethod
134 | def intervalValue(maxValue,numbers):
135 | """
136 | 返回间隔线间隔大小
137 | maxValue-最大值
138 | numbers-分割线个数
139 | """
140 | b = len(str(int(maxValue)))
141 | if b==1 and int(maxValue)==0:
142 | interval = round(maxValue /numbers, 2)
143 | i3=2
144 | while(interval==0):
145 | interval=round(maxValue /numbers, i3+1)
146 | i3=i3+1
147 |
148 | elif b==1 and int(maxValue)!=0:
149 | interval = int(maxValue /numbers)
150 | else:
151 | loc = maxValue / 10 ** (b - 1)
152 | interval = int(loc) * 0.2 * 10 ** (b - 1)
153 | return interval
154 |
155 | def dispForcePlot(self,saveName,timeSleep,disp=None,force=None):
156 | """滞回曲线绘制"""
157 | if disp==None and force==None:
158 | dispForce= self.saveInstance.getRefResponse()
159 | dispX= np.array(prePostPlot.strToListConvert(dispForce, 'refDisp', 'float'))[:,2]
160 | forceY = np.array(prePostPlot.strToListConvert(dispForce, 'refLoad', 'float'))[:, 2]
161 | else:
162 | dispX=disp
163 | forceY=force
164 | ###绘图窗口设置
165 |
166 | user32 = ctypes.windll.user32
167 | screensizex, screensizey = 0.9*user32.GetSystemMetrics(0), 0.9*user32.GetSystemMetrics(1)
168 | plotter = pv.Plotter(shape=(1, 1), border=True, window_size=[int(screensizex), int(screensizey)])
169 | plotter.set_background(color="white")
170 | ###数据格式处理
171 | maxDisp=1.1*max(np.abs(dispX))
172 | maxForce = max(np.abs(forceY))
173 | screenRatio=user32.GetSystemMetrics(0)/float(user32.GetSystemMetrics(1))
174 | ratio=screenRatio*maxForce/float(maxDisp)
175 | ###坐标轴绘制
176 | plotter.camera_position = [(0, 0, 5 * maxForce), (0, 0, 0), (0, 1, 0)]
177 | lineX= np.array([[-1.2*ratio*maxDisp,0, 0], [1.2*ratio*maxDisp,0, 0]])
178 | arrayXUp= np.array([[1.15*ratio*maxDisp,0.02*maxForce, 0], [1.2*ratio*maxDisp,0, 0]])
179 | arrayXDown = np.array([[1.15 * ratio * maxDisp, -0.02 * maxForce, 0], [1.2 * ratio * maxDisp, 0, 0]])
180 | lineY = np.array([[0, -1.2*maxForce, 0], [0, 1.2*maxForce, 0]])
181 | arrayYLeft = np.array([[-0.02*maxForce, 1.12*maxForce, 0], [0, 1.2*maxForce, 0]])
182 | arrayYRight = np.array([[0.02 * maxForce, 1.12 * maxForce, 0], [0, 1.2 * maxForce, 0]])
183 | plotter.add_lines(lineX, color="k", width=2)
184 | plotter.add_lines(lineY, color="k", width=2)
185 | plotter.add_lines(arrayXUp, color="k", width=2)
186 | plotter.add_lines(arrayXDown, color="k", width=2)
187 | plotter.add_lines(arrayYLeft, color="k", width=2)
188 | plotter.add_lines(arrayYRight, color="k", width=2)
189 | ###坐标标签绘制
190 | plotter.add_point_labels(np.array([1.8*maxForce,-0.1*maxForce,0]),labels=["disp. (m)"],
191 | text_color="red",font_size=20,font_family='times',fill_shape=False,
192 | shape=None)
193 | plotter.add_point_labels(np.array([-0.4*maxForce, 1.12* maxForce, 0]), labels=["force (kN)"],
194 | text_color="red", font_size=20, font_family='times', fill_shape=False,
195 | shape=None)
196 | ###间隔大小
197 | intervalX=prePostPlot.intervalValue(maxDisp,5)
198 | intervalY = prePostPlot.intervalValue(maxForce, 5)
199 | ###分割线绘制
200 | bottomLine=np.array([[-1*ratio*maxDisp,-1.1*maxForce, 0], [1*ratio*maxDisp,-1.1*maxForce, 0]])
201 | upLine = np.array([[-1 * ratio * maxDisp, 1.1 * maxForce, 0], [1 * ratio * maxDisp, 1.1 * maxForce, 0]])
202 | leftLine = np.array([[-1 * ratio * maxDisp, -1.1 * maxForce, 0], [-1 * ratio * maxDisp, 1.1 *maxForce, 0]])
203 | rightLine = np.array([[1 * ratio * maxDisp, -1.1 * maxForce, 0], [1 * ratio * maxDisp, 1.1 * maxForce, 0]])
204 | plotter.add_lines(bottomLine, color="k", width=1)
205 | plotter.add_lines(upLine, color="k", width=1)
206 | plotter.add_lines(leftLine, color="k", width=1)
207 | plotter.add_lines(rightLine, color="k", width=1)
208 |
209 | indexX=0
210 | while((indexX*intervalX)<(maxDisp-intervalX)):
211 | indexX=indexX+1
212 | posVertical = np.array([[ratio*intervalX*indexX, -1.1 * maxForce, 0],
213 | [ratio*intervalX*indexX, 1.1 * maxForce, 0]])
214 | negVertical = np.array([[-ratio*intervalX * indexX, -1.1 * maxForce, 0],
215 | [-ratio*intervalX * indexX, 1.1 * maxForce, 0]])
216 | plotter.add_lines(posVertical, color="grey", width=0.1)
217 | plotter.add_lines(negVertical, color="grey", width=0.1)
218 | textPos=ratio*intervalX*(indexX-1)
219 | plotter.add_point_labels(np.array([textPos+0.8*intervalX*ratio, -1.2 * maxForce, 0]),
220 | labels=[str(intervalX*indexX)], text_color="k", font_size=15,
221 | font_family='times', fill_shape=False, shape=None)
222 | plotter.add_point_labels(np.array([-textPos -1.2 * intervalX * ratio, -1.2 * maxForce, 0]),
223 | labels=[str(-intervalX * indexX)], text_color="k", font_size=15,
224 | font_family='times', fill_shape=False, shape=None)
225 | plotter.add_point_labels(np.array([maxForce*0.01, -1.2 * maxForce, 0]),
226 | labels=[str(0)], text_color="k", font_size=15,
227 | font_family='times', fill_shape=False, shape=None)
228 |
229 | indexY = 0
230 | while ((indexY * intervalY) < (maxForce-intervalY)):
231 | indexY = indexY + 1
232 | posHorizontal = np.array([[-1 * ratio * maxDisp, indexY*intervalY, 0],
233 | [1 * ratio * maxDisp, indexY*intervalY, 0]])
234 | negHorizontal = np.array([[-1 * ratio * maxDisp, -indexY * intervalY, 0],
235 | [1 * ratio * maxDisp, -indexY * intervalY, 0]])
236 | plotter.add_lines(posHorizontal, color="grey", width=0.1)
237 | plotter.add_lines(negHorizontal, color="grey", width=0.1)
238 | textPos = intervalY * (indexY - 1)
239 | plotter.add_point_labels(np.array([-1.15 * ratio * maxDisp, textPos+0.9*intervalY, 0]),
240 | labels=[str(intervalY*indexY)],text_color="k", font_size=15,
241 | font_family='times', fill_shape=False,shape=None)
242 | plotter.add_point_labels(np.array([-1.15 * ratio * maxDisp, -textPos-1.1*intervalY, 0]),
243 | labels=[str(-intervalY * indexY)], text_color="k", font_size=15,
244 | font_family='times', fill_shape=False, shape=None)
245 | plotter.add_point_labels(np.array([-1.15 * ratio * maxDisp, maxForce*0.01, 0]),
246 | labels=[str(0.0)], text_color="k", font_size=15,
247 | font_family='times', fill_shape=False, shape=None)
248 | ###动态图绘制
249 | plotter.show(interactive=False, auto_close=False)
250 | plotter.open_gif(str(saveName)+'.gif')
251 | num=len(dispX)-1
252 | for i1 in range(num):
253 | lines=np.array([[ratio*dispX[i1],forceY[i1],0], [ratio*dispX[i1+1],forceY[i1+1],0]])
254 | plotter.add_lines(lines,color="red",width=2)
255 | plotter.write_frame()
256 | time.sleep(timeSleep)
257 | ################################################################################
258 | if __name__ == '__main__':
259 | dbPath="postResultDB.db"
260 | instance=prePostPlot(dbPath)
261 | instance.prePlot()
262 | componentMame="mises"
263 | colorValue=371000
264 | saveName="plasticStrain"
265 | timeSleep=0.1
266 | instance.postPlot(componentMame,colorValue,saveName,timeSleep) #绘制应力及等效塑性应变动态图
267 | saveName1="dispForce"
268 | instance.dispForcePlot(saveName1,timeSleep) #绘制加载点力与位移滞回曲线
269 |
270 |
--------------------------------------------------------------------------------
/prePostProcess.py.bak:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @File : 234.py
3 | # @Date : 2020-09-02 18:14
4 | # @Email : {guojj@tongji.edu.cn/guojj01@gmail.com}
5 | # @Author : guojj
6 |
7 |
8 | ###导入必要的模块
9 | import numpy as np
10 | import pyvista as pv
11 | import pygmsh
12 | import ctypes
13 | import os
14 | import shutil
15 | import time
16 | import pyqtgraph as pg
17 | import array
18 | from numba import jit
19 | import meshio
20 | import re
21 | import json
22 | from saveDataToSqlite import SaveData
23 |
24 | class prePostPlot(object):
25 | """模型及结果显示类"""
26 | def __init__(self,dbPath):
27 | self.saveInstance = SaveData(dbPath)
28 |
29 | def prePlot(self):
30 | """前处理模型展示"""
31 | nodes=self.saveInstance.getAllNode()
32 | elements=self.saveInstance.getAllEle()
33 | nodesProcess=prePostPlot.strToListConvert(nodes,'coords','float')
34 | elementsProcess=prePostPlot.strToListConvert(elements,'connectivity','int')
35 | prePostPlot.staticPlot(nodesProcess,elementsProcess)
36 |
37 | def postPlot(self,comp,colorValue,saveName,sleepValue):
38 | """后处理结果绘制"""
39 | nodes = self.saveInstance.getAllNode()
40 | elements = self.saveInstance.getAllEle()
41 | nodesProcess = prePostPlot.strToListConvert(nodes, 'coords', 'float')
42 | elementsProcess = prePostPlot.strToListConvert(elements, 'connectivity', 'int')
43 | if comp=="mises":
44 | response=self.saveInstance.getAllMises()
45 | responsePorcess = prePostPlot.strToListConvert(response, 'mises', 'float')
46 | elif comp=="PEEQ":
47 | response = self.saveInstance.getAllPEEQ()
48 | responsePorcess = prePostPlot.strToListConvert(response, 'PEEQ', 'float')
49 | nodeDisp=self.saveInstance.getAllDisp()
50 | dispXProcess=prePostPlot.strToListConvert(nodeDisp, 'dispX', 'float')
51 | dispYProcess=prePostPlot.strToListConvert(nodeDisp, 'dispY', 'float')
52 | dispZProcess = prePostPlot.strToListConvert(nodeDisp, 'dispZ', 'float')
53 | prePostPlot.dynamicPlot(nodesProcess,elementsProcess,dispXProcess,dispYProcess
54 | ,dispZProcess,responsePorcess,colorValue,saveName,sleepValue)
55 |
56 | @staticmethod
57 | def dynamicPlot(nodes,elements,dispX,dispY,dispZ,varValue,colorValue,saveName,sleepValue):
58 | """"""
59 | ##绘图窗口设置
60 | user32 = ctypes.windll.user32
61 | screensizex, screensizey = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)
62 | plotter = pv.Plotter(shape=(1,1), border=True, window_size=[int(screensizex), int(screensizey)])
63 | plotter.set_background(color="white")
64 | ##数据格式处理
65 | vertices=np.array(nodes)
66 | elementProcess = [[len(each)] + list(map(lambda item: item - 1, each)) for each in elements]
67 | faces = np.hstack(elementProcess)
68 | surf = pv.PolyData(vertices, faces)
69 | scales = np.array([varValue[j1][0] for j1 in range(len(varValue))])
70 | ##动态图绘制
71 | plotter.add_mesh(surf, show_edges=False, scalars=scales, edge_color="blue", interpolate_before_map=True,
72 | cmap="jet", clim=[0, colorValue], show_scalar_bar=True)
73 | plotter.show(interactive=False, auto_close=False)
74 | plotter.add_axes()
75 | plotter.camera_position = (2, 2, -2)
76 | plotter.open_gif(saveName+'.gif')
77 | for i1 in range(len(varValue[0]) - 1):
78 | scaless = np.array([varValue[j1][i1] for j1 in range(len(varValue))])
79 | pts = np.array([[dispX[j1][i1] + vertices[j1][0], dispY[j1][i1] + vertices[j1][1], \
80 | dispZ[j1][i1] + vertices[j1][2]] for j1 in range(len(dispX))])
81 | plotter.update_scalars(scaless)
82 | plotter.update_coordinates(pts)
83 | plotter.write_frame()
84 | time.sleep(sleepValue)
85 | plotter.close()
86 |
87 | @staticmethod
88 | def staticPlot(nodes,elements,showNodes=False,showEle=False):
89 | """
90 | 静态图形绘制
91 | """
92 | vertices=np.array(nodes)
93 | elementProcess=[[len(each)]+list(map(lambda item:item-1,each)) for each in elements]
94 | faces=np.hstack(elementProcess)
95 | surf = pv.PolyData(vertices, faces)
96 | ##绘图窗口设置
97 | user32 = ctypes.windll.user32
98 | screensizex, screensizey = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)
99 | plotter = pv.Plotter(shape=(1,1), border=True, window_size=[int(1 * screensizex),
100 | int(1 * screensizey)])
101 | plotter.set_background(color="white")
102 | ##坐标轴绘制
103 | arrowX=pv.Arrow(start=(0,0,0),direction=(1,0,0),tip_length=0.3,tip_radius=0.1,
104 | shaft_radius=0.05,scale=0.1)
105 | arrowY=pv.Arrow(start=(0,0,0),direction=(0,1,0),tip_length=0.3,tip_radius=0.1,
106 | shaft_radius=0.05,scale=0.1)
107 | arrowZ=pv.Arrow(start=(0,0,0),direction=(0,0,1),tip_length=0.3,tip_radius=0.1,
108 | shaft_radius=0.05,scale=0.1)
109 | plotter.add_mesh(arrowX, color="red", show_edges=False)
110 | plotter.add_mesh(arrowY, color="green", show_edges=False)
111 | plotter.add_mesh(arrowZ, color="blue", show_edges=False)
112 | ##图形绘制
113 | plotter.add_mesh(surf, show_edges=True, edge_color="blue",style='surface')
114 | if showNodes==True:
115 | labelRange = [(i1 + 1) for i1 in range(len(vertices))]
116 | plotter.add_point_labels(vertices,labelRange, bold=False, point_size=0,
117 | font_size=16,text_color="red",font_family="times",show_points=False,shape=None,tolerance=1.0)
118 | if showEle==True:
119 | pass
120 | plotter.show(interactive=True, auto_close=False)
121 |
122 | @staticmethod
123 | def strToListConvert(strList,keys,types):
124 | """
125 | pass
126 | 将字符化列表转为数字列表,'[1,2,3]'to [1,2,3]
127 | 其中strList为字典列表,keys为键值,types为转换目标类型
128 | """
129 | temp1=[each[keys][1:-1].split() for each in strList]
130 | returnList=[list(map(float,each)) for each in temp1]
131 | if types=='float':
132 | finalList=returnList
133 | elif types=='int':
134 | finalList=[list(map(eval(types),each)) for each in returnList]
135 | else:
136 | print("types must be float or int!")
137 | return finalList
138 |
139 | @staticmethod
140 | def intervalValue(maxValue,numbers):
141 | """
142 | 返回间隔线间隔大小
143 | maxValue-最大值
144 | numbers-分割线个数
145 | """
146 | b = len(str(int(maxValue)))
147 | if b==1 and int(maxValue)==0:
148 | interval = round(maxValue /numbers, 2)
149 | i3=2
150 | while(interval==0):
151 | interval=round(maxValue /numbers, i3+1)
152 | i3=i3+1
153 |
154 | elif b==1 and int(maxValue)!=0:
155 | interval = int(maxValue /numbers)
156 | else:
157 | loc = maxValue / 10 ** (b - 1)
158 | interval = int(loc) * 0.2 * 10 ** (b - 1)
159 | return interval
160 |
161 | def dispForcePlot(self,saveName,timeSleep,disp=None,force=None):
162 | """滞回曲线绘制"""
163 | if disp==None and force==None:
164 | dispForce= self.saveInstance.getRefResponse()
165 | dispX= np.array(prePostPlot.strToListConvert(dispForce, 'refDisp', 'float'))[:,2]
166 | forceY = np.array(prePostPlot.strToListConvert(dispForce, 'refLoad', 'float'))[:, 2]
167 | else:
168 | dispX=disp
169 | forceY=force
170 | ###绘图窗口设置
171 |
172 | user32 = ctypes.windll.user32
173 | screensizex, screensizey = 0.9*user32.GetSystemMetrics(0), 0.9*user32.GetSystemMetrics(1)
174 | plotter = pv.Plotter(shape=(1, 1), border=True, window_size=[int(screensizex), int(screensizey)])
175 | plotter.set_background(color="white")
176 | ###数据格式处理
177 | maxDisp=1.1*max(np.abs(dispX))
178 | maxForce = max(np.abs(forceY))
179 | screenRatio=user32.GetSystemMetrics(0)/float(user32.GetSystemMetrics(1))
180 | ratio=screenRatio*maxForce/float(maxDisp)
181 | ###坐标轴绘制
182 | plotter.camera_position = [(0, 0, 5 * maxForce), (0, 0, 0), (0, 1, 0)]
183 | lineX= np.array([[-1.2*ratio*maxDisp,0, 0], [1.2*ratio*maxDisp,0, 0]])
184 | arrayXUp= np.array([[1.15*ratio*maxDisp,0.02*maxForce, 0], [1.2*ratio*maxDisp,0, 0]])
185 | arrayXDown = np.array([[1.15 * ratio * maxDisp, -0.02 * maxForce, 0], [1.2 * ratio * maxDisp, 0, 0]])
186 | lineY = np.array([[0, -1.2*maxForce, 0], [0, 1.2*maxForce, 0]])
187 | arrayYLeft = np.array([[-0.02*maxForce, 1.12*maxForce, 0], [0, 1.2*maxForce, 0]])
188 | arrayYRight = np.array([[0.02 * maxForce, 1.12 * maxForce, 0], [0, 1.2 * maxForce, 0]])
189 | plotter.add_lines(lineX, color="k", width=2)
190 | plotter.add_lines(lineY, color="k", width=2)
191 | plotter.add_lines(arrayXUp, color="k", width=2)
192 | plotter.add_lines(arrayXDown, color="k", width=2)
193 | plotter.add_lines(arrayYLeft, color="k", width=2)
194 | plotter.add_lines(arrayYRight, color="k", width=2)
195 | ###坐标标签绘制
196 | plotter.add_point_labels(np.array([1.8*maxForce,-0.1*maxForce,0]),labels=["disp. (m)"],
197 | text_color="red",font_size=20,font_family='times',fill_shape=False,
198 | shape=None)
199 | plotter.add_point_labels(np.array([-0.4*maxForce, 1.12* maxForce, 0]), labels=["force (kN)"],
200 | text_color="red", font_size=20, font_family='times', fill_shape=False,
201 | shape=None)
202 | ###间隔大小
203 | intervalX=prePostPlot.intervalValue(maxDisp,5)
204 | intervalY = prePostPlot.intervalValue(maxForce, 5)
205 | ###分割线绘制
206 | bottomLine=np.array([[-1*ratio*maxDisp,-1.1*maxForce, 0], [1*ratio*maxDisp,-1.1*maxForce, 0]])
207 | upLine = np.array([[-1 * ratio * maxDisp, 1.1 * maxForce, 0], [1 * ratio * maxDisp, 1.1 * maxForce, 0]])
208 | leftLine = np.array([[-1 * ratio * maxDisp, -1.1 * maxForce, 0], [-1 * ratio * maxDisp, 1.1 *maxForce, 0]])
209 | rightLine = np.array([[1 * ratio * maxDisp, -1.1 * maxForce, 0], [1 * ratio * maxDisp, 1.1 * maxForce, 0]])
210 | plotter.add_lines(bottomLine, color="k", width=1)
211 | plotter.add_lines(upLine, color="k", width=1)
212 | plotter.add_lines(leftLine, color="k", width=1)
213 | plotter.add_lines(rightLine, color="k", width=1)
214 |
215 | indexX=0
216 | while((indexX*intervalX)<(maxDisp-intervalX)):
217 | indexX=indexX+1
218 | posVertical = np.array([[ratio*intervalX*indexX, -1.1 * maxForce, 0],
219 | [ratio*intervalX*indexX, 1.1 * maxForce, 0]])
220 | negVertical = np.array([[-ratio*intervalX * indexX, -1.1 * maxForce, 0],
221 | [-ratio*intervalX * indexX, 1.1 * maxForce, 0]])
222 | plotter.add_lines(posVertical, color="grey", width=0.1)
223 | plotter.add_lines(negVertical, color="grey", width=0.1)
224 | textPos=ratio*intervalX*(indexX-1)
225 | plotter.add_point_labels(np.array([textPos+0.8*intervalX*ratio, -1.2 * maxForce, 0]),
226 | labels=[str(intervalX*indexX)], text_color="k", font_size=15,
227 | font_family='times', fill_shape=False, shape=None)
228 | plotter.add_point_labels(np.array([-textPos -1.2 * intervalX * ratio, -1.2 * maxForce, 0]),
229 | labels=[str(-intervalX * indexX)], text_color="k", font_size=15,
230 | font_family='times', fill_shape=False, shape=None)
231 | plotter.add_point_labels(np.array([maxForce*0.01, -1.2 * maxForce, 0]),
232 | labels=[str(0)], text_color="k", font_size=15,
233 | font_family='times', fill_shape=False, shape=None)
234 |
235 | indexY = 0
236 | while ((indexY * intervalY) < (maxForce-intervalY)):
237 | indexY = indexY + 1
238 | posHorizontal = np.array([[-1 * ratio * maxDisp, indexY*intervalY, 0],
239 | [1 * ratio * maxDisp, indexY*intervalY, 0]])
240 | negHorizontal = np.array([[-1 * ratio * maxDisp, -indexY * intervalY, 0],
241 | [1 * ratio * maxDisp, -indexY * intervalY, 0]])
242 | plotter.add_lines(posHorizontal, color="grey", width=0.1)
243 | plotter.add_lines(negHorizontal, color="grey", width=0.1)
244 | textPos = intervalY * (indexY - 1)
245 | plotter.add_point_labels(np.array([-1.15 * ratio * maxDisp, textPos+0.9*intervalY, 0]),
246 | labels=[str(intervalY*indexY)],text_color="k", font_size=15,
247 | font_family='times', fill_shape=False,shape=None)
248 | plotter.add_point_labels(np.array([-1.15 * ratio * maxDisp, -textPos-1.1*intervalY, 0]),
249 | labels=[str(-intervalY * indexY)], text_color="k", font_size=15,
250 | font_family='times', fill_shape=False, shape=None)
251 | plotter.add_point_labels(np.array([-1.15 * ratio * maxDisp, maxForce*0.01, 0]),
252 | labels=[str(0.0)], text_color="k", font_size=15,
253 | font_family='times', fill_shape=False, shape=None)
254 | ###动态图绘制
255 | plotter.show(interactive=False, auto_close=False)
256 | plotter.open_gif(str(saveName)+'.gif')
257 | num=len(dispX)-1
258 | for i1 in range(num):
259 | lines=np.array([[ratio*dispX[i1],forceY[i1],0], [ratio*dispX[i1+1],forceY[i1+1],0]])
260 | plotter.add_lines(lines,color="red",width=2)
261 | plotter.write_frame()
262 | time.sleep(timeSleep)
263 | ################################################################################
264 | if __name__ == '__main__':
265 | dbPath="postResultDB.db"
266 | instance=prePostPlot(dbPath)
267 | # # instance.prePlot()
268 | componentMame="mises"
269 | colorValue=371000
270 | saveName="plasticStrain"
271 | timeSleep=0.1
272 | instance.postPlot(componentMame,colorValue,saveName,timeSleep)
273 | saveName1="dispForce"
274 | instance.dispForcePlot(saveName1,timeSleep)
275 |
276 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | pyvista==0.25.3
2 | records==0.5.3
3 | numpy==1.19.1
4 |
--------------------------------------------------------------------------------
/runAbaqus.py:
--------------------------------------------------------------------------------
1 | #-*-coding: UTF-8-*-
2 | #####Units: Length-m, Force-kN, mass-ton, Stress-kpa(10e-3MPa), g=9.81m/s2
3 | #####Units: Length-mm, Force-N, mass-ton, Stress-Mpa, g=9810mm/s2 pho=ton/mm3
4 | #########################################################################
5 | # Author: Junjun Guo
6 | # E-mail: guojj@tongji.edu.cn/guojj_ce@163.com/guojj01@gmail.com
7 | # Environemet: Successfully executed in python 3.8
8 | # Date: 2021-09-19
9 | #########################################################################
10 | ########################---导入必要模块---#################################
11 | import os
12 | import shutil
13 | import numpy as np
14 | from abaqus import *
15 | from abaqusConstants import *#导入abaqus常量
16 | from symbolicConstants import *#导入abaqus符号常量
17 | from caeModules import *#导入CAE各模块
18 | from odbAccess import *#odb操作模块
19 | import regionToolset#集合选择
20 | ###########---1---基于abaqus环境进行计算----#################################
21 | numStep=10 #荷载步数
22 | maxInc=0.05 #每个荷载步增量大小,总量为1
23 | stepDisp=20 #每个荷载步位移大小(mm)
24 | PlateSeedSize=5 #钢板网格尺寸(mm)
25 | RodSeedSize=5 #连接杆网格尺寸(mm)
26 | trianglePlateTopWidth=100 #钢板顶边宽度(mm)
27 | trianglePlateBottomWidth=500#梯形钢板底部宽度(mm)
28 | trianglePlateHeight=600#梯形钢板高度(mm)
29 | rodRaidus=20#连接杆半径(mm)
30 | fy=406.307 #钢材屈服强度(Mpa)
31 | fu=723.320 #钢材极限强度(Mpa)
32 | E=1.91E+05 #钢材弹性模量(Mpa)
33 | epsilon=0.103 #最大强度对应的应变
34 | shellThinkness=15 ##三角钢板厚度(mm)
35 | slotHeight=100 #滑槽内部高度(mm)
36 | slotThickness=20#滑槽厚度(mm)
37 | slotDepth=200 #滑槽深度(mm)
38 | #########################################################################
39 | ########################---清除历史结果---#################################
40 | import fnmatch #用于文件名称匹配
41 | listName=os.listdir(os.getcwd())#获取当前文件夹路文件目录
42 | for fileName in listName:
43 | try:
44 | if fnmatch.fnmatch(fileName,'Job-pushOver.*'):
45 | os.remove(fileName)#清除历史abaqus数据
46 | except:
47 | os.system('taskkill /f /t /im '+"Job-pushOver.023")#杀死进程中abaqus任务
48 | ##########################################################################
49 | ###########################---初始化模型---#################################
50 | session.viewports["Viewport: 1"].setValues(displayedObject=None)#视图设置
51 | mdb.models.changeKey(fromName="Model-1",toName="selfCenteringSteelDamper")#修改模型名称
52 | steelDamperModel=mdb.models["selfCenteringSteelDamper"]#模型变量
53 | #########################################################################
54 | ###########################---生成部件---##################################
55 | ####---三角钢板---
56 | trianglePlateSketch_1=steelDamperModel.ConstrainedSketch(name="trianglePlateSketch_1",sheetSize=2000)#设置草图绘制
57 | trianglePlateSketch_1.Line(point1=(0,0),point2=(trianglePlateBottomWidth, 0))
58 | upperCoord=(trianglePlateBottomWidth-trianglePlateTopWidth)*0.5
59 | trianglePlateSketch_1.Line(point1=(trianglePlateBottomWidth, 0),point2=(trianglePlateBottomWidth-upperCoord,trianglePlateHeight))
60 | trianglePlateSketch_1.Line(point1=(trianglePlateBottomWidth-upperCoord,trianglePlateHeight),point2=(upperCoord,trianglePlateHeight))
61 | trianglePlateSketch_1.Line(point1=(upperCoord,trianglePlateHeight),point2=(0, 0))
62 | trianglePlatePart_1=steelDamperModel.Part(name="trianglePlatePart_1",dimensionality=THREE_D,type=DEFORMABLE_BODY)#生成部件
63 | trianglePlatePart_1.BaseShell(sketch=trianglePlateSketch_1)#生成部件壳体
64 | ####---连接杆---
65 | connectingRodSketch=steelDamperModel.ConstrainedSketch(name="connectingRodSketch",sheetSize=2000)#设置草图绘制
66 | connectingRodSketch.CircleByCenterPerimeter(center=(0.0, 0.0), point1=(0.0,rodRaidus))
67 | connectingRodPart=steelDamperModel.Part(name="connectingRodPart",dimensionality=THREE_D,type=DEFORMABLE_BODY)
68 | connectingRodPart.BaseSolidExtrude(sketch=connectingRodSketch, depth=trianglePlateTopWidth)
69 | ####---滑槽---
70 | connectingSlotSketch=steelDamperModel.ConstrainedSketch(name="connectingSlotSketch",sheetSize=2000)#设置草图绘制
71 | connectingSlotSketch.Line(point1=(0,0),point2=(slotThickness, 0))
72 | connectingSlotSketch.Line(point1=(slotThickness, 0),point2=(slotThickness, slotHeight))
73 | connectingSlotSketch.Line(point1=(slotThickness, slotHeight),point2=(slotThickness+rodRaidus*2, slotHeight))
74 | connectingSlotSketch.Line(point1=(slotThickness+rodRaidus*2, slotHeight),point2=(slotThickness+rodRaidus*2,0))
75 | connectingSlotSketch.Line(point1=(slotThickness+rodRaidus*2,0),point2=(slotThickness*2+rodRaidus*2, 0))
76 | connectingSlotSketch.Line(point1=(slotThickness*2+rodRaidus*2, 0),point2=(slotThickness*2+rodRaidus*2,slotHeight+slotThickness))
77 | connectingSlotSketch.Line(point1=(slotThickness*2+rodRaidus*2,slotHeight+slotThickness),
78 | point2=(0,slotHeight+slotThickness))
79 | connectingSlotSketch.Line(point1=(0,slotHeight+slotThickness),point2=(0,0))
80 | slotPart=steelDamperModel.Part(name="slotPart",dimensionality=THREE_D,type=DEFORMABLE_BODY)#生成部件
81 | slotPart.BaseSolidExtrude(sketch=connectingSlotSketch, depth=slotDepth)
82 | #########################################################################
83 | ###########################---材料定义---##################################
84 | ####---弹性材料---
85 | elasticMaterial=steelDamperModel.Material(name="elasticMaterial")#线弹性材料名称定义
86 | elasticMaterial.Elastic(table=((E, 0.3), ))#线弹性材料定义
87 | ####---弹塑性材料---
88 | elasPlasticMaterial=steelDamperModel.Material(name="elasPlasticMaterial")#弹塑性材料名称定义
89 | elasPlasticMaterial.Elastic(table=((E,0.3),))#弹塑性材料弹性部分定义
90 | stressStrainTable=((fy,0),(fu,epsilon),(fu+1,1))#塑性应力应变关系表格
91 | elasPlasticMaterial.Plastic(table=stressStrainTable)#弹塑性材料塑性部分定义
92 | #########################################################################
93 | ###########################---创建截面---##################################
94 | ###---三角钢板弹塑性截面---
95 | bendPlateSection=steelDamperModel.HomogeneousShellSection(name="bendPlateSection",
96 | material="elasPlasticMaterial",thickness=shellThinkness)#建立各向同性壳截面
97 | ###---连接杆弹性截面---
98 | solidSection=steelDamperModel.HomogeneousSolidSection(name='solidSection', material='elasticMaterial')
99 | #########################################################################
100 | ###########################---截面指定---##################################
101 | ###---三角钢板截面指定---
102 | trianglePart= steelDamperModel.parts['trianglePlatePart_1']
103 | bendPlateFace=(trianglePart.faces,)#选取三角板所有的面
104 | trianglePart.SectionAssignment(region=bendPlateFace, sectionName='bendPlateSection')#截面指定
105 | ###---连接杆截面指定---
106 | rod_region=(connectingRodPart.cells,)
107 | connectingRodPart.SectionAssignment(region=rod_region, sectionName='solidSection')#连接杆截面指定
108 | ###---滑槽截面指定---
109 | slot_region=(slotPart.cells,)
110 | slotPart.SectionAssignment(region=slot_region, sectionName='solidSection')#滑槽截面指定
111 | #########################################################################
112 | ###########################---装配件---###################################
113 | ###---三角钢板装配件---
114 | rootAssembly=steelDamperModel.rootAssembly#根装配件
115 | #生成三角形钢板装配件实例
116 | trianglePlateInstance_1=rootAssembly.Instance(name="trianglePlateInstance_1",part=trianglePlatePart_1,dependent=ON)
117 | #生成连接杆装配件实例
118 | connectingRod_instance=rootAssembly.Instance(name="connectingRod_instance",part=connectingRodPart,dependent=ON)
119 | #连接杆与钢板装配实例
120 | ###移动连接杆到钢板顶部
121 | fixedPoint=trianglePlateInstance_1.vertices[0]
122 | movablePoint=connectingRod_instance.InterestingPoint(edge=connectingRod_instance.edges[0], rule=MIDDLE)
123 | rootAssembly.CoincidentPoint(fixedPoint=fixedPoint, movablePoint=movablePoint)
124 | ###转动连接杆
125 | rootAssembly.rotate(instanceList=('connectingRod_instance', ),
126 | axisPoint=((trianglePlateBottomWidth-trianglePlateTopWidth)*0.5,0,0.0), axisDirection=(0.0,1, 0.0), angle=90.0)
127 | ###沿X轴平行移动连接杆
128 | connectingRod_instance.ConvertConstraints()#将连接杆实例转换为绝对位置
129 | rootAssembly.translate(instanceList=('connectingRod_instance', ), vector=(trianglePlateTopWidth, 0.0,0.0))
130 | ####对连接杆与钢板进行布尔并运算
131 | trianglePlateRod_instance=rootAssembly.InstanceFromBooleanMerge(name='trianglePlateRod_instance', instances=(trianglePlateInstance_1,
132 | connectingRod_instance,),keepIntersections=OFF, originalInstances=SUPPRESS,domain=GEOMETRY)
133 | ###滑槽装配件实例
134 | slot_instance=rootAssembly.Instance(name="slot_instance",part=slotPart,dependent=ON)
135 | fixedPoint=trianglePlateRod_instance.vertices[2]
136 | movablePoint=slot_instance.InterestingPoint(edge=slot_instance.edges[2],rule=MIDDLE)
137 | rootAssembly.CoincidentPoint(fixedPoint=fixedPoint,movablePoint=movablePoint)
138 | rootAssembly.rotate(instanceList=('slot_instance',),axisPoint=(0,0,0),axisDirection=(0,1,0),angle=90)
139 | slot_instance.ConvertConstraints()
140 | rootAssembly.translate(instanceList=('slot_instance',),vector=((trianglePlateBottomWidth-slotDepth)*0.5,0,0))
141 | rootAssembly.translate(instanceList=('slot_instance',),vector=(0,trianglePlateHeight+2*rodRaidus+slotThickness+5,0))
142 | #########################################################################
143 | ###########################---荷载步设置---################################
144 | ####---创建荷载步---
145 | steelDamperModel.StaticStep(name='pushOver_1', previous='Initial', initialInc=maxInc, maxInc=maxInc, nlgeom=ON)
146 | for i1 in range(numStep-1):
147 | previousName = "pushOver_" + str(i1 + 1)
148 | currentName = "pushOver_" + str(i1 + 2)
149 | steelDamperModel.StaticStep(name=currentName,previous=previousName, initialInc=maxInc, maxInc=maxInc,nlgeom=ON)
150 | #########################################################################
151 | ###########################---场变量输出设置---#############################
152 | #场变量输入名称修改
153 | steelDamperModel.fieldOutputRequests.changeKey(fromName='F-Output-1',toName='Selected Field Outputs')
154 | #########################################################################
155 | ###########################---耦合设置---##################################
156 | ###---参考点与顶部线耦合设置---
157 | refPointCoord=(trianglePlateBottomWidth*0.5,trianglePlateHeight+2*rodRaidus+5+slotThickness,0)#参考点坐标
158 | refPointid=rootAssembly.ReferencePoint(refPointCoord).id#建立参考点
159 | #建立参考点集合
160 | refPointRegion=rootAssembly.Set(referencePoints=(rootAssembly.referencePoints[refPointid],), name='refPointSet')
161 | slotUpFace = slot_instance.faces.findAt((refPointCoord,),)#通过边上一点选择边
162 | region_slotUpFace=regionToolset.Region(faces=slotUpFace)#集合域
163 | steelDamperModel.Coupling(name='coupling_refAndTopFace',controlPoint=refPointRegion,surface=region_slotUpFace,
164 | couplingType=KINEMATIC,influenceRadius=WHOLE_SURFACE)#建立控制点与边之间分布耦合
165 | #接触面设置
166 | leftSlotNode=(trianglePlateBottomWidth*0.5,trianglePlateHeight,rodRaidus)
167 | leftSlotSurface=slot_instance.faces.findAt((leftSlotNode,))#通过面上一点选取面
168 | rootAssembly.Surface(side1Faces=leftSlotSurface,name="leftSlotSurfaceInstance")
169 | region_leftSlotSurface=rootAssembly.surfaces['leftSlotSurfaceInstance']
170 | ####################
171 | rightSlotNode=(trianglePlateBottomWidth*0.5,trianglePlateHeight,-rodRaidus)
172 | rightSlotSurface=slot_instance.faces.findAt((rightSlotNode,))#通过面上一点选取面
173 | rootAssembly.Surface(side1Faces=rightSlotSurface,name="rightSlotSurfaceInstance")
174 | region_rightSlotSurface=rootAssembly.surfaces['rightSlotSurfaceInstance']
175 | ####################
176 | rodSurfaceNode=(trianglePlateBottomWidth*0.5,trianglePlateHeight+2*rodRaidus,0)
177 | rodSurface=trianglePlateRod_instance.faces.findAt((rodSurfaceNode,))
178 | rootAssembly.Surface(side1Faces=rodSurface,name="rodSurfaceInstance")
179 | region_rodSurface=rootAssembly.surfaces['rodSurfaceInstance']
180 | # ###法向耦合约束设置
181 | frictionless_interaction=steelDamperModel.ContactProperty('Frictionless')
182 | frictionless_interaction.TangentialBehavior(formulation=FRICTIONLESS)
183 | steelDamperModel.SurfaceToSurfaceContactStd(name='leftNormalInter',createStepName='Initial', master=region_leftSlotSurface,
184 | slave=region_rodSurface, sliding=FINITE, interactionProperty='Frictionless')
185 | steelDamperModel.SurfaceToSurfaceContactStd(name='rightNormalInter',createStepName='Initial', master=region_rightSlotSurface,
186 | slave=region_rodSurface, sliding=FINITE, interactionProperty='Frictionless')
187 | #########################################################################
188 | ###########################---边界条件设置---##############################
189 | ###---约束边界条件---
190 | bottomPointCoord=(trianglePlateBottomWidth*0.5,0,0)#底边上一点
191 | plateBottomEdge = trianglePlateRod_instance.edges.findAt((bottomPointCoord,),)#通过边上一点选择边
192 | region_bottomEdge=regionToolset.Region(edges=plateBottomEdge)#集合域
193 | steelDamperModel.DisplacementBC(name='initBC', createStepName='Initial',region=region_bottomEdge,
194 | u1=SET, u2=SET, u3=SET, ur1=SET,ur2=SET, ur3=SET)#底边固接
195 | steelDamperModel.DisplacementBC(name='refPointConstraint', createStepName='Initial',region=refPointRegion,
196 | u1=SET,u2=SET,u3=UNSET,ur1=SET,ur2=SET,ur3=SET)
197 | #########################################################################
198 | ###########################---PushOver荷载设置---##########################
199 | region_pushOver = rootAssembly.sets['refPointSet']#参考点集
200 | # 沿整体坐标系Z做加载100mm,创建pushover位移荷载
201 | steelDamperModel.DisplacementBC(name='pushover', createStepName='pushOver_1', region=region_pushOver, u3=stepDisp)
202 | for i2 in range(numStep-1):
203 | stepName = "pushOver_" + str(i2 + 2)
204 | u3 = (i2 + 2) * stepDisp * (-1) ** (i2 + 1)
205 | steelDamperModel.boundaryConditions['pushover'].setValuesInStep(stepName=stepName, u3=u3)#随后荷载步修改
206 | #########################################################################
207 | ###########################---网格划分---##################################
208 | ###---钢板部件网格划分---
209 | meshPart=steelDamperModel.parts['trianglePlateRod_instance']#选取需要划分网格的部件(对部件进行网格划分)
210 | plate_findNode1=(0,0,0)
211 | plate_findNode2=(trianglePlateBottomWidth*0.5+1.5*trianglePlateTopWidth,trianglePlateHeight,0)#两对角点需求四条线
212 | plateEdges=trianglePlateRod_instance.edges.findAt((plate_findNode1,),(plate_findNode2,))
213 | meshPart.seedEdgeBySize(edges=plateEdges,size=PlateSeedSize)#指定钢板划分网格最大尺寸mm
214 | plateFaces_findNode=(0,0,0)
215 | plateFace=trianglePlateRod_instance.faces.findAt((plateFaces_findNode,),)
216 | plateFaceRegion=(plateFace,)
217 | eleType1=mesh.ElemType(elemCode=S4R)#单元类型设置
218 | eleType2=mesh.ElemType(elemCode=S3)#单元类型设置
219 | meshPart.setElementType(regions=plateFaceRegion, elemTypes=(eleType1, eleType2))#单元类型指定
220 | ###---连接杆网格划分---
221 | rod_findNode=(trianglePlateBottomWidth*0.5,trianglePlateHeight,0)
222 | rodCells=trianglePlateRod_instance.cells.findAt((rod_findNode,),)
223 | rodCellRegion=(rodCells,)
224 | rodEdge_findNode1=((trianglePlateBottomWidth-trianglePlateTopWidth)*0.5,trianglePlateHeight,0)
225 | rodEdge_findNode2=(0.5*trianglePlateBottomWidth+1.5*trianglePlateTopWidth,trianglePlateHeight,0)
226 | rodEdges=trianglePlateRod_instance.edges.findAt((rodEdge_findNode1,),(rodEdge_findNode2,))
227 | meshPart.seedEdgeBySize(edges=rodEdges,size=RodSeedSize)#指定连接杆网格最大尺寸mm
228 | elemType1 = mesh.ElemType(elemCode=C3D8I)
229 | elemType2 = mesh.ElemType(elemCode=C3D6)
230 | elemType3 = mesh.ElemType(elemCode=C3D4)
231 | meshPart.setElementType(regions=rodCellRegion, elemTypes=(eleType1, eleType2,elemType3))#单元类型指定
232 | meshPart.generateMesh()#生成装配件实例网格
233 | ###---滑槽网格划分---
234 | meshPart_slot=steelDamperModel.parts['slotPart']#选取需要划分网格的部件(对部件进行网格划分)
235 | slot_findNode=(trianglePlateBottomWidth*0.5,trianglePlateHeight+2*rodRaidus+slotThickness,0)
236 | slotCells=slot_instance.cells.findAt((slot_findNode,),)
237 | slotCellRegion=(slotCells,)
238 | slotEdges=slot_instance.edges
239 | meshPart_slot.seedEdgeBySize(edges=slotEdges,size=RodSeedSize)#指定连接杆网格最大尺寸mm
240 | elemType1 = mesh.ElemType(elemCode=C3D8I)
241 | elemType2 = mesh.ElemType(elemCode=C3D6)
242 | elemType3 = mesh.ElemType(elemCode=C3D4)
243 | meshPart_slot.setElementType(regions=slotCellRegion, elemTypes=(eleType1, eleType2,elemType3))#单元类型指定
244 | meshPart_slot.generateMesh()#生成装配件实例网格
245 | #########################################################################
246 | ###########################---任务设置---##################################
247 | # mdb.Job(name='Job-pushOver', model='selfCenteringSteelDamper',multiprocessingMode=DEFAULT,
248 | # numCpus=12,numDomains=12, numGPUs=1)#任务参数设置
249 | # mdb.jobs['Job-pushOver'].submit(consistencyChecking=OFF)#提交任务
250 |
251 |
252 |
253 | #########################################################################
254 | #########################################################################
255 |
256 |
257 |
258 |
259 |
260 |
--------------------------------------------------------------------------------
/saveDataToSqlite.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @File : 234.py
3 | # @Date : 2020-09-02 18:14
4 | # @Email : {guojj@tongji.edu.cn/guojj01@gmail.com}
5 | # @Author : guojj
6 |
7 |
8 | ###导入必要的模块
9 | import records
10 | import numpy as np
11 |
12 |
13 | class SaveData(object):
14 | """将提取的数据存储到数据库中"""
15 |
16 | def __init__(self,dbPath):
17 | self._dbPath=dbPath
18 |
19 | @classmethod
20 | def initDB(self,dbPath):
21 | """初始化数据库"""
22 | self.db = records.Database('sqlite:///'+dbPath)
23 | tableNames=self.db.get_table_names()
24 | for each in tableNames:
25 | self.db.query("DROP TABLE IF EXISTS "+each)
26 |
27 | def saveNodes(self,nodes):
28 | """将节点列表存入数据库,[(tag1,x1,y1,z1),..]"""
29 | db=records.Database('sqlite:///'+self._dbPath)
30 | nodesDict=[{'tags':int(each[0]),'coords':str(each[1:])} for each in nodes]
31 | nodesTable="""
32 | CREATE TABLE IF NOT EXISTS
33 | nodes(
34 | tags INT NOT NULL,
35 | coords MESSAGE_TEXT NOT NULL);"""
36 | db.query(nodesTable)
37 | insertNodes="""
38 | INSERT INTO
39 | nodes(tags,coords)
40 | values (:tags,:coords)
41 | """
42 | db.bulk_query(insertNodes,nodesDict)
43 |
44 | def saveElements(self,elements):
45 | """将单元列表存入数据库,[(tag1,n1,n2,..),..]"""
46 | db=records.Database('sqlite:///'+self._dbPath)
47 | elesDict=[{'tags':int(each[0]),'connectivity':str(each[1:])} for each in elements]
48 | elesTable="""
49 | CREATE TABLE IF NOT EXISTS
50 | elements(
51 | tags INT NOT NULL,
52 | connectivity MESSAGE_TEXT NOT NULL);"""
53 | db.query(elesTable)
54 | insertEles="""
55 | INSERT INTO
56 | elements(tags,connectivity)
57 | values (:tags,:connectivity)
58 | """
59 | db.bulk_query(insertEles,elesDict)
60 |
61 | def getNode(self,tags):
62 | """返回特定节点的坐标"""
63 | db=records.Database('sqlite:///'+self._dbPath)
64 | conn = db.get_connection()
65 | try:
66 | queryValue=conn.query('select * from nodes where tags=='+str(tags)+';')
67 | returnValue=queryValue.all(as_dict=True)[0]['coords']
68 | return returnValue
69 | except :
70 | print("Please enter correct node tag (integer)!")
71 | return
72 |
73 | def getAllNode(self):
74 | """返回所有节点坐标"""
75 | db=records.Database('sqlite:///'+self._dbPath)
76 | conn = db.get_connection()
77 | try:
78 | queryValue=conn.query('select * from nodes;')
79 | returnValue=queryValue.all(as_dict=True)
80 | return returnValue
81 | except :
82 | print("table nodes doesn't exitst!")
83 | return
84 |
85 | def getEle(self,tags):
86 | """返回特定节点的坐标"""
87 | db=records.Database('sqlite:///'+self._dbPath)
88 | conn = db.get_connection()
89 | try:
90 | queryValue=conn.query('select * from elements where tags=='+str(tags)+';')
91 | returnValue=queryValue.all(as_dict=True)[0]['connectivity']
92 | return returnValue
93 | except :
94 | print("Please enter correct element tag (integer)!")
95 | return
96 |
97 | def getAllEle(self):
98 | """返回所有单元信息"""
99 | db=records.Database('sqlite:///'+self._dbPath)
100 | conn = db.get_connection()
101 | try:
102 | queryValue=conn.query('select * from elements;')
103 | returnValue=queryValue.all(as_dict=True)
104 | return returnValue
105 | except :
106 | print("table elements doesn't exitst!")
107 | return
108 |
109 | def saveMisesStress(self,mises):
110 | """将Mises应力列表存储到数据库"""
111 | db=records.Database('sqlite:///'+self._dbPath)
112 | elesDict=[{'eleTag':int(each[0]),'mises':str(each[1:])} for each in mises]
113 |
114 | elesTable="""
115 | CREATE TABLE IF NOT EXISTS
116 | mises(
117 | eleTag INT NOT NULL,
118 | mises MESSAGE_TEXT NOT NULL);"""
119 | db.query(elesTable)
120 | insertEles="""
121 | INSERT INTO
122 | mises(eleTag,mises)
123 | values (:eleTag,:mises)
124 | """
125 | db.bulk_query(insertEles,elesDict)
126 |
127 | def getEleMises(self,eletags):
128 | """返回特定单元的Mises应力"""
129 | db=records.Database('sqlite:///'+self._dbPath)
130 | conn = db.get_connection()
131 | try:
132 | queryValue=conn.query('select * from mises where eleTag=='+str(eletags)+';')
133 | returnValue=queryValue.all(as_dict=True)[0]['mises']
134 | return returnValue
135 | except :
136 | print("Please enter correct element tag (integer)!")
137 | return
138 |
139 | def getAllMises(self):
140 | """返回所有单元的Mises应力"""
141 | db = records.Database('sqlite:///' + self._dbPath)
142 | conn = db.get_connection()
143 | try:
144 | queryValue = conn.query('select * from mises;')
145 | returnValue = queryValue.all(as_dict=True)
146 | return returnValue
147 | except:
148 | print("table mises doesn't exitst!")
149 | return
150 |
151 | def savePEEQ(self,PEEQ):
152 | """将等效塑性应变列表存储到数据库"""
153 | db=records.Database('sqlite:///'+self._dbPath)
154 | elesDict=[{'eleTag':int(each[0]),'PEEQ':str(each[1:])} for each in PEEQ]
155 |
156 | elesTable="""
157 | CREATE TABLE IF NOT EXISTS
158 | peeq(
159 | eleTag INT NOT NULL,
160 | PEEQ MESSAGE_TEXT NOT NULL);"""
161 | db.query(elesTable)
162 | insertEles="""
163 | INSERT INTO
164 | peeq(eleTag,PEEQ)
165 | values (:eleTag,:PEEQ)
166 | """
167 | db.bulk_query(insertEles,elesDict)
168 |
169 | def getAllPEEQ(self):
170 | """返回所有单元的等效塑性应变"""
171 | db = records.Database('sqlite:///' + self._dbPath)
172 | conn = db.get_connection()
173 | try:
174 | queryValue = conn.query('select * from peeq;')
175 | returnValue = queryValue.all(as_dict=True)
176 | return returnValue
177 | except:
178 | print("table peeq doesn't exitst!")
179 | return
180 |
181 | def saveNodeDisp(self,dispX,dispY,dispZ):
182 | """保存节点位移"""
183 | db=records.Database('sqlite:///'+self._dbPath)
184 | nodeDispDict=[{'nodeTag':int(x[0]),'dispX':str(x[1:]),'dispY':str(y[1:]),'dispZ':str(z[1:])}
185 | for x,y,z in zip(dispX,dispY,dispZ)]
186 | nodeDispTable="""
187 | CREATE TABLE IF NOT EXISTS
188 | nodeDisp(
189 | nodeTag INT NOT NULL,
190 | dispX MESSAGE_TEXT NOT NULL,
191 | dispY MESSAGE_TEXT NOT NULL,
192 | dispZ MESSAGE_TEXT NOT NULL);"""
193 | db.query(nodeDispTable)
194 | insertEles="""
195 | INSERT INTO
196 | nodeDisp(nodeTag,dispX,dispY,dispZ)
197 | values (:nodeTag,:dispX,:dispY,:dispZ)
198 | """
199 | db.bulk_query(insertEles,nodeDispDict)
200 |
201 | def getnodeDisp(self,nodeTag):
202 | """返回特定节点位移"""
203 | db=records.Database('sqlite:///'+self._dbPath)
204 | conn = db.get_connection()
205 | try:
206 | queryValue=conn.query('select * from nodeDisp where nodeTag=='+str(nodeTag)+';')
207 | returnValueX=queryValue.all(as_dict=True)[0]['dispX']
208 | returnValueY = queryValue.all(as_dict=True)[0]['dispY']
209 | returnValueZ = queryValue.all(as_dict=True)[0]['dispZ']
210 | return returnValueX,returnValueY,returnValueZ
211 | except :
212 | print("Please enter correct node tag (integer)!")
213 | return
214 |
215 | def getAllDisp(self):
216 | """返回所有节点位移"""
217 | db = records.Database('sqlite:///' + self._dbPath)
218 | conn = db.get_connection()
219 | try:
220 | queryValue = conn.query('select * from nodeDisp;')
221 | returnValue = queryValue.all(as_dict=True)
222 | return returnValue
223 | except:
224 | print("table nodeDisp doesn't exitst!")
225 | return
226 |
227 | def saveDispForce(self,refDisp,refLoad):
228 | """保存加载点力与位移时程"""
229 | db=records.Database('sqlite:///'+self._dbPath)
230 | loadForceDict=[{'refDisp':str(x),'refLoad':str(y)}
231 | for x,y in zip(refDisp,refLoad)]
232 | dispForceTable="""
233 | CREATE TABLE IF NOT EXISTS
234 | dispForce(
235 | refDisp MESSAGE_TEXT NOT NULL,
236 | refLoad MESSAGE_TEXT NOT NULL);"""
237 | db.query(dispForceTable)
238 | insertEles="""
239 | INSERT INTO
240 | dispForce(refDisp,refLoad)
241 | values (:refDisp,:refLoad)
242 | """
243 | db.bulk_query(insertEles,loadForceDict)
244 |
245 | def getRefResponse(self):
246 | """返回加载点力与位移时程"""
247 | db = records.Database('sqlite:///' + self._dbPath)
248 | conn = db.get_connection()
249 | try:
250 | queryValue = conn.query('select * from dispForce;')
251 | returnValue = queryValue.all(as_dict=True)
252 | return returnValue
253 | except:
254 | print("table dispForce doesn't exitst!")
255 | return
256 |
257 |
258 |
259 | ################################################################################
260 | if __name__ == '__main__':
261 | dbPath="postResultDB.db"
262 | SaveData.initDB(dbPath)
263 | saveInstance=SaveData(dbPath)
264 | nodes=np.loadtxt("postResults/nodes.txt")
265 | saveInstance.saveNodes(nodes)
266 | elements=np.loadtxt("postResults/elements.txt")
267 | saveInstance.saveElements(elements)
268 | mises=np.loadtxt("postResults/misesStress.txt")
269 | saveInstance.saveMisesStress(mises)
270 | PEEQ=np.loadtxt("postResults/PEEQ.txt")
271 | saveInstance.savePEEQ(PEEQ)
272 | dispX=np.loadtxt("postResults/dispX.txt")
273 | dispY= np.loadtxt("postResults/dispY.txt")
274 | dispZ = np.loadtxt("postResults/dispZ.txt")
275 | saveInstance.saveNodeDisp(dispX,dispY,dispZ)
276 | refDisp = np.loadtxt("postResults/refDisp.txt")
277 | refLoad = np.loadtxt("postResults/refLoad.txt")
278 | saveInstance.saveDispForce(refDisp,refLoad)
279 |
280 |
281 |
282 |
283 |
--------------------------------------------------------------------------------