Compare commits
93 Commits
patch_23Ju
...
patch_6Jul
| Author | SHA1 | Date | |
|---|---|---|---|
| 4339379948 | |||
| 87af3b1fd9 | |||
| 0423971205 | |||
| 4ee7c6f5ca | |||
| 7f63c09667 | |||
| a5234d7aea | |||
| be8360ac4b | |||
| 4de9cec1b6 | |||
| 09ad293425 | |||
| e625e79171 | |||
| f1088a5003 | |||
| ea4f16bd79 | |||
| d0a397d6cb | |||
| f670dba3d0 | |||
| 6fc0a94e87 | |||
| 5c0c8bb4cd | |||
| 9eeb97b039 | |||
| 9ca9b5e2ff | |||
| db73eca29f | |||
| 2d1941ed9b | |||
| e634c5a2de | |||
| 22f3db4723 | |||
| a1574fc03d | |||
| d68fb1cbb8 | |||
| 060e32973e | |||
| a4a15f24bd | |||
| 883b7aaa0e | |||
| 1fff30af90 | |||
| a490e04d24 | |||
| b445f8eadf | |||
| b79044d4f6 | |||
| 711afe5062 | |||
| 3bf2c60276 | |||
| d5119b2d75 | |||
| b2b621a2e1 | |||
| b5250d11f6 | |||
| 9dad95d101 | |||
| f6faad335c | |||
| 5548704700 | |||
| e0939ac795 | |||
| d5921e9fb9 | |||
| aa3f4b7690 | |||
| 38075455b6 | |||
| fa30635465 | |||
| 0c2f7c74be | |||
| 91bce7ccf9 | |||
| d0470799ac | |||
| 076990c28a | |||
| 661e51b607 | |||
| d076040471 | |||
| 2f9c0a3b8e | |||
| b9d213ee2b | |||
| fa3c7727e1 | |||
| 9fec8a0470 | |||
| b889776557 | |||
| 8fca667e4b | |||
| f7077d9672 | |||
| f89a7266bf | |||
| 1257955662 | |||
| c2c6dc1458 | |||
| 18983c307e | |||
| 05fbf93455 | |||
| 73b948dcfc | |||
| 374eef2b17 | |||
| dc7243838b | |||
| 57d5cfede3 | |||
| c081d383d1 | |||
| f8364342c2 | |||
| 488d1b7a79 | |||
| dadd1c8b4d | |||
| f092da80a9 | |||
| b9029ada77 | |||
| f47aaa5f3c | |||
| 5e165e6782 | |||
| 02625b2855 | |||
| bb47fa8783 | |||
| c79dc53c6a | |||
| 72a1364d85 | |||
| 198fe7ecd7 | |||
| a9f3f90025 | |||
| 3d066283b6 | |||
| 29e60fa53a | |||
| 078f2a0a47 | |||
| bdd908c303 | |||
| b45a95107d | |||
| 9f852f5f58 | |||
| fea28d8028 | |||
| afed8bb978 | |||
| 03c93b31d6 | |||
| d3f31547f9 | |||
| 7c7468ffc2 | |||
| bab292b551 | |||
| 13643e185c |
112
.github/CONTRIBUTING.md
vendored
Normal file
112
.github/CONTRIBUTING.md
vendored
Normal file
@ -0,0 +1,112 @@
|
||||
# Contributing to LAMMPS via GitHub
|
||||
|
||||
Thank your for considering to contribute to the LAMMPS software project.
|
||||
|
||||
The following is a set of guidelines as well as explanations of policies and workflows for contributing to the LAMMPS molecular dynamics software project. These guidelines focus on submitting issues or pull requests on the LAMMPS GitHub project.
|
||||
|
||||
Thus please also have a look at:
|
||||
* [The Section on submitting new features for inclusion in LAMMPS of the Manual](http://lammps.sandia.gov/doc/Section_modify.html#mod-15)
|
||||
* [The LAMMPS GitHub Tutorial in the Manual](http://lammps.sandia.gov/doc/tutorial_github.html)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
[I don't want to read this whole thing, I just have a question!](#i-dont-want-to-read-this-whole-thing-i-just-have-a-question)
|
||||
|
||||
[How Can I Contribute?](#how-can-i-contribute)
|
||||
* [Discussing How To Use LAMMPS](#discussing-how-to-use-lammps)
|
||||
* [Reporting Bugs](#reporting-bugs)
|
||||
* [Suggesting Enhancements](#suggesting-enhancements)
|
||||
* [Contributing Code](#contributing-code)
|
||||
|
||||
[GitHub Workflows](#github-workflows)
|
||||
* [Issues](#issues)
|
||||
* [Pull Requests](#pull-requests)
|
||||
|
||||
__
|
||||
|
||||
## I don't want to read this whole thing I just have a question!
|
||||
|
||||
> **Note:** Please do not file an issue to ask a general question about LAMMPS, its features, how to use specific commands, or how perform simulations or analysis in LAMMPS. Instead post your question to the ['lammps-users' mailing list](http://lammps.sandia.gov/mail.html). You do not need to be subscribed to post to the list (but a mailing list subscription avoids having your post delayed until it is approved by a mailing list moderator). Most posts to the mailing list receive a response within less than 24 hours. Before posting to the mailing list, please read the [mailing list guidelines](http://lammps.sandia.gov/guidelines.html). Following those guidelines will help greatly to get a helpful response. Always mention which LAMMPS version you are using.
|
||||
|
||||
## How Can I Contribute?
|
||||
|
||||
There are several ways how you can actively contribute to the LAMMPS project: you can discuss compiling and using LAMMPS, and solving LAMMPS related problems with other LAMMPS users on the lammps-users mailing list, you can report bugs or suggest enhancements by creating issues on GitHub (or posting them to the lammps-users mailing list), and you can contribute by submitting pull requests on GitHub or e-mail your code
|
||||
to one of the [LAMMPS core developers](http://lammps.sandia.gov/authors.html). As you may see from the aforementioned developer page, the LAMMPS software package includes the efforts of a very large number of contributors beyond the principal authors and maintainers.
|
||||
|
||||
### Discussing How To Use LAMMPS
|
||||
|
||||
The LAMMPS mailing list is hosted at SourceForge. The mailing list began in 2005, and now includes tens of thousands of messages in thousands of threads. LAMMPS developers try to respond to posted questions in a timely manner, but there are no guarantees. Please consider that people live in different timezone and may not have time to answer e-mails outside of their work hours.
|
||||
You can post to list by sending your email to lammps-users at lists.sourceforge.net (no subscription required), but before posting, please read the [mailing list guidelines](http://lammps.sandia.gov/guidelines.html) to maximize your chances to receive a helpful response.
|
||||
|
||||
Anyone can browse/search previous questions/answers in the archives. You do not have to subscribe to the list to post questions, receive answers (to your questions), or browse/search the archives. You **do** need to subscribe to the list if you want emails for **all** the posts (as individual messages or in digest form), or to answer questions yourself. Feel free to sign up and help us out! Answering questions from fellow LAMMPS users is a great way to pay back the community for providing you a useful tool for free, and to pass on the advice you have received yourself to others. It improves your karma and helps you understand your own research better.
|
||||
|
||||
If you post a message and you are a subscriber, your message will appear immediately. If you are not a subscriber, your message will be moderated, which typically takes one business day. Either way, when someone replies the reply will usually be sent to both, your personal email address and the mailing list. When replying to people, that responded to your post to the list, please always included the mailing list in your replies (i.e. use "Reply All" and **not** "Reply"). Responses will appear on the list in a few minutes, but it can take a few hours for postings and replies to show up in the SourceForge archive. Sending replies also to the mailing list is important, so that responses are archived and people with a similar issue can search for possible solutions in the mailing list archive.
|
||||
|
||||
### Reporting Bugs
|
||||
|
||||
While developers writing code for LAMMPS are careful to test their code, LAMMPS is such a large and complex software, that it is impossible to test for all combinations of features under all normal and not so normal circumstances. Thus bugs do happen, and if you suspect, that you have encountered one, please try to document it and report it as an [Issue](https://github.com/lammps/lammps/issues) on the LAMMPS GitHub project web page. However, before reporting a bug, you need to check whether this is something that may have already been corrected. The [Latest Features and Bug Fixes in LAMMPS](http://lammps.sandia.gov/bug.html) web page lists all significant changes to LAMMPS over the years. It also tells you what the current latest development version of LAMMPS is, and you should test whether your issue still applies to that version.
|
||||
|
||||
When you click on the green "New Issue" button, you will be provided with a text field, where you can enter your message. That text field with contain a template with several headlines and some descriptions. Keep the headlines that are relevant to your reported potential bug and replace the descriptions with the information as suggested by the descriptions.
|
||||
You can also attach small text files (please add the file name extension `.txt` or it will be rejected), images, or small compressed text files (using gzip, do not use RAR or 7-ZIP or similar tools that are uncommon outside of Windows machines). In many cases, bugs are best illustrated by providing a small input deck (do **not** attach your entire production input, but remove everything that is not required to reproduce the issue, and scale down your system size, that the resulting calculation runs fast and can be run on small desktop quickly).
|
||||
|
||||
To be able to submit an issue on GitHub, you have to register for an account (for GitHub in general). If you do not want to do that, or have other reservations against submitting an issue there, you can - as an alternative and in decreasing preference - either send an e-mail to the lammps-users mailing list, the original authors of the feature that you suspect to be affected, or one or more of the core LAMMPS developers.
|
||||
|
||||
### Suggesting Enhancements
|
||||
|
||||
The LAMMPS developers welcome suggestions for enhancements or new features. These should be submitted using the [GitHub Issue Tracker](https://github.com/lammps/lammps/issues) of the LAMMPS project. This is particularly recommended, when you plan to implement the feature or enhancement yourself, as this allows to coordinate in case there are other similar or conflicting ongoing developments.
|
||||
The LAMMPS developers will review your submission and consider implementing it. Whether this will actually happen depends on many factors: how difficult it would be, how much effort it would take, how many users would benefit from it, how well the individual developer would understand the underlying physics of the feature, and whether this is a feature that would fit into a software like LAMMPS, or would be better implemented as a separate tool. Because of these factors, it matters how well the suggested enhancement is formulated and the overall benefit is argued convincingly.
|
||||
|
||||
To be able to submit an issue on GitHub, you have to register for an account (for GitHub in general). If you do not want to do that, or have other reservations against submitting an issue there, you can - as an alternative - send an e-mail to the lammps-users mailing list.
|
||||
|
||||
### Contributing Code
|
||||
|
||||
We encourage users to submit new features or modifications for LAMMPS to the core developers so they can be added to the LAMMPS distribution. The preferred way to manage and coordinate this is by submitting a pull request at the LAMMPS project on GitHub. For any larger modifications or programming project, you are encouraged to contact the LAMMPS developers ahead of time, in order to discuss implementation strategies and coding guidelines, that will make it easier to integrate your contribution and result in less work for everybody involved. You are also encouraged to search through the list of open issues on GitHub and submit a new issue for a planned feature, so you would not duplicate the work of others (and possibly get scooped by them) or have your work duplicated by others.
|
||||
|
||||
How quickly your contribution will be integrated depends largely on how much effort it will cause to integrate and test it, how much it requires changes to the core code base, and of how much interest it is to the larger LAMMPS community. Please see below for a checklist of typical requirements. Once you have prepared everything, see [this tutorial](http://lammps.sandia.gov/doc/tutorial_github.html)
|
||||
for instructions on how to submit your changes or new files through a GitHub pull request
|
||||
|
||||
Here is a checklist of steps you need to follow to submit a single file or user package for our consideration. Following these steps will save both you and us time. See existing files in packages in the source directory for examples. If you are uncertain, please ask on the lammps-users mailing list.
|
||||
|
||||
* All source files you provide must compile with the most current version of LAMMPS with multiple configurations. In particular you need to test compiling LAMMPS from scratch with `-DLAMMPS_BIGBIG` set in addition to the default `-DLAMMPS_SMALLBIG` setting. Your code will need to work correctly in serial and in parallel using MPI.
|
||||
* For consistency with the rest of LAMMPS and especially, if you want your contribution(s) to be added to main LAMMPS code or one of its standard packages, it needs to be written in a style compatible with other LAMMPS source files. This means: 2-character indentation per level, no tabs, no lines over 80 characters. I/O is done via the C-style stdio library, class header files should not import any system headers outside <stdio.h>, STL containers should be avoided in headers, and forward declarations used where possible or needed. All added code should be placed into the LAMMPS_NS namespace or a sub-namespace; global or static variables should be avoided, as they conflict with the modular nature of LAMMPS and the C++ class structure. Header files must not import namespaces with using. This all is so the developers can more easily understand, integrate, and maintain your contribution and reduce conflicts with other parts of LAMMPS. This basically means that the code accesses data structures, performs its operations, and is formatted similar to other LAMMPS source files, including the use of the error class for error and warning messages.
|
||||
* If you want your contribution to be added as a user-contributed feature, and it is a single file (actually a `<name>.cpp` and `<name>.h` file) it can be rapidly added to the USER-MISC directory. Include the one-line entry to add to the USER-MISC/README file in that directory, along with the 2 source files. You can do this multiple times if you wish to contribute several individual features.
|
||||
* If you want your contribution to be added as a user-contribution and it is several related features, it is probably best to make it a user package directory with a name like USER-FOO. In addition to your new files, the directory should contain a README text file. The README should contain your name and contact information and a brief description of what your new package does. If your files depend on other LAMMPS style files also being installed (e.g. because your file is a derived class from the other LAMMPS class), then an Install.sh file is also needed to check for those dependencies. See other README and Install.sh files in other USER directories as examples. Send us a tarball of this USER-FOO directory.
|
||||
* Your new source files need to have the LAMMPS copyright, GPL notice, and your name and email address at the top, like other user-contributed LAMMPS source files. They need to create a class that is inside the LAMMPS namespace. If the file is for one of the USER packages, including USER-MISC, then we are not as picky about the coding style (see above). I.e. the files do not need to be in the same stylistic format and syntax as other LAMMPS files, though that would be nice for developers as well as users who try to read your code.
|
||||
* You **must** also create or extend a documentation file for each new command or style you are adding to LAMMPS. For simplicity and convenience, the documentation of groups of closely related commands or styles may be combined into a single file. This will be one file for a single-file feature. For a package, it might be several files. These are simple text files with a specific markup language, that are then auto-converted to HTML and PDF. The tools for this conversion are included in the source distribution, and the translation can be as simple as doing "make html pdf" in the doc folder. Thus the documentation source files must be in the same format and style as other `<name>.txt` files in the lammps/doc/src directory for similar commands and styles; use one or more of them as a starting point. A description of the markup can also be found in `lammps/doc/utils/txt2html/README.html` As appropriate, the text files can include links to equations (see doc/Eqs/*.tex for examples, we auto-create the associated JPG files), or figures (see doc/JPG for examples), or even additional PDF files with further details (see doc/PDF for examples). The doc page should also include literature citations as appropriate; see the bottom of doc/fix_nh.txt for examples and the earlier part of the same file for how to format the cite itself. The "Restrictions" section of the doc page should indicate that your command is only available if LAMMPS is built with the appropriate USER-MISC or USER-FOO package. See other user package doc files for examples of how to do this. The prerequisite for building the HTML format files are Python 3.x and virtualenv, the requirement for generating the PDF format manual is the htmldoc software. Please run at least "make html" and carefully inspect and proofread the resulting HTML format doc page before submitting your code.
|
||||
* For a new package (or even a single command) you should include one or more example scripts demonstrating its use. These should run in no more than a couple minutes, even on a single processor, and not require large data files as input. See directories under examples/USER for examples of input scripts other users provided for their packages. These example inputs are also required for validating memory accesses and testing for memory leaks with valgrind
|
||||
* If there is a paper of yours describing your feature (either the algorithm/science behind the feature itself, or its initial usage, or its implementation in LAMMPS), you can add the citation to the *.cpp source file. See src/USER-EFF/atom_vec_electron.cpp for an example. A LaTeX citation is stored in a variable at the top of the file and a single line of code that references the variable is added to the constructor of the class. Whenever a user invokes your feature from their input script, this will cause LAMMPS to output the citation to a log.cite file and prompt the user to examine the file. Note that you should only use this for a paper you or your group authored. E.g. adding a cite in the code for a paper by Nose and Hoover if you write a fix that implements their integrator is not the intended usage. That kind of citation should just be in the doc page you provide.
|
||||
|
||||
Finally, as a general rule-of-thumb, the more clear and self-explanatory you make your documentation and README files, and the easier you make it for people to get started, e.g. by providing example scripts, the more likely it is that users will try out your new feature.
|
||||
|
||||
If the new features/files are broadly useful we may add them as core files to LAMMPS or as part of a standard package. Else we will add them as a user-contributed file or package. Examples of user packages are in src sub-directories that start with USER. The USER-MISC package is simply a collection of (mostly) unrelated single files, which is the simplest way to have your contribution quickly added to the LAMMPS distribution. You can see a list of the both standard and user packages by typing "make package" in the LAMMPS src directory.
|
||||
|
||||
Note that by providing us files to release, you are agreeing to make them open-source, i.e. we can release them under the terms of the GPL, used as a license for the rest of LAMMPS. See Section 1.4 for details.
|
||||
|
||||
With user packages and files, all we are really providing (aside from the fame and fortune that accompanies having your name in the source code and on the Authors page of the LAMMPS WWW site), is a means for you to distribute your work to the LAMMPS user community, and a mechanism for others to easily try out your new feature. This may help you find bugs or make contact with new collaborators. Note that you are also implicitly agreeing to support your code which means answer questions, fix bugs, and maintain it if LAMMPS changes in some way that breaks it (an unusual event).
|
||||
|
||||
To be able to submit an issue on GitHub, you have to register for an account (for GitHub in general). If you do not want to do that, or have other reservations or difficulties to submit a pull request, you can - as an alternative - contact one or more of the core LAMMPS developers and ask if one of them would be interested in manually merging your code into LAMMPS and send them your source code. Since the effort to merge a pull request is a small fraction of the effort of integrating source code manually (which would usually be done by converting the contribution into a pull request), your chances to have your new code included quickly are the best with a pull request.
|
||||
|
||||
If you prefer to submit patches or full files, you should first make certain, that your code works correctly with the latest patch-level version of LAMMPS and contains all bug fixes from it. Then create a gzipped tar file of all changed or added files or a corresponding patch file using 'diff -u' or 'diff -c' and compress it with gzip. Please only use gzip compression, as this works well on all platforms.
|
||||
|
||||
## GitHub Workflows
|
||||
|
||||
This section briefly summarizes the steps that will happen **after** you have submitted either an issue or a pull request on the LAMMPS GitHub project page.
|
||||
|
||||
### Issues
|
||||
|
||||
After submitting an issue, one or more of the LAMMPS developers will review it and categorize it by assigning labels. Confirmed bug reports will be labeled `bug`; if the bug report also contains a suggestion for how to fix it, it will be labeled `bugfix`; if the issue is a feature request, it will be labeled `enhancement`. Other labels may be attached as well, depending on which parts of the LAMMPS code are affected. If the assessment is, that the issue does not warrant any changes, the `wontfix` label will be applied and if the submission is incorrect or something that should not be submitted as an issue, the `invalid` label will be applied. In both of the last two cases, the issue will then be closed without further action.
|
||||
|
||||
For feature requests, what happens next is that developers may comment on the viability or relevance of the request, discuss and make suggestions for how to implement it. If a LAMMPS developer or user is planning to implement the feature, the issue will be assigned to that developer. For developers, that are not yet listed as LAMMPS project collaborators, they will receive an invitation to be added to the LAMMPS project as a collaborator so they can get assigned. If the requested feature or enhancement is implemented, it will usually be submitted as a pull request, which will contain a reference to the issue number. And once the pull request is reviewed and accepted for inclusion into LAMMPS, the issue will be closed. For details on how pull requests are processed, please see below.
|
||||
|
||||
For bug reports, the next step is that one of the core LAMMPS developers will self-assign to the issue and try to confirm the bug. If confirmed, the `bug` label and potentially other labels are added to classify the issue and its impact to LAMMPS. Before confirming, further questions may be asked or requests for providing additional input files or details about the steps required to reproduce the issue. Any bugfix is likely to be submitted as a pull request (more about that below) and since most bugs require only local changes, the bugfix may be included in a pull request specifically set up to collect such local bugfixes or small enhancements. Once the bugfix is included in the master branch, the issue will be closed.
|
||||
|
||||
### Pull Requests
|
||||
|
||||
For submitting pull requests, there is a [detailed tutorial](http://lammps.sandia.gov/doc/tutorial_github.html) in the LAMMPS manual. Thus only a brief breakdown of the steps is presented here.
|
||||
Immediately after the submission, the LAMMPS continuing integration server at ci.lammps.org will download your submitted branch and perform a simple compilation test, i.e. will test whether your submitted code can be compiled under various conditions. It will also do a check on whether your included documentation translates cleanly. Whether these tests are successful or fail will be recorded. If a test fails, please inspect the corresponding output on the CI server and take the necessary steps, if needed, so that the code can compile cleanly again. The test will be re-run each the pull request is updated with a push to the remote branch on GitHub.
|
||||
Next a LAMMPS core developer will self-assign and do an overall technical assessment of the submission. If you are not yet registered as a LAMMPS collaborator, you will receive an invitation for that.
|
||||
You may also receive comments and suggestions on the overall submission or specific details. If permitted, additional changes may be pushed into your pull request branch or a pull request may be filed in your LAMMPS fork on GitHub to include those changes.
|
||||
The LAMMPS developer may then decide to assign the pull request to another developer (e.g. when that developer is more knowledgeable about the submitted feature or enhancement or has written the modified code). It may also happen, that additional developers are requested to provide a review and approve the changes. For submissions, that may change the general behavior of LAMMPS, or where a possibility of unwanted side effects exists, additional tests may be requested by the assigned developer.
|
||||
If the assigned developer is satisfied and considers the submission ready for inclusion into LAMMPS, the pull request will be assigned to the LAMMPS lead developer, Steve Plimpton (@sjplimp), who will then have the final decision on whether the submission will be included, additional changes are required or it will be ultimately rejected. After the pull request is merged, you may delete the pull request branch in your personal LAMMPS fork.
|
||||
Since the learning curve for git is quite steep for efficiently managing remote repositories, local and remote branches, pull requests and more, do not hesitate to ask questions, if you are not sure about how to do certain steps that are asked of you. Even if the changes asked of you do not make sense to you, they may be important for the LAMMPS developers. Please also note, that these all are guidelines and not set in stone.
|
||||
|
||||
31
.github/ISSUE_TEMPLATE.md
vendored
Normal file
31
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
## Summary
|
||||
|
||||
_Please provide a brief description of the issue_
|
||||
|
||||
## Type of Issue
|
||||
|
||||
_Is this a 'Bug Report' or a 'Suggestion for an Enhancement'?_
|
||||
|
||||
## Detailed Description (Enhancement Suggestion)
|
||||
|
||||
_Explain how you would like to see LAMMPS enhanced, what feature(s) you are looking for, provide references to relevant background information, and whether you are willing to implement the enhancement yourself or would like to participate in the implementation_
|
||||
|
||||
## LAMMPS Version (Bug Report)
|
||||
|
||||
_Please specify which LAMMPS version this issue was detected with. If this is not the latest development version, please stop and test that version, too, and report it here if the bug persists_
|
||||
|
||||
## Expected Behavior (Bug Report)
|
||||
|
||||
_Describe the expected behavior. Quote from the LAMMPS manual where needed or explain why the expected behavior is meaningful, especially when it differs from the manual_
|
||||
|
||||
## Actual Behavior (Bug Report)
|
||||
|
||||
_Describe the actual behavior, how it differs from the expected behavior, and how this can be observed. Try to be specific and do **not* use vague terms like "doesn't work" or "wrong result". Do not assume that the person reading this has any experience with or knowledge of your specific research._
|
||||
|
||||
## Steps to Reproduce (Bug Report)
|
||||
|
||||
_Describe the steps required to quickly reproduce the issue. You can attach (small) files to the section below or add URLs where to download an archive with all necessary files. Please try to create input that are as small as possible and run as fast as possible. NOTE: the less effort and time it takes to reproduce your issue, the more likely, that somebody will look into it._
|
||||
|
||||
## Further Information, Files, and Links
|
||||
|
||||
_Put any additional information here, attach relevant text or image files and URLs to external sites, e.g. relevant publications_
|
||||
29
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
29
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
## Purpose
|
||||
|
||||
_Briefly describe the new feature(s), enhancement(s), or bugfix(es) included in this pull request. If this addresses an open GitHub Issue, mention the issue number, e.g. with `fixes #221` or `closes #135`, so that issue will be automatically closed when the pull request is merged_
|
||||
|
||||
## Author(s)
|
||||
|
||||
_Please state name and affiliation of the author or authors that should be credited with the changes in this pull request_
|
||||
|
||||
## Backward Compatibility
|
||||
|
||||
_Please state whether any changes in the pull request break backward compatibility for inputs, and - if yes - explain what has been changed and why_
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
_Provide any relevant details about how the changes are implemented, how correctness was verified, how other features - if any - in LAMMPS are affected_
|
||||
|
||||
## Post Submission Checklist
|
||||
|
||||
_Please check the fields below as they are completed_
|
||||
- [ ] The feature or features in this pull request is complete
|
||||
- [ ] Suitable new documentation files and/or updates to the existing docs are included
|
||||
- [ ] One or more example input decks are included
|
||||
- [ ] The source code follows the LAMMPS formatting guidelines
|
||||
|
||||
## Further Information, Files, and Links
|
||||
|
||||
_Put any additional information here, attach relevant text or image files, and URLs to external sites (e.g. DOIs or webpages)_
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<!-- HTML_ONLY -->
|
||||
<HEAD>
|
||||
<TITLE>LAMMPS Users Manual</TITLE>
|
||||
<META NAME="docnumber" CONTENT="23 Jun 2017 version">
|
||||
<META NAME="docnumber" CONTENT="6 Jul 2017 version">
|
||||
<META NAME="author" CONTENT="http://lammps.sandia.gov - Sandia National Laboratories">
|
||||
<META NAME="copyright" CONTENT="Copyright (2003) Sandia Corporation. This software and manual is distributed under the GNU General Public License.">
|
||||
</HEAD>
|
||||
@ -21,7 +21,7 @@
|
||||
<H1></H1>
|
||||
|
||||
LAMMPS Documentation :c,h3
|
||||
23 Jun 2017 version :c,h4
|
||||
6 Jul 2017 version :c,h4
|
||||
|
||||
Version info: :h4
|
||||
|
||||
|
||||
@ -1039,6 +1039,7 @@ package"_Section_start.html#start_3.
|
||||
"lj/sdk (gko)"_pair_sdk.html,
|
||||
"lj/sdk/coul/long (go)"_pair_sdk.html,
|
||||
"lj/sdk/coul/msm (o)"_pair_sdk.html,
|
||||
"meam/c"_pair_meam.html,
|
||||
"meam/spline (o)"_pair_meam_spline.html,
|
||||
"meam/sw/spline"_pair_meam_sw_spline.html,
|
||||
"mgpt"_pair_mgpt.html,
|
||||
|
||||
@ -4696,9 +4696,9 @@ Self-explanatory. :dd
|
||||
|
||||
{Fix bond/create induced too many angles/dihedrals/impropers per atom} :dt
|
||||
|
||||
See the read_data command for info on setting the "extra angle per
|
||||
atom", etc header values to allow for additional angles, etc to be
|
||||
formed. :dd
|
||||
See the read_data command for info on using the "extra/angle/per/atom",
|
||||
(or dihedral, improper) keywords to allow for additional
|
||||
angles, dihedrals, and impropers to be formed. :dd
|
||||
|
||||
{Fix bond/create needs ghost atoms from further away} :dt
|
||||
|
||||
@ -7876,18 +7876,20 @@ See the setting for tagint in the src/lmptype.h file. :dd
|
||||
|
||||
{New bond exceeded bonds per atom in create_bonds} :dt
|
||||
|
||||
See the read_data command for info on setting the "extra bond per
|
||||
atom" header value to allow for additional bonds to be formed. :dd
|
||||
See the read_data command for info on using the "extra/bond/per/atom"
|
||||
keyword to allow for additional bonds to be formed
|
||||
|
||||
{New bond exceeded bonds per atom in fix bond/create} :dt
|
||||
|
||||
See the read_data command for info on setting the "extra bond per
|
||||
atom" header value to allow for additional bonds to be formed. :dd
|
||||
See the read_data command for info on using the "extra/bond/per/atom"
|
||||
keyword to allow for additional bonds to be formed :dd
|
||||
|
||||
{New bond exceeded special list size in fix bond/create} :dt
|
||||
|
||||
See the special_bonds extra command for info on how to leave space in
|
||||
the special bonds list to allow for additional bonds to be formed. :dd
|
||||
See the "special_bonds extra" command
|
||||
(or the "read_data extra/special/per/atom" command)
|
||||
for info on how to leave space in the special bonds
|
||||
list to allow for additional bonds to be formed. :dd
|
||||
|
||||
{Newton bond change after simulation box is defined} :dt
|
||||
|
||||
@ -9664,9 +9666,10 @@ you are running. :dd
|
||||
|
||||
{Special list size exceeded in fix bond/create} :dt
|
||||
|
||||
See the read_data command for info on setting the "extra special per
|
||||
atom" header value to allow for additional special values to be
|
||||
stored. :dd
|
||||
See the special_bonds extra command
|
||||
(or the read_data extra/special/per/atom command)
|
||||
for info on how to leave space in the special bonds
|
||||
list to allow for additional bonds to be formed. :dd
|
||||
|
||||
{Specified processors != physical processors} :dt
|
||||
|
||||
@ -9683,23 +9686,23 @@ Self-explanatory. :dd
|
||||
|
||||
{Subsequent read data induced too many angles per atom} :dt
|
||||
|
||||
See the create_box extra/angle/per/atom or read_data "extra angle per
|
||||
atom" header value to set this limit larger. :dd
|
||||
See the extra/angle/per/atom keyword for the create_box
|
||||
or the read_data command to set this limit larger :dd
|
||||
|
||||
{Subsequent read data induced too many bonds per atom} :dt
|
||||
|
||||
See the create_box extra/bond/per/atom or read_data "extra bond per
|
||||
atom" header value to set this limit larger. :dd
|
||||
See the extra/bond/per/atom keyword for the create_box
|
||||
or the read_data command to set this limit larger :dd
|
||||
|
||||
{Subsequent read data induced too many dihedrals per atom} :dt
|
||||
|
||||
See the create_box extra/dihedral/per/atom or read_data "extra
|
||||
dihedral per atom" header value to set this limit larger. :dd
|
||||
See the extra/dihedral/per/atom keyword for the create_box
|
||||
or the read_data command to set this limit larger :dd
|
||||
|
||||
{Subsequent read data induced too many impropers per atom} :dt
|
||||
|
||||
See the create_box extra/improper/per/atom or read_data "extra
|
||||
improper per atom" header value to set this limit larger. :dd
|
||||
See the extra/improper/per/atom keyword for the create_box
|
||||
or the read_data command to set this limit larger :dd
|
||||
|
||||
{Substitution for illegal variable} :dt
|
||||
|
||||
|
||||
@ -121,6 +121,7 @@ Package, Description, Doc page, Example, Library
|
||||
"USER-INTEL"_#USER-INTEL, optimized Intel CPU and KNL styles,"Section 5.3.2"_accelerate_intel.html, WWW bench, -
|
||||
"USER-LB"_#USER-LB, Lattice Boltzmann fluid,"fix lb/fluid"_fix_lb_fluid.html, USER/lb, -
|
||||
"USER-MANIFOLD"_#USER-MANIFOLD, motion on 2d surfaces,"fix manifoldforce"_fix_manifoldforce.html, USER/manifold, -
|
||||
"USER-MEAMC"_#USER-MEAMC, modified EAM potential (C++), "pair_style meam/c"_pair_meam.html, meam, -
|
||||
"USER-MGPT"_#USER-MGPT, fast MGPT multi-ion potentials, "pair_style mgpt"_pair_mgpt.html, USER/mgpt, -
|
||||
"USER-MISC"_#USER-MISC, single-file contributions, USER-MISC/README, USER/misc, -
|
||||
"USER-MOLFILE"_#USER-MOLFILE, "VMD"_vmd_home molfile plug-ins,"dump molfile"_dump_molfile.html, -, ext
|
||||
@ -2051,6 +2052,37 @@ http://lammps.sandia.gov/movies.html#manifold :ul
|
||||
|
||||
:line
|
||||
|
||||
USER-MEAMC package :link(USER-MEAMC),h4
|
||||
|
||||
[Contents:]
|
||||
|
||||
A pair style for the modified embedded atom (MEAM) potential
|
||||
translated from the Fortran version in the "MEAM"_MEAM package
|
||||
to plain C++. In contrast to the MEAM package, no library
|
||||
needs to be compiled and the pair style can be instantiated
|
||||
multiple times.
|
||||
|
||||
[Author:] Sebastian Huetter, (Otto-von-Guericke University Magdeburg)
|
||||
based on the Fortran version of Greg Wagner (Northwestern U) while at
|
||||
Sandia.
|
||||
|
||||
[Install or un-install:]
|
||||
|
||||
make yes-user-meamc
|
||||
make machine :pre
|
||||
|
||||
make no-user-meamc
|
||||
make machine :pre
|
||||
|
||||
[Supporting info:]
|
||||
|
||||
src/USER-MEAMC: filenames -> commands
|
||||
src/USER-MEAMC/README
|
||||
"pair meam/c"_pair_meam.html
|
||||
examples/meam :ul
|
||||
|
||||
:line
|
||||
|
||||
USER-MOLFILE package :link(USER-MOLFILE),h4
|
||||
|
||||
[Contents:]
|
||||
|
||||
@ -106,6 +106,8 @@ $t should be 2 for Intel Xeon CPUs and 2 or 4 for Intel Xeon Phi :l
|
||||
For some of the simple 2-body potentials without long-range
|
||||
electrostatics, performance and scalability can be better with
|
||||
the "newton off" setting added to the input script :l
|
||||
For simulations on higher node counts, add "processors * * * grid
|
||||
numa" to the beginning of the input script for better scalability :l
|
||||
If using {kspace_style pppm} in the input script, add
|
||||
"kspace_modify diff ad" for better performance :l
|
||||
:ule
|
||||
@ -392,6 +394,10 @@ hybrid intel omp"_suffix.html command can also be used within the
|
||||
input script to automatically append the "omp" suffix to styles when
|
||||
USER-INTEL styles are not available.
|
||||
|
||||
NOTE: For simulations on higher node counts, add "processors * * *
|
||||
grid numa"_processors.html" to the beginning of the input script for
|
||||
better scalability.
|
||||
|
||||
When running on many nodes, performance might be better when using
|
||||
fewer OpenMP threads and more MPI tasks. This will depend on the
|
||||
simulation and the machine. Using the "verlet/split"_run_style.html
|
||||
|
||||
@ -10,53 +10,93 @@ create_bonds command :h3
|
||||
|
||||
[Syntax:]
|
||||
|
||||
create_bonds group-ID group2-ID btype rmin rmax :pre
|
||||
create_bonds style args ... keyword value ... :pre
|
||||
|
||||
group-ID = ID of first group
|
||||
group2-ID = ID of second group, bonds will be between atoms in the 2 groups
|
||||
btype = bond type of created bonds
|
||||
rmin = minimum distance between pair of atoms to bond together
|
||||
rmax = minimum distance between pair of atoms to bond together :ul
|
||||
style = {many} or {single/bond} or {single/angle} or {single/dihedral} :ule,l
|
||||
{many} args = group-ID group2-ID btype rmin rmax
|
||||
group-ID = ID of first group
|
||||
group2-ID = ID of second group, bonds will be between atoms in the 2 groups
|
||||
btype = bond type of created bonds
|
||||
rmin = minimum distance between pair of atoms to bond together
|
||||
rmax = minimum distance between pair of atoms to bond together
|
||||
{single/bond} args = btype batom1 batom2
|
||||
btype = bond type of new bond
|
||||
batom1,batom2 = atom IDs for two atoms in bond
|
||||
{single/angle} args = atype aatom1 aatom2 aatom3
|
||||
atype = bond type of new angle
|
||||
aatom1,aatom2,aatom3 = atom IDs for three atoms in angle
|
||||
{single/dihedral} args = dtype datom1 datom2 datom3 datom4
|
||||
dtype = bond type of new dihedral
|
||||
datom1,datom2,datom3,datom4 = atom IDs for four atoms in dihedral :pre
|
||||
zero or more keyword/value pairs may be appended :l
|
||||
keyword = {special} :l
|
||||
{special} value = {yes} or {no} :pre
|
||||
:ule
|
||||
|
||||
[Examples:]
|
||||
|
||||
create_bonds all all 1 1.0 1.2
|
||||
create_bonds surf solvent 3 2.0 2.4 :pre
|
||||
create_bonds many all all 1 1.0 1.2
|
||||
create_bonds many surf solvent 3 2.0 2.4
|
||||
create_bond single/bond 1 1 2
|
||||
create_bond single/angle 5 52 98 107 special no :pre
|
||||
|
||||
[Description:]
|
||||
|
||||
Create bonds between pairs of atoms that meet specified distance
|
||||
criteria. The bond interactions can then be computed during a
|
||||
simulation by the bond potential defined by the
|
||||
"bond_style"_bond_style.html and "bond_coeff"_bond_coeff.html
|
||||
commands. This command is useful for adding bonds to a system,
|
||||
e.g. between nearest neighbors in a lattice of atoms, without having
|
||||
to enumerate all the bonds in the data file read by the
|
||||
"read_data"_read_data.html command.
|
||||
Create bonds between pairs of atoms that meet a specified distance
|
||||
criteria. Or create a single bond, angle, or dihedral between 2, 3,
|
||||
or 4 specified atoms.
|
||||
|
||||
Note that the flexibility of this command is limited. It can be used
|
||||
several times to create different types of bond at different
|
||||
distances. But it cannot typically create all the bonds that would
|
||||
normally be defined in a complex system of molecules. Also note that
|
||||
this command does not add any 3-body or 4-body interactions which,
|
||||
depending on your model, may be induced by added bonds,
|
||||
e.g. "angle"_angle_style.html, "dihedral"_dihedral_style.html, or
|
||||
"improper"_improper_style.html interactions.
|
||||
The new bond (angle, dihedral) interactions will then be computed
|
||||
during a simulation by the bond (angle, dihedral) potential defined by
|
||||
the "bond_style"_bond_style.html, "bond_coeff"_bond_coeff.html,
|
||||
"angle_style"_angle_style.html, "angle_coeff"_angle_coeff.html,
|
||||
"dihedral_style"_dihedral_style.html,
|
||||
"dihedral_coeff"_dihedral_coeff.html commands.
|
||||
|
||||
All created bonds will be between pairs of atoms I,J where I is in one
|
||||
of the two specified groups, and J is in the other. The two groups
|
||||
can be the same, e.g. group "all". The created bonds will be of bond
|
||||
type {btype}, where {btype} must be a value between 1 and the number
|
||||
of bond types defined. This maximum value is set by the "bond types"
|
||||
field in the header of the data file read by the
|
||||
"read_data"_read_data.html command, or via the optional "bond/types"
|
||||
argument of the "create_box"_create_box.html command.
|
||||
The {many} style is useful for adding bonds to a system, e.g. between
|
||||
nearest neighbors in a lattice of atoms, without having to enumerate
|
||||
all the bonds in the data file read by the "read_data"_read_data.html
|
||||
command.
|
||||
|
||||
The {single} styles are useful for adding bonds, angles, dihedrals
|
||||
to a system incrementally, then continuing a simulation.
|
||||
|
||||
Note that this command does not auto-create any angle or dihedral
|
||||
interactions when a bond is added. Nor does it auto-create any bonds
|
||||
when an angle or dihedral is added. Or auto-create any angles when a
|
||||
dihedral is added. Thus the flexibility of this command is limited.
|
||||
It can be used several times to create different types of bond at
|
||||
different distances. But it cannot typically auto-create all the
|
||||
bonds or angles or dihedral that would normally be defined in a data
|
||||
file for a complex system of molecules.
|
||||
|
||||
NOTE: If the system has no bonds (angles, dihedrals) to begin with, or
|
||||
if more bonds per atom are being added than currently exist, then you
|
||||
must insure that the number of bond types and the maximum number of
|
||||
bonds per atom are set to large enough values. And similarly for
|
||||
angles and dihedrals. Otherwise an error may occur when too many
|
||||
bonds (angles, dihedrals) are added to an atom. If the
|
||||
"read_data"_read_data.html command is used to define the system, these
|
||||
parameters can be set via the "bond types" and "extra bond per atom"
|
||||
fields in the header section of the data file. If the
|
||||
"create_box"_create_box.html command is used to define the system,
|
||||
these 2 parameters can be set via its optional "bond/types" and
|
||||
"extra/bond/per/atom" arguments. And similarly for angles and
|
||||
dihedrals. See the doc pages for these 2 commands for details.
|
||||
|
||||
:line
|
||||
|
||||
The {many} style will create bonds between pairs of atoms I,J where I
|
||||
is in one of the two specified groups, and J is in the other. The two
|
||||
groups can be the same, e.g. group "all". The created bonds will be
|
||||
of bond type {btype}, where {btype} must be a value between 1 and the
|
||||
number of bond types defined.
|
||||
|
||||
For a bond to be created, an I,J pair of atoms must be a distance D
|
||||
apart such that {rmin} <= D <= {rmax}.
|
||||
|
||||
The following settings must have been made in an input
|
||||
script before this command is used:
|
||||
The following settings must have been made in an input script before
|
||||
this style is used:
|
||||
|
||||
special_bonds weight for 1-2 interactions must be 0.0
|
||||
a "pair_style"_pair_style.html must be defined
|
||||
@ -69,8 +109,8 @@ cannot appear in the neighbor list, to avoid creation of duplicate
|
||||
bonds. The neighbor list for all atom type pairs must also extend to
|
||||
a distance that encompasses the {rmax} for new bonds to create.
|
||||
|
||||
An additional requirement is that your system must be ready to perform
|
||||
a simulation. This means, for example, that all
|
||||
An additional requirement for this style is that your system must be
|
||||
ready to perform a simulation. This means, for example, that all
|
||||
"pair_style"_pair_style.html coefficients be set via the
|
||||
"pair_coeff"_pair_coeff.html command. A "bond_style"_bond_style.html
|
||||
command and all bond coefficients must also be set, even if no bonds
|
||||
@ -83,17 +123,58 @@ executes, e.g. if you wish to use long-range Coulombic interactions
|
||||
via the "kspace_style"_kspace_style.html command for your subsequent
|
||||
simulation.
|
||||
|
||||
NOTE: If the system has no bonds to begin with, or if more bonds per
|
||||
atom are being added than currently exist, then you must insure that
|
||||
the number of bond types and the maximum number of bonds per atom are
|
||||
set to large enough values. Otherwise an error may occur when too
|
||||
many bonds are added to an atom. If the "read_data"_read_data.html
|
||||
command is used to define the system, these 2 parameters can be set
|
||||
via the "bond types" and "extra bond per atom" fields in the header
|
||||
section of the data file. If the "create_box"_create_box.html command
|
||||
is used to define the system, these 2 parameters can be set via its
|
||||
optional "bond/types" and "extra/bond/per/atom" arguments. See the
|
||||
doc pages for the 2 commands for details.
|
||||
:line
|
||||
|
||||
The {single/bond} style creates a single bond of type {btype} between
|
||||
two atoms with IDs {batom1} and {batom2}. {Btype} must be a value
|
||||
between 1 and the number of bond types defined.
|
||||
|
||||
The {single/angle} style creates a single angle of type {atype}
|
||||
between three atoms with IDs {aatom1}, {aatom2}, and {aatom3}. The
|
||||
ordering of the atoms is the same as in the {Angles} section of a data
|
||||
file read by the "read_data"_read_data command. I.e. the 3 atoms are
|
||||
ordered linearly within the angle; the central atom is {aatom2}.
|
||||
{Atype} must be a value between 1 and the number of angle types
|
||||
defined.
|
||||
|
||||
The {single/dihedral} style creates a single dihedral of type {btype}
|
||||
between two atoms with IDs {batom1} and {batom2}. The ordering of the
|
||||
atoms is the same as in the {Dihedrals} section of a data file read by
|
||||
the "read_data"_read_data command. I.e. the 4 atoms are ordered
|
||||
linearly within the dihedral. {Dtype} must be a value between 1 and
|
||||
the number of dihedral types defined.
|
||||
|
||||
:line
|
||||
|
||||
The keyword {special} controls whether an internal list of special
|
||||
bonds is created after one or more bonds, or a single angle or
|
||||
dihedral is added to the system.
|
||||
|
||||
The default value is {yes}. A value of {no} cannot be used
|
||||
with the {many} style.
|
||||
|
||||
This is an expensive operation since the bond topology for the system
|
||||
must be walked to find all 1-2, 1-3, 1-4 interactions to store in an
|
||||
internal list, which is used when pairwise interactions are weighted;
|
||||
see the "special_bonds"_special_bonds.html command for details.
|
||||
|
||||
Thus if you are adding a few bonds or a large list of angles all at
|
||||
the same time, by using this command repeatedly, it is more efficient
|
||||
to only trigger the internal list to be created once, after the last
|
||||
bond (or angle, or dihedral) is added:
|
||||
|
||||
create_bonds single/bond 5 52 98 special no
|
||||
create_bonds single/bond 5 73 74 special no
|
||||
...
|
||||
create_bonds single/bond 5 17 386 special no
|
||||
create_bonds single/bond 4 112 183 special yes :pre
|
||||
|
||||
Note that you MUST insure the internal list is re-built after the last
|
||||
bond (angle, dihedral) is added, before performing a simulation.
|
||||
Otherwise pairwise interactions will not be properly excluded or
|
||||
weighted. LAMMPS does NOT check that you have done this correctly.
|
||||
|
||||
:line
|
||||
|
||||
[Restrictions:]
|
||||
|
||||
@ -105,4 +186,6 @@ molecule template files via the "molecule"_molecule.html and
|
||||
|
||||
"create_atoms"_create_atoms.html, "delete_bonds"_delete_bonds.html
|
||||
|
||||
[Default:] none
|
||||
[Default:]
|
||||
|
||||
The keyword default is special = yes.
|
||||
|
||||
@ -17,19 +17,22 @@ msst = style name of this fix :l
|
||||
dir = {x} or {y} or {z} :l
|
||||
shockvel = shock velocity (strictly positive, distance/time units) :l
|
||||
zero or more keyword value pairs may be appended :l
|
||||
keyword = {q} or {mu} or {p0} or {v0} or {e0} or {tscale} :l
|
||||
keyword = {q} or {mu} or {p0} or {v0} or {e0} or {tscale} or {beta} or {dftb} :l
|
||||
{q} value = cell mass-like parameter (mass^2/distance^4 units)
|
||||
{mu} value = artificial viscosity (mass/length/time units)
|
||||
{p0} value = initial pressure in the shock equations (pressure units)
|
||||
{v0} value = initial simulation cell volume in the shock equations (distance^3 units)
|
||||
{e0} value = initial total energy (energy units)
|
||||
{tscale} value = reduction in initial temperature (unitless fraction between 0.0 and 1.0) :pre
|
||||
{tscale} value = reduction in initial temperature (unitless fraction between 0.0 and 1.0)
|
||||
{dftb} value = {yes} or {no} for whether using MSST in conjunction with DFTB+
|
||||
{beta} value = scale factor on energy contribution of DFTB+ :pre
|
||||
:ule
|
||||
|
||||
[Examples:]
|
||||
|
||||
fix 1 all msst y 100.0 q 1.0e5 mu 1.0e5
|
||||
fix 2 all msst z 50.0 q 1.0e4 mu 1.0e4 v0 4.3419e+03 p0 3.7797e+03 e0 -9.72360e+02 tscale 0.01 :pre
|
||||
fix 2 all msst z 50.0 q 1.0e4 mu 1.0e4 v0 4.3419e+03 p0 3.7797e+03 e0 -9.72360e+02 tscale 0.01
|
||||
fix 1 all msst y 100.0 q 1.0e5 mu 1.0e5 dftb yes beta 0.5 :pre
|
||||
|
||||
[Description:]
|
||||
|
||||
@ -58,11 +61,11 @@ oscillations have physical significance in some cases. The optional
|
||||
symmetry to equilibrate to the shock Hugoniot and Rayleigh line more
|
||||
rapidly in such cases.
|
||||
|
||||
{tscale} is a factor between 0 and 1 that determines what fraction of
|
||||
thermal kinetic energy is converted to compressive strain kinetic
|
||||
energy at the start of the simulation. Setting this parameter to a
|
||||
non-zero value may assist in compression at the start of simulations
|
||||
where it is slow to occur.
|
||||
The keyword {tscale} is a factor between 0 and 1 that determines what
|
||||
fraction of thermal kinetic energy is converted to compressive strain
|
||||
kinetic energy at the start of the simulation. Setting this parameter
|
||||
to a non-zero value may assist in compression at the start of
|
||||
simulations where it is slow to occur.
|
||||
|
||||
If keywords {e0}, {p0},or {v0} are not supplied, these quantities will
|
||||
be calculated on the first step, after the energy specified by
|
||||
@ -77,17 +80,40 @@ For all pressure styles, the simulation box stays orthogonal in shape.
|
||||
Parrinello-Rahman boundary conditions (tilted box) are supported by
|
||||
LAMMPS, but are not implemented for MSST.
|
||||
|
||||
This fix computes a temperature and pressure each timestep. To do
|
||||
this, the fix creates its own computes of style "temp" and "pressure",
|
||||
as if these commands had been issued:
|
||||
This fix computes a temperature and pressure and potential energy each
|
||||
timestep. To do this, the fix creates its own computes of style "temp"
|
||||
"pressure", and "pe", as if these commands had been issued:
|
||||
|
||||
compute fix-ID_temp group-ID temp
|
||||
compute fix-ID_press group-ID pressure fix-ID_temp :pre
|
||||
compute fix-ID_MSST_temp all temp
|
||||
compute fix-ID_MSST_press all pressure fix-ID_MSST_temp :pre
|
||||
compute fix-ID_MSST_pe all pe :pre
|
||||
|
||||
See the "compute temp"_compute_temp.html and "compute
|
||||
pressure"_compute_pressure.html commands for details. Note that the
|
||||
IDs of the new computes are the fix-ID + underscore + "temp" or fix_ID
|
||||
+ underscore + "press". The group for the new computes is "all".
|
||||
IDs of the new computes are the fix-ID + "_MSST_temp" or "_MSST_press"
|
||||
or "_MSST_pe". The group for the new computes is "all".
|
||||
|
||||
:line
|
||||
|
||||
The {dftb} and {beta} keywords are to allow this fix to be used when
|
||||
LAMMPS is being driven by DFTB+, a density-functional tight-binding
|
||||
code.
|
||||
|
||||
If the keyword {dftb} is used with a value of {yes}, then the MSST
|
||||
equations are altered to account for an energy contribution compute by
|
||||
DFTB+. In this case, you must define a "fix
|
||||
external"_fix_external.html command in your input script, which is
|
||||
used to callback to DFTB+ during the LAMMPS timestepping. DFTB+ will
|
||||
communicate its info to LAMMPS via that fix.
|
||||
|
||||
The keyword {beta} is a scale factor on the DFTB+ energy contribution.
|
||||
The value of {beta} must be between 0.0 and 1.0 inclusive. A value of
|
||||
0.0 means no contribution, a value of 1.0 means a full contribution.
|
||||
|
||||
(July 2017) More information about these keywords and the use of
|
||||
LAMMPS with DFTB+ will be added to the LAMMMPS documention soon.
|
||||
|
||||
:line
|
||||
|
||||
[Restart, fix_modify, output, run start/stop, minimize info:]
|
||||
|
||||
@ -149,8 +175,9 @@ all.
|
||||
|
||||
[Default:]
|
||||
|
||||
The keyword defaults are q = 10, mu = 0, tscale = 0.01. p0, v0, and e0
|
||||
are calculated on the first step.
|
||||
The keyword defaults are q = 10, mu = 0, tscale = 0.01, dftb = no,
|
||||
beta = 0.0. Note that p0, v0, and e0 are calculated on the first
|
||||
timestep.
|
||||
|
||||
:line
|
||||
|
||||
|
||||
@ -7,10 +7,13 @@
|
||||
:line
|
||||
|
||||
pair_style meam command :h3
|
||||
pair_style meam/c command :h3
|
||||
|
||||
[Syntax:]
|
||||
|
||||
pair_style meam :pre
|
||||
pair_style style :pre
|
||||
|
||||
style = {meam} or {meam/c}
|
||||
|
||||
[Examples:]
|
||||
|
||||
@ -30,7 +33,8 @@ using modified embedded-atom method (MEAM) potentials
|
||||
"EAM potentials"_pair_eam.html which adds angular forces. It is
|
||||
thus suitable for modeling metals and alloys with fcc, bcc, hcp and
|
||||
diamond cubic structures, as well as covalently bonded materials like
|
||||
silicon and carbon.
|
||||
silicon and carbon. Style {meam/c} is a translation of the {meam} code
|
||||
from (mostly) Fortran to C++. It is functionally equivalent to {meam}.
|
||||
|
||||
In the MEAM formulation, the total energy E of a system of atoms is
|
||||
given by:
|
||||
@ -331,10 +335,14 @@ This pair style can only be used via the {pair} keyword of the
|
||||
|
||||
[Restrictions:]
|
||||
|
||||
This style is part of the MEAM package. It is only enabled if LAMMPS
|
||||
The {meam} style is part of the MEAM package. It is only enabled if LAMMPS
|
||||
was built with that package, which also requires the MEAM library be
|
||||
built and linked with LAMMPS. See the "Making
|
||||
LAMMPS"_Section_start.html#start_3 section for more info.
|
||||
built and linked with LAMMPS.
|
||||
The {meam/c} style is provided in the USER-MEAMC package. It is only enabled
|
||||
if LAMMPS was built with that package. In contrast to the {meam} style,
|
||||
{meam/c} does not require a separate library to be compiled and it can be
|
||||
instantiated multiple times in a "hybrid"_pair_hybrid.html pair style.
|
||||
See the "Making LAMMPS"_Section_start.html#start_3 section for more info.
|
||||
|
||||
[Related commands:]
|
||||
|
||||
|
||||
@ -80,10 +80,12 @@ For a given entry, if the first three arguments are all different,
|
||||
then the entry is for the {K} and {theta_0} parameters (the cutoff in
|
||||
this case is irrelevant).
|
||||
|
||||
It is {not} required that the potential file contain entries for all
|
||||
of the elements listed in the pair_coeff command. It can also contain
|
||||
entries for additional elements not being used in a particular
|
||||
simulation; LAMMPS ignores those entries.
|
||||
It is required that the potential file contains entries for {all}
|
||||
permutations of the elements listed in the pair_coeff command.
|
||||
If certain combinations are not parameterized the corresponding
|
||||
parameters should be set to zero. The potential file can also
|
||||
contain entries for additional elements which are not used in
|
||||
a particular simulation; LAMMPS ignores those entries.
|
||||
|
||||
:line
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ read_data file keyword args ... :pre
|
||||
|
||||
file = name of data file to read in :ulb,l
|
||||
zero or more keyword/arg pairs may be appended :l
|
||||
keyword = {add} or {offset} or {shift} or {extra/atom/types} or {extra/bond/types} or {extra/angle/types} or {extra/dihedral/types} or {extra/improper/types} or {group} or {nocoeff} or {fix} :l
|
||||
keyword = {add} or {offset} or {shift} or {extra/atom/types} or {extra/bond/types} or {extra/angle/types} or {extra/dihedral/types} or {extra/improper/types} or {extra/bond/per/atom} or {extra/angle/per/atom} or {extra/dihedral/per/atom} or {extra/improper/per/atom} or {group} or {nocoeff} or {fix} :l
|
||||
{add} arg = {append} or {Nstart} or {merge}
|
||||
append = add new atoms with IDs appended to current IDs
|
||||
Nstart = add new atoms with IDs starting with Nstart
|
||||
@ -32,6 +32,11 @@ keyword = {add} or {offset} or {shift} or {extra/atom/types} or {extra/bond/type
|
||||
{extra/angle/types} arg = # of extra angle types
|
||||
{extra/dihedral/types} arg = # of extra dihedral types
|
||||
{extra/improper/types} arg = # of extra improper types
|
||||
{extra/bond/per/atom} arg = leave space for this many new bonds per atom
|
||||
{extra/angle/per/atom} arg = leave space for this many new angles per atom
|
||||
{extra/dihedral/per/atom} arg = leave space for this many new dihedrals per atom
|
||||
{extra/improper/per/atom} arg = leave space for this many new impropers per atom
|
||||
{extra/special/per/atom} arg = leave space for extra 1-2,1-3,1-4 interactions per atom
|
||||
{group} args = groupID
|
||||
groupID = add atoms in data file to this group
|
||||
{nocoeff} = ignore force field parameters
|
||||
@ -264,11 +269,11 @@ is different than the default.
|
||||
{angle types} = # of angle types in system
|
||||
{dihedral types} = # of dihedral types in system
|
||||
{improper types} = # of improper types in system
|
||||
{extra bond per atom} = leave space for this many new bonds per atom
|
||||
{extra angle per atom} = leave space for this many new angles per atom
|
||||
{extra dihedral per atom} = leave space for this many new dihedrals per atom
|
||||
{extra improper per atom} = leave space for this many new impropers per atom
|
||||
{extra special per atom} = leave space for this many new special bonds per atom
|
||||
{extra bond per atom} = leave space for this many new bonds per atom (deprecated, use extra/bond/per/atom keyword)
|
||||
{extra angle per atom} = leave space for this many new angles per atom (deprecated, use extra/angle/per/atom keyword)
|
||||
{extra dihedral per atom} = leave space for this many new dihedrals per atom (deprecated, use extra/dihedral/per/atom keyword)
|
||||
{extra improper per atom} = leave space for this many new impropers per atom (deprecated, use extra/improper/per/atom keyword)
|
||||
{extra special per atom} = leave space for this many new special bonds per atom (deprecated, use extra/special/per/atom keyword)
|
||||
{ellipsoids} = # of ellipsoids in system
|
||||
{lines} = # of line segments in system
|
||||
{triangles} = # of triangles in system
|
||||
@ -367,25 +372,32 @@ read_data command will generate an error in this case.
|
||||
The "extra bond per atom" setting (angle, dihedral, improper) is only
|
||||
needed if new bonds (angles, dihedrals, impropers) will be added to
|
||||
the system when a simulation runs, e.g. by using the "fix
|
||||
bond/create"_fix_bond_create.html command. This will pre-allocate
|
||||
space in LAMMPS data structures for storing the new bonds (angles,
|
||||
bond/create"_fix_bond_create.html command. Using this header flag
|
||||
is deprecated; please use the {extra/bond/per/atom} keyword (and
|
||||
correspondingly for angles, dihedrals and impropers) in the
|
||||
read_data command instead. Either will pre-allocate space in LAMMPS
|
||||
data structures for storing the new bonds (angles,
|
||||
dihedrals, impropers).
|
||||
|
||||
The "extra special per atom" setting is typically only needed if new
|
||||
bonds/angles/etc will be added to the system, e.g. by using the "fix
|
||||
bond/create"_fix_bond_create.html command. Or if entire new molecules
|
||||
will be added to the system, e.g. by using the "fix
|
||||
deposit"_fix_deposit.html or "fix pour"_fix_pour.html commands, which
|
||||
will have more special 1-2,1-3,1-4 neighbors than any other molecules
|
||||
defined in the data file. Using this setting will pre-allocate space
|
||||
in the LAMMPS data structures for storing these neighbors. See the
|
||||
will be added to the system, e.g. by using the
|
||||
"fix deposit"_fix_deposit.html or "fix pour"_fix_pour.html commands,
|
||||
which will have more special 1-2,1-3,1-4 neighbors than any other
|
||||
molecules defined in the data file. Using this header flag is
|
||||
deprecated; please use the {extra/special/per/atom} keyword instead.
|
||||
Using this setting will pre-allocate space in the LAMMPS data
|
||||
structures for storing these neighbors. See the
|
||||
"special_bonds"_special_bonds.html and "molecule"_molecule.html doc
|
||||
pages for more discussion of 1-2,1-3,1-4 neighbors.
|
||||
|
||||
NOTE: All of the "extra" settings are only used if they appear in the
|
||||
first data file read; see the description of the {add} keyword above
|
||||
for reading multiple data files. If they appear in later data files,
|
||||
they are ignored.
|
||||
NOTE: All of the "extra" settings are only applied in the first data
|
||||
file read and when no simulation box has yet been created; as soon as
|
||||
the simulation box is created (and read_data implies that), these
|
||||
settings are {locked} and cannot be changed anymore. Please see the
|
||||
description of the {add} keyword above for reading multiple data files.
|
||||
If they appear in later data files, they are ignored.
|
||||
|
||||
The "ellipsoids" and "lines" and "triangles" and "bodies" settings are
|
||||
only used with "atom_style ellipsoid or line or tri or
|
||||
|
||||
@ -41,5 +41,8 @@ fortran a simple wrapper on the LAMMPS library API that
|
||||
can be called from Fortran
|
||||
fortran2 a more sophisticated wrapper on the LAMMPS library API that
|
||||
can be called from Fortran
|
||||
fortran3 wrapper written by Nir Goldman (LLNL), as an
|
||||
extension to fortran2, used for calling LAMMPS
|
||||
from Fortran DFTB+ code
|
||||
|
||||
Each sub-directory has its own README.
|
||||
Each sub-directory has its own README with more details.
|
||||
|
||||
236
examples/COUPLE/fortran3/LAMMPS-wrapper.cpp
Normal file
236
examples/COUPLE/fortran3/LAMMPS-wrapper.cpp
Normal file
@ -0,0 +1,236 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
www.cs.sandia.gov/~sjplimp/lammps.html
|
||||
Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
Contributing author: Karl D. Hammond <karlh@ugcs.caltech.edu>
|
||||
University of Tennessee, Knoxville (USA), 2012
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* This is set of "wrapper" functions to assist LAMMPS.F90, which itself
|
||||
provides a (I hope) robust Fortran interface to library.cpp and
|
||||
library.h. All functions herein COULD be added to library.cpp instead of
|
||||
including this as a separate file. See the README for instructions. */
|
||||
|
||||
#include <mpi.h>
|
||||
#include "LAMMPS-wrapper.h"
|
||||
#include <library.h>
|
||||
#include <lammps.h>
|
||||
#include <atom.h>
|
||||
#include <fix.h>
|
||||
#include <compute.h>
|
||||
#include <modify.h>
|
||||
#include <error.h>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
void lammps_open_fortran_wrapper (int argc, char **argv,
|
||||
MPI_Fint communicator, void **ptr)
|
||||
{
|
||||
MPI_Comm C_communicator = MPI_Comm_f2c (communicator);
|
||||
lammps_open (argc, argv, C_communicator, ptr);
|
||||
}
|
||||
|
||||
int lammps_get_ntypes (void *ptr)
|
||||
{
|
||||
class LAMMPS *lmp = (class LAMMPS *) ptr;
|
||||
int ntypes = lmp->atom->ntypes;
|
||||
return ntypes;
|
||||
}
|
||||
|
||||
void lammps_error_all (void *ptr, const char *file, int line, const char *str)
|
||||
{
|
||||
class LAMMPS *lmp = (class LAMMPS *) ptr;
|
||||
lmp->error->all (file, line, str);
|
||||
}
|
||||
|
||||
int lammps_extract_compute_vectorsize (void *ptr, char *id, int style)
|
||||
{
|
||||
class LAMMPS *lmp = (class LAMMPS *) ptr;
|
||||
int icompute = lmp->modify->find_compute(id);
|
||||
if ( icompute < 0 ) return 0;
|
||||
class Compute *compute = lmp->modify->compute[icompute];
|
||||
|
||||
if ( style == 0 )
|
||||
{
|
||||
if ( !compute->vector_flag )
|
||||
return 0;
|
||||
else
|
||||
return compute->size_vector;
|
||||
}
|
||||
else if ( style == 1 )
|
||||
{
|
||||
return lammps_get_natoms (ptr);
|
||||
}
|
||||
else if ( style == 2 )
|
||||
{
|
||||
if ( !compute->local_flag )
|
||||
return 0;
|
||||
else
|
||||
return compute->size_local_rows;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lammps_extract_compute_arraysize (void *ptr, char *id, int style,
|
||||
int *nrows, int *ncols)
|
||||
{
|
||||
class LAMMPS *lmp = (class LAMMPS *) ptr;
|
||||
int icompute = lmp->modify->find_compute(id);
|
||||
if ( icompute < 0 )
|
||||
{
|
||||
*nrows = 0;
|
||||
*ncols = 0;
|
||||
}
|
||||
class Compute *compute = lmp->modify->compute[icompute];
|
||||
|
||||
if ( style == 0 )
|
||||
{
|
||||
if ( !compute->array_flag )
|
||||
{
|
||||
*nrows = 0;
|
||||
*ncols = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*nrows = compute->size_array_rows;
|
||||
*ncols = compute->size_array_cols;
|
||||
}
|
||||
}
|
||||
else if ( style == 1 )
|
||||
{
|
||||
if ( !compute->peratom_flag )
|
||||
{
|
||||
*nrows = 0;
|
||||
*ncols = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*nrows = lammps_get_natoms (ptr);
|
||||
*ncols = compute->size_peratom_cols;
|
||||
}
|
||||
}
|
||||
else if ( style == 2 )
|
||||
{
|
||||
if ( !compute->local_flag )
|
||||
{
|
||||
*nrows = 0;
|
||||
*ncols = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*nrows = compute->size_local_rows;
|
||||
*ncols = compute->size_local_cols;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*nrows = 0;
|
||||
*ncols = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int lammps_extract_fix_vectorsize (void *ptr, char *id, int style)
|
||||
{
|
||||
class LAMMPS *lmp = (class LAMMPS *) ptr;
|
||||
int ifix = lmp->modify->find_fix(id);
|
||||
if ( ifix < 0 ) return 0;
|
||||
class Fix *fix = lmp->modify->fix[ifix];
|
||||
|
||||
if ( style == 0 )
|
||||
{
|
||||
if ( !fix->vector_flag )
|
||||
return 0;
|
||||
else
|
||||
return fix->size_vector;
|
||||
}
|
||||
else if ( style == 1 )
|
||||
{
|
||||
return lammps_get_natoms (ptr);
|
||||
}
|
||||
else if ( style == 2 )
|
||||
{
|
||||
if ( !fix->local_flag )
|
||||
return 0;
|
||||
else
|
||||
return fix->size_local_rows;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lammps_extract_fix_arraysize (void *ptr, char *id, int style,
|
||||
int *nrows, int *ncols)
|
||||
{
|
||||
class LAMMPS *lmp = (class LAMMPS *) ptr;
|
||||
int ifix = lmp->modify->find_fix(id);
|
||||
if ( ifix < 0 )
|
||||
{
|
||||
*nrows = 0;
|
||||
*ncols = 0;
|
||||
}
|
||||
class Fix *fix = lmp->modify->fix[ifix];
|
||||
|
||||
if ( style == 0 )
|
||||
{
|
||||
if ( !fix->array_flag )
|
||||
{
|
||||
*nrows = 0;
|
||||
*ncols = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*nrows = fix->size_array_rows;
|
||||
*ncols = fix->size_array_cols;
|
||||
}
|
||||
}
|
||||
else if ( style == 1 )
|
||||
{
|
||||
if ( !fix->peratom_flag )
|
||||
{
|
||||
*nrows = 0;
|
||||
*ncols = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*nrows = lammps_get_natoms (ptr);
|
||||
*ncols = fix->size_peratom_cols;
|
||||
}
|
||||
}
|
||||
else if ( style == 2 )
|
||||
{
|
||||
if ( !fix->local_flag )
|
||||
{
|
||||
*nrows = 0;
|
||||
*ncols = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*nrows = fix->size_local_rows;
|
||||
*ncols = fix->size_local_cols;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*nrows = 0;
|
||||
*ncols = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/* vim: set ts=3 sts=3 expandtab: */
|
||||
40
examples/COUPLE/fortran3/LAMMPS-wrapper.h
Normal file
40
examples/COUPLE/fortran3/LAMMPS-wrapper.h
Normal file
@ -0,0 +1,40 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
www.cs.sandia.gov/~sjplimp/lammps.html
|
||||
Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
Contributing author: Karl D. Hammond <karlh@ugcs.caltech.edu>
|
||||
University of Tennessee, Knoxville (USA), 2012
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* This is set of "wrapper" functions to assist LAMMPS.F90, which itself
|
||||
provides a (I hope) robust Fortran interface to library.cpp and
|
||||
library.h. All prototypes herein COULD be added to library.h instead of
|
||||
including this as a separate file. See the README for instructions. */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Prototypes for auxiliary functions */
|
||||
void lammps_open_fortran_wrapper (int, char**, MPI_Fint, void**);
|
||||
int lammps_get_ntypes (void*);
|
||||
int lammps_extract_compute_vectorsize (void*, char*, int);
|
||||
void lammps_extract_compute_arraysize (void*, char*, int, int*, int*);
|
||||
int lammps_extract_fix_vectorsize (void*, char*, int);
|
||||
void lammps_extract_fix_arraysize (void*, char*, int, int*, int*);
|
||||
void lammps_error_all (void*, const char*, int, const char*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* vim: set ts=3 sts=3 expandtab: */
|
||||
57
examples/COUPLE/fortran3/LAMMPS-wrapper2.cpp
Normal file
57
examples/COUPLE/fortran3/LAMMPS-wrapper2.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
www.cs.sandia.gov/~sjplimp/lammps.html
|
||||
Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
Contributing author: Karl D. Hammond <karlh@ugcs.caltech.edu>
|
||||
University of Tennessee, Knoxville (USA), 2012
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* This is set of "wrapper" functions to assist LAMMPS.F90, which itself
|
||||
provides a (I hope) robust Fortran interface to library.cpp and
|
||||
library.h. All functions herein COULD be added to library.cpp instead of
|
||||
including this as a separate file. See the README for instructions. */
|
||||
|
||||
#include <mpi.h>
|
||||
#include "LAMMPS-wrapper2.h"
|
||||
#include <library.h>
|
||||
#include <lammps.h>
|
||||
#include <atom.h>
|
||||
#include <input.h>
|
||||
#include <modify.h>
|
||||
#include <fix.h>
|
||||
#include <fix_external.h>
|
||||
#include <compute.h>
|
||||
#include <modify.h>
|
||||
#include <error.h>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
extern "C" void f_callback(void *, bigint, int, tagint *, double **, double **);
|
||||
|
||||
void lammps_set_callback (void *ptr) {
|
||||
class LAMMPS *lmp = (class LAMMPS *) ptr;
|
||||
int ifix = lmp->modify->find_fix_by_style("external");
|
||||
FixExternal *fix = (FixExternal *) lmp->modify->fix[ifix];
|
||||
fix->set_callback(f_callback, ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
void lammps_set_user_energy (void *ptr, double energy) {
|
||||
class LAMMPS *lmp = (class LAMMPS *) ptr;
|
||||
int ifix = lmp->modify->find_fix_by_style("external");
|
||||
FixExternal *fix = (FixExternal *) lmp->modify->fix[ifix];
|
||||
fix->set_energy(energy);
|
||||
return;
|
||||
}
|
||||
|
||||
34
examples/COUPLE/fortran3/LAMMPS-wrapper2.h
Normal file
34
examples/COUPLE/fortran3/LAMMPS-wrapper2.h
Normal file
@ -0,0 +1,34 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
www.cs.sandia.gov/~sjplimp/lammps.html
|
||||
Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
Contributing author: Nir Goldman, ngoldman@llnl.gov, Oct. 19th, 2016
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* This is set of "wrapper" functions to assist LAMMPS.F90, which itself
|
||||
provides a (I hope) robust Fortran interface to library.cpp and
|
||||
library.h. All prototypes herein COULD be added to library.h instead of
|
||||
including this as a separate file. See the README for instructions. */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Prototypes for auxiliary functions */
|
||||
void lammps_set_callback (void *);
|
||||
void lammps_set_user_energy (void*, double);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* vim: set ts=3 sts=3 expandtab: */
|
||||
956
examples/COUPLE/fortran3/LAMMPS.F90
Normal file
956
examples/COUPLE/fortran3/LAMMPS.F90
Normal file
@ -0,0 +1,956 @@
|
||||
!! -----------------------------------------------------------------------
|
||||
! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
! www.cs.sandia.gov/~sjplimp/lammps.html
|
||||
! Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
|
||||
!
|
||||
! Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
! DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
! certain rights in this software. This software is distributed under
|
||||
! the GNU General Public License.
|
||||
!
|
||||
! See the README file in the top-level LAMMPS directory.
|
||||
!--------------------------------------------------------------------------
|
||||
|
||||
!! ------------------------------------------------------------------------
|
||||
! Contributing author: Karl D. Hammond <karlh@ugcs.caltech.edu>
|
||||
! University of Tennessee, Knoxville (USA), 2012
|
||||
!--------------------------------------------------------------------------
|
||||
|
||||
!! LAMMPS, a Fortran 2003 module containing an interface between Fortran
|
||||
!! programs and the C-style functions in library.cpp that ship with LAMMPS.
|
||||
!! This file should be accompanied by LAMMPS-wrapper.cpp and LAMMPS-wrapper.h,
|
||||
!! which define wrapper functions that ease portability and enforce array
|
||||
!! dimensions.
|
||||
!!
|
||||
!! Everything in this module should be 100% portable by way of Fortran 2003's
|
||||
!! ISO_C_BINDING intrinsic module. See the README for instructions for
|
||||
!! compilation and use.
|
||||
!!
|
||||
!! Here are the PUBLIC functions and subroutines included in this module.
|
||||
!! subroutine lammps_open (command_line, communicator, ptr)
|
||||
!! subroutine lammps_open_no_mpi (command_line, ptr)
|
||||
!! subroutine lammps_close (ptr)
|
||||
!! subroutine lammps_file (ptr, str)
|
||||
!! subroutine lammps_command (ptr, str)
|
||||
!! subroutine lammps_free (ptr)
|
||||
!! subroutine lammps_extract_global (global, ptr, name)
|
||||
!! subroutine lammps_extract_atom (atom, ptr, name)
|
||||
!! subroutine lammps_extract_fix (fix, ptr, id, style, type, i, j)
|
||||
!! subroutine lammps_extract_compute (compute, ptr, id, style, type)
|
||||
!! subroutine lammps_extract_variable (variable, ptr, name, group)
|
||||
!! function lammps_get_natoms (ptr)
|
||||
!! subroutine lammps_gather_atoms (ptr, name, count, data)
|
||||
!! subroutine lammps_scatter_atoms (ptr, name, data)
|
||||
|
||||
#define FLERR __FILE__,__LINE__
|
||||
! The above line allows for similar error checking as is done with standard
|
||||
! LAMMPS files.
|
||||
|
||||
module LAMMPS
|
||||
|
||||
use, intrinsic :: ISO_C_binding, only : C_double, C_int, C_ptr, C_char, &
|
||||
C_NULL_CHAR, C_loc, C_F_pointer, lammps_instance => C_ptr
|
||||
implicit none
|
||||
private
|
||||
public :: lammps_open, lammps_open_no_mpi, lammps_close, lammps_file, &
|
||||
lammps_command, lammps_free, lammps_extract_global, &
|
||||
lammps_extract_atom, lammps_extract_compute, lammps_extract_fix, &
|
||||
lammps_extract_variable, lammps_get_natoms, lammps_gather_atoms, &
|
||||
lammps_scatter_atoms, lammps_set_callback, lammps_set_user_energy
|
||||
public :: lammps_instance, C_ptr, C_double, C_int
|
||||
|
||||
!! Functions supplemental to the prototypes in library.h. {{{1
|
||||
!! The function definitions (in C++) are contained in LAMMPS-wrapper.cpp.
|
||||
!! I would have written the first in Fortran, but the MPI libraries (which
|
||||
!! were written in C) have C-based functions to convert from Fortran MPI
|
||||
!! handles to C MPI handles, and there is no Fortran equivalent for those
|
||||
!! functions.
|
||||
interface
|
||||
subroutine lammps_open_wrapper (argc, argv, communicator, ptr) &
|
||||
bind (C, name='lammps_open_fortran_wrapper')
|
||||
import :: C_int, C_ptr
|
||||
integer (C_int), value :: argc
|
||||
type (C_ptr), dimension(*) :: argv
|
||||
integer, value :: communicator
|
||||
type (C_ptr) :: ptr
|
||||
end subroutine lammps_open_wrapper
|
||||
subroutine lammps_actual_error_all (ptr, file, line, str) &
|
||||
bind (C, name='lammps_error_all')
|
||||
import :: C_int, C_char, C_ptr
|
||||
type (C_ptr), value :: ptr
|
||||
character (kind=C_char), dimension(*), intent(in) :: file, str
|
||||
integer (C_int), value :: line
|
||||
end subroutine lammps_actual_error_all
|
||||
function lammps_get_ntypes (ptr) result (ntypes) &
|
||||
bind (C, name='lammps_get_ntypes')
|
||||
import :: C_int, C_ptr
|
||||
type (C_ptr), value :: ptr
|
||||
integer (C_int) :: ntypes
|
||||
end function lammps_get_ntypes
|
||||
function lammps_actual_extract_compute_vectorsize (ptr, id, style) &
|
||||
result (vectorsize) bind (C, name='lammps_extract_compute_vectorsize')
|
||||
import :: C_int, C_char, C_ptr
|
||||
integer (C_int) :: vectorsize
|
||||
type (C_ptr), value :: ptr
|
||||
character (kind=C_char), dimension(*) :: id
|
||||
integer (C_int), value :: style
|
||||
end function lammps_actual_extract_compute_vectorsize
|
||||
subroutine lammps_actual_extract_compute_arraysize (ptr, id, style, &
|
||||
nrows, ncols) bind (C, name='lammps_extract_compute_arraysize')
|
||||
import :: C_int, C_char, C_ptr
|
||||
integer (C_int) :: arraysize
|
||||
type (C_ptr), value :: ptr
|
||||
character (kind=C_char), dimension(*) :: id
|
||||
integer (C_int), value :: style
|
||||
integer (C_int) :: nrows, ncols
|
||||
end subroutine lammps_actual_extract_compute_arraysize
|
||||
function lammps_actual_extract_fix_vectorsize (ptr, id, style) &
|
||||
result (vectorsize) bind (C, name='lammps_extract_fix_vectorsize')
|
||||
import :: C_int, C_char, C_ptr
|
||||
integer (C_int) :: vectorsize
|
||||
type (C_ptr), value :: ptr
|
||||
character (kind=C_char), dimension(*) :: id
|
||||
integer (C_int), value :: style
|
||||
end function lammps_actual_extract_fix_vectorsize
|
||||
subroutine lammps_actual_extract_fix_arraysize (ptr, id, style, &
|
||||
nrows, ncols) bind (C, name='lammps_extract_fix_arraysize')
|
||||
import :: C_int, C_char, C_ptr
|
||||
type (C_ptr), value :: ptr
|
||||
character (kind=C_char), dimension(*) :: id
|
||||
integer (C_int), value :: style
|
||||
integer (C_int) :: nrows, ncols
|
||||
end subroutine lammps_actual_extract_fix_arraysize
|
||||
end interface
|
||||
|
||||
!! Functions/subroutines defined in library.h and library.cpp {{{1
|
||||
interface
|
||||
subroutine lammps_actual_open_no_mpi (argc, argv, ptr) &
|
||||
bind (C, name='lammps_open_no_mpi')
|
||||
import :: C_int, C_ptr
|
||||
integer (C_int), value :: argc
|
||||
type (C_ptr), dimension(*) :: argv
|
||||
type (C_ptr) :: ptr
|
||||
end subroutine lammps_actual_open_no_mpi
|
||||
|
||||
subroutine lammps_close (ptr) bind (C, name='lammps_close')
|
||||
import :: C_ptr
|
||||
type (C_ptr), value :: ptr
|
||||
end subroutine lammps_close
|
||||
|
||||
subroutine lammps_actual_file (ptr, str) bind (C, name='lammps_file')
|
||||
import :: C_ptr, C_char
|
||||
type (C_ptr), value :: ptr
|
||||
character (kind=C_char), dimension(*) :: str
|
||||
end subroutine lammps_actual_file
|
||||
|
||||
function lammps_actual_command (ptr, str) result (command) &
|
||||
bind (C, name='lammps_command')
|
||||
import :: C_ptr, C_char
|
||||
type (C_ptr), value :: ptr
|
||||
character (kind=C_char), dimension(*) :: str
|
||||
type (C_ptr) :: command
|
||||
end function lammps_actual_command
|
||||
|
||||
subroutine lammps_free (ptr) bind (C, name='lammps_free')
|
||||
import :: C_ptr
|
||||
type (C_ptr), value :: ptr
|
||||
end subroutine lammps_free
|
||||
|
||||
function lammps_actual_extract_global (ptr, name) &
|
||||
bind (C, name='lammps_extract_global') result (global)
|
||||
import :: C_ptr, C_char
|
||||
type (C_ptr), value :: ptr
|
||||
character (kind=C_char), dimension(*) :: name
|
||||
type (C_ptr) :: global
|
||||
end function lammps_actual_extract_global
|
||||
|
||||
function lammps_actual_extract_atom (ptr, name) &
|
||||
bind (C, name='lammps_extract_atom') result (atom)
|
||||
import :: C_ptr, C_char
|
||||
type (C_ptr), value :: ptr
|
||||
character (kind=C_char), dimension(*) :: name
|
||||
type (C_ptr) :: atom
|
||||
end function lammps_actual_extract_atom
|
||||
|
||||
function lammps_actual_extract_compute (ptr, id, style, type) &
|
||||
result (compute) bind (C, name='lammps_extract_compute')
|
||||
import :: C_ptr, C_char, C_int
|
||||
type (C_ptr), value :: ptr
|
||||
character (kind=C_char), dimension(*) :: id
|
||||
integer (C_int), value :: style, type
|
||||
type (C_ptr) :: compute
|
||||
end function lammps_actual_extract_compute
|
||||
|
||||
function lammps_actual_extract_fix (ptr, id, style, type, i, j) &
|
||||
result (fix) bind (C, name='lammps_extract_fix')
|
||||
import :: C_ptr, C_char, C_int
|
||||
type (C_ptr), value :: ptr
|
||||
character (kind=C_char), dimension(*) :: id
|
||||
integer (C_int), value :: style, type, i, j
|
||||
type (C_ptr) :: fix
|
||||
end function lammps_actual_extract_fix
|
||||
|
||||
function lammps_actual_extract_variable (ptr, name, group) &
|
||||
result (variable) bind (C, name='lammps_extract_variable')
|
||||
import :: C_ptr, C_char
|
||||
type (C_ptr), value :: ptr
|
||||
character (kind=C_char), dimension(*) :: name, group
|
||||
type (C_ptr) :: variable
|
||||
end function lammps_actual_extract_variable
|
||||
|
||||
function lammps_get_natoms (ptr) result (natoms) &
|
||||
bind (C, name='lammps_get_natoms')
|
||||
import :: C_ptr, C_int
|
||||
type (C_ptr), value :: ptr
|
||||
integer (C_int) :: natoms
|
||||
end function lammps_get_natoms
|
||||
|
||||
subroutine lammps_set_callback (ptr) &
|
||||
bind (C, name='lammps_set_callback')
|
||||
import :: C_ptr
|
||||
type (C_ptr), value :: ptr
|
||||
end subroutine lammps_set_callback
|
||||
|
||||
subroutine lammps_set_user_energy (ptr, energy) &
|
||||
bind (C, name='lammps_set_user_energy')
|
||||
import :: C_ptr, C_double
|
||||
type (C_ptr), value :: ptr
|
||||
real(C_double), value :: energy
|
||||
end subroutine lammps_set_user_energy
|
||||
|
||||
subroutine lammps_actual_gather_atoms (ptr, name, type, count, data) &
|
||||
bind (C, name='lammps_gather_atoms')
|
||||
import :: C_ptr, C_int, C_char
|
||||
type (C_ptr), value :: ptr, data
|
||||
character (kind=C_char), dimension(*) :: name
|
||||
integer (C_int), value :: type, count
|
||||
end subroutine lammps_actual_gather_atoms
|
||||
|
||||
subroutine lammps_actual_scatter_atoms (ptr, name, type, count, data) &
|
||||
bind (C, name='lammps_scatter_atoms')
|
||||
import :: C_ptr, C_int, C_char
|
||||
type (C_ptr), value :: ptr, data
|
||||
character (kind=C_char), dimension(*) :: name
|
||||
integer (C_int), value :: type, count
|
||||
end subroutine lammps_actual_scatter_atoms
|
||||
end interface
|
||||
|
||||
! Generic functions for the wrappers below {{{1
|
||||
|
||||
interface lammps_extract_global
|
||||
module procedure lammps_extract_global_i, &
|
||||
lammps_extract_global_dp
|
||||
end interface lammps_extract_global
|
||||
|
||||
interface lammps_extract_atom
|
||||
module procedure lammps_extract_atom_ia, &
|
||||
lammps_extract_atom_dpa, &
|
||||
lammps_extract_atom_dp2a
|
||||
end interface lammps_extract_atom
|
||||
|
||||
interface lammps_extract_compute
|
||||
module procedure lammps_extract_compute_dp, &
|
||||
lammps_extract_compute_dpa, &
|
||||
lammps_extract_compute_dp2a
|
||||
end interface lammps_extract_compute
|
||||
|
||||
interface lammps_extract_fix
|
||||
module procedure lammps_extract_fix_dp, &
|
||||
lammps_extract_fix_dpa, &
|
||||
lammps_extract_fix_dp2a
|
||||
end interface lammps_extract_fix
|
||||
|
||||
interface lammps_extract_variable
|
||||
module procedure lammps_extract_variable_dp, &
|
||||
lammps_extract_variable_dpa
|
||||
end interface lammps_extract_variable
|
||||
|
||||
interface lammps_gather_atoms
|
||||
module procedure lammps_gather_atoms_ia, lammps_gather_atoms_dpa
|
||||
end interface lammps_gather_atoms
|
||||
|
||||
interface lammps_scatter_atoms
|
||||
module procedure lammps_scatter_atoms_ia, lammps_scatter_atoms_dpa
|
||||
end interface lammps_scatter_atoms
|
||||
|
||||
contains !! Wrapper functions local to this module {{{1
|
||||
|
||||
subroutine lammps_open (command_line, communicator, ptr)
|
||||
character (len=*), intent(in) :: command_line
|
||||
integer, intent(in) :: communicator
|
||||
type (C_ptr) :: ptr
|
||||
integer (C_int) :: argc
|
||||
type (C_ptr), dimension(:), allocatable :: argv
|
||||
character (kind=C_char), dimension(len_trim(command_line)+1), target :: &
|
||||
c_command_line
|
||||
c_command_line = string2Cstring (command_line)
|
||||
call Cstring2argcargv (c_command_line, argc, argv)
|
||||
call lammps_open_wrapper (argc, argv, communicator, ptr)
|
||||
deallocate (argv)
|
||||
end subroutine lammps_open
|
||||
|
||||
!-----------------------------------------------------------------------------
|
||||
|
||||
subroutine lammps_open_no_mpi (command_line, ptr)
|
||||
character (len=*), intent(in) :: command_line
|
||||
type (C_ptr) :: ptr
|
||||
integer (C_int) :: argc
|
||||
type (C_ptr), dimension(:), allocatable :: argv
|
||||
character (kind=C_char), dimension(len_trim(command_line)+1), target :: &
|
||||
c_command_line
|
||||
c_command_line = string2Cstring (command_line)
|
||||
call Cstring2argcargv (c_command_line, argc, argv)
|
||||
call lammps_actual_open_no_mpi (argc, argv, ptr)
|
||||
deallocate (argv)
|
||||
end subroutine lammps_open_no_mpi
|
||||
|
||||
!-----------------------------------------------------------------------------
|
||||
|
||||
subroutine lammps_file (ptr, str)
|
||||
type (C_ptr) :: ptr
|
||||
character (len=*) :: str
|
||||
character (kind=C_char), dimension(len_trim(str)+1) :: Cstr
|
||||
Cstr = string2Cstring (str)
|
||||
call lammps_actual_file (ptr, Cstr)
|
||||
end subroutine lammps_file
|
||||
|
||||
!-----------------------------------------------------------------------------
|
||||
|
||||
subroutine lammps_command (ptr, str)
|
||||
type (C_ptr) :: ptr
|
||||
character (len=*) :: str
|
||||
character (kind=C_char), dimension(len_trim(str)+1) :: Cstr
|
||||
type (C_ptr) :: dummy
|
||||
Cstr = string2Cstring (str)
|
||||
dummy = lammps_actual_command (ptr, Cstr)
|
||||
end subroutine lammps_command
|
||||
|
||||
!-----------------------------------------------------------------------------
|
||||
|
||||
! lammps_extract_global {{{2
|
||||
function lammps_extract_global_Cptr (ptr, name) result (global)
|
||||
type (C_ptr) :: global
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: name
|
||||
character (kind=C_char), dimension(len_trim(name)+1) :: Cname
|
||||
Cname = string2Cstring (name)
|
||||
global = lammps_actual_extract_global (ptr, Cname)
|
||||
end function lammps_extract_global_Cptr
|
||||
subroutine lammps_extract_global_i (global, ptr, name)
|
||||
integer (C_int), pointer, intent(out) :: global
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: name
|
||||
type (C_ptr) :: Cptr
|
||||
Cptr = lammps_extract_global_Cptr (ptr, name)
|
||||
call C_F_pointer (Cptr, global)
|
||||
end subroutine lammps_extract_global_i
|
||||
subroutine lammps_extract_global_dp (global, ptr, name)
|
||||
real (C_double), pointer, intent(out) :: global
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: name
|
||||
type (C_ptr) :: Cptr
|
||||
Cptr = lammps_extract_global_Cptr (ptr, name)
|
||||
call C_F_pointer (Cptr, global)
|
||||
end subroutine lammps_extract_global_dp
|
||||
|
||||
!-----------------------------------------------------------------------------
|
||||
|
||||
! lammps_extract_atom {{{2
|
||||
function lammps_extract_atom_Cptr (ptr, name) result (atom)
|
||||
type (C_ptr) :: atom
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: name
|
||||
character (kind=C_char), dimension(len_trim(name)+1) :: Cname
|
||||
Cname = string2Cstring (name)
|
||||
atom = lammps_actual_extract_atom (ptr, Cname)
|
||||
end function lammps_extract_atom_Cptr
|
||||
subroutine lammps_extract_atom_ia (atom, ptr, name)
|
||||
integer (C_int), dimension(:), pointer, intent(out) :: atom
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: name
|
||||
type (C_ptr) :: Cptr
|
||||
integer (C_int), pointer :: nelements
|
||||
call lammps_extract_global_i (nelements, ptr, 'nlocal')
|
||||
Cptr = lammps_extract_atom_Cptr (ptr, name)
|
||||
call C_F_pointer (Cptr, atom, (/nelements/))
|
||||
end subroutine lammps_extract_atom_ia
|
||||
subroutine lammps_extract_atom_dpa (atom, ptr, name)
|
||||
real (C_double), dimension(:), pointer, intent(out) :: atom
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: name
|
||||
type (C_ptr) :: Cptr
|
||||
integer (C_int), pointer :: nlocal
|
||||
integer :: nelements
|
||||
real (C_double), dimension(:), pointer :: Fptr
|
||||
if ( name == 'mass' ) then
|
||||
nelements = lammps_get_ntypes (ptr) + 1
|
||||
else if ( name == 'x' .or. name == 'v' .or. name == 'f' .or. &
|
||||
name == 'mu' .or. name == 'omega' .or. name == 'torque' .or. &
|
||||
name == 'angmom' ) then
|
||||
! We should not be getting a rank-2 array here!
|
||||
call lammps_error_all (ptr, FLERR, 'You cannot extract those atom&
|
||||
& data (' // trim(name) // ') into a rank 1 array.')
|
||||
return
|
||||
else
|
||||
! Everything else we can get is probably nlocal units long
|
||||
call lammps_extract_global_i (nlocal, ptr, 'nlocal')
|
||||
nelements = nlocal
|
||||
end if
|
||||
Cptr = lammps_extract_atom_Cptr (ptr, name)
|
||||
call C_F_pointer (Cptr, Fptr, (/nelements/))
|
||||
if ( name == 'mass' ) then
|
||||
!atom(0:) => Fptr
|
||||
atom => Fptr
|
||||
else
|
||||
atom => Fptr
|
||||
end if
|
||||
end subroutine lammps_extract_atom_dpa
|
||||
subroutine lammps_extract_atom_dp2a (atom, ptr, name)
|
||||
real (C_double), dimension(:,:), pointer, intent(out) :: atom
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: name
|
||||
type (C_ptr) :: Cptr
|
||||
type (C_ptr), pointer, dimension(:) :: Catom
|
||||
integer (C_int), pointer :: nelements
|
||||
if ( name /= 'x' .and. name /= 'v' .and. name /= 'f' .and. &
|
||||
name /= 'mu' .and. name /= 'omega' .and. name /= 'tandque' .and. &
|
||||
name /= 'angmom' .and. name /= 'fexternal' ) then
|
||||
! We should not be getting a rank-2 array here!
|
||||
call lammps_error_all (ptr, FLERR, 'You cannot extract those atom&
|
||||
& data (' // trim(name) // ') into a rank 2 array.')
|
||||
return
|
||||
end if
|
||||
Cptr = lammps_extract_atom_Cptr (ptr, name)
|
||||
call lammps_extract_global_i (nelements, ptr, 'nlocal')
|
||||
! Catom will now be the array of void* pointers that the void** pointer
|
||||
! pointed to. Catom(1) is now the pointer to the first element.
|
||||
call C_F_pointer (Cptr, Catom, (/nelements/))
|
||||
! Now get the actual array, which has its shape transposed from what we
|
||||
! might think of it in C
|
||||
call C_F_pointer (Catom(1), atom, (/3, nelements/))
|
||||
end subroutine lammps_extract_atom_dp2a
|
||||
|
||||
!-----------------------------------------------------------------------------
|
||||
|
||||
! lammps_extract_compute {{{2
|
||||
function lammps_extract_compute_Cptr (ptr, id, style, type) result (compute)
|
||||
type (C_ptr) :: compute
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: id
|
||||
integer, intent(in) :: style, type
|
||||
integer (kind=C_int) :: Cstyle, Ctype
|
||||
character (kind=C_char), dimension(len_trim(id)+1) :: Cid
|
||||
Cid = string2Cstring (id)
|
||||
Cstyle = style
|
||||
Ctype = type
|
||||
compute = lammps_actual_extract_compute (ptr, Cid, Cstyle, Ctype)
|
||||
end function lammps_extract_compute_Cptr
|
||||
subroutine lammps_extract_compute_dp (compute, ptr, id, style, type)
|
||||
real (C_double), pointer, intent(out) :: compute
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: id
|
||||
integer, intent(in) :: style, type
|
||||
type (C_ptr) :: Cptr
|
||||
! The only valid values of (style,type) are (0,0) for scalar 'compute'
|
||||
if ( style /= 0 ) then
|
||||
call lammps_error_all (ptr, FLERR, 'You cannot pack per-atom/local&
|
||||
& data into a scalar.')
|
||||
return
|
||||
end if
|
||||
if ( type == 1 ) then
|
||||
call lammps_error_all (ptr, FLERR, 'You cannot extract a compute&
|
||||
& vector (rank 1) into a scalar.')
|
||||
return
|
||||
else if ( type == 2 ) then
|
||||
call lammps_error_all (ptr, FLERR, 'You cannot extract a compute&
|
||||
& array (rank 2) into a scalar.')
|
||||
return
|
||||
end if
|
||||
Cptr = lammps_extract_compute_Cptr (ptr, id, style, type)
|
||||
call C_F_pointer (Cptr, compute)
|
||||
end subroutine lammps_extract_compute_dp
|
||||
subroutine lammps_extract_compute_dpa (compute, ptr, id, style, type)
|
||||
real (C_double), dimension(:), pointer, intent(out) :: compute
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: id
|
||||
integer, intent(in) :: style, type
|
||||
type (C_ptr) :: Cptr
|
||||
integer :: nelements
|
||||
! Check for the correct dimensionality
|
||||
if ( type == 0 ) then
|
||||
call lammps_error_all (ptr, FLERR, 'You cannot extract a compute&
|
||||
& scalar (rank 0) into a rank 1 variable.')
|
||||
return
|
||||
else if ( type == 2 ) then
|
||||
call lammps_error_all (ptr, FLERR, 'You cannot extract a compute&
|
||||
& array (rank 2) into a rank 1 variable.')
|
||||
return
|
||||
end if
|
||||
nelements = lammps_extract_compute_vectorsize (ptr, id, style)
|
||||
Cptr = lammps_extract_compute_Cptr (ptr, id, style, type)
|
||||
call C_F_pointer (Cptr, compute, (/nelements/))
|
||||
end subroutine lammps_extract_compute_dpa
|
||||
subroutine lammps_extract_compute_dp2a (compute, ptr, id, style, type)
|
||||
real (C_double), dimension(:,:), pointer, intent(out) :: compute
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: id
|
||||
integer, intent(in) :: style, type
|
||||
type (C_ptr) :: Cptr
|
||||
type (C_ptr), pointer, dimension(:) :: Ccompute
|
||||
integer :: nr, nc
|
||||
! Check for the correct dimensionality
|
||||
if ( type == 0 ) then
|
||||
call lammps_error_all (ptr, FLERR, 'You cannot extract a compute&
|
||||
& scalar (rank 0) into a rank 2 variable.')
|
||||
return
|
||||
else if ( type == 1 ) then
|
||||
call lammps_error_all (ptr, FLERR, 'You cannot extract a compute&
|
||||
& array (rank 1) into a rank 2 variable.')
|
||||
return
|
||||
end if
|
||||
call lammps_extract_compute_arraysize (ptr, id, style, nr, nc)
|
||||
Cptr = lammps_extract_compute_Cptr (ptr, id, style, type)
|
||||
call C_F_pointer (Cptr, Ccompute, (/nr/))
|
||||
! Note that the matrix is transposed, from Fortran's perspective
|
||||
call C_F_pointer (Ccompute(1), compute, (/nc, nr/))
|
||||
end subroutine lammps_extract_compute_dp2a
|
||||
|
||||
!-----------------------------------------------------------------------------
|
||||
|
||||
! lammps_extract_fix {{{2
|
||||
function lammps_extract_fix_Cptr (ptr, id, style, type, i, j) &
|
||||
result (fix)
|
||||
type (C_ptr) :: fix
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: id
|
||||
integer, intent(in) :: style, type, i, j
|
||||
character (kind=C_char), dimension(len_trim(id)+1) :: Cid
|
||||
integer (kind=C_int) :: Cstyle, Ctype, Ci, Cj
|
||||
Cid = string2Cstring (id)
|
||||
Cstyle = style
|
||||
Ctype = type
|
||||
Ci = i - 1 ! This is for consistency with the values from f_ID[i],
|
||||
Cj = j - 1 ! which is different from what library.cpp uses!
|
||||
if ( (type >= 1 .and. Ci < 0) .or. &
|
||||
(type == 2 .and. (Ci < 0 .or. Cj < 0) ) ) then
|
||||
call lammps_error_all (ptr, FLERR, 'Index out of range in&
|
||||
& lammps_extract_fix')
|
||||
end if
|
||||
fix = lammps_actual_extract_fix (ptr, Cid, Cstyle, Ctype, Ci, Cj)
|
||||
end function lammps_extract_fix_Cptr
|
||||
subroutine lammps_extract_fix_dp (fix, ptr, id, style, type, i, j)
|
||||
real (C_double), intent(out) :: fix
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: id
|
||||
integer, intent(in) :: style, type, i, j
|
||||
type (C_ptr) :: Cptr
|
||||
real (C_double), pointer :: Fptr
|
||||
! Check for the correct dimensionality
|
||||
if ( style /= 0 ) then
|
||||
select case (type)
|
||||
case (0)
|
||||
call lammps_error_all (ptr, FLERR, 'There is no per-atom or local&
|
||||
& scalar data available from fixes.')
|
||||
case (1)
|
||||
call lammps_error_all (ptr, FLERR, 'You cannot extract a fix''s &
|
||||
&per-atom/local vector (rank 1) into a scalar.')
|
||||
case (2)
|
||||
call lammps_error_all (ptr, FLERR, 'You cannot extract a fix''s &
|
||||
&per-atom/local array (rank 2) into a scalar.')
|
||||
case default
|
||||
call lammps_error_all (ptr, FLERR, 'Invalid extract_fix style/&
|
||||
&type combination.')
|
||||
end select
|
||||
return
|
||||
end if
|
||||
Cptr = lammps_extract_fix_Cptr (ptr, id, style, type, i, j)
|
||||
call C_F_pointer (Cptr, Fptr)
|
||||
fix = Fptr
|
||||
nullify (Fptr)
|
||||
! Memory is only allocated for "global" fix variables
|
||||
if ( style == 0 ) call lammps_free (Cptr)
|
||||
end subroutine lammps_extract_fix_dp
|
||||
subroutine lammps_extract_fix_dpa (fix, ptr, id, style, type, i, j)
|
||||
real (C_double), dimension(:), pointer, intent(out) :: fix
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: id
|
||||
integer, intent(in) :: style, type, i, j
|
||||
type (C_ptr) :: Cptr
|
||||
integer :: fix_len
|
||||
! Check for the correct dimensionality
|
||||
if ( style == 0 ) then
|
||||
call lammps_error_all (ptr, FLERR, 'You can''t extract the&
|
||||
& whole vector from global fix data')
|
||||
return
|
||||
else if ( type == 0 ) then
|
||||
call lammps_error_all (ptr, FLERR, 'You can''t extract a fix&
|
||||
& scalar into a rank 1 variable')
|
||||
return
|
||||
else if ( type == 2 ) then
|
||||
call lammps_error_all (ptr, FLERR, 'You cannot extract a fix&
|
||||
& array into a rank 1 variable.')
|
||||
return
|
||||
else if ( type /= 1 ) then
|
||||
call lammps_error_all (ptr, FLERR, 'Invalid type for fix extraction.')
|
||||
return
|
||||
end if
|
||||
fix_len = lammps_extract_fix_vectorsize (ptr, id, style)
|
||||
call C_F_pointer (Cptr, fix, (/fix_len/))
|
||||
! Memory is only allocated for "global" fix variables, which we should
|
||||
! never get here, so no need to call lammps_free!
|
||||
end subroutine lammps_extract_fix_dpa
|
||||
subroutine lammps_extract_fix_dp2a (fix, ptr, id, style, type, i, j)
|
||||
real (C_double), dimension(:,:), pointer, intent(out) :: fix
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: id
|
||||
integer, intent(in) :: style, type, i, j
|
||||
type (C_ptr) :: Cptr
|
||||
type (C_ptr), pointer, dimension(:) :: Cfix
|
||||
integer :: nr, nc
|
||||
! Check for the correct dimensionality
|
||||
if ( style == 0 ) then
|
||||
call lammps_error_all (ptr, FLERR, 'It is not possible to extract the&
|
||||
& entire array from global fix data.')
|
||||
return
|
||||
else if ( type == 0 ) then
|
||||
call lammps_error_all (ptr, FLERR, 'You cannot extract a fix&
|
||||
& scalar (rank 0) into a rank 2 variable.')
|
||||
return
|
||||
else if ( type == 1 ) then
|
||||
call lammps_error_all (ptr, FLERR, 'You cannot extract a fix&
|
||||
& vector (rank 1) into a rank 2 variable.')
|
||||
return
|
||||
end if
|
||||
call lammps_extract_fix_arraysize (ptr, id, style, nr, nc)
|
||||
! Extract pointer to first element as Cfix(1)
|
||||
call C_F_pointer (Cptr, Cfix, (/nr/))
|
||||
! Now extract the array, which is transposed
|
||||
call C_F_pointer (Cfix(1), fix, (/nc, nr/))
|
||||
end subroutine lammps_extract_fix_dp2a
|
||||
|
||||
!-----------------------------------------------------------------------------
|
||||
|
||||
! lammps_extract_variable {{{2
|
||||
function lammps_extract_variable_Cptr (ptr, name, group) result (variable)
|
||||
type (C_ptr) :: ptr, variable
|
||||
character (len=*) :: name
|
||||
character (len=*), optional :: group
|
||||
character (kind=C_char), dimension(len_trim(name)+1) :: Cname
|
||||
character (kind=C_char), dimension(:), allocatable :: Cgroup
|
||||
Cname = string2Cstring (name)
|
||||
if ( present(group) ) then
|
||||
allocate (Cgroup(len_trim(group)+1))
|
||||
Cgroup = string2Cstring (group)
|
||||
else
|
||||
allocate (Cgroup(1))
|
||||
Cgroup(1) = C_NULL_CHAR
|
||||
end if
|
||||
variable = lammps_actual_extract_variable (ptr, Cname, Cgroup)
|
||||
deallocate (Cgroup)
|
||||
end function lammps_extract_variable_Cptr
|
||||
subroutine lammps_extract_variable_dp (variable, ptr, name, group)
|
||||
real (C_double), intent(out) :: variable
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: name
|
||||
character (len=*), intent(in), optional :: group
|
||||
type (C_ptr) :: Cptr
|
||||
real (C_double), pointer :: Fptr
|
||||
if ( present(group) ) then
|
||||
Cptr = lammps_extract_variable_Cptr (ptr, name, group)
|
||||
else
|
||||
Cptr = lammps_extract_variable_Cptr (ptr, name)
|
||||
end if
|
||||
call C_F_pointer (Cptr, Fptr)
|
||||
variable = Fptr
|
||||
nullify (Fptr)
|
||||
call lammps_free (Cptr)
|
||||
end subroutine lammps_extract_variable_dp
|
||||
subroutine lammps_extract_variable_dpa (variable, ptr, name, group)
|
||||
real (C_double), dimension(:), allocatable, intent(out) :: variable
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: name
|
||||
character (len=*), intent(in), optional :: group
|
||||
type (C_ptr) :: Cptr
|
||||
real (C_double), dimension(:), pointer :: Fptr
|
||||
integer :: natoms
|
||||
if ( present(group) ) then
|
||||
Cptr = lammps_extract_variable_Cptr (ptr, name, group)
|
||||
else
|
||||
Cptr = lammps_extract_variable_Cptr (ptr, name)
|
||||
end if
|
||||
natoms = lammps_get_natoms (ptr)
|
||||
allocate (variable(natoms))
|
||||
call C_F_pointer (Cptr, Fptr, (/natoms/))
|
||||
variable = Fptr
|
||||
nullify (Fptr)
|
||||
call lammps_free (Cptr)
|
||||
end subroutine lammps_extract_variable_dpa
|
||||
|
||||
!-------------------------------------------------------------------------2}}}
|
||||
|
||||
subroutine lammps_gather_atoms_ia (ptr, name, count, data)
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: name
|
||||
integer, intent(in) :: count
|
||||
integer, dimension(:), allocatable, intent(out) :: data
|
||||
type (C_ptr) :: Cdata
|
||||
integer (C_int), dimension(:), pointer :: Fdata
|
||||
integer (C_int) :: natoms
|
||||
character (kind=C_char), dimension(len_trim(name)+1) :: Cname
|
||||
integer (C_int), parameter :: Ctype = 0_C_int
|
||||
integer (C_int) :: Ccount
|
||||
natoms = lammps_get_natoms (ptr)
|
||||
Cname = string2Cstring (name)
|
||||
if ( count /= 1 .and. count /= 3 ) then
|
||||
call lammps_error_all (ptr, FLERR, 'lammps_gather_atoms requires&
|
||||
& count to be either 1 or 3')
|
||||
else
|
||||
Ccount = count
|
||||
end if
|
||||
allocate ( Fdata(count*natoms) )
|
||||
allocate ( data(count*natoms) )
|
||||
Cdata = C_loc (Fdata(1))
|
||||
call lammps_actual_gather_atoms (ptr, Cname, Ctype, Ccount, Cdata)
|
||||
data = Fdata
|
||||
deallocate (Fdata)
|
||||
end subroutine lammps_gather_atoms_ia
|
||||
subroutine lammps_gather_atoms_dpa (ptr, name, count, data)
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: name
|
||||
integer, intent(in) :: count
|
||||
double precision, dimension(:), allocatable, intent(out) :: data
|
||||
type (C_ptr) :: Cdata
|
||||
real (C_double), dimension(:), pointer :: Fdata
|
||||
integer (C_int) :: natoms
|
||||
character (kind=C_char), dimension(len_trim(name)+1) :: Cname
|
||||
integer (C_int), parameter :: Ctype = 1_C_int
|
||||
integer (C_int) :: Ccount
|
||||
natoms = lammps_get_natoms (ptr)
|
||||
Cname = string2Cstring (name)
|
||||
if ( count /= 1 .and. count /= 3 ) then
|
||||
call lammps_error_all (ptr, FLERR, 'lammps_gather_atoms requires&
|
||||
& count to be either 1 or 3')
|
||||
else
|
||||
Ccount = count
|
||||
end if
|
||||
allocate ( Fdata(count*natoms) )
|
||||
allocate ( data(count*natoms) )
|
||||
Cdata = C_loc (Fdata(1))
|
||||
call lammps_actual_gather_atoms (ptr, Cname, Ctype, Ccount, Cdata)
|
||||
data = Fdata(:)
|
||||
deallocate (Fdata)
|
||||
end subroutine lammps_gather_atoms_dpa
|
||||
|
||||
!-----------------------------------------------------------------------------
|
||||
|
||||
subroutine lammps_scatter_atoms_ia (ptr, name, data)
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: name
|
||||
integer, dimension(:), intent(in) :: data
|
||||
integer (kind=C_int) :: natoms, Ccount
|
||||
integer (kind=C_int), parameter :: Ctype = 0_C_int
|
||||
character (kind=C_char), dimension(len_trim(name)+1) :: Cname
|
||||
integer (C_int), dimension(size(data)), target :: Fdata
|
||||
type (C_ptr) :: Cdata
|
||||
natoms = lammps_get_natoms (ptr)
|
||||
Cname = string2Cstring (name)
|
||||
Ccount = size(data) / natoms
|
||||
if ( Ccount /= 1 .and. Ccount /= 3 ) &
|
||||
call lammps_error_all (ptr, FLERR, 'lammps_gather_atoms requires&
|
||||
& count to be either 1 or 3')
|
||||
Fdata = data
|
||||
Cdata = C_loc (Fdata(1))
|
||||
call lammps_actual_scatter_atoms (ptr, Cname, Ctype, Ccount, Cdata)
|
||||
end subroutine lammps_scatter_atoms_ia
|
||||
subroutine lammps_scatter_atoms_dpa (ptr, name, data)
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: name
|
||||
double precision, dimension(:), intent(in) :: data
|
||||
integer (kind=C_int) :: natoms, Ccount
|
||||
integer (kind=C_int), parameter :: Ctype = 1_C_int
|
||||
character (kind=C_char), dimension(len_trim(name)+1) :: Cname
|
||||
real (C_double), dimension(size(data)), target :: Fdata
|
||||
type (C_ptr) :: Cdata
|
||||
natoms = lammps_get_natoms (ptr)
|
||||
Cname = string2Cstring (name)
|
||||
Ccount = size(data) / natoms
|
||||
if ( Ccount /= 1 .and. Ccount /= 3 ) &
|
||||
call lammps_error_all (ptr, FLERR, 'lammps_gather_atoms requires&
|
||||
& count to be either 1 or 3')
|
||||
Fdata = data
|
||||
Cdata = C_loc (Fdata(1))
|
||||
call lammps_actual_scatter_atoms (ptr, Cname, Ctype, Ccount, Cdata)
|
||||
end subroutine lammps_scatter_atoms_dpa
|
||||
|
||||
!-----------------------------------------------------------------------------
|
||||
|
||||
function lammps_extract_compute_vectorsize (ptr, id, style) &
|
||||
result (vectorsize)
|
||||
integer :: vectorsize
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: id
|
||||
integer, intent(in) :: style
|
||||
integer (C_int) :: Cvectorsize, Cstyle
|
||||
character (kind=C_char), dimension(len_trim(id)+1) :: Cid
|
||||
Cid = string2Cstring (id)
|
||||
Cstyle = int(style, C_int)
|
||||
Cvectorsize = lammps_actual_extract_compute_vectorsize (ptr, Cid, Cstyle)
|
||||
vectorsize = int(Cvectorsize, kind(vectorsize))
|
||||
end function lammps_extract_compute_vectorsize
|
||||
|
||||
!-----------------------------------------------------------------------------
|
||||
|
||||
function lammps_extract_fix_vectorsize (ptr, id, style) &
|
||||
result (vectorsize)
|
||||
integer :: vectorsize
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: id
|
||||
integer, intent(in) :: style
|
||||
integer (C_int) :: Cvectorsize, Cstyle
|
||||
character (kind=C_char), dimension(len_trim(id)+1) :: Cid
|
||||
Cid = string2Cstring (id)
|
||||
Cstyle = int(style, C_int)
|
||||
Cvectorsize = lammps_actual_extract_fix_vectorsize (ptr, Cid, Cstyle)
|
||||
vectorsize = int(Cvectorsize, kind(vectorsize))
|
||||
end function lammps_extract_fix_vectorsize
|
||||
|
||||
!-----------------------------------------------------------------------------
|
||||
|
||||
subroutine lammps_extract_compute_arraysize (ptr, id, style, nrows, ncols)
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: id
|
||||
integer, intent(in) :: style
|
||||
integer, intent(out) :: nrows, ncols
|
||||
integer (C_int) :: Cstyle, Cnrows, Cncols
|
||||
character (kind=C_char), dimension(len_trim(id)+1) :: Cid
|
||||
Cid = string2Cstring (id)
|
||||
Cstyle = int (style, C_int)
|
||||
call lammps_actual_extract_compute_arraysize (ptr, Cid, Cstyle, &
|
||||
Cnrows, Cncols)
|
||||
nrows = int (Cnrows, kind(nrows))
|
||||
ncols = int (Cncols, kind(ncols))
|
||||
end subroutine lammps_extract_compute_arraysize
|
||||
|
||||
!-----------------------------------------------------------------------------
|
||||
|
||||
subroutine lammps_extract_fix_arraysize (ptr, id, style, nrows, ncols)
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: id
|
||||
integer, intent(in) :: style
|
||||
integer, intent(out) :: nrows, ncols
|
||||
integer (C_int) :: Cstyle, Cnrows, Cncols
|
||||
character (kind=C_char), dimension(len_trim(id)+1) :: Cid
|
||||
Cid = string2Cstring (id)
|
||||
Cstyle = int (style, kind(Cstyle))
|
||||
call lammps_actual_extract_fix_arraysize (ptr, Cid, Cstyle, &
|
||||
Cnrows, Cncols)
|
||||
nrows = int (Cnrows, kind(nrows))
|
||||
ncols = int (Cncols, kind(ncols))
|
||||
end subroutine lammps_extract_fix_arraysize
|
||||
|
||||
!-----------------------------------------------------------------------------
|
||||
|
||||
subroutine lammps_error_all (ptr, file, line, str)
|
||||
type (C_ptr), intent(in) :: ptr
|
||||
character (len=*), intent(in) :: file, str
|
||||
integer, intent(in) :: line
|
||||
character (kind=C_char), dimension(len_trim(file)+1) :: Cfile
|
||||
character (kind=C_char), dimension(len_trim(str)+1) :: Cstr
|
||||
integer (C_int) :: Cline
|
||||
Cline = int(line, kind(Cline))
|
||||
Cfile = string2Cstring (file)
|
||||
Cstr = string2Cstring (str)
|
||||
call lammps_actual_error_all (ptr, Cfile, Cline, Cstr)
|
||||
end subroutine lammps_error_all
|
||||
|
||||
!-----------------------------------------------------------------------------
|
||||
|
||||
! Locally defined helper functions {{{1
|
||||
|
||||
pure function string2Cstring (string) result (C_string)
|
||||
use, intrinsic :: ISO_C_binding, only : C_char, C_NULL_CHAR
|
||||
character (len=*), intent(in) :: string
|
||||
character (len=1, kind=C_char) :: C_string (len_trim(string)+1)
|
||||
integer :: i, n
|
||||
n = len_trim (string)
|
||||
forall (i = 1:n)
|
||||
C_string(i) = string(i:i)
|
||||
end forall
|
||||
C_string(n+1) = C_NULL_CHAR
|
||||
end function string2Cstring
|
||||
|
||||
!-----------------------------------------------------------------------------
|
||||
|
||||
subroutine Cstring2argcargv (Cstring, argc, argv)
|
||||
!! Converts a C-style string to argc and argv, that is, words in Cstring
|
||||
!! become C-style strings in argv. IMPORTANT: Cstring is modified by
|
||||
!! this routine! I would make Cstring local TO this routine and accept
|
||||
!! a Fortran-style string instead, but we run into scoping and
|
||||
!! allocation problems that way. This routine assumes the string is
|
||||
!! null-terminated, as all C-style strings must be.
|
||||
|
||||
character (kind=C_char), dimension(*), target, intent(inout) :: Cstring
|
||||
integer (C_int), intent(out) :: argc
|
||||
type (C_ptr), dimension(:), allocatable, intent(out) :: argv
|
||||
|
||||
integer :: StringStart, SpaceIndex, strlen, argnum
|
||||
|
||||
argc = 1_C_int
|
||||
|
||||
! Find the length of the string
|
||||
strlen = 1
|
||||
do while ( Cstring(strlen) /= C_NULL_CHAR )
|
||||
strlen = strlen + 1
|
||||
end do
|
||||
|
||||
! Find the number of non-escaped spaces
|
||||
SpaceIndex = 2
|
||||
do while ( SpaceIndex < strlen )
|
||||
if ( Cstring(SpaceIndex) == ' ' .and. &
|
||||
Cstring(SpaceIndex-1) /= '\' ) then
|
||||
argc = argc + 1_C_int
|
||||
! Find the next non-space character
|
||||
do while ( Cstring(SpaceIndex+1) == ' ')
|
||||
SpaceIndex = SpaceIndex + 1
|
||||
end do
|
||||
end if
|
||||
SpaceIndex = SpaceIndex + 1
|
||||
end do
|
||||
|
||||
! Now allocate memory for argv
|
||||
allocate (argv(argc))
|
||||
|
||||
! Now find the string starting and ending locations
|
||||
StringStart = 1
|
||||
SpaceIndex = 2
|
||||
argnum = 1
|
||||
do while ( SpaceIndex < strlen )
|
||||
if ( Cstring(SpaceIndex) == ' ' .and. &
|
||||
Cstring(SpaceIndex-1) /= '\' ) then
|
||||
! Found a real space => split strings and store this one
|
||||
Cstring(Spaceindex) = C_NULL_CHAR ! Replaces space with NULL
|
||||
argv(argnum) = C_loc(Cstring(StringStart))
|
||||
argnum = argnum + 1
|
||||
! Find the next non-space character
|
||||
do while ( Cstring(SpaceIndex+1) == ' ')
|
||||
SpaceIndex = SpaceIndex + 1
|
||||
end do
|
||||
StringStart = SpaceIndex + 1
|
||||
else if ( Cstring(SpaceIndex) == ' ' .and. &
|
||||
Cstring(SpaceIndex-1) == '\' ) then
|
||||
! Escaped space => remove backslash and move rest of array
|
||||
Cstring(SpaceIndex-1:strlen-1) = Cstring(SpaceIndex:strlen)
|
||||
strlen = strlen - 1 ! Last character is still C_NULL_CHAR
|
||||
end if
|
||||
SpaceIndex = SpaceIndex + 1
|
||||
end do
|
||||
! Now handle the last argument
|
||||
argv(argnum) = C_loc(Cstring(StringStart))
|
||||
|
||||
end subroutine Cstring2argcargv
|
||||
|
||||
! 1}}}
|
||||
|
||||
end module LAMMPS
|
||||
|
||||
! vim: foldmethod=marker tabstop=3 softtabstop=3 shiftwidth=3 expandtab
|
||||
33
examples/COUPLE/fortran3/README
Normal file
33
examples/COUPLE/fortran3/README
Normal file
@ -0,0 +1,33 @@
|
||||
This directory has an example of using a callback function to obtain
|
||||
forces from a fortran code for a LAMMPS simulation. The reader should
|
||||
refer to the README file in COUPLE/fortran2 before proceeding. Here,
|
||||
the LAMMPS.F90 file has been modified slightly and additional files
|
||||
named LAMMPS-wrapper2.h and LAMMPS-wrapper2.cpp have been included in
|
||||
order to supply wrapper functions to set the LAMMPS callback function
|
||||
and total energy.
|
||||
|
||||
In this example, the callback function is set to run the
|
||||
semi-empirical quantum code DFTB+ in serial and then read in the total
|
||||
energy, forces, and stress tensor from file. In this case, nlocal =
|
||||
the total number of atoms in the system, so particle positions can be
|
||||
read from the pos array directly, and DFTB+ forces can simply be
|
||||
included via the fext array. The user should take care in the case of
|
||||
a parallel calculation, where LAMMPS can assign different particules
|
||||
to each processor. For example, the user should use functions such as
|
||||
lammps_gather_atoms() and lammps_scatter_atoms() in the case where the
|
||||
fortran force calculating code requires the positions of all atoms,
|
||||
etc.
|
||||
|
||||
A few more important notes:
|
||||
|
||||
-The stress tensor from DFTB+ is passed in to LAMMPS via pointer.
|
||||
-Calling the subroutine lammps_set_callback() is required in order to set
|
||||
a pointer to the callback function in LAMMPS.
|
||||
-The subroutine lammps_set_user_energy() passes in the potential energy
|
||||
from DFTB+ to LAMMPS.
|
||||
|
||||
This example was created by Nir Goldman, whom you can contact with
|
||||
questions:
|
||||
|
||||
Nir Goldman, LLNL
|
||||
ngoldman@llnl.gov
|
||||
148
examples/COUPLE/fortran3/data.diamond
Normal file
148
examples/COUPLE/fortran3/data.diamond
Normal file
@ -0,0 +1,148 @@
|
||||
# Position data file
|
||||
|
||||
64 atoms
|
||||
1 atom types
|
||||
|
||||
0 7.134 xlo xhi
|
||||
0 7.134 ylo yhi
|
||||
0 7.134 zlo zhi
|
||||
|
||||
0.00000000 0.00000000 0.00000000 xy xz yz
|
||||
|
||||
Masses
|
||||
|
||||
1 12.010000
|
||||
|
||||
Atoms
|
||||
|
||||
1 1 0 0 0 0
|
||||
2 1 0 0.89175 0.89175 0.89175
|
||||
3 1 0 1.7835 1.7835 0
|
||||
4 1 0 2.67525 2.67525 0.89175
|
||||
5 1 0 0 1.7835 1.7835
|
||||
6 1 0 0.89175 2.67525 2.67525
|
||||
7 1 0 1.7835 0 1.7835
|
||||
8 1 0 2.67525 0.89175 2.67525
|
||||
9 1 0 0 0 3.567
|
||||
10 1 0 0.89175 0.89175 4.45875
|
||||
11 1 0 1.7835 1.7835 3.567
|
||||
12 1 0 2.67525 2.67525 4.45875
|
||||
13 1 0 0 1.7835 5.3505
|
||||
14 1 0 0.89175 2.67525 6.24225
|
||||
15 1 0 1.7835 0 5.3505
|
||||
16 1 0 2.67525 0.89175 6.24225
|
||||
17 1 0 0 3.567 0
|
||||
18 1 0 0.89175 4.45875 0.89175
|
||||
19 1 0 1.7835 5.3505 0
|
||||
20 1 0 2.67525 6.24225 0.89175
|
||||
21 1 0 0 5.3505 1.7835
|
||||
22 1 0 0.89175 6.24225 2.67525
|
||||
23 1 0 1.7835 3.567 1.7835
|
||||
24 1 0 2.67525 4.45875 2.67525
|
||||
25 1 0 0 3.567 3.567
|
||||
26 1 0 0.89175 4.45875 4.45875
|
||||
27 1 0 1.7835 5.3505 3.567
|
||||
28 1 0 2.67525 6.24225 4.45875
|
||||
29 1 0 0 5.3505 5.3505
|
||||
30 1 0 0.89175 6.24225 6.24225
|
||||
31 1 0 1.7835 3.567 5.3505
|
||||
32 1 0 2.67525 4.45875 6.24225
|
||||
33 1 0 3.567 0 0
|
||||
34 1 0 4.45875 0.89175 0.89175
|
||||
35 1 0 5.3505 1.7835 0
|
||||
36 1 0 6.24225 2.67525 0.89175
|
||||
37 1 0 3.567 1.7835 1.7835
|
||||
38 1 0 4.45875 2.67525 2.67525
|
||||
39 1 0 5.3505 0 1.7835
|
||||
40 1 0 6.24225 0.89175 2.67525
|
||||
41 1 0 3.567 0 3.567
|
||||
42 1 0 4.45875 0.89175 4.45875
|
||||
43 1 0 5.3505 1.7835 3.567
|
||||
44 1 0 6.24225 2.67525 4.45875
|
||||
45 1 0 3.567 1.7835 5.3505
|
||||
46 1 0 4.45875 2.67525 6.24225
|
||||
47 1 0 5.3505 0 5.3505
|
||||
48 1 0 6.24225 0.89175 6.24225
|
||||
49 1 0 3.567 3.567 0
|
||||
50 1 0 4.45875 4.45875 0.89175
|
||||
51 1 0 5.3505 5.3505 0
|
||||
52 1 0 6.24225 6.24225 0.89175
|
||||
53 1 0 3.567 5.3505 1.7835
|
||||
54 1 0 4.45875 6.24225 2.67525
|
||||
55 1 0 5.3505 3.567 1.7835
|
||||
56 1 0 6.24225 4.45875 2.67525
|
||||
57 1 0 3.567 3.567 3.567
|
||||
58 1 0 4.45875 4.45875 4.45875
|
||||
59 1 0 5.3505 5.3505 3.567
|
||||
60 1 0 6.24225 6.24225 4.45875
|
||||
61 1 0 3.567 5.3505 5.3505
|
||||
62 1 0 4.45875 6.24225 6.24225
|
||||
63 1 0 5.3505 3.567 5.3505
|
||||
64 1 0 6.24225 4.45875 6.24225
|
||||
|
||||
Velocities
|
||||
|
||||
1 -0.00733742 -0.0040297 -0.00315229
|
||||
2 -0.00788609 -0.00567535 -0.00199152
|
||||
3 -0.00239042 0.00710139 -0.00335049
|
||||
4 0.00678551 0.0019976 0.00219289
|
||||
5 0.00413717 0.00275709 0.000937637
|
||||
6 -0.00126313 0.00485636 0.00727862
|
||||
7 0.00337547 -0.00234623 -0.000922223
|
||||
8 -0.00792183 -0.00509186 -0.00104168
|
||||
9 0.00414091 0.00390285 0.000845961
|
||||
10 -0.000284543 0.0010771 -0.00458404
|
||||
11 -0.00394968 -0.00446363 -0.00361688
|
||||
12 0.00067088 -0.00655175 -0.00752464
|
||||
13 0.00306632 -0.00245545 -0.00183867
|
||||
14 -0.0082145 -0.00564127 0.000281191
|
||||
15 0.00504454 0.0045835 0.000495763
|
||||
16 0.0035767 0.00320441 -0.00486426
|
||||
17 0.00420597 0.00262005 -0.0049459
|
||||
18 0.00440579 -1.76783e-05 0.00449311
|
||||
19 -0.00406463 0.00613304 0.00285599
|
||||
20 0.00171215 -0.00517887 0.00124326
|
||||
21 0.0011118 0.00334129 -0.0015222
|
||||
22 -0.00838394 -0.00112906 -0.00353379
|
||||
23 -0.00578527 -0.00415501 0.00297043
|
||||
24 -0.00211466 0.000964108 -0.00716523
|
||||
25 -0.000204107 -0.00380986 0.00681648
|
||||
26 0.00677838 0.00540935 0.0044354
|
||||
27 -0.00266809 -0.00358382 -0.00241889
|
||||
28 -0.0003973 0.00236566 0.00558871
|
||||
29 0.000754103 0.00457797 0.000105531
|
||||
30 -0.00246049 0.00110428 0.00511088
|
||||
31 0.00248891 0.00623314 0.00461597
|
||||
32 -0.00509423 0.000570503 0.00720856
|
||||
33 -0.00244427 -0.00374384 0.00618767
|
||||
34 -0.000360752 -8.10558e-05 0.00314052
|
||||
35 0.00435313 -0.00630587 -0.0070309
|
||||
36 0.00651087 -0.00389833 3.72525e-05
|
||||
37 0.00631828 -0.00316064 0.00231522
|
||||
38 -0.00579624 -0.00345068 -0.000277486
|
||||
39 0.00483974 0.000715028 0.000206355
|
||||
40 -0.00388164 -0.00189242 -0.00554862
|
||||
41 0.00398115 0.00152915 0.00756919
|
||||
42 -0.000552263 0.00352025 -0.000246143
|
||||
43 -0.00800284 0.00555703 0.00425716
|
||||
44 -0.00734405 -0.00752512 0.00667173
|
||||
45 -0.00545636 0.00421035 0.00399552
|
||||
46 0.00480246 0.00621147 -0.00492715
|
||||
47 -0.00424168 0.00621818 -9.37733e-05
|
||||
48 -0.00649561 0.00612908 -0.0020753
|
||||
49 -0.0075007 -0.00384737 -0.00687913
|
||||
50 -0.00203903 -0.00764372 0.0023883
|
||||
51 0.00442642 0.00744072 -0.0049344
|
||||
52 -0.00280486 -0.00509128 -0.00678045
|
||||
53 0.00679491 0.00583493 0.00333875
|
||||
54 0.00574665 -0.00521074 0.00523475
|
||||
55 0.00305618 -0.00320094 0.00341297
|
||||
56 0.004304 0.000615544 -0.00668787
|
||||
57 0.00564532 0.00327373 0.00388611
|
||||
58 0.000676899 0.00210326 0.00495295
|
||||
59 0.000160781 -0.00744313 -0.00279828
|
||||
60 0.00623521 0.00371301 0.00178015
|
||||
61 0.00520759 0.000642669 0.00207913
|
||||
62 0.00398042 0.0046438 -0.00359978
|
||||
63 -0.00478071 -0.00304932 -0.00765125
|
||||
64 0.00282671 -0.00548392 -0.00692691
|
||||
16
examples/COUPLE/fortran3/in.simple
Normal file
16
examples/COUPLE/fortran3/in.simple
Normal file
@ -0,0 +1,16 @@
|
||||
units real
|
||||
atom_style charge
|
||||
atom_modify map array
|
||||
atom_modify sort 0 0.0
|
||||
read_data data.diamond
|
||||
neighbor 1.0 bin
|
||||
neigh_modify delay 0 every 5 check no
|
||||
fix 1 all nve
|
||||
fix 2 all external pf/callback 1 1
|
||||
|
||||
fix_modify 2 energy yes
|
||||
thermo_style custom step temp etotal ke pe lx ly lz pxx pyy pzz press
|
||||
|
||||
thermo 1
|
||||
timestep 0.5
|
||||
|
||||
45
examples/COUPLE/fortran3/makefile
Normal file
45
examples/COUPLE/fortran3/makefile
Normal file
@ -0,0 +1,45 @@
|
||||
SHELL = /bin/sh
|
||||
|
||||
# Path to LAMMPS extraction directory
|
||||
LAMMPS_ROOT = ../../..
|
||||
LAMMPS_SRC = $(LAMMPS_ROOT)/src
|
||||
|
||||
# Uncomment the line below if using the MPI stubs library
|
||||
MPI_STUBS = #-I$(LAMMPS_SRC)/STUBS
|
||||
|
||||
FC = mpif90 # replace with your Fortran compiler
|
||||
CXX = mpicc # replace with your C++ compiler
|
||||
|
||||
# Flags for Fortran compiler, C++ compiler, and C preprocessor, respectively
|
||||
FFLAGS = -O2 -fPIC
|
||||
CXXFLAGS = -O2 -fPIC
|
||||
CPPFLAGS = -DOMPI_SKIP_MPICXX=1 -DMPICH_SKIP_MPICXX
|
||||
|
||||
all : liblammps_fortran.a liblammps_fortran.so simpleF.x
|
||||
|
||||
liblammps_fortran.so : LAMMPS.o LAMMPS-wrapper.o LAMMPS-wrapper2.o
|
||||
$(FC) $(FFLAGS) -shared -o $@ $^
|
||||
|
||||
simpleF.x: simple.o LAMMPS.o LAMMPS-wrapper.o LAMMPS-wrapper2.o
|
||||
$(FC) $(FFLAGS) simple.o -o simpleF.x liblammps_fortran.a $(LAMMPS_SRC)/liblammps_mvapich.a -lstdc++ /usr/local/tools/fftw/lib/libfftw.a
|
||||
|
||||
liblammps_fortran.a : LAMMPS.o LAMMPS-wrapper.o LAMMPS-wrapper2.o
|
||||
$(AR) rs $@ $^
|
||||
|
||||
LAMMPS.o lammps.mod : LAMMPS.F90
|
||||
$(FC) $(CPPFLAGS) $(FFLAGS) -c $<
|
||||
|
||||
simple.o : simple.f90
|
||||
$(FC) $(FFLAGS) -c $<
|
||||
|
||||
LAMMPS-wrapper.o : LAMMPS-wrapper.cpp LAMMPS-wrapper.h
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -I$(LAMMPS_SRC) $(MPI_STUBS)
|
||||
|
||||
LAMMPS-wrapper2.o : LAMMPS-wrapper2.cpp LAMMPS-wrapper2.h
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -I$(LAMMPS_SRC) $(MPI_STUBS)
|
||||
|
||||
clean :
|
||||
$(RM) *.o *.mod liblammps_fortran.a liblammps_fortran.so
|
||||
|
||||
dist :
|
||||
tar -czvf fortran-interface-callback.tar.gz LAMMPS-wrapper.h LAMMPS-wrapper.cpp LAMMPS-wrapper2.h LAMMPS-wrapper2.cpp LAMMPS.F90 makefile README simple.f90
|
||||
114
examples/COUPLE/fortran3/simple.f90
Normal file
114
examples/COUPLE/fortran3/simple.f90
Normal file
@ -0,0 +1,114 @@
|
||||
module callback
|
||||
implicit none
|
||||
contains
|
||||
subroutine fortran_callback(lmp, timestep, nlocal, ids, c_pos, c_fext) &
|
||||
& bind(C, name='f_callback')
|
||||
use, intrinsic :: ISO_C_binding
|
||||
use LAMMPS
|
||||
implicit none
|
||||
type (C_ptr), value :: lmp
|
||||
integer(C_int64_t), intent(in), value :: timestep
|
||||
integer(C_int), intent(in), value :: nlocal
|
||||
real (C_double), dimension(:,:), pointer :: x
|
||||
type(c_ptr) :: c_pos, c_fext, c_ids
|
||||
double precision, pointer :: fext(:,:), pos(:,:)
|
||||
integer, intent(in) :: ids(nlocal)
|
||||
real (C_double), dimension(:), pointer :: virial => NULL()
|
||||
real (C_double) :: etot
|
||||
real(C_double), pointer :: ts_lmp
|
||||
double precision :: stress(3,3), ts_dftb
|
||||
integer :: natom , i
|
||||
real (C_double), parameter :: econv = 627.4947284155114 ! converts from Ha to
|
||||
double precision, parameter :: fconv = 1185.793095983065 ! converts from Ha/bohr to
|
||||
double precision, parameter :: autoatm = 2.9037166638E8
|
||||
double precision lx, ly, lz
|
||||
real (C_double), pointer :: boxxlo, boxxhi
|
||||
real (C_double), pointer :: boxylo, boxyhi
|
||||
real (C_double), pointer :: boxzlo, boxzhi
|
||||
double precision, parameter :: nktv2p = 68568.4149999999935972
|
||||
double precision :: volume
|
||||
type (C_ptr) :: Cptr
|
||||
type (C_ptr), pointer, dimension(:) :: Catom
|
||||
|
||||
call c_f_pointer(c_pos, pos, [3,nlocal])
|
||||
call c_f_pointer(c_fext, fext, [3,nlocal])
|
||||
call lammps_extract_global(boxxlo, lmp, 'boxxlo')
|
||||
call lammps_extract_global(boxxhi, lmp, 'boxxhi')
|
||||
call lammps_extract_global(boxylo, lmp, 'boxylo')
|
||||
call lammps_extract_global(boxyhi, lmp, 'boxyhi')
|
||||
call lammps_extract_global(boxzlo, lmp, 'boxzlo')
|
||||
call lammps_extract_global(boxzhi, lmp, 'boxzhi')
|
||||
lx = boxxhi - boxxlo
|
||||
ly = boxyhi - boxylo
|
||||
lz = boxzhi - boxzlo
|
||||
volume = lx*ly*lz
|
||||
open (unit = 10, status = 'replace', action = 'write', file='lammps.gen')
|
||||
write(10,*)nlocal,"S"
|
||||
write(10,*) "C"
|
||||
do i = 1, nlocal
|
||||
write(10,'(2I,3F15.6)')i,1,pos(:,ids(i))
|
||||
enddo
|
||||
write(10,*)"0.0 0.0 0.0"
|
||||
write(10,*)lx,0,0
|
||||
write(10,*)0,ly,0
|
||||
write(10,*)0,0,lz
|
||||
close(10)
|
||||
call system("./dftb+ > dftb.out")
|
||||
open (unit = 10, status = 'old', file = 'results.out')
|
||||
read(10,*)etot
|
||||
read(10,*)ts_dftb
|
||||
do i = 1, 3
|
||||
read(10,*)stress(i,:)
|
||||
enddo
|
||||
stress (:,:) = stress(:,:)*autoatm
|
||||
etot = etot*econv
|
||||
call lammps_extract_global(ts_lmp, lmp, 'TS_dftb')
|
||||
ts_lmp = ts_dftb
|
||||
do i = 1, nlocal
|
||||
read(10,*)fext(:,ids(i))
|
||||
fext(:,ids(i)) = fext(:,ids(i))*fconv
|
||||
enddo
|
||||
close(10)
|
||||
call lammps_set_user_energy (lmp, etot)
|
||||
call lammps_extract_atom (virial, lmp, 'virial')
|
||||
if (.not. associated(virial)) then
|
||||
print*,'virial pointer not associated.'
|
||||
STOP
|
||||
endif
|
||||
virial(1) = stress(1,1)/(nktv2p/volume)
|
||||
virial(2) = stress(2,2)/(nktv2p/volume)
|
||||
virial(3) = stress(3,3)/(nktv2p/volume)
|
||||
virial(4) = stress(1,2)/(nktv2p/volume)
|
||||
virial(5) = stress(1,3)/(nktv2p/volume)
|
||||
virial(6) = stress(2,3)/(nktv2p/volume)
|
||||
|
||||
end subroutine
|
||||
end module callback
|
||||
|
||||
|
||||
program simple_fortran_callback
|
||||
|
||||
use MPI
|
||||
use LAMMPS
|
||||
use callback
|
||||
use, intrinsic :: ISO_C_binding, only : C_double, C_ptr, C_int, C_FUNPTR
|
||||
implicit none
|
||||
type (C_ptr) :: lmp
|
||||
integer :: error, narg, me, nprocs
|
||||
|
||||
call MPI_Init (error)
|
||||
call MPI_Comm_rank (MPI_COMM_WORLD, me, error)
|
||||
call MPI_Comm_size (MPI_COMM_WORLD, nprocs, error)
|
||||
|
||||
call lammps_open_no_mpi ('lmp -log log.simple', lmp)
|
||||
call lammps_file (lmp, 'in.simple')
|
||||
call lammps_set_callback(lmp)
|
||||
|
||||
call lammps_command (lmp, 'run 10')
|
||||
call lammps_close (lmp)
|
||||
call MPI_Finalize (error)
|
||||
|
||||
|
||||
end program simple_fortran_callback
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ bond_coeff 1 10.0 1.2
|
||||
# need to preserve 1-3, 1-4 pairwise interactions during hard collisions
|
||||
|
||||
special_bonds lj/coul 0 1 1
|
||||
create_bonds all all 1 1.0 1.5
|
||||
create_bonds many all all 1 1.0 1.5
|
||||
|
||||
neighbor 0.3 bin
|
||||
neigh_modify delay 0 every 1 check yes
|
||||
|
||||
@ -32,7 +32,7 @@ pair_coeff 1 1 10.0 1.0 2.5
|
||||
bond_style harmonic
|
||||
bond_coeff 1 10.0 1.2
|
||||
|
||||
create_bonds all all 1 1.0 1.5
|
||||
create_bonds many all all 1 1.0 1.5
|
||||
|
||||
neighbor 0.3 bin
|
||||
neigh_modify delay 0 every 1 check yes
|
||||
|
||||
30
examples/meam/in.meamc
Normal file
30
examples/meam/in.meamc
Normal file
@ -0,0 +1,30 @@
|
||||
# Test of MEAM potential for SiC system
|
||||
|
||||
units metal
|
||||
boundary p p p
|
||||
|
||||
atom_style atomic
|
||||
|
||||
read_data data.meam
|
||||
|
||||
pair_style meam/c
|
||||
pair_coeff * * library.meam Si C SiC.meam Si C
|
||||
|
||||
neighbor 0.3 bin
|
||||
neigh_modify delay 10
|
||||
|
||||
fix 1 all nve
|
||||
thermo 10
|
||||
timestep 0.001
|
||||
|
||||
#dump 1 all atom 50 dump.meam
|
||||
|
||||
#dump 2 all image 10 image.*.jpg element element &
|
||||
# axes yes 0.8 0.02 view 60 -30
|
||||
#dump_modify 2 pad 3 element Si C
|
||||
|
||||
#dump 3 all movie 10 movie.mpg element element &
|
||||
# axes yes 0.8 0.02 view 60 -30
|
||||
#dump_modify 3 pad 3 element Si C
|
||||
|
||||
run 100
|
||||
79
examples/meam/in.meamc.shear
Normal file
79
examples/meam/in.meamc.shear
Normal file
@ -0,0 +1,79 @@
|
||||
# 3d metal shear simulation
|
||||
|
||||
units metal
|
||||
boundary s s p
|
||||
|
||||
atom_style atomic
|
||||
lattice fcc 3.52
|
||||
region box block 0 16.0 0 10.0 0 2.828427
|
||||
create_box 3 box
|
||||
|
||||
lattice fcc 3.52 orient x 1 0 0 orient y 0 1 1 orient z 0 -1 1 &
|
||||
origin 0.5 0 0
|
||||
create_atoms 1 box
|
||||
|
||||
pair_style meam/c
|
||||
pair_coeff * * library.meam Ni4 Ni.meam Ni4 Ni4 Ni4
|
||||
|
||||
neighbor 0.3 bin
|
||||
neigh_modify delay 5
|
||||
|
||||
region lower block INF INF INF 0.9 INF INF
|
||||
region upper block INF INF 6.1 INF INF INF
|
||||
group lower region lower
|
||||
group upper region upper
|
||||
group boundary union lower upper
|
||||
group mobile subtract all boundary
|
||||
|
||||
set group lower type 2
|
||||
set group upper type 3
|
||||
|
||||
# void
|
||||
|
||||
#region void cylinder z 8 5 2.5 INF INF
|
||||
#delete_atoms region void
|
||||
|
||||
# temp controllers
|
||||
|
||||
compute new3d mobile temp
|
||||
compute new2d mobile temp/partial 0 1 1
|
||||
|
||||
# equilibrate
|
||||
|
||||
velocity mobile create 300.0 5812775 temp new3d
|
||||
fix 1 all nve
|
||||
fix 2 boundary setforce 0.0 0.0 0.0
|
||||
|
||||
fix 3 mobile temp/rescale 10 300.0 300.0 10.0 1.0
|
||||
fix_modify 3 temp new3d
|
||||
|
||||
thermo 25
|
||||
thermo_modify temp new3d
|
||||
|
||||
timestep 0.001
|
||||
run 100
|
||||
|
||||
# shear
|
||||
|
||||
velocity upper set 1.0 0 0
|
||||
velocity mobile ramp vx 0.0 1.0 y 1.4 8.6 sum yes
|
||||
|
||||
unfix 3
|
||||
fix 3 mobile temp/rescale 10 300.0 300.0 10.0 1.0
|
||||
fix_modify 3 temp new2d
|
||||
|
||||
#dump 1 all atom 500 dump.meam.shear
|
||||
|
||||
#dump 2 all image 100 image.*.jpg type type &
|
||||
# axes yes 0.8 0.02 view 0 0 zoom 1.5 up 0 1 0 adiam 2.0
|
||||
#dump_modify 2 pad 4
|
||||
|
||||
#dump 3 all movie 100 movie.mpg type type &
|
||||
# axes yes 0.8 0.02 view 0 0 zoom 1.5 up 0 1 0 adiam 2.0
|
||||
#dump_modify 3 pad 4
|
||||
|
||||
thermo 100
|
||||
thermo_modify temp new2d
|
||||
|
||||
reset_timestep 0
|
||||
run 3000
|
||||
@ -1,4 +1,5 @@
|
||||
LAMMPS (5 Oct 2016)
|
||||
LAMMPS (19 May 2017)
|
||||
using 1 OpenMP thread(s) per MPI task
|
||||
# Test of MEAM potential for SiC system
|
||||
|
||||
units metal
|
||||
@ -34,13 +35,23 @@ timestep 0.001
|
||||
|
||||
run 100
|
||||
Neighbor list info ...
|
||||
2 neighbor list requests
|
||||
update every 1 steps, delay 10 steps, check yes
|
||||
max neighbors/atom: 2000, page size: 100000
|
||||
master list distance cutoff = 4.3
|
||||
ghost atom cutoff = 4.3
|
||||
binsize = 2.15 -> bins = 6 6 6
|
||||
Memory usage per processor = 7.39054 Mbytes
|
||||
binsize = 2.15, bins = 6 6 6
|
||||
2 neighbor lists, perpetual/occasional/extra = 2 0 0
|
||||
(1) pair meam, perpetual
|
||||
attributes: full, newton on
|
||||
pair build: full/bin/atomonly
|
||||
stencil: full/bin/3d
|
||||
bin: standard
|
||||
(2) pair meam, perpetual, half/full from (1)
|
||||
attributes: half, newton on
|
||||
pair build: halffull/newton
|
||||
stencil: none
|
||||
bin: none
|
||||
Per MPI rank memory allocation (min/avg/max) = 8.103 | 8.103 | 8.103 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press
|
||||
0 0 -636.38121 0 -636.38121 -76571.819
|
||||
10 1807.8862 -666.21959 0 -636.54126 -150571.49
|
||||
@ -53,20 +64,20 @@ Step Temp E_pair E_mol TotEng Press
|
||||
80 2126.0903 -671.43755 0 -636.53557 -97475.831
|
||||
90 2065.755 -670.4349 0 -636.52338 -95858.837
|
||||
100 2051.4553 -670.20799 0 -636.53122 -107068.9
|
||||
Loop time of 0.094512 on 1 procs for 100 steps with 128 atoms
|
||||
Loop time of 0.0864418 on 1 procs for 100 steps with 128 atoms
|
||||
|
||||
Performance: 91.417 ns/day, 0.263 hours/ns, 1058.067 timesteps/s
|
||||
99.4% CPU use with 1 MPI tasks x no OpenMP threads
|
||||
Performance: 99.952 ns/day, 0.240 hours/ns, 1156.848 timesteps/s
|
||||
99.6% CPU use with 1 MPI tasks x 1 OpenMP threads
|
||||
|
||||
MPI task timing breakdown:
|
||||
Section | min time | avg time | max time |%varavg| %total
|
||||
---------------------------------------------------------------
|
||||
Pair | 0.091268 | 0.091268 | 0.091268 | 0.0 | 96.57
|
||||
Neigh | 0.0021861 | 0.0021861 | 0.0021861 | 0.0 | 2.31
|
||||
Comm | 0.00059438 | 0.00059438 | 0.00059438 | 0.0 | 0.63
|
||||
Output | 9.0837e-05 | 9.0837e-05 | 9.0837e-05 | 0.0 | 0.10
|
||||
Modify | 0.00024438 | 0.00024438 | 0.00024438 | 0.0 | 0.26
|
||||
Other | | 0.000128 | | | 0.14
|
||||
Pair | 0.082592 | 0.082592 | 0.082592 | 0.0 | 95.55
|
||||
Neigh | 0.0028124 | 0.0028124 | 0.0028124 | 0.0 | 3.25
|
||||
Comm | 0.00049043 | 0.00049043 | 0.00049043 | 0.0 | 0.57
|
||||
Output | 0.00014329 | 0.00014329 | 0.00014329 | 0.0 | 0.17
|
||||
Modify | 0.00025415 | 0.00025415 | 0.00025415 | 0.0 | 0.29
|
||||
Other | | 0.0001497 | | | 0.17
|
||||
|
||||
Nlocal: 128 ave 128 max 128 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
@ -1,4 +1,5 @@
|
||||
LAMMPS (5 Oct 2016)
|
||||
LAMMPS (19 May 2017)
|
||||
using 1 OpenMP thread(s) per MPI task
|
||||
# Test of MEAM potential for SiC system
|
||||
|
||||
units metal
|
||||
@ -34,13 +35,23 @@ timestep 0.001
|
||||
|
||||
run 100
|
||||
Neighbor list info ...
|
||||
2 neighbor list requests
|
||||
update every 1 steps, delay 10 steps, check yes
|
||||
max neighbors/atom: 2000, page size: 100000
|
||||
master list distance cutoff = 4.3
|
||||
ghost atom cutoff = 4.3
|
||||
binsize = 2.15 -> bins = 6 6 6
|
||||
Memory usage per processor = 7.319 Mbytes
|
||||
binsize = 2.15, bins = 6 6 6
|
||||
2 neighbor lists, perpetual/occasional/extra = 2 0 0
|
||||
(1) pair meam, perpetual
|
||||
attributes: full, newton on
|
||||
pair build: full/bin/atomonly
|
||||
stencil: full/bin/3d
|
||||
bin: standard
|
||||
(2) pair meam, perpetual, half/full from (1)
|
||||
attributes: half, newton on
|
||||
pair build: halffull/newton
|
||||
stencil: none
|
||||
bin: none
|
||||
Per MPI rank memory allocation (min/avg/max) = 8.024 | 8.026 | 8.027 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press
|
||||
0 0 -636.38121 0 -636.38121 -76571.819
|
||||
10 1807.8862 -666.21959 0 -636.54126 -150571.49
|
||||
@ -53,20 +64,20 @@ Step Temp E_pair E_mol TotEng Press
|
||||
80 2126.0903 -671.43755 0 -636.53557 -97475.831
|
||||
90 2065.755 -670.4349 0 -636.52338 -95858.837
|
||||
100 2051.4553 -670.20799 0 -636.53122 -107068.9
|
||||
Loop time of 0.0350628 on 4 procs for 100 steps with 128 atoms
|
||||
Loop time of 0.0389078 on 4 procs for 100 steps with 128 atoms
|
||||
|
||||
Performance: 246.415 ns/day, 0.097 hours/ns, 2852.026 timesteps/s
|
||||
98.4% CPU use with 4 MPI tasks x no OpenMP threads
|
||||
Performance: 222.063 ns/day, 0.108 hours/ns, 2570.177 timesteps/s
|
||||
99.4% CPU use with 4 MPI tasks x 1 OpenMP threads
|
||||
|
||||
MPI task timing breakdown:
|
||||
Section | min time | avg time | max time |%varavg| %total
|
||||
---------------------------------------------------------------
|
||||
Pair | 0.030952 | 0.031776 | 0.032203 | 0.3 | 90.63
|
||||
Neigh | 0.00058937 | 0.00061423 | 0.00063896 | 0.1 | 1.75
|
||||
Comm | 0.0018125 | 0.0022421 | 0.0030777 | 1.1 | 6.39
|
||||
Output | 0.00018525 | 0.00019765 | 0.00021911 | 0.1 | 0.56
|
||||
Modify | 8.0585e-05 | 9.0539e-05 | 9.7752e-05 | 0.1 | 0.26
|
||||
Other | | 0.0001422 | | | 0.41
|
||||
Pair | 0.031958 | 0.033267 | 0.034691 | 0.6 | 85.50
|
||||
Neigh | 0.00079155 | 0.00086409 | 0.00098801 | 0.0 | 2.22
|
||||
Comm | 0.0025704 | 0.0041765 | 0.005573 | 1.9 | 10.73
|
||||
Output | 0.0002749 | 0.00029588 | 0.00033569 | 0.0 | 0.76
|
||||
Modify | 9.4891e-05 | 0.00010347 | 0.00011587 | 0.0 | 0.27
|
||||
Other | | 0.000201 | | | 0.52
|
||||
|
||||
Nlocal: 32 ave 36 max 30 min
|
||||
Histogram: 1 2 0 0 0 0 0 0 0 1
|
||||
@ -1,4 +1,5 @@
|
||||
LAMMPS (5 Oct 2016)
|
||||
LAMMPS (19 May 2017)
|
||||
using 1 OpenMP thread(s) per MPI task
|
||||
# 3d metal shear simulation
|
||||
|
||||
units metal
|
||||
@ -62,38 +63,48 @@ fix_modify 3 temp new3d
|
||||
|
||||
thermo 25
|
||||
thermo_modify temp new3d
|
||||
WARNING: Temperature for thermo pressure is not for group all (../thermo.cpp:474)
|
||||
WARNING: Temperature for thermo pressure is not for group all (../thermo.cpp:489)
|
||||
|
||||
timestep 0.001
|
||||
run 100
|
||||
Neighbor list info ...
|
||||
2 neighbor list requests
|
||||
update every 1 steps, delay 5 steps, check yes
|
||||
max neighbors/atom: 2000, page size: 100000
|
||||
master list distance cutoff = 4.3
|
||||
ghost atom cutoff = 4.3
|
||||
binsize = 2.15 -> bins = 27 17 5
|
||||
Memory usage per processor = 8.55725 Mbytes
|
||||
binsize = 2.15, bins = 27 17 5
|
||||
2 neighbor lists, perpetual/occasional/extra = 2 0 0
|
||||
(1) pair meam, perpetual
|
||||
attributes: full, newton on
|
||||
pair build: full/bin/atomonly
|
||||
stencil: full/bin/3d
|
||||
bin: standard
|
||||
(2) pair meam, perpetual, half/full from (1)
|
||||
attributes: half, newton on
|
||||
pair build: halffull/newton
|
||||
stencil: none
|
||||
bin: none
|
||||
Per MPI rank memory allocation (min/avg/max) = 9.788 | 9.788 | 9.788 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press Volume
|
||||
0 300 -8232.7767 0 -8179.1466 1386.6643 19547.02
|
||||
25 222.78953 -8188.1215 0 -8148.2941 9095.9008 19547.02
|
||||
50 300 -8149.7654 0 -8096.1353 10633.141 19684.382
|
||||
75 304.80657 -8163.4557 0 -8108.9665 7045.457 19759.745
|
||||
100 300 -8173.6884 0 -8120.0584 5952.521 19886.589
|
||||
Loop time of 1.72323 on 1 procs for 100 steps with 1912 atoms
|
||||
Loop time of 1.58103 on 1 procs for 100 steps with 1912 atoms
|
||||
|
||||
Performance: 5.014 ns/day, 4.787 hours/ns, 58.031 timesteps/s
|
||||
99.8% CPU use with 1 MPI tasks x no OpenMP threads
|
||||
Performance: 5.465 ns/day, 4.392 hours/ns, 63.250 timesteps/s
|
||||
99.6% CPU use with 1 MPI tasks x 1 OpenMP threads
|
||||
|
||||
MPI task timing breakdown:
|
||||
Section | min time | avg time | max time |%varavg| %total
|
||||
---------------------------------------------------------------
|
||||
Pair | 1.7026 | 1.7026 | 1.7026 | 0.0 | 98.80
|
||||
Neigh | 0.014496 | 0.014496 | 0.014496 | 0.0 | 0.84
|
||||
Comm | 0.0015783 | 0.0015783 | 0.0015783 | 0.0 | 0.09
|
||||
Output | 6.0081e-05 | 6.0081e-05 | 6.0081e-05 | 0.0 | 0.00
|
||||
Modify | 0.0034628 | 0.0034628 | 0.0034628 | 0.0 | 0.20
|
||||
Other | | 0.00101 | | | 0.06
|
||||
Pair | 1.5561 | 1.5561 | 1.5561 | 0.0 | 98.42
|
||||
Neigh | 0.018544 | 0.018544 | 0.018544 | 0.0 | 1.17
|
||||
Comm | 0.0013864 | 0.0013864 | 0.0013864 | 0.0 | 0.09
|
||||
Output | 0.00011396 | 0.00011396 | 0.00011396 | 0.0 | 0.01
|
||||
Modify | 0.0038245 | 0.0038245 | 0.0038245 | 0.0 | 0.24
|
||||
Other | | 0.001096 | | | 0.07
|
||||
|
||||
Nlocal: 1912 ave 1912 max 1912 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
@ -128,11 +139,11 @@ fix_modify 3 temp new2d
|
||||
|
||||
thermo 100
|
||||
thermo_modify temp new2d
|
||||
WARNING: Temperature for thermo pressure is not for group all (../thermo.cpp:474)
|
||||
WARNING: Temperature for thermo pressure is not for group all (../thermo.cpp:489)
|
||||
|
||||
reset_timestep 0
|
||||
run 3000
|
||||
Memory usage per processor = 8.73384 Mbytes
|
||||
Per MPI rank memory allocation (min/avg/max) = 9.964 | 9.964 | 9.964 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press Volume
|
||||
0 300.39988 -8173.6884 0 -8137.8874 4992.9811 19894.297
|
||||
100 292.06374 -8177.7096 0 -8142.9021 2568.3762 19871.53
|
||||
@ -144,53 +155,53 @@ Step Temp E_pair E_mol TotEng Press Volume
|
||||
700 300 -8148.1328 0 -8112.3794 3506.9234 20435.302
|
||||
800 300 -8139.1821 0 -8103.4288 3628.3957 20509.519
|
||||
900 305.03425 -8126.7734 0 -8090.4201 5316.2206 20638.992
|
||||
1000 304.00321 -8112.1616 0 -8075.9311 7441.9639 20767.243
|
||||
1100 304.14051 -8096.5041 0 -8060.2573 9646.698 20888.167
|
||||
1200 302.78461 -8080.5931 0 -8044.5079 11516.21 20995.917
|
||||
1300 308.67046 -8061.6724 0 -8024.8857 11496.487 21130.013
|
||||
1400 309.83019 -8046.2701 0 -8009.3452 12926.847 21247.271
|
||||
1500 300 -8035.0322 0 -7999.2789 15346.188 21370.637
|
||||
1600 300 -8030.6678 0 -7994.9144 14802.342 21496.446
|
||||
1700 300 -8024.5988 0 -7988.8454 13177.445 21611.262
|
||||
1800 300 -8023.045 0 -7987.2916 10240.041 21740.735
|
||||
1900 300 -8028.2797 0 -7992.5263 6912.1441 21866.544
|
||||
2000 300 -8036.4487 0 -8000.6953 3561.8365 21977.695
|
||||
2100 300 -8037.8249 0 -8002.0715 2879.2618 22109.611
|
||||
2200 300 -8033.6682 0 -7997.9148 4936.3695 22224.427
|
||||
2300 304.49349 -8033.4561 0 -7997.1673 5593.0915 22356.343
|
||||
2400 300 -8033.2969 0 -7997.5436 7537.0891 22473.601
|
||||
2500 300 -8033.1874 0 -7997.4341 11476.447 22598.189
|
||||
2600 307.77395 -8026.9234 0 -7990.2436 15758.81 22720.333
|
||||
2700 300 -8021.1736 0 -7985.4203 17948.896 22832.706
|
||||
2800 300 -8017.0863 0 -7981.3329 17154.618 22957.293
|
||||
2900 300 -8012.0514 0 -7976.298 13224.292 23089.209
|
||||
3000 304.58031 -8008.1654 0 -7971.8661 8572.9227 23211.354
|
||||
Loop time of 55.136 on 1 procs for 3000 steps with 1912 atoms
|
||||
1000 304.00321 -8112.1616 0 -8075.9311 7441.9638 20767.243
|
||||
1100 304.14047 -8096.5041 0 -8060.2573 9646.6976 20888.167
|
||||
1200 302.78457 -8080.5931 0 -8044.5079 11516.209 20995.917
|
||||
1300 308.67054 -8061.6724 0 -8024.8857 11496.479 21130.013
|
||||
1400 309.8301 -8046.27 0 -8009.3452 12926.835 21247.271
|
||||
1500 300 -8035.0321 0 -7999.2788 15346.455 21370.637
|
||||
1600 300 -8030.6657 0 -7994.9123 14802.869 21496.446
|
||||
1700 300 -8024.5251 0 -7988.7718 13176.923 21611.262
|
||||
1800 300 -8022.9963 0 -7987.243 10260.665 21741.956
|
||||
1900 300 -8028.0522 0 -7992.2988 6955.1367 21867.765
|
||||
2000 300 -8037.2708 0 -8001.5175 3520.3749 21987.467
|
||||
2100 300 -8035.9945 0 -8000.2412 3237.6121 22109.611
|
||||
2200 300 -8036.1882 0 -8000.4348 4295.1386 22223.205
|
||||
2300 300 -8032.7689 0 -7997.0155 6231.2346 22355.121
|
||||
2400 300 -8034.6621 0 -7998.9088 8585.3799 22468.716
|
||||
2500 300 -8031.7774 0 -7996.0241 11627.871 22587.196
|
||||
2600 300 -8024.032 0 -7988.2786 16254.69 22716.669
|
||||
2700 308.64215 -8017.407 0 -7980.6237 18440.226 22835.149
|
||||
2800 300 -8015.7348 0 -7979.9814 17601.716 22957.293
|
||||
2900 305.82558 -8013.7448 0 -7977.2972 14123.494 23089.209
|
||||
3000 300 -8011.0289 0 -7975.2755 9957.2884 23205.247
|
||||
Loop time of 51.9315 on 1 procs for 3000 steps with 1912 atoms
|
||||
|
||||
Performance: 4.701 ns/day, 5.105 hours/ns, 54.411 timesteps/s
|
||||
99.9% CPU use with 1 MPI tasks x no OpenMP threads
|
||||
Performance: 4.991 ns/day, 4.808 hours/ns, 57.768 timesteps/s
|
||||
99.7% CPU use with 1 MPI tasks x 1 OpenMP threads
|
||||
|
||||
MPI task timing breakdown:
|
||||
Section | min time | avg time | max time |%varavg| %total
|
||||
---------------------------------------------------------------
|
||||
Pair | 54.317 | 54.317 | 54.317 | -nan | 98.51
|
||||
Neigh | 0.63189 | 0.63189 | 0.63189 | 0.0 | 1.15
|
||||
Comm | 0.051245 | 0.051245 | 0.051245 | 0.0 | 0.09
|
||||
Output | 0.0005548 | 0.0005548 | 0.0005548 | 0.0 | 0.00
|
||||
Modify | 0.10452 | 0.10452 | 0.10452 | 0.0 | 0.19
|
||||
Other | | 0.03128 | | | 0.06
|
||||
Pair | 50.918 | 50.918 | 50.918 | 0.0 | 98.05
|
||||
Neigh | 0.81033 | 0.81033 | 0.81033 | 0.0 | 1.56
|
||||
Comm | 0.047331 | 0.047331 | 0.047331 | 0.0 | 0.09
|
||||
Output | 0.0011976 | 0.0011976 | 0.0011976 | 0.0 | 0.00
|
||||
Modify | 0.11889 | 0.11889 | 0.11889 | 0.0 | 0.23
|
||||
Other | | 0.03606 | | | 0.07
|
||||
|
||||
Nlocal: 1912 ave 1912 max 1912 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Nghost: 1667 ave 1667 max 1667 min
|
||||
Nghost: 1672 ave 1672 max 1672 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Neighs: 23365 ave 23365 max 23365 min
|
||||
Neighs: 23557 ave 23557 max 23557 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
FullNghs: 46730 ave 46730 max 46730 min
|
||||
FullNghs: 47114 ave 47114 max 47114 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
|
||||
Total # of neighbors = 46730
|
||||
Ave neighs/atom = 24.4404
|
||||
Total # of neighbors = 47114
|
||||
Ave neighs/atom = 24.6412
|
||||
Neighbor list builds = 221
|
||||
Dangerous builds = 0
|
||||
Total wall time: 0:00:56
|
||||
Total wall time: 0:00:53
|
||||
@ -1,4 +1,5 @@
|
||||
LAMMPS (5 Oct 2016)
|
||||
LAMMPS (19 May 2017)
|
||||
using 1 OpenMP thread(s) per MPI task
|
||||
# 3d metal shear simulation
|
||||
|
||||
units metal
|
||||
@ -62,38 +63,48 @@ fix_modify 3 temp new3d
|
||||
|
||||
thermo 25
|
||||
thermo_modify temp new3d
|
||||
WARNING: Temperature for thermo pressure is not for group all (../thermo.cpp:474)
|
||||
WARNING: Temperature for thermo pressure is not for group all (../thermo.cpp:489)
|
||||
|
||||
timestep 0.001
|
||||
run 100
|
||||
Neighbor list info ...
|
||||
2 neighbor list requests
|
||||
update every 1 steps, delay 5 steps, check yes
|
||||
max neighbors/atom: 2000, page size: 100000
|
||||
master list distance cutoff = 4.3
|
||||
ghost atom cutoff = 4.3
|
||||
binsize = 2.15 -> bins = 27 17 5
|
||||
Memory usage per processor = 7.74146 Mbytes
|
||||
binsize = 2.15, bins = 27 17 5
|
||||
2 neighbor lists, perpetual/occasional/extra = 2 0 0
|
||||
(1) pair meam, perpetual
|
||||
attributes: full, newton on
|
||||
pair build: full/bin/atomonly
|
||||
stencil: full/bin/3d
|
||||
bin: standard
|
||||
(2) pair meam, perpetual, half/full from (1)
|
||||
attributes: half, newton on
|
||||
pair build: halffull/newton
|
||||
stencil: none
|
||||
bin: none
|
||||
Per MPI rank memory allocation (min/avg/max) = 8.954 | 8.957 | 8.959 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press Volume
|
||||
0 300 -8232.7767 0 -8179.1466 1386.6643 19547.02
|
||||
25 221.59546 -8187.6813 0 -8148.0673 9100.4509 19547.02
|
||||
50 300 -8150.0685 0 -8096.4384 10317.407 19685.743
|
||||
75 307.76021 -8164.6669 0 -8109.6496 6289.7138 19757.814
|
||||
100 300 -8176.5141 0 -8122.884 4162.2559 19873.327
|
||||
Loop time of 0.469502 on 4 procs for 100 steps with 1912 atoms
|
||||
Loop time of 0.482293 on 4 procs for 100 steps with 1912 atoms
|
||||
|
||||
Performance: 18.402 ns/day, 1.304 hours/ns, 212.992 timesteps/s
|
||||
99.7% CPU use with 4 MPI tasks x no OpenMP threads
|
||||
Performance: 17.914 ns/day, 1.340 hours/ns, 207.343 timesteps/s
|
||||
98.7% CPU use with 4 MPI tasks x 1 OpenMP threads
|
||||
|
||||
MPI task timing breakdown:
|
||||
Section | min time | avg time | max time |%varavg| %total
|
||||
---------------------------------------------------------------
|
||||
Pair | 0.44052 | 0.45213 | 0.45813 | 1.0 | 96.30
|
||||
Neigh | 0.0036478 | 0.0037832 | 0.003854 | 0.1 | 0.81
|
||||
Comm | 0.0055377 | 0.011533 | 0.02316 | 6.5 | 2.46
|
||||
Output | 9.0837e-05 | 9.8228e-05 | 0.00011325 | 0.1 | 0.02
|
||||
Modify | 0.00098062 | 0.0010158 | 0.0010564 | 0.1 | 0.22
|
||||
Other | | 0.0009408 | | | 0.20
|
||||
Pair | 0.44374 | 0.45604 | 0.46922 | 1.4 | 94.56
|
||||
Neigh | 0.0047338 | 0.0049097 | 0.0051899 | 0.2 | 1.02
|
||||
Comm | 0.0054841 | 0.019044 | 0.031472 | 6.9 | 3.95
|
||||
Output | 0.00012755 | 0.00013644 | 0.00015831 | 0.0 | 0.03
|
||||
Modify | 0.0011139 | 0.0011852 | 0.0012643 | 0.2 | 0.25
|
||||
Other | | 0.0009753 | | | 0.20
|
||||
|
||||
Nlocal: 478 ave 492 max 465 min
|
||||
Histogram: 2 0 0 0 0 0 0 0 1 1
|
||||
@ -128,11 +139,11 @@ fix_modify 3 temp new2d
|
||||
|
||||
thermo 100
|
||||
thermo_modify temp new2d
|
||||
WARNING: Temperature for thermo pressure is not for group all (../thermo.cpp:474)
|
||||
WARNING: Temperature for thermo pressure is not for group all (../thermo.cpp:489)
|
||||
|
||||
reset_timestep 0
|
||||
run 3000
|
||||
Memory usage per processor = 7.78572 Mbytes
|
||||
Per MPI rank memory allocation (min/avg/max) = 8.999 | 9.002 | 9.005 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press Volume
|
||||
0 295.32113 -8176.5141 0 -8141.3183 3169.3113 19886.93
|
||||
100 292.00251 -8176.5358 0 -8141.7356 -825.04802 19918.765
|
||||
@ -144,53 +155,53 @@ Step Temp E_pair E_mol TotEng Press Volume
|
||||
700 296.44479 -8149.7914 0 -8114.4618 1985.4155 20421.046
|
||||
800 307.75738 -8139.1649 0 -8102.487 4319.078 20513.183
|
||||
900 304.61422 -8126.9246 0 -8090.6214 6654.0963 20640.213
|
||||
1000 300 -8113.8464 0 -8078.0931 7760.1242 20768.465
|
||||
1100 300.17874 -8097.7469 0 -8061.9722 8438.1263 20874.731
|
||||
1200 306.01444 -8083.3367 0 -8046.8665 10835.585 20994.432
|
||||
1000 300 -8113.8464 0 -8078.0931 7760.1239 20768.465
|
||||
1100 300.17873 -8097.7469 0 -8061.9722 8438.126 20874.731
|
||||
1200 306.01441 -8083.3367 0 -8046.8665 10835.586 20994.432
|
||||
1300 300 -8067.022 0 -8031.2686 11216.067 21126.348
|
||||
1400 300 -8053.223 0 -8017.4697 10570.21 21253.378
|
||||
1500 300 -8043.4848 0 -8007.7314 11360.829 21375.523
|
||||
1600 300 -8034.6216 0 -7998.8683 11371.642 21498.889
|
||||
1700 300 -8028.6774 0 -7992.924 9595.8772 21613.705
|
||||
1800 300 -8033.0808 0 -7997.3274 8767.6261 21743.178
|
||||
1900 303.30302 -8035.1958 0 -7999.0488 8059.5152 21859.215
|
||||
2000 300 -8025.0857 0 -7989.3323 9308.9938 21980.138
|
||||
2100 300 -8041.5796 0 -8005.8263 6656.0066 22108.39
|
||||
2200 300 -8039.6315 0 -8003.8781 7532.9687 22226.87
|
||||
2300 300 -8053.203 0 -8017.4497 8466.9094 22356.343
|
||||
2400 300 -8050.9154 0 -8015.162 11784.136 22467.494
|
||||
2500 300 -8037.6394 0 -8001.886 16464.786 22588.417
|
||||
2600 300 -8030.9221 0 -7995.1688 16807.326 22719.112
|
||||
2700 300 -8025.2102 0 -7989.4569 13729.61 22837.592
|
||||
2800 300 -8014.5312 0 -7978.7779 6784.6283 22953.629
|
||||
2900 300 -8007.4768 0 -7971.7234 1362.3131 23084.324
|
||||
3000 300 -7994.5614 0 -7958.808 -1726.5273 23194.254
|
||||
Loop time of 14.8108 on 4 procs for 3000 steps with 1912 atoms
|
||||
1400 300 -8053.223 0 -8017.4697 10570.206 21253.378
|
||||
1500 300 -8043.4849 0 -8007.7315 11360.766 21375.523
|
||||
1600 300 -8034.621 0 -7998.8676 11371.584 21498.889
|
||||
1700 300 -8028.6783 0 -7992.925 9596.524 21613.705
|
||||
1800 300 -8033.0818 0 -7997.3285 8767.2651 21743.178
|
||||
1900 303.18912 -8035.194 0 -7999.0606 8059.9558 21859.215
|
||||
2000 300 -8025.0327 0 -7989.2794 9305.7521 21980.138
|
||||
2100 300 -8041.4626 0 -8005.7092 6623.8789 22108.39
|
||||
2200 300 -8040.3133 0 -8004.5599 7512.9368 22225.648
|
||||
2300 300 -8055.6567 0 -8019.9033 8281.354 22344.128
|
||||
2400 304.05922 -8050.289 0 -8014.0518 11964.826 22476.044
|
||||
2500 305.75646 -8037.0481 0 -8000.6087 16594.032 22595.746
|
||||
2600 307.71105 -8031.2253 0 -7994.5529 18381.745 22708.119
|
||||
2700 307.397 -8026.5338 0 -7989.8988 13944.653 22829.042
|
||||
2800 309.3455 -8020.2305 0 -7983.3634 7037.4046 22954.851
|
||||
2900 301.2859 -8010.4731 0 -7974.5665 3843.8972 23072.109
|
||||
3000 303.29908 -8000.0395 0 -7963.8929 364.90172 23207.69
|
||||
Loop time of 14.5278 on 4 procs for 3000 steps with 1912 atoms
|
||||
|
||||
Performance: 17.501 ns/day, 1.371 hours/ns, 202.555 timesteps/s
|
||||
99.8% CPU use with 4 MPI tasks x no OpenMP threads
|
||||
Performance: 17.842 ns/day, 1.345 hours/ns, 206.500 timesteps/s
|
||||
99.4% CPU use with 4 MPI tasks x 1 OpenMP threads
|
||||
|
||||
MPI task timing breakdown:
|
||||
Section | min time | avg time | max time |%varavg| %total
|
||||
---------------------------------------------------------------
|
||||
Pair | 14.05 | 14.237 | 14.332 | 2.9 | 96.12
|
||||
Neigh | 0.1592 | 0.16414 | 0.1671 | 0.8 | 1.11
|
||||
Comm | 0.26002 | 0.35589 | 0.54696 | 18.8 | 2.40
|
||||
Output | 0.00061679 | 0.00065172 | 0.0007441 | 0.2 | 0.00
|
||||
Modify | 0.02895 | 0.030174 | 0.03104 | 0.5 | 0.20
|
||||
Other | | 0.02338 | | | 0.16
|
||||
Pair | 13.872 | 13.929 | 13.998 | 1.4 | 95.88
|
||||
Neigh | 0.20891 | 0.21114 | 0.21272 | 0.3 | 1.45
|
||||
Comm | 0.25364 | 0.32377 | 0.37706 | 8.9 | 2.23
|
||||
Output | 0.0011427 | 0.0012097 | 0.0013931 | 0.3 | 0.01
|
||||
Modify | 0.033687 | 0.033991 | 0.034694 | 0.2 | 0.23
|
||||
Other | | 0.02871 | | | 0.20
|
||||
|
||||
Nlocal: 478 ave 509 max 448 min
|
||||
Histogram: 2 0 0 0 0 0 0 0 0 2
|
||||
Nghost: 799.25 ave 844 max 756 min
|
||||
Histogram: 1 1 0 0 0 0 0 1 0 1
|
||||
Neighs: 5813.25 ave 6081 max 5602 min
|
||||
Histogram: 2 0 0 0 0 0 1 0 0 1
|
||||
FullNghs: 11626.5 ave 12151 max 11205 min
|
||||
Histogram: 1 1 0 0 0 0 1 0 0 1
|
||||
Nlocal: 478 ave 509 max 445 min
|
||||
Histogram: 1 1 0 0 0 0 0 0 1 1
|
||||
Nghost: 804 ave 845 max 759 min
|
||||
Histogram: 1 1 0 0 0 0 0 0 1 1
|
||||
Neighs: 5827 ave 6177 max 5496 min
|
||||
Histogram: 1 0 0 1 0 1 0 0 0 1
|
||||
FullNghs: 11654 ave 12330 max 11039 min
|
||||
Histogram: 1 0 0 1 0 1 0 0 0 1
|
||||
|
||||
Total # of neighbors = 46506
|
||||
Ave neighs/atom = 24.3232
|
||||
Neighbor list builds = 225
|
||||
Total # of neighbors = 46616
|
||||
Ave neighs/atom = 24.3808
|
||||
Neighbor list builds = 223
|
||||
Dangerous builds = 0
|
||||
Total wall time: 0:00:15
|
||||
95
examples/meam/log.19May17.meamc.g++.1
Normal file
95
examples/meam/log.19May17.meamc.g++.1
Normal file
@ -0,0 +1,95 @@
|
||||
LAMMPS (19 May 2017)
|
||||
using 1 OpenMP thread(s) per MPI task
|
||||
# Test of MEAM potential for SiC system
|
||||
|
||||
units metal
|
||||
boundary p p p
|
||||
|
||||
atom_style atomic
|
||||
|
||||
read_data data.meam
|
||||
orthogonal box = (-6 -6 -6) to (5.97232 5.97232 5.97232)
|
||||
1 by 1 by 1 MPI processor grid
|
||||
reading atoms ...
|
||||
128 atoms
|
||||
|
||||
pair_style meam/c
|
||||
pair_coeff * * library.meam Si C SiC.meam Si C
|
||||
Reading potential file library.meam with DATE: 2012-06-29
|
||||
Reading potential file SiC.meam with DATE: 2007-06-11
|
||||
|
||||
neighbor 0.3 bin
|
||||
neigh_modify delay 10
|
||||
|
||||
fix 1 all nve
|
||||
thermo 10
|
||||
timestep 0.001
|
||||
|
||||
#dump 1 all atom 50 dump.meam
|
||||
|
||||
#dump 2 all image 10 image.*.jpg element element # axes yes 0.8 0.02 view 60 -30
|
||||
#dump_modify 2 pad 3 element Si C
|
||||
|
||||
#dump 3 all movie 10 movie.mpg element element # axes yes 0.8 0.02 view 60 -30
|
||||
#dump_modify 3 pad 3 element Si C
|
||||
|
||||
run 100
|
||||
Neighbor list info ...
|
||||
update every 1 steps, delay 10 steps, check yes
|
||||
max neighbors/atom: 2000, page size: 100000
|
||||
master list distance cutoff = 4.3
|
||||
ghost atom cutoff = 4.3
|
||||
binsize = 2.15, bins = 6 6 6
|
||||
2 neighbor lists, perpetual/occasional/extra = 2 0 0
|
||||
(1) pair meam/c, perpetual
|
||||
attributes: full, newton on
|
||||
pair build: full/bin/atomonly
|
||||
stencil: full/bin/3d
|
||||
bin: standard
|
||||
(2) pair meam/c, perpetual, half/full from (1)
|
||||
attributes: half, newton on
|
||||
pair build: halffull/newton
|
||||
stencil: none
|
||||
bin: none
|
||||
Per MPI rank memory allocation (min/avg/max) = 8.103 | 8.103 | 8.103 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press
|
||||
0 0 -636.38121 0 -636.38121 -76571.819
|
||||
10 1807.8862 -666.21959 0 -636.54126 -150571.49
|
||||
20 1932.4467 -668.2581 0 -636.53498 -120223.52
|
||||
30 1951.3652 -668.58139 0 -636.54771 -100508.4
|
||||
40 2172.5974 -672.22715 0 -636.5617 -110753.34
|
||||
50 2056.9149 -670.33108 0 -636.56468 -105418.07
|
||||
60 1947.9564 -668.52788 0 -636.55015 -111413.04
|
||||
70 1994.7712 -669.28849 0 -636.54225 -109645.76
|
||||
80 2126.0903 -671.43755 0 -636.53557 -97475.832
|
||||
90 2065.7549 -670.4349 0 -636.52338 -95858.836
|
||||
100 2051.4553 -670.20799 0 -636.53122 -107068.89
|
||||
Loop time of 0.0778153 on 1 procs for 100 steps with 128 atoms
|
||||
|
||||
Performance: 111.032 ns/day, 0.216 hours/ns, 1285.094 timesteps/s
|
||||
99.5% CPU use with 1 MPI tasks x 1 OpenMP threads
|
||||
|
||||
MPI task timing breakdown:
|
||||
Section | min time | avg time | max time |%varavg| %total
|
||||
---------------------------------------------------------------
|
||||
Pair | 0.073801 | 0.073801 | 0.073801 | 0.0 | 94.84
|
||||
Neigh | 0.0029731 | 0.0029731 | 0.0029731 | 0.0 | 3.82
|
||||
Comm | 0.00047708 | 0.00047708 | 0.00047708 | 0.0 | 0.61
|
||||
Output | 0.00015664 | 0.00015664 | 0.00015664 | 0.0 | 0.20
|
||||
Modify | 0.00025702 | 0.00025702 | 0.00025702 | 0.0 | 0.33
|
||||
Other | | 0.0001504 | | | 0.19
|
||||
|
||||
Nlocal: 128 ave 128 max 128 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Nghost: 543 ave 543 max 543 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Neighs: 1526 ave 1526 max 1526 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
FullNghs: 3052 ave 3052 max 3052 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
|
||||
Total # of neighbors = 3052
|
||||
Ave neighs/atom = 23.8438
|
||||
Neighbor list builds = 10
|
||||
Dangerous builds = 10
|
||||
Total wall time: 0:00:00
|
||||
95
examples/meam/log.19May17.meamc.g++.4
Normal file
95
examples/meam/log.19May17.meamc.g++.4
Normal file
@ -0,0 +1,95 @@
|
||||
LAMMPS (19 May 2017)
|
||||
using 1 OpenMP thread(s) per MPI task
|
||||
# Test of MEAM potential for SiC system
|
||||
|
||||
units metal
|
||||
boundary p p p
|
||||
|
||||
atom_style atomic
|
||||
|
||||
read_data data.meam
|
||||
orthogonal box = (-6 -6 -6) to (5.97232 5.97232 5.97232)
|
||||
1 by 2 by 2 MPI processor grid
|
||||
reading atoms ...
|
||||
128 atoms
|
||||
|
||||
pair_style meam/c
|
||||
pair_coeff * * library.meam Si C SiC.meam Si C
|
||||
Reading potential file library.meam with DATE: 2012-06-29
|
||||
Reading potential file SiC.meam with DATE: 2007-06-11
|
||||
|
||||
neighbor 0.3 bin
|
||||
neigh_modify delay 10
|
||||
|
||||
fix 1 all nve
|
||||
thermo 10
|
||||
timestep 0.001
|
||||
|
||||
#dump 1 all atom 50 dump.meam
|
||||
|
||||
#dump 2 all image 10 image.*.jpg element element # axes yes 0.8 0.02 view 60 -30
|
||||
#dump_modify 2 pad 3 element Si C
|
||||
|
||||
#dump 3 all movie 10 movie.mpg element element # axes yes 0.8 0.02 view 60 -30
|
||||
#dump_modify 3 pad 3 element Si C
|
||||
|
||||
run 100
|
||||
Neighbor list info ...
|
||||
update every 1 steps, delay 10 steps, check yes
|
||||
max neighbors/atom: 2000, page size: 100000
|
||||
master list distance cutoff = 4.3
|
||||
ghost atom cutoff = 4.3
|
||||
binsize = 2.15, bins = 6 6 6
|
||||
2 neighbor lists, perpetual/occasional/extra = 2 0 0
|
||||
(1) pair meam/c, perpetual
|
||||
attributes: full, newton on
|
||||
pair build: full/bin/atomonly
|
||||
stencil: full/bin/3d
|
||||
bin: standard
|
||||
(2) pair meam/c, perpetual, half/full from (1)
|
||||
attributes: half, newton on
|
||||
pair build: halffull/newton
|
||||
stencil: none
|
||||
bin: none
|
||||
Per MPI rank memory allocation (min/avg/max) = 8.024 | 8.026 | 8.027 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press
|
||||
0 0 -636.38121 0 -636.38121 -76571.819
|
||||
10 1807.8862 -666.21959 0 -636.54126 -150571.49
|
||||
20 1932.4467 -668.2581 0 -636.53498 -120223.52
|
||||
30 1951.3652 -668.58139 0 -636.54771 -100508.4
|
||||
40 2172.5974 -672.22715 0 -636.5617 -110753.34
|
||||
50 2056.9149 -670.33108 0 -636.56468 -105418.07
|
||||
60 1947.9564 -668.52788 0 -636.55015 -111413.04
|
||||
70 1994.7712 -669.28849 0 -636.54225 -109645.76
|
||||
80 2126.0903 -671.43755 0 -636.53557 -97475.832
|
||||
90 2065.7549 -670.4349 0 -636.52338 -95858.836
|
||||
100 2051.4553 -670.20799 0 -636.53122 -107068.89
|
||||
Loop time of 0.037066 on 4 procs for 100 steps with 128 atoms
|
||||
|
||||
Performance: 233.097 ns/day, 0.103 hours/ns, 2697.887 timesteps/s
|
||||
97.4% CPU use with 4 MPI tasks x 1 OpenMP threads
|
||||
|
||||
MPI task timing breakdown:
|
||||
Section | min time | avg time | max time |%varavg| %total
|
||||
---------------------------------------------------------------
|
||||
Pair | 0.029985 | 0.031596 | 0.033021 | 0.8 | 85.24
|
||||
Neigh | 0.0007906 | 0.00085384 | 0.00088596 | 0.0 | 2.30
|
||||
Comm | 0.0025654 | 0.0040313 | 0.0057514 | 2.2 | 10.88
|
||||
Output | 0.00027013 | 0.00029153 | 0.00033426 | 0.0 | 0.79
|
||||
Modify | 9.5367e-05 | 0.00010639 | 0.00012016 | 0.0 | 0.29
|
||||
Other | | 0.0001866 | | | 0.50
|
||||
|
||||
Nlocal: 32 ave 36 max 30 min
|
||||
Histogram: 1 2 0 0 0 0 0 0 0 1
|
||||
Nghost: 293.75 ave 305 max 285 min
|
||||
Histogram: 2 0 0 0 0 0 0 1 0 1
|
||||
Neighs: 381.5 ave 413 max 334 min
|
||||
Histogram: 1 0 0 0 1 0 0 0 0 2
|
||||
FullNghs: 763 ave 866 max 678 min
|
||||
Histogram: 1 0 1 0 0 1 0 0 0 1
|
||||
|
||||
Total # of neighbors = 3052
|
||||
Ave neighs/atom = 23.8438
|
||||
Neighbor list builds = 10
|
||||
Dangerous builds = 10
|
||||
Total wall time: 0:00:00
|
||||
207
examples/meam/log.19May17.meamc.shear.g++.1
Normal file
207
examples/meam/log.19May17.meamc.shear.g++.1
Normal file
@ -0,0 +1,207 @@
|
||||
LAMMPS (19 May 2017)
|
||||
using 1 OpenMP thread(s) per MPI task
|
||||
# 3d metal shear simulation
|
||||
|
||||
units metal
|
||||
boundary s s p
|
||||
|
||||
atom_style atomic
|
||||
lattice fcc 3.52
|
||||
Lattice spacing in x,y,z = 3.52 3.52 3.52
|
||||
region box block 0 16.0 0 10.0 0 2.828427
|
||||
create_box 3 box
|
||||
Created orthogonal box = (0 0 0) to (56.32 35.2 9.95606)
|
||||
1 by 1 by 1 MPI processor grid
|
||||
|
||||
lattice fcc 3.52 orient x 1 0 0 orient y 0 1 1 orient z 0 -1 1 origin 0.5 0 0
|
||||
Lattice spacing in x,y,z = 3.52 4.97803 4.97803
|
||||
create_atoms 1 box
|
||||
Created 1912 atoms
|
||||
|
||||
pair_style meam/c
|
||||
pair_coeff * * library.meam Ni4 Ni.meam Ni4 Ni4 Ni4
|
||||
Reading potential file library.meam with DATE: 2012-06-29
|
||||
Reading potential file Ni.meam with DATE: 2007-06-11
|
||||
|
||||
neighbor 0.3 bin
|
||||
neigh_modify delay 5
|
||||
|
||||
region lower block INF INF INF 0.9 INF INF
|
||||
region upper block INF INF 6.1 INF INF INF
|
||||
group lower region lower
|
||||
264 atoms in group lower
|
||||
group upper region upper
|
||||
264 atoms in group upper
|
||||
group boundary union lower upper
|
||||
528 atoms in group boundary
|
||||
group mobile subtract all boundary
|
||||
1384 atoms in group mobile
|
||||
|
||||
set group lower type 2
|
||||
264 settings made for type
|
||||
set group upper type 3
|
||||
264 settings made for type
|
||||
|
||||
# void
|
||||
|
||||
#region void cylinder z 8 5 2.5 INF INF
|
||||
#delete_atoms region void
|
||||
|
||||
# temp controllers
|
||||
|
||||
compute new3d mobile temp
|
||||
compute new2d mobile temp/partial 0 1 1
|
||||
|
||||
# equilibrate
|
||||
|
||||
velocity mobile create 300.0 5812775 temp new3d
|
||||
fix 1 all nve
|
||||
fix 2 boundary setforce 0.0 0.0 0.0
|
||||
|
||||
fix 3 mobile temp/rescale 10 300.0 300.0 10.0 1.0
|
||||
fix_modify 3 temp new3d
|
||||
|
||||
thermo 25
|
||||
thermo_modify temp new3d
|
||||
WARNING: Temperature for thermo pressure is not for group all (../thermo.cpp:489)
|
||||
|
||||
timestep 0.001
|
||||
run 100
|
||||
Neighbor list info ...
|
||||
update every 1 steps, delay 5 steps, check yes
|
||||
max neighbors/atom: 2000, page size: 100000
|
||||
master list distance cutoff = 4.3
|
||||
ghost atom cutoff = 4.3
|
||||
binsize = 2.15, bins = 27 17 5
|
||||
2 neighbor lists, perpetual/occasional/extra = 2 0 0
|
||||
(1) pair meam/c, perpetual
|
||||
attributes: full, newton on
|
||||
pair build: full/bin/atomonly
|
||||
stencil: full/bin/3d
|
||||
bin: standard
|
||||
(2) pair meam/c, perpetual, half/full from (1)
|
||||
attributes: half, newton on
|
||||
pair build: halffull/newton
|
||||
stencil: none
|
||||
bin: none
|
||||
Per MPI rank memory allocation (min/avg/max) = 9.788 | 9.788 | 9.788 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press Volume
|
||||
0 300 -8232.7767 0 -8179.1466 1386.6643 19547.02
|
||||
25 222.78953 -8188.1215 0 -8148.2941 9095.9003 19547.02
|
||||
50 300 -8149.7654 0 -8096.1353 10633.139 19684.382
|
||||
75 304.80657 -8163.4557 0 -8108.9665 7045.4555 19759.745
|
||||
100 300 -8173.6884 0 -8120.0584 5952.5197 19886.589
|
||||
Loop time of 1.46986 on 1 procs for 100 steps with 1912 atoms
|
||||
|
||||
Performance: 5.878 ns/day, 4.083 hours/ns, 68.034 timesteps/s
|
||||
99.6% CPU use with 1 MPI tasks x 1 OpenMP threads
|
||||
|
||||
MPI task timing breakdown:
|
||||
Section | min time | avg time | max time |%varavg| %total
|
||||
---------------------------------------------------------------
|
||||
Pair | 1.445 | 1.445 | 1.445 | 0.0 | 98.31
|
||||
Neigh | 0.018564 | 0.018564 | 0.018564 | 0.0 | 1.26
|
||||
Comm | 0.0012956 | 0.0012956 | 0.0012956 | 0.0 | 0.09
|
||||
Output | 0.00012612 | 0.00012612 | 0.00012612 | 0.0 | 0.01
|
||||
Modify | 0.0038197 | 0.0038197 | 0.0038197 | 0.0 | 0.26
|
||||
Other | | 0.001095 | | | 0.07
|
||||
|
||||
Nlocal: 1912 ave 1912 max 1912 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Nghost: 1672 ave 1672 max 1672 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Neighs: 23806 ave 23806 max 23806 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
FullNghs: 47612 ave 47612 max 47612 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
|
||||
Total # of neighbors = 47612
|
||||
Ave neighs/atom = 24.9017
|
||||
Neighbor list builds = 5
|
||||
Dangerous builds = 0
|
||||
|
||||
# shear
|
||||
|
||||
velocity upper set 1.0 0 0
|
||||
velocity mobile ramp vx 0.0 1.0 y 1.4 8.6 sum yes
|
||||
|
||||
unfix 3
|
||||
fix 3 mobile temp/rescale 10 300.0 300.0 10.0 1.0
|
||||
fix_modify 3 temp new2d
|
||||
|
||||
#dump 1 all atom 500 dump.meam.shear
|
||||
|
||||
#dump 2 all image 100 image.*.jpg type type # axes yes 0.8 0.02 view 0 0 zoom 1.5 up 0 1 0 adiam 2.0
|
||||
#dump_modify 2 pad 4
|
||||
|
||||
#dump 3 all movie 100 movie.mpg type type # axes yes 0.8 0.02 view 0 0 zoom 1.5 up 0 1 0 adiam 2.0
|
||||
#dump_modify 3 pad 4
|
||||
|
||||
thermo 100
|
||||
thermo_modify temp new2d
|
||||
WARNING: Temperature for thermo pressure is not for group all (../thermo.cpp:489)
|
||||
|
||||
reset_timestep 0
|
||||
run 3000
|
||||
Per MPI rank memory allocation (min/avg/max) = 9.964 | 9.964 | 9.964 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press Volume
|
||||
0 300.39988 -8173.6884 0 -8137.8874 4992.9799 19894.297
|
||||
100 292.06374 -8177.7096 0 -8142.9021 2568.3756 19871.53
|
||||
200 306.69894 -8177.1357 0 -8140.584 874.24118 20047.24
|
||||
300 295.68216 -8172.9213 0 -8137.6825 -1049.0799 20091.759
|
||||
400 308.99955 -8169.6355 0 -8132.8096 -1785.9554 20121.698
|
||||
500 303.85688 -8163.9842 0 -8127.7712 -150.60892 20183.813
|
||||
600 300 -8157.7627 0 -8122.0093 1492.8514 20279.887
|
||||
700 300 -8148.1314 0 -8112.3781 3507.1949 20435.297
|
||||
800 300 -8139.1805 0 -8103.4272 3628.5908 20509.519
|
||||
900 305.03217 -8126.7741 0 -8090.421 5313.7881 20638.992
|
||||
1000 303.7648 -8112.1574 0 -8075.9554 7433.3181 20767.243
|
||||
1100 302.39719 -8096.1399 0 -8060.1009 9681.7685 20888.167
|
||||
1200 304.04919 -8080.7022 0 -8044.4663 11621.974 21011.532
|
||||
1300 303.56395 -8062.0984 0 -8025.9203 11410.793 21125.127
|
||||
1400 309.92338 -8046.0008 0 -8009.0648 12408.158 21246.05
|
||||
1500 300 -8034.7094 0 -7998.956 14845.312 21363.308
|
||||
1600 300 -8028.4585 0 -7992.7051 15120.908 21489.117
|
||||
1700 308.23904 -8015.9618 0 -7979.2265 14714.73 21612.483
|
||||
1800 300 -8013.5458 0 -7977.7924 11955.065 21737.07
|
||||
1900 300 -8012.2984 0 -7976.545 6667.1353 21854.329
|
||||
2000 300 -8025.6019 0 -7989.8485 2006.6545 21981.359
|
||||
2100 300 -8027.6823 0 -7991.9289 16.47633 22109.611
|
||||
2200 300 -8029.6905 0 -7993.9372 -603.98293 22224.427
|
||||
2300 300 -8033.2663 0 -7997.513 -464.68645 22351.457
|
||||
2400 300 -8040.6863 0 -8004.9329 -640.54641 22467.494
|
||||
2500 300 -8037.0332 0 -8001.2799 1504.2444 22587.196
|
||||
2600 300 -8036.0909 0 -8000.3375 4190.2052 22708.119
|
||||
2700 308.97892 -8028.5269 0 -7991.7035 5755.7418 22832.706
|
||||
2800 305.27189 -8023.8286 0 -7987.4469 2611.7551 22962.179
|
||||
2900 301.94251 -8017.4523 0 -7981.4675 358.11928 23078.216
|
||||
3000 305.67682 -8009.853 0 -7973.4231 -2345.487 23197.918
|
||||
Loop time of 48.351 on 1 procs for 3000 steps with 1912 atoms
|
||||
|
||||
Performance: 5.361 ns/day, 4.477 hours/ns, 62.046 timesteps/s
|
||||
99.7% CPU use with 1 MPI tasks x 1 OpenMP threads
|
||||
|
||||
MPI task timing breakdown:
|
||||
Section | min time | avg time | max time |%varavg| %total
|
||||
---------------------------------------------------------------
|
||||
Pair | 47.356 | 47.356 | 47.356 | 0.0 | 97.94
|
||||
Neigh | 0.79977 | 0.79977 | 0.79977 | 0.0 | 1.65
|
||||
Comm | 0.043133 | 0.043133 | 0.043133 | 0.0 | 0.09
|
||||
Output | 0.0011899 | 0.0011899 | 0.0011899 | 0.0 | 0.00
|
||||
Modify | 0.11648 | 0.11648 | 0.11648 | 0.0 | 0.24
|
||||
Other | | 0.03404 | | | 0.07
|
||||
|
||||
Nlocal: 1912 ave 1912 max 1912 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Nghost: 1662 ave 1662 max 1662 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Neighs: 23143 ave 23143 max 23143 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
FullNghs: 46286 ave 46286 max 46286 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
|
||||
Total # of neighbors = 46286
|
||||
Ave neighs/atom = 24.2082
|
||||
Neighbor list builds = 220
|
||||
Dangerous builds = 0
|
||||
Total wall time: 0:00:49
|
||||
207
examples/meam/log.19May17.meamc.shear.g++.4
Normal file
207
examples/meam/log.19May17.meamc.shear.g++.4
Normal file
@ -0,0 +1,207 @@
|
||||
LAMMPS (19 May 2017)
|
||||
using 1 OpenMP thread(s) per MPI task
|
||||
# 3d metal shear simulation
|
||||
|
||||
units metal
|
||||
boundary s s p
|
||||
|
||||
atom_style atomic
|
||||
lattice fcc 3.52
|
||||
Lattice spacing in x,y,z = 3.52 3.52 3.52
|
||||
region box block 0 16.0 0 10.0 0 2.828427
|
||||
create_box 3 box
|
||||
Created orthogonal box = (0 0 0) to (56.32 35.2 9.95606)
|
||||
2 by 2 by 1 MPI processor grid
|
||||
|
||||
lattice fcc 3.52 orient x 1 0 0 orient y 0 1 1 orient z 0 -1 1 origin 0.5 0 0
|
||||
Lattice spacing in x,y,z = 3.52 4.97803 4.97803
|
||||
create_atoms 1 box
|
||||
Created 1912 atoms
|
||||
|
||||
pair_style meam/c
|
||||
pair_coeff * * library.meam Ni4 Ni.meam Ni4 Ni4 Ni4
|
||||
Reading potential file library.meam with DATE: 2012-06-29
|
||||
Reading potential file Ni.meam with DATE: 2007-06-11
|
||||
|
||||
neighbor 0.3 bin
|
||||
neigh_modify delay 5
|
||||
|
||||
region lower block INF INF INF 0.9 INF INF
|
||||
region upper block INF INF 6.1 INF INF INF
|
||||
group lower region lower
|
||||
264 atoms in group lower
|
||||
group upper region upper
|
||||
264 atoms in group upper
|
||||
group boundary union lower upper
|
||||
528 atoms in group boundary
|
||||
group mobile subtract all boundary
|
||||
1384 atoms in group mobile
|
||||
|
||||
set group lower type 2
|
||||
264 settings made for type
|
||||
set group upper type 3
|
||||
264 settings made for type
|
||||
|
||||
# void
|
||||
|
||||
#region void cylinder z 8 5 2.5 INF INF
|
||||
#delete_atoms region void
|
||||
|
||||
# temp controllers
|
||||
|
||||
compute new3d mobile temp
|
||||
compute new2d mobile temp/partial 0 1 1
|
||||
|
||||
# equilibrate
|
||||
|
||||
velocity mobile create 300.0 5812775 temp new3d
|
||||
fix 1 all nve
|
||||
fix 2 boundary setforce 0.0 0.0 0.0
|
||||
|
||||
fix 3 mobile temp/rescale 10 300.0 300.0 10.0 1.0
|
||||
fix_modify 3 temp new3d
|
||||
|
||||
thermo 25
|
||||
thermo_modify temp new3d
|
||||
WARNING: Temperature for thermo pressure is not for group all (../thermo.cpp:489)
|
||||
|
||||
timestep 0.001
|
||||
run 100
|
||||
Neighbor list info ...
|
||||
update every 1 steps, delay 5 steps, check yes
|
||||
max neighbors/atom: 2000, page size: 100000
|
||||
master list distance cutoff = 4.3
|
||||
ghost atom cutoff = 4.3
|
||||
binsize = 2.15, bins = 27 17 5
|
||||
2 neighbor lists, perpetual/occasional/extra = 2 0 0
|
||||
(1) pair meam/c, perpetual
|
||||
attributes: full, newton on
|
||||
pair build: full/bin/atomonly
|
||||
stencil: full/bin/3d
|
||||
bin: standard
|
||||
(2) pair meam/c, perpetual, half/full from (1)
|
||||
attributes: half, newton on
|
||||
pair build: halffull/newton
|
||||
stencil: none
|
||||
bin: none
|
||||
Per MPI rank memory allocation (min/avg/max) = 8.954 | 8.957 | 8.959 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press Volume
|
||||
0 300 -8232.7767 0 -8179.1466 1386.6643 19547.02
|
||||
25 221.59546 -8187.6813 0 -8148.0673 9100.4505 19547.02
|
||||
50 300 -8150.0685 0 -8096.4384 10317.406 19685.743
|
||||
75 307.76021 -8164.6669 0 -8109.6496 6289.7123 19757.814
|
||||
100 300 -8176.5141 0 -8122.884 4162.2548 19873.327
|
||||
Loop time of 0.435874 on 4 procs for 100 steps with 1912 atoms
|
||||
|
||||
Performance: 19.822 ns/day, 1.211 hours/ns, 229.424 timesteps/s
|
||||
98.8% CPU use with 4 MPI tasks x 1 OpenMP threads
|
||||
|
||||
MPI task timing breakdown:
|
||||
Section | min time | avg time | max time |%varavg| %total
|
||||
---------------------------------------------------------------
|
||||
Pair | 0.4092 | 0.41563 | 0.42184 | 0.7 | 95.35
|
||||
Neigh | 0.0048575 | 0.004932 | 0.0049984 | 0.1 | 1.13
|
||||
Comm | 0.0069079 | 0.013151 | 0.019513 | 4.2 | 3.02
|
||||
Output | 0.00012398 | 0.00013405 | 0.00015688 | 0.0 | 0.03
|
||||
Modify | 0.0011275 | 0.0011509 | 0.0011735 | 0.1 | 0.26
|
||||
Other | | 0.0008795 | | | 0.20
|
||||
|
||||
Nlocal: 478 ave 492 max 465 min
|
||||
Histogram: 2 0 0 0 0 0 0 0 1 1
|
||||
Nghost: 809 ave 822 max 795 min
|
||||
Histogram: 1 1 0 0 0 0 0 0 0 2
|
||||
Neighs: 5916 ave 6133 max 5658 min
|
||||
Histogram: 1 0 0 1 0 0 0 0 1 1
|
||||
FullNghs: 11832 ave 12277 max 11299 min
|
||||
Histogram: 1 0 0 1 0 0 0 0 1 1
|
||||
|
||||
Total # of neighbors = 47328
|
||||
Ave neighs/atom = 24.7531
|
||||
Neighbor list builds = 5
|
||||
Dangerous builds = 0
|
||||
|
||||
# shear
|
||||
|
||||
velocity upper set 1.0 0 0
|
||||
velocity mobile ramp vx 0.0 1.0 y 1.4 8.6 sum yes
|
||||
|
||||
unfix 3
|
||||
fix 3 mobile temp/rescale 10 300.0 300.0 10.0 1.0
|
||||
fix_modify 3 temp new2d
|
||||
|
||||
#dump 1 all atom 500 dump.meam.shear
|
||||
|
||||
#dump 2 all image 100 image.*.jpg type type # axes yes 0.8 0.02 view 0 0 zoom 1.5 up 0 1 0 adiam 2.0
|
||||
#dump_modify 2 pad 4
|
||||
|
||||
#dump 3 all movie 100 movie.mpg type type # axes yes 0.8 0.02 view 0 0 zoom 1.5 up 0 1 0 adiam 2.0
|
||||
#dump_modify 3 pad 4
|
||||
|
||||
thermo 100
|
||||
thermo_modify temp new2d
|
||||
WARNING: Temperature for thermo pressure is not for group all (../thermo.cpp:489)
|
||||
|
||||
reset_timestep 0
|
||||
run 3000
|
||||
Per MPI rank memory allocation (min/avg/max) = 8.999 | 9.002 | 9.005 Mbytes
|
||||
Step Temp E_pair E_mol TotEng Press Volume
|
||||
0 295.32113 -8176.5141 0 -8141.3183 3169.3102 19886.93
|
||||
100 292.0025 -8176.5358 0 -8141.7356 -825.04852 19918.765
|
||||
200 306.11682 -8176.7718 0 -8140.2895 -1370.6881 19948.878
|
||||
300 300 -8172.6262 0 -8136.8729 -1735.9794 20085.715
|
||||
400 306.88504 -8168.4351 0 -8131.8612 -933.05532 20117.008
|
||||
500 308.99111 -8166.2909 0 -8129.466 -1049.3442 20198.267
|
||||
600 304.22555 -8158.0946 0 -8121.8377 583.69142 20328.753
|
||||
700 296.41606 -8149.7777 0 -8114.4515 1986.7982 20421.032
|
||||
800 307.88628 -8139.1709 0 -8102.4776 4311.4142 20513.183
|
||||
900 303.37209 -8126.9382 0 -8090.7829 6712.7316 20640.213
|
||||
1000 300 -8113.7973 0 -8078.044 7630.2594 20750.143
|
||||
1100 300.07815 -8098.1383 0 -8062.3756 8423.7063 20879.616
|
||||
1200 300 -8083.3163 0 -8047.563 10772.917 21000.539
|
||||
1300 300 -8066.6741 0 -8030.9208 10834.336 21128.791
|
||||
1400 300 -8050.8799 0 -8015.1265 10842.382 21257.043
|
||||
1500 300 -8040.3206 0 -8004.5673 11852.589 21362.087
|
||||
1600 300 -8033.2471 0 -7997.4937 11298.745 21492.782
|
||||
1700 300 -8030.6375 0 -7994.8842 10850.43 21610.04
|
||||
1800 300 -8035.1631 0 -7999.4097 9985.6107 21734.628
|
||||
1900 308.56562 -8040.1954 0 -8003.4213 9865.7107 21859.215
|
||||
2000 300 -8030.1651 0 -7994.4117 11817.502 21980.138
|
||||
2100 300 -8031.6147 0 -7995.8613 12791.357 22101.061
|
||||
2200 300 -8033.7793 0 -7998.0259 13823.043 22234.198
|
||||
2300 300 -8040.5964 0 -8004.8431 16204.549 22350.236
|
||||
2400 309.42867 -8045.9414 0 -8009.0644 18506.386 22465.051
|
||||
2500 300 -8054.2629 0 -8018.5095 20099.612 22593.303
|
||||
2600 300 -8054.9562 0 -8019.2028 20036.318 22721.555
|
||||
2700 300 -8051.4788 0 -8015.7254 16993.437 22844.921
|
||||
2800 300 -8050.6908 0 -8014.9374 9048.5896 22964.622
|
||||
2900 309.90783 -8044.3096 0 -8007.3754 5017.0198 23080.659
|
||||
3000 300 -8035.8165 0 -8000.0632 2084.8999 23207.69
|
||||
Loop time of 13.4901 on 4 procs for 3000 steps with 1912 atoms
|
||||
|
||||
Performance: 19.214 ns/day, 1.249 hours/ns, 222.386 timesteps/s
|
||||
99.4% CPU use with 4 MPI tasks x 1 OpenMP threads
|
||||
|
||||
MPI task timing breakdown:
|
||||
Section | min time | avg time | max time |%varavg| %total
|
||||
---------------------------------------------------------------
|
||||
Pair | 12.851 | 12.919 | 12.945 | 1.1 | 95.76
|
||||
Neigh | 0.20449 | 0.20777 | 0.21169 | 0.6 | 1.54
|
||||
Comm | 0.27479 | 0.30264 | 0.36667 | 6.8 | 2.24
|
||||
Output | 0.0010171 | 0.0010971 | 0.0012388 | 0.3 | 0.01
|
||||
Modify | 0.033248 | 0.033878 | 0.034567 | 0.3 | 0.25
|
||||
Other | | 0.02594 | | | 0.19
|
||||
|
||||
Nlocal: 478 ave 506 max 450 min
|
||||
Histogram: 2 0 0 0 0 0 0 0 0 2
|
||||
Nghost: 790.5 ave 822 max 751 min
|
||||
Histogram: 1 0 1 0 0 0 0 0 0 2
|
||||
Neighs: 5829.5 ave 6014 max 5672 min
|
||||
Histogram: 2 0 0 0 0 0 0 0 1 1
|
||||
FullNghs: 11659 ave 12027 max 11320 min
|
||||
Histogram: 2 0 0 0 0 0 0 0 1 1
|
||||
|
||||
Total # of neighbors = 46636
|
||||
Ave neighs/atom = 24.3912
|
||||
Neighbor list builds = 220
|
||||
Dangerous builds = 0
|
||||
Total wall time: 0:00:13
|
||||
5
src/.gitignore
vendored
5
src/.gitignore
vendored
@ -31,6 +31,11 @@
|
||||
/fix_*manifold*.cpp
|
||||
/fix_*manifold*.h
|
||||
|
||||
/meam*.h
|
||||
/meam*.cpp
|
||||
/pair_meamc.cpp
|
||||
/pair_meamc.h
|
||||
|
||||
/fix_qeq*.cpp
|
||||
/fix_qeq*.h
|
||||
|
||||
|
||||
@ -218,8 +218,6 @@ void FixQEqReaxKokkos<DeviceType>::pre_force(int vflag)
|
||||
d_ilist = k_list->d_ilist;
|
||||
inum = list->inum;
|
||||
|
||||
k_list->clean_copy();
|
||||
//cleanup_copy();
|
||||
copymode = 1;
|
||||
|
||||
int teamsize = TEAMSIZE;
|
||||
|
||||
@ -22,21 +22,14 @@ enum{NSQ,BIN,MULTI};
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
template<class Device>
|
||||
void NeighListKokkos<Device>::clean_copy()
|
||||
NeighListKokkos<Device>::NeighListKokkos(class LAMMPS *lmp):NeighList(lmp)
|
||||
{
|
||||
ilist = NULL;
|
||||
numneigh = NULL;
|
||||
firstneigh = NULL;
|
||||
firstdouble = NULL;
|
||||
dnum = 0;
|
||||
iskip = NULL;
|
||||
ijskip = NULL;
|
||||
|
||||
ipage = NULL;
|
||||
dpage = NULL;
|
||||
|
||||
_stride = 1;
|
||||
maxneighs = 16;
|
||||
kokkos = 1;
|
||||
maxatoms = 0;
|
||||
}
|
||||
execution_space = ExecutionSpaceFromDevice<Device>::space;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
|
||||
@ -68,18 +68,13 @@ class NeighListKokkos: public NeighList {
|
||||
public:
|
||||
int maxneighs;
|
||||
|
||||
void clean_copy();
|
||||
void grow(int nmax);
|
||||
typename ArrayTypes<Device>::t_neighbors_2d d_neighbors;
|
||||
typename DAT::tdual_int_1d k_ilist; // local indices of I atoms
|
||||
typename ArrayTypes<Device>::t_int_1d d_ilist;
|
||||
typename ArrayTypes<Device>::t_int_1d d_numneigh; // # of J neighs for each I
|
||||
|
||||
NeighListKokkos(class LAMMPS *lmp):
|
||||
NeighList(lmp) {_stride = 1; maxneighs = 16; kokkos = 1; maxatoms = 0;
|
||||
execution_space = ExecutionSpaceFromDevice<Device>::space;
|
||||
};
|
||||
~NeighListKokkos() {numneigh = NULL; ilist = NULL;};
|
||||
NeighListKokkos(class LAMMPS *lmp);
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
AtomNeighbors get_neighbors(const int &i) const {
|
||||
|
||||
@ -265,7 +265,7 @@ class NeighborKokkosExecute
|
||||
h_new_maxneighs() = neigh_list.maxneighs;
|
||||
};
|
||||
|
||||
~NeighborKokkosExecute() {neigh_list.clean_copy();};
|
||||
~NeighborKokkosExecute() {neigh_list.copymode = 1;};
|
||||
|
||||
template<int HalfNeigh, int Newton, int Tri>
|
||||
KOKKOS_FUNCTION
|
||||
|
||||
@ -120,9 +120,6 @@ void PairCoulDSFKokkos<DeviceType>::compute(int eflag_in, int vflag_in)
|
||||
|
||||
int inum = list->inum;
|
||||
|
||||
// Call cleanup_copy which sets allocations NULL which are destructed by the PairStyle
|
||||
|
||||
k_list->clean_copy();
|
||||
copymode = 1;
|
||||
|
||||
// loop over neighbors of my atoms
|
||||
|
||||
@ -121,9 +121,6 @@ void PairCoulWolfKokkos<DeviceType>::compute(int eflag_in, int vflag_in)
|
||||
|
||||
int inum = list->inum;
|
||||
|
||||
// Call cleanup_copy which sets allocations NULL which are destructed by the PairStyle
|
||||
|
||||
k_list->clean_copy();
|
||||
copymode = 1;
|
||||
|
||||
// loop over neighbors of my atoms
|
||||
|
||||
@ -122,9 +122,6 @@ void PairEAMAlloyKokkos<DeviceType>::compute(int eflag_in, int vflag_in)
|
||||
d_ilist = k_list->d_ilist;
|
||||
int inum = list->inum;
|
||||
|
||||
// Call cleanup_copy which sets allocations NULL which are destructed by the PairStyle
|
||||
|
||||
k_list->clean_copy();
|
||||
copymode = 1;
|
||||
|
||||
// zero out density
|
||||
|
||||
@ -122,9 +122,6 @@ void PairEAMFSKokkos<DeviceType>::compute(int eflag_in, int vflag_in)
|
||||
d_ilist = k_list->d_ilist;
|
||||
int inum = list->inum;
|
||||
|
||||
// Call cleanup_copy which sets allocations NULL which are destructed by the PairStyle
|
||||
|
||||
k_list->clean_copy();
|
||||
copymode = 1;
|
||||
|
||||
// zero out density
|
||||
|
||||
@ -117,9 +117,6 @@ void PairEAMKokkos<DeviceType>::compute(int eflag_in, int vflag_in)
|
||||
d_ilist = k_list->d_ilist;
|
||||
int inum = list->inum;
|
||||
|
||||
// Call cleanup_copy which sets allocations NULL which are destructed by the PairStyle
|
||||
|
||||
k_list->clean_copy();
|
||||
copymode = 1;
|
||||
|
||||
// zero out density
|
||||
@ -868,4 +865,4 @@ template class PairEAMKokkos<LMPDeviceType>;
|
||||
#ifdef KOKKOS_HAVE_CUDA
|
||||
template class PairEAMKokkos<LMPHostType>;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,7 +87,7 @@ struct PairComputeFunctor {
|
||||
vatom(c.d_vatom),list(*list_ptr) {};
|
||||
|
||||
// Call cleanup_copy which sets allocations NULL which are destructed by the PairStyle
|
||||
~PairComputeFunctor() {c.cleanup_copy();list.clean_copy();};
|
||||
~PairComputeFunctor() {c.cleanup_copy();list.copymode = 1;};
|
||||
|
||||
KOKKOS_INLINE_FUNCTION int sbmask(const int& j) const {
|
||||
return j >> SBBITS & 3;
|
||||
@ -344,7 +344,7 @@ struct PairComputeFunctor<PairStyle,N2,STACKPARAMS,Specialisation> {
|
||||
PairComputeFunctor(PairStyle* c_ptr,
|
||||
NeighListKokkos<device_type>* list_ptr):
|
||||
c(*c_ptr),list(*list_ptr) {};
|
||||
~PairComputeFunctor() {c.cleanup_copy();list.clean_copy();};
|
||||
~PairComputeFunctor() {c.cleanup_copy();list.copymode = 1;};
|
||||
|
||||
KOKKOS_INLINE_FUNCTION int sbmask(const int& j) const {
|
||||
return j >> SBBITS & 3;
|
||||
|
||||
@ -709,8 +709,6 @@ void PairReaxCKokkos<DeviceType>::compute(int eflag_in, int vflag_in)
|
||||
d_neighbors = k_list->d_neighbors;
|
||||
d_ilist = k_list->d_ilist;
|
||||
|
||||
k_list->clean_copy();
|
||||
|
||||
if (eflag_global) {
|
||||
for (int i = 0; i < 14; i++)
|
||||
pvector[i] = 0.0;
|
||||
@ -3985,7 +3983,6 @@ void PairReaxCKokkos<DeviceType>::FindBond(int &numbonds)
|
||||
const int inum = list->inum;
|
||||
NeighListKokkos<DeviceType>* k_list = static_cast<NeighListKokkos<DeviceType>*>(list);
|
||||
d_ilist = k_list->d_ilist;
|
||||
k_list->clean_copy();
|
||||
|
||||
numbonds = 0;
|
||||
PairReaxCKokkosFindBondFunctor<DeviceType> find_bond_functor(this);
|
||||
|
||||
@ -115,7 +115,6 @@ void PairSWKokkos<DeviceType>::compute(int eflag_in, int vflag_in)
|
||||
d_numneigh = k_list->d_numneigh;
|
||||
d_neighbors = k_list->d_neighbors;
|
||||
|
||||
k_list->clean_copy();
|
||||
copymode = 1;
|
||||
|
||||
EV_FLOAT ev;
|
||||
|
||||
@ -200,7 +200,6 @@ void PairTersoffKokkos<DeviceType>::compute(int eflag_in, int vflag_in)
|
||||
d_neighbors = k_list->d_neighbors;
|
||||
d_ilist = k_list->d_ilist;
|
||||
|
||||
k_list->clean_copy();
|
||||
copymode = 1;
|
||||
|
||||
EV_FLOAT ev;
|
||||
|
||||
@ -200,7 +200,6 @@ void PairTersoffMODKokkos<DeviceType>::compute(int eflag_in, int vflag_in)
|
||||
d_neighbors = k_list->d_neighbors;
|
||||
d_ilist = k_list->d_ilist;
|
||||
|
||||
k_list->clean_copy();
|
||||
copymode = 1;
|
||||
|
||||
EV_FLOAT ev;
|
||||
|
||||
@ -214,7 +214,6 @@ void PairTersoffZBLKokkos<DeviceType>::compute(int eflag_in, int vflag_in)
|
||||
d_neighbors = k_list->d_neighbors;
|
||||
d_ilist = k_list->d_ilist;
|
||||
|
||||
k_list->clean_copy();
|
||||
copymode = 1;
|
||||
|
||||
EV_FLOAT ev;
|
||||
|
||||
@ -114,7 +114,6 @@ void PairVashishtaKokkos<DeviceType>::compute(int eflag_in, int vflag_in)
|
||||
d_numneigh = k_list->d_numneigh;
|
||||
d_neighbors = k_list->d_neighbors;
|
||||
|
||||
k_list->clean_copy();
|
||||
copymode = 1;
|
||||
|
||||
EV_FLOAT ev;
|
||||
|
||||
@ -186,6 +186,10 @@ void PPPM::init()
|
||||
// error check
|
||||
|
||||
triclinic_check();
|
||||
|
||||
if (triclinic != domain->triclinic)
|
||||
error->all(FLERR,"Must redefine kspace_style after changing to triclinic box");
|
||||
|
||||
if (domain->triclinic && differentiation_flag == 1)
|
||||
error->all(FLERR,"Cannot (yet) use PPPM with triclinic box "
|
||||
"and kspace_modify diff ad");
|
||||
|
||||
@ -332,9 +332,9 @@ void PPPMTIP4P::fieldforce_ad()
|
||||
|
||||
const double qfactor = qqrd2e * scale;
|
||||
|
||||
s1 = x[i][0]*hx_inv;
|
||||
s2 = x[i][1]*hy_inv;
|
||||
s3 = x[i][2]*hz_inv;
|
||||
s1 = xi[0]*hx_inv;
|
||||
s2 = xi[1]*hy_inv;
|
||||
s3 = xi[2]*hz_inv;
|
||||
sf = sf_coeff[0]*sin(2*MY_PI*s1);
|
||||
sf += sf_coeff[1]*sin(4*MY_PI*s1);
|
||||
sf *= 2.0*q[i]*q[i];
|
||||
@ -486,6 +486,8 @@ void PPPMTIP4P::fieldforce_peratom()
|
||||
|
||||
void PPPMTIP4P::find_M(int i, int &iH1, int &iH2, double *xM)
|
||||
{
|
||||
double **x = atom->x;
|
||||
|
||||
iH1 = atom->map(atom->tag[i] + 1);
|
||||
iH2 = atom->map(atom->tag[i] + 2);
|
||||
|
||||
@ -493,63 +495,98 @@ void PPPMTIP4P::find_M(int i, int &iH1, int &iH2, double *xM)
|
||||
if (atom->type[iH1] != typeH || atom->type[iH2] != typeH)
|
||||
error->one(FLERR,"TIP4P hydrogen has incorrect atom type");
|
||||
|
||||
// set iH1,iH2 to index of closest image to O
|
||||
|
||||
iH1 = domain->closest_image(i,iH1);
|
||||
iH2 = domain->closest_image(i,iH2);
|
||||
|
||||
if (triclinic) {
|
||||
find_M_triclinic(i,iH1,iH2,xM);
|
||||
return;
|
||||
|
||||
// need to use custom code to find the closest image for triclinic,
|
||||
// since local atoms are in lambda coordinates, but ghosts are not.
|
||||
|
||||
int *sametag = atom->sametag;
|
||||
double xo[3],xh1[3],xh2[3];
|
||||
|
||||
domain->lamda2x(x[i],xo);
|
||||
domain->lamda2x(x[iH1],xh1);
|
||||
domain->lamda2x(x[iH2],xh2);
|
||||
|
||||
double delx = xo[0] - xh1[0];
|
||||
double dely = xo[1] - xh1[1];
|
||||
double delz = xo[2] - xh1[2];
|
||||
double rsqmin = delx*delx + dely*dely + delz*delz;
|
||||
double rsq;
|
||||
int closest = iH1;
|
||||
|
||||
while (sametag[iH1] >= 0) {
|
||||
iH1 = sametag[iH1];
|
||||
delx = xo[0] - x[iH1][0];
|
||||
dely = xo[1] - x[iH1][1];
|
||||
delz = xo[2] - x[iH1][2];
|
||||
rsq = delx*delx + dely*dely + delz*delz;
|
||||
if (rsq < rsqmin) {
|
||||
rsqmin = rsq;
|
||||
closest = iH1;
|
||||
xh1[0] = x[iH1][0];
|
||||
xh1[1] = x[iH1][1];
|
||||
xh1[2] = x[iH1][2];
|
||||
}
|
||||
}
|
||||
iH1 = closest;
|
||||
|
||||
closest = iH2;
|
||||
delx = xo[0] - xh2[0];
|
||||
dely = xo[1] - xh2[1];
|
||||
delz = xo[2] - xh2[2];
|
||||
rsqmin = delx*delx + dely*dely + delz*delz;
|
||||
|
||||
while (sametag[iH2] >= 0) {
|
||||
iH2 = sametag[iH2];
|
||||
delx = xo[0] - x[iH2][0];
|
||||
dely = xo[1] - x[iH2][1];
|
||||
delz = xo[2] - x[iH2][2];
|
||||
rsq = delx*delx + dely*dely + delz*delz;
|
||||
if (rsq < rsqmin) {
|
||||
rsqmin = rsq;
|
||||
closest = iH2;
|
||||
xh2[0] = x[iH2][0];
|
||||
xh2[1] = x[iH2][1];
|
||||
xh2[2] = x[iH2][2];
|
||||
}
|
||||
}
|
||||
iH2 = closest;
|
||||
|
||||
// finally compute M in real coordinates ...
|
||||
|
||||
double delx1 = xh1[0] - xo[0];
|
||||
double dely1 = xh1[1] - xo[1];
|
||||
double delz1 = xh1[2] - xo[2];
|
||||
|
||||
double delx2 = xh2[0] - xo[0];
|
||||
double dely2 = xh2[1] - xo[1];
|
||||
double delz2 = xh2[2] - xo[2];
|
||||
|
||||
xM[0] = xo[0] + alpha * 0.5 * (delx1 + delx2);
|
||||
xM[1] = xo[1] + alpha * 0.5 * (dely1 + dely2);
|
||||
xM[2] = xo[2] + alpha * 0.5 * (delz1 + delz2);
|
||||
|
||||
// ... and convert M to lamda space for PPPM
|
||||
|
||||
domain->x2lamda(xM,xM);
|
||||
|
||||
} else {
|
||||
|
||||
// set iH1,iH2 to index of closest image to O
|
||||
|
||||
iH1 = domain->closest_image(i,iH1);
|
||||
iH2 = domain->closest_image(i,iH2);
|
||||
|
||||
double delx1 = x[iH1][0] - x[i][0];
|
||||
double dely1 = x[iH1][1] - x[i][1];
|
||||
double delz1 = x[iH1][2] - x[i][2];
|
||||
|
||||
double delx2 = x[iH2][0] - x[i][0];
|
||||
double dely2 = x[iH2][1] - x[i][1];
|
||||
double delz2 = x[iH2][2] - x[i][2];
|
||||
|
||||
xM[0] = x[i][0] + alpha * 0.5 * (delx1 + delx2);
|
||||
xM[1] = x[i][1] + alpha * 0.5 * (dely1 + dely2);
|
||||
xM[2] = x[i][2] + alpha * 0.5 * (delz1 + delz2);
|
||||
}
|
||||
|
||||
double **x = atom->x;
|
||||
|
||||
double delx1 = x[iH1][0] - x[i][0];
|
||||
double dely1 = x[iH1][1] - x[i][1];
|
||||
double delz1 = x[iH1][2] - x[i][2];
|
||||
|
||||
double delx2 = x[iH2][0] - x[i][0];
|
||||
double dely2 = x[iH2][1] - x[i][1];
|
||||
double delz2 = x[iH2][2] - x[i][2];
|
||||
|
||||
xM[0] = x[i][0] + alpha * 0.5 * (delx1 + delx2);
|
||||
xM[1] = x[i][1] + alpha * 0.5 * (dely1 + dely2);
|
||||
xM[2] = x[i][2] + alpha * 0.5 * (delz1 + delz2);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
triclinic version of find_M()
|
||||
calculation of M coords done in real space
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PPPMTIP4P::find_M_triclinic(int i, int iH1, int iH2, double *xM)
|
||||
{
|
||||
double **x = atom->x;
|
||||
|
||||
// convert from lamda to real space
|
||||
// may be possible to do this more efficiently in lamda space
|
||||
|
||||
domain->lamda2x(x[i],x[i]);
|
||||
domain->lamda2x(x[iH1],x[iH1]);
|
||||
domain->lamda2x(x[iH2],x[iH2]);
|
||||
|
||||
double delx1 = x[iH1][0] - x[i][0];
|
||||
double dely1 = x[iH1][1] - x[i][1];
|
||||
double delz1 = x[iH1][2] - x[i][2];
|
||||
|
||||
double delx2 = x[iH2][0] - x[i][0];
|
||||
double dely2 = x[iH2][1] - x[i][1];
|
||||
double delz2 = x[iH2][2] - x[i][2];
|
||||
|
||||
xM[0] = x[i][0] + alpha * 0.5 * (delx1 + delx2);
|
||||
xM[1] = x[i][1] + alpha * 0.5 * (dely1 + dely2);
|
||||
xM[2] = x[i][2] + alpha * 0.5 * (delz1 + delz2);
|
||||
|
||||
// convert back to lamda space
|
||||
|
||||
domain->x2lamda(x[i],x[i]);
|
||||
domain->x2lamda(x[iH1],x[iH1]);
|
||||
domain->x2lamda(x[iH2],x[iH2]);
|
||||
domain->x2lamda(xM,xM);
|
||||
}
|
||||
|
||||
@ -39,7 +39,6 @@ class PPPMTIP4P : public PPPM {
|
||||
|
||||
private:
|
||||
void find_M(int, int &, int &, double *);
|
||||
void find_M_triclinic(int, int, int, double *);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ PACKAGE = asphere body class2 colloid compress coreshell dipole gpu \
|
||||
|
||||
PACKUSER = user-atc user-awpmd user-cgdna user-cgsdk user-colvars \
|
||||
user-diffraction user-dpd user-drude user-eff user-fep user-h5md \
|
||||
user-intel user-lb user-manifold user-mgpt user-misc user-molfile \
|
||||
user-intel user-lb user-manifold user-meamc user-mgpt user-misc user-molfile \
|
||||
user-netcdf user-omp user-phonon user-qmmm user-qtb \
|
||||
user-quip user-reaxc user-smd user-smtbq user-sph user-tally \
|
||||
user-vtk
|
||||
|
||||
@ -13,8 +13,8 @@
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Contributing authors: Laurence Fried (LLNL), Evan Reed (LLNL, Stanford)
|
||||
implementation of the Multi-Scale Shock Method
|
||||
See Reed, Fried, Joannopoulos, Phys Rev Lett, 90, 235503 (2003)
|
||||
implementation of the Multi-Scale Shock Method
|
||||
see Reed, Fried, Joannopoulos, Phys Rev Lett, 90, 235503 (2003)
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#include <string.h>
|
||||
@ -26,13 +26,15 @@
|
||||
#include "comm.h"
|
||||
#include "output.h"
|
||||
#include "modify.h"
|
||||
#include "fix_external.h"
|
||||
#include "compute.h"
|
||||
#include "kspace.h"
|
||||
#include "update.h"
|
||||
#include "respa.h"
|
||||
#include "domain.h"
|
||||
#include "error.h"
|
||||
#include "thermo.h"
|
||||
#include "memory.h"
|
||||
#include "error.h"
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
using namespace FixConst;
|
||||
@ -40,9 +42,9 @@ using namespace FixConst;
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
FixMSST::FixMSST(LAMMPS *lmp, int narg, char **arg) :
|
||||
Fix(lmp, narg, arg), old_velocity(NULL), rfix(NULL),
|
||||
id_temp(NULL), id_press(NULL), id_pe(NULL), temperature(NULL),
|
||||
pressure(NULL), pe(NULL), atoms_allocated(0)
|
||||
Fix(lmp, narg, arg), old_velocity(NULL), rfix(NULL),
|
||||
id_temp(NULL), id_press(NULL), id_pe(NULL), temperature(NULL),
|
||||
pressure(NULL), pe(NULL)
|
||||
{
|
||||
if (narg < 4) error->all(FLERR,"Illegal fix msst command");
|
||||
|
||||
@ -63,6 +65,11 @@ FixMSST::FixMSST(LAMMPS *lmp, int narg, char **arg) :
|
||||
p0 = 0.0;
|
||||
v0 = 1.0;
|
||||
e0 = 0.0;
|
||||
TS_int = 0;
|
||||
T0S0 = 0.0;
|
||||
S_elec = 0.0;
|
||||
S_elec_1 = 0.0;
|
||||
S_elec_2 = 0.0;
|
||||
|
||||
qmass = 1.0e1;
|
||||
mu = 0.0;
|
||||
@ -71,48 +78,67 @@ FixMSST::FixMSST(LAMMPS *lmp, int narg, char **arg) :
|
||||
v0_set = 0;
|
||||
e0_set = 0;
|
||||
tscale = 0.01;
|
||||
dftb = 0;
|
||||
beta = 0.0;
|
||||
|
||||
if ( strcmp(arg[3],"x") == 0 )
|
||||
direction = 0;
|
||||
else if ( strcmp(arg[3],"y") == 0 )
|
||||
direction = 1;
|
||||
else if ( strcmp(arg[3],"z") == 0 )
|
||||
direction = 2;
|
||||
else {
|
||||
error->all(FLERR,"Illegal fix msst command");
|
||||
}
|
||||
if (strcmp(arg[3],"x") == 0) direction = 0;
|
||||
else if (strcmp(arg[3],"y") == 0) direction = 1;
|
||||
else if (strcmp(arg[3],"z") == 0) direction = 2;
|
||||
else error->all(FLERR,"Illegal fix msst command");
|
||||
|
||||
velocity = force->numeric(FLERR,arg[4]);
|
||||
if ( velocity < 0 )
|
||||
error->all(FLERR,"Illegal fix msst command");
|
||||
if (velocity < 0) error->all(FLERR,"Illegal fix msst command");
|
||||
|
||||
for ( int iarg = 5; iarg < narg; iarg++ ) {
|
||||
if ( strcmp(arg[iarg],"q") == 0 ) {
|
||||
// optional args
|
||||
|
||||
int iarg = 5;
|
||||
while (iarg < narg) {
|
||||
if (strcmp(arg[iarg],"q") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix msst command");
|
||||
qmass = force->numeric(FLERR,arg[iarg+1]);
|
||||
iarg++;
|
||||
} else if ( strcmp(arg[iarg],"mu") == 0 ) {
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"mu") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix msst command");
|
||||
mu = force->numeric(FLERR,arg[iarg+1]);
|
||||
iarg++;
|
||||
} else if ( strcmp(arg[iarg],"p0") == 0 ) {
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"p0") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix msst command");
|
||||
p0 = force->numeric(FLERR,arg[iarg+1]);
|
||||
iarg++;
|
||||
p0_set = 1;
|
||||
} else if ( strcmp(arg[iarg],"v0") == 0 ) {
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"v0") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix msst command");
|
||||
v0 = force->numeric(FLERR,arg[iarg+1]);
|
||||
v0_set = 1;
|
||||
iarg++;
|
||||
} else if ( strcmp(arg[iarg],"e0") == 0 ) {
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"e0") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix msst command");
|
||||
e0 = force->numeric(FLERR,arg[iarg+1]);
|
||||
e0_set = 1;
|
||||
iarg++;
|
||||
} else if ( strcmp(arg[iarg],"tscale") == 0 ) {
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"tscale") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix msst command");
|
||||
tscale = force->numeric(FLERR,arg[iarg+1]);
|
||||
if (tscale < 0.0 || tscale > 1.0)
|
||||
error->all(FLERR,"Fix msst tscale must satisfy 0 <= tscale < 1");
|
||||
iarg++;
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"dftb") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix msst command");
|
||||
if (strcmp(arg[iarg+1],"yes") == 0) dftb = 1;
|
||||
else if (strcmp(arg[iarg+1],"yes") == 0) dftb = 0;
|
||||
else error->all(FLERR,"Illegal fix msst command");
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"beta") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix msst command");
|
||||
beta = force->numeric(FLERR,arg[iarg+1]);
|
||||
if (beta < 0.0 || beta > 1.0)
|
||||
error->all(FLERR,"Illegal fix msst command");
|
||||
iarg += 2;
|
||||
} else error->all(FLERR,"Illegal fix msst command");
|
||||
}
|
||||
|
||||
// output MSST info
|
||||
|
||||
if (comm->me == 0) {
|
||||
if (screen) {
|
||||
fprintf(screen,"MSST parameters:\n");
|
||||
@ -166,15 +192,15 @@ FixMSST::FixMSST(LAMMPS *lmp, int narg, char **arg) :
|
||||
|
||||
if (domain->nonperiodic) error->all(FLERR,"Fix msst requires a periodic box");
|
||||
|
||||
// create a new compute temp style
|
||||
// id = fix-ID + temp
|
||||
// create a new temperature compute
|
||||
// id = fix-ID + "MSST_temp"
|
||||
// compute group = all since pressure is always global (group all)
|
||||
// and thus its KE/temperature contribution should use group all
|
||||
|
||||
int n = strlen(id) + 6;
|
||||
int n = strlen(id) + 10;
|
||||
id_temp = new char[n];
|
||||
strcpy(id_temp,id);
|
||||
strcat(id_temp,"_temp");
|
||||
strcat(id_temp,"MSST_temp");
|
||||
|
||||
char **newarg = new char*[3];
|
||||
newarg[0] = id_temp;
|
||||
@ -184,14 +210,14 @@ FixMSST::FixMSST(LAMMPS *lmp, int narg, char **arg) :
|
||||
delete [] newarg;
|
||||
tflag = 1;
|
||||
|
||||
// create a new compute pressure style
|
||||
// id = fix-ID + press, compute group = all
|
||||
// create a new pressure compute
|
||||
// id = fix-ID + "MSST_press", compute group = all
|
||||
// pass id_temp as 4th arg to pressure constructor
|
||||
|
||||
n = strlen(id) + 7;
|
||||
n = strlen(id) + 11;
|
||||
id_press = new char[n];
|
||||
strcpy(id_press,id);
|
||||
strcat(id_press,"_press");
|
||||
strcat(id_press,"MSST_press");
|
||||
|
||||
newarg = new char*[4];
|
||||
newarg[0] = id_press;
|
||||
@ -202,33 +228,30 @@ FixMSST::FixMSST(LAMMPS *lmp, int narg, char **arg) :
|
||||
delete [] newarg;
|
||||
pflag = 1;
|
||||
|
||||
// create a new compute potential energy compute
|
||||
// create a new potential energy compute
|
||||
// id = fix-ID + "MSST_pe", compute group = all
|
||||
|
||||
n = strlen(id) + 4;
|
||||
n = strlen(id) + 8;
|
||||
id_pe = new char[n];
|
||||
strcpy(id_pe,id);
|
||||
strcat(id_pe,"_pe");
|
||||
strcat(id_pe,"MSST_pe");
|
||||
|
||||
newarg = new char*[3];
|
||||
newarg[0] = id_pe;
|
||||
newarg[1] = (char*)"all";
|
||||
newarg[2] = (char*)"pe";
|
||||
newarg[1] = (char*) "all";
|
||||
newarg[2] = (char*) "pe";
|
||||
modify->add_compute(3,newarg);
|
||||
delete [] newarg;
|
||||
peflag = 1;
|
||||
|
||||
// initialize the time derivative of the volume.
|
||||
omega[0] = omega[1] = omega[2] = 0.0;
|
||||
// initialize the time derivative of the volume
|
||||
|
||||
omega[0] = omega[1] = omega[2] = 0.0;
|
||||
nrigid = 0;
|
||||
rfix = NULL;
|
||||
|
||||
old_velocity = new double* [atom->nlocal];
|
||||
for ( int j = 0; j < atom->nlocal; j++ ) {
|
||||
old_velocity[j] = new double [3];
|
||||
}
|
||||
atoms_allocated = atom->nlocal;
|
||||
|
||||
maxold = -1;
|
||||
old_velocity = NULL;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -247,11 +270,7 @@ FixMSST::~FixMSST()
|
||||
delete [] id_press;
|
||||
delete [] id_pe;
|
||||
|
||||
for ( int j = 0; j < atoms_allocated; j++ ) {
|
||||
delete [] old_velocity[j];
|
||||
}
|
||||
delete [] old_velocity;
|
||||
|
||||
memory->destroy(old_velocity);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -323,6 +342,15 @@ void FixMSST::init()
|
||||
strcmp(modify->fix[i]->style,"poems") == 0) rfix[nrigid++] = i;
|
||||
}
|
||||
|
||||
// find fix external being used to drive LAMMPS from DFTB+
|
||||
|
||||
if (dftb) {
|
||||
for (int i = 0; i < modify->nfix; i++)
|
||||
if (strcmp(modify->fix[i]->style,"external") == 0)
|
||||
fix_external = (FixExternal *) modify->fix[i];
|
||||
if (fix_external == NULL)
|
||||
error->all(FLERR,"Fix msst dftb cannot be used w/out fix external");
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -406,6 +434,7 @@ void FixMSST::setup(int vflag)
|
||||
|
||||
// trigger virial computation on next timestep
|
||||
|
||||
pe->addstep(update->ntimestep+1);
|
||||
pressure->addstep(update->ntimestep+1);
|
||||
}
|
||||
|
||||
@ -415,10 +444,10 @@ void FixMSST::setup(int vflag)
|
||||
|
||||
void FixMSST::initial_integrate(int vflag)
|
||||
{
|
||||
int sd;
|
||||
double p_msst; // MSST driving pressure.
|
||||
int i, k;
|
||||
double vol;
|
||||
int i,k;
|
||||
double p_msst; // MSST driving pressure
|
||||
double vol,TS,TS_term,escale_term;
|
||||
|
||||
int nlocal = atom->nlocal;
|
||||
int *mask = atom->mask;
|
||||
double **v = atom->v;
|
||||
@ -426,21 +455,51 @@ void FixMSST::initial_integrate(int vflag)
|
||||
double *mass = atom->mass;
|
||||
int *type = atom->type;
|
||||
double **x = atom->x;
|
||||
int sd = direction;
|
||||
|
||||
// check to see if old_velocity is correctly allocated
|
||||
// realloc old_velocity if necessary
|
||||
|
||||
check_alloc(nlocal);
|
||||
if (nlocal > maxold) {
|
||||
memory->destroy(old_velocity);
|
||||
maxold = atom->nmax;
|
||||
memory->create(old_velocity,maxold,3,"msst:old_velocity");
|
||||
}
|
||||
|
||||
sd = direction;
|
||||
// for DFTB, extract TS_dftb from fix external
|
||||
// must convert energy to mv^2 units
|
||||
|
||||
if (dftb) {
|
||||
double TS_dftb = fix_external->compute_vector(0);
|
||||
TS = force->ftm2v*TS_dftb;
|
||||
if (update->ntimestep == 1) T0S0 = TS;
|
||||
} else {
|
||||
TS = 0.0;
|
||||
T0S0 = 0.0;
|
||||
}
|
||||
|
||||
// compute new pressure and volume
|
||||
|
||||
// compute new pressure and volume.
|
||||
temperature->compute_vector();
|
||||
pressure->compute_vector();
|
||||
couple();
|
||||
vol = compute_vol();
|
||||
|
||||
// update S_elec terms and compute TS_dot via finite differences
|
||||
|
||||
S_elec_2 = S_elec_1;
|
||||
S_elec_1 = S_elec;
|
||||
double Temp = temperature->compute_scalar();
|
||||
S_elec = TS/Temp;
|
||||
TS_dot = Temp*(3.0*S_elec-4.0*S_elec_1+S_elec_2)/(2.0*update->dt);
|
||||
TS_int += (update->dt*TS_dot);
|
||||
//TS_int += (update->dt*TS_dot)/total_mass;
|
||||
|
||||
// compute etot + extra terms for conserved quantity
|
||||
|
||||
double e_scale = compute_etotal() + compute_scalar();
|
||||
|
||||
// propagate the time derivative of
|
||||
// the volume 1/2 step at fixed vol, r, rdot.
|
||||
// the volume 1/2 step at fixed vol, r, rdot
|
||||
|
||||
p_msst = nktv2p * mvv2e * velocity * velocity * total_mass *
|
||||
( v0 - vol)/( v0 * v0);
|
||||
@ -448,13 +507,11 @@ void FixMSST::initial_integrate(int vflag)
|
||||
(qmass * nktv2p * mvv2e);
|
||||
double B = total_mass * mu / ( qmass * vol );
|
||||
|
||||
// prevent blow-up of the volume.
|
||||
// prevent blow-up of the volume
|
||||
|
||||
if ( vol > v0 && A > 0.0 ) {
|
||||
A = -A;
|
||||
}
|
||||
if (vol > v0 && A > 0.0) A = -A;
|
||||
|
||||
// use taylor expansion to avoid singularity at B == 0.
|
||||
// use Taylor expansion to avoid singularity at B = 0
|
||||
|
||||
if ( B * dthalf > 1.0e-06 ) {
|
||||
omega[sd] = ( omega[sd] + A * ( exp(B * dthalf) - 1.0 ) / B )
|
||||
@ -465,73 +522,124 @@ void FixMSST::initial_integrate(int vflag)
|
||||
}
|
||||
|
||||
// propagate velocity sum 1/2 step by
|
||||
// temporarily propagating the velocities.
|
||||
// temporarily propagating the velocities
|
||||
|
||||
velocity_sum = compute_vsum();
|
||||
for (i = 0; i < nlocal; i++) {
|
||||
if (mask[i] & groupbit) {
|
||||
for ( k = 0; k < 3; k++ ) {
|
||||
double C = f[i][k] * force->ftm2v / mass[type[i]];
|
||||
double D = mu * omega[sd] * omega[sd] /
|
||||
(velocity_sum * mass[type[i]] * vol );
|
||||
old_velocity[i][k] = v[i][k];
|
||||
if ( k == direction ) {
|
||||
D = D - 2.0 * omega[sd] / vol;
|
||||
|
||||
if (dftb) {
|
||||
for (i = 0; i < nlocal; i++) {
|
||||
if (mask[i] & groupbit) {
|
||||
for ( k = 0; k < 3; k++ ) {
|
||||
double C = f[i][k] * force->ftm2v / mass[type[i]];
|
||||
TS_term = TS_dot/(mass[type[i]]*velocity_sum);
|
||||
escale_term = force->ftm2v*beta*(e0-e_scale) /
|
||||
(mass[type[i]]*velocity_sum);
|
||||
double D = mu * omega[sd] * omega[sd] /
|
||||
(velocity_sum * mass[type[i]] * vol );
|
||||
D += escale_term - TS_term;
|
||||
old_velocity[i][k] = v[i][k];
|
||||
if ( k == direction ) D -= 2.0 * omega[sd] / vol;
|
||||
if ( fabs(dthalf * D) > 1.0e-06 ) {
|
||||
double expd = exp(D * dthalf);
|
||||
v[i][k] = expd * ( C + D * v[i][k] - C / expd ) / D;
|
||||
} else {
|
||||
v[i][k] = v[i][k] + ( C + D * v[i][k] ) * dthalf +
|
||||
0.5 * (D * D * v[i][k] + C * D ) * dthalf * dthalf;
|
||||
}
|
||||
}
|
||||
if ( fabs(dthalf * D) > 1.0e-06 ) {
|
||||
double expd = exp(D * dthalf);
|
||||
v[i][k] = expd * ( C + D * v[i][k] - C / expd ) / D;
|
||||
} else {
|
||||
v[i][k] = v[i][k] + ( C + D * v[i][k] ) * dthalf +
|
||||
0.5 * (D * D * v[i][k] + C * D ) * dthalf * dthalf;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < nlocal; i++) {
|
||||
if (mask[i] & groupbit) {
|
||||
for ( k = 0; k < 3; k++ ) {
|
||||
double C = f[i][k] * force->ftm2v / mass[type[i]];
|
||||
double D = mu * omega[sd] * omega[sd] /
|
||||
(velocity_sum * mass[type[i]] * vol );
|
||||
old_velocity[i][k] = v[i][k];
|
||||
if ( k == direction ) {
|
||||
D = D - 2.0 * omega[sd] / vol;
|
||||
}
|
||||
if ( fabs(dthalf * D) > 1.0e-06 ) {
|
||||
double expd = exp(D * dthalf);
|
||||
v[i][k] = expd * ( C + D * v[i][k] - C / expd ) / D;
|
||||
} else {
|
||||
v[i][k] = v[i][k] + ( C + D * v[i][k] ) * dthalf +
|
||||
0.5 * (D * D * v[i][k] + C * D ) * dthalf * dthalf;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
velocity_sum = compute_vsum();
|
||||
|
||||
// reset the velocities.
|
||||
// reset the velocities
|
||||
|
||||
for (i = 0; i < nlocal; i++) {
|
||||
if (mask[i] & groupbit) {
|
||||
for ( k = 0; k < 3; k++ ) {
|
||||
v[i][k] = old_velocity[i][k];
|
||||
}
|
||||
v[i][0] = old_velocity[i][0];
|
||||
v[i][1] = old_velocity[i][1];
|
||||
v[i][2] = old_velocity[i][2];
|
||||
}
|
||||
}
|
||||
|
||||
// propagate velocities 1/2 step using the new velocity sum.
|
||||
// propagate velocities 1/2 step using the new velocity sum
|
||||
|
||||
for (i = 0; i < nlocal; i++) {
|
||||
if (mask[i] & groupbit) {
|
||||
for ( k = 0; k < 3; k++ ) {
|
||||
double C = f[i][k] * force->ftm2v / mass[type[i]];
|
||||
double D = mu * omega[sd] * omega[sd] /
|
||||
(velocity_sum * mass[type[i]] * vol );
|
||||
if ( k == direction ) {
|
||||
D = D - 2.0 * omega[sd] / vol;
|
||||
if (dftb) {
|
||||
for (i = 0; i < nlocal; i++) {
|
||||
if (mask[i] & groupbit) {
|
||||
for ( k = 0; k < 3; k++ ) {
|
||||
double C = f[i][k] * force->ftm2v / mass[type[i]];
|
||||
TS_term = TS_dot/(mass[type[i]]*velocity_sum);
|
||||
escale_term = force->ftm2v*beta*(e0-e_scale) /
|
||||
(mass[type[i]]*velocity_sum);
|
||||
double D = mu * omega[sd] * omega[sd] /
|
||||
(velocity_sum * mass[type[i]] * vol );
|
||||
D += escale_term - TS_term;
|
||||
if ( k == direction ) D -= 2.0 * omega[sd] / vol;
|
||||
if ( fabs(dthalf * D) > 1.0e-06 ) {
|
||||
double expd = exp(D * dthalf);
|
||||
v[i][k] = expd * ( C + D * v[i][k] - C / expd ) / D;
|
||||
} else {
|
||||
v[i][k] = v[i][k] + ( C + D * v[i][k] ) * dthalf +
|
||||
0.5 * (D * D * v[i][k] + C * D ) * dthalf * dthalf;
|
||||
}
|
||||
}
|
||||
if ( fabs(dthalf * D) > 1.0e-06 ) {
|
||||
double expd = exp(D * dthalf);
|
||||
v[i][k] = expd * ( C + D * v[i][k] - C / expd ) / D;
|
||||
} else {
|
||||
v[i][k] = v[i][k] + ( C + D * v[i][k] ) * dthalf +
|
||||
0.5 * (D * D * v[i][k] + C * D ) * dthalf * dthalf;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < nlocal; i++) {
|
||||
if (mask[i] & groupbit) {
|
||||
for ( k = 0; k < 3; k++ ) {
|
||||
double C = f[i][k] * force->ftm2v / mass[type[i]];
|
||||
double D = mu * omega[sd] * omega[sd] /
|
||||
(velocity_sum * mass[type[i]] * vol );
|
||||
if ( k == direction ) {
|
||||
D = D - 2.0 * omega[sd] / vol;
|
||||
}
|
||||
if ( fabs(dthalf * D) > 1.0e-06 ) {
|
||||
double expd = exp(D * dthalf);
|
||||
v[i][k] = expd * ( C + D * v[i][k] - C / expd ) / D;
|
||||
} else {
|
||||
v[i][k] = v[i][k] + ( C + D * v[i][k] ) * dthalf +
|
||||
0.5 * (D * D * v[i][k] + C * D ) * dthalf * dthalf;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// propagate the volume 1/2 step.
|
||||
// propagate the volume 1/2 step
|
||||
|
||||
double vol1 = vol + omega[sd] * dthalf;
|
||||
|
||||
// rescale positions and change box size.
|
||||
// rescale positions and change box size
|
||||
|
||||
dilation[sd] = vol1/vol;
|
||||
remap(0);
|
||||
|
||||
// propagate particle positions 1 time step.
|
||||
// propagate particle positions 1 time step
|
||||
|
||||
for (i = 0; i < nlocal; i++) {
|
||||
if (mask[i] & groupbit) {
|
||||
@ -541,11 +649,11 @@ void FixMSST::initial_integrate(int vflag)
|
||||
}
|
||||
}
|
||||
|
||||
// propagate the volume 1/2 step.
|
||||
// propagate the volume 1/2 step
|
||||
|
||||
double vol2 = vol1 + omega[sd] * dthalf;
|
||||
|
||||
// rescale positions and change box size.
|
||||
// rescale positions and change box size
|
||||
|
||||
dilation[sd] = vol2/vol1;
|
||||
remap(0);
|
||||
@ -560,6 +668,8 @@ void FixMSST::initial_integrate(int vflag)
|
||||
void FixMSST::final_integrate()
|
||||
{
|
||||
int i;
|
||||
double p_msst; // MSST driving pressure
|
||||
double TS_term,escale_term;
|
||||
|
||||
// v update only for atoms in MSST group
|
||||
|
||||
@ -570,32 +680,60 @@ void FixMSST::final_integrate()
|
||||
int *mask = atom->mask;
|
||||
int nlocal = atom->nlocal;
|
||||
double vol = compute_vol();
|
||||
double p_msst;
|
||||
|
||||
int sd = direction;
|
||||
|
||||
// propagate particle velocities 1/2 step.
|
||||
// compute etot + extra terms for conserved quantity
|
||||
|
||||
for (i = 0; i < nlocal; i++) {
|
||||
if (mask[i] & groupbit) {
|
||||
for ( int k = 0; k < 3; k++ ) {
|
||||
double C = f[i][k] * force->ftm2v / mass[type[i]];
|
||||
double D = mu * omega[sd] * omega[sd] /
|
||||
(velocity_sum * mass[type[i]] * vol );
|
||||
if ( k == direction ) {
|
||||
D = D - 2.0 * omega[sd] / vol;
|
||||
double e_scale = compute_etotal() + compute_scalar();
|
||||
|
||||
// propagate particle velocities 1/2 step
|
||||
|
||||
if (dftb) {
|
||||
for (i = 0; i < nlocal; i++) {
|
||||
if (mask[i] & groupbit) {
|
||||
for ( int k = 0; k < 3; k++ ) {
|
||||
double C = f[i][k] * force->ftm2v / mass[type[i]];
|
||||
TS_term = TS_dot/(mass[type[i]]*velocity_sum);
|
||||
escale_term = force->ftm2v*beta*(e0-e_scale) /
|
||||
(mass[type[i]]*velocity_sum);
|
||||
double D = mu * omega[sd] * omega[sd] /
|
||||
(velocity_sum * mass[type[i]] * vol );
|
||||
D += escale_term - TS_term;
|
||||
if ( k == direction ) D -= 2.0 * omega[sd] / vol;
|
||||
if ( fabs(dthalf * D) > 1.0e-06 ) {
|
||||
double expd = exp(D * dthalf);
|
||||
v[i][k] = expd * ( C + D * v[i][k] - C / expd ) / D;
|
||||
} else {
|
||||
v[i][k] = v[i][k] + ( C + D * v[i][k] ) * dthalf +
|
||||
0.5 * (D * D * v[i][k] + C * D ) * dthalf * dthalf;
|
||||
}
|
||||
}
|
||||
if ( fabs(dthalf * D) > 1.0e-06 ) {
|
||||
double expd = exp(D * dthalf);
|
||||
v[i][k] = expd * ( C + D * v[i][k] - C / expd ) / D;
|
||||
} else {
|
||||
v[i][k] = v[i][k] + ( C + D * v[i][k] ) * dthalf +
|
||||
0.5 * (D * D * v[i][k] + C * D ) * dthalf * dthalf;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < nlocal; i++) {
|
||||
if (mask[i] & groupbit) {
|
||||
for ( int k = 0; k < 3; k++ ) {
|
||||
double C = f[i][k] * force->ftm2v / mass[type[i]];
|
||||
double D = mu * omega[sd] * omega[sd] /
|
||||
(velocity_sum * mass[type[i]] * vol );
|
||||
if ( k == direction ) {
|
||||
D = D - 2.0 * omega[sd] / vol;
|
||||
}
|
||||
if ( fabs(dthalf * D) > 1.0e-06 ) {
|
||||
double expd = exp(D * dthalf);
|
||||
v[i][k] = expd * ( C + D * v[i][k] - C / expd ) / D;
|
||||
} else {
|
||||
v[i][k] = v[i][k] + ( C + D * v[i][k] ) * dthalf +
|
||||
0.5 * (D * D * v[i][k] + C * D ) * dthalf * dthalf;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// compute new pressure and volume.
|
||||
// compute new pressure and volume
|
||||
|
||||
temperature->compute_vector();
|
||||
|
||||
@ -604,7 +742,7 @@ void FixMSST::final_integrate()
|
||||
velocity_sum = compute_vsum();
|
||||
vol = compute_vol();
|
||||
|
||||
// propagate the time derivative of the volume 1/2 step at fixed V, r, rdot.
|
||||
// propagate the time derivative of the volume 1/2 step at fixed V, r, rdot
|
||||
|
||||
p_msst = nktv2p * mvv2e * velocity * velocity * total_mass *
|
||||
( v0 - vol )/( v0 * v0 );
|
||||
@ -612,11 +750,9 @@ void FixMSST::final_integrate()
|
||||
( qmass * nktv2p * mvv2e );
|
||||
double B = total_mass * mu / ( qmass * vol );
|
||||
|
||||
// prevent blow-up of the volume.
|
||||
// prevent blow-up of the volume
|
||||
|
||||
if ( vol > v0 && A > 0.0 ) {
|
||||
A = -A;
|
||||
}
|
||||
if ( vol > v0 && A > 0.0 ) A = -A;
|
||||
|
||||
// use taylor expansion to avoid singularity at B == 0.
|
||||
|
||||
@ -632,8 +768,9 @@ void FixMSST::final_integrate()
|
||||
|
||||
lagrangian_position -= velocity*vol/v0*update->dt;
|
||||
|
||||
// trigger virial computation on next timestep
|
||||
// trigger energy and virial computation on next timestep
|
||||
|
||||
pe->addstep(update->ntimestep+1);
|
||||
pressure->addstep(update->ntimestep+1);
|
||||
}
|
||||
|
||||
@ -707,11 +844,12 @@ void FixMSST::remap(int flag)
|
||||
void FixMSST::write_restart(FILE *fp)
|
||||
{
|
||||
int n = 0;
|
||||
double list[4];
|
||||
double list[5];
|
||||
list[n++] = omega[direction];
|
||||
list[n++] = e0;
|
||||
list[n++] = v0;
|
||||
list[n++] = p0;
|
||||
list[n++] = TS_int;
|
||||
if (comm->me == 0) {
|
||||
int size = n * sizeof(double);
|
||||
fwrite(&size,sizeof(int),1,fp);
|
||||
@ -731,6 +869,8 @@ void FixMSST::restart(char *buf)
|
||||
e0 = list[n++];
|
||||
v0 = list[n++];
|
||||
p0 = list[n++];
|
||||
TS_int = list[n++];
|
||||
tscale = 0.0; // set tscale to zero for restart
|
||||
p0_set = 1;
|
||||
v0_set = 1;
|
||||
e0_set = 1;
|
||||
@ -752,11 +892,13 @@ int FixMSST::modify_param(int narg, char **arg)
|
||||
strcpy(id_temp,arg[1]);
|
||||
|
||||
int icompute = modify->find_compute(id_temp);
|
||||
if (icompute < 0) error->all(FLERR,"Could not find fix_modify temperature ID");
|
||||
if (icompute < 0)
|
||||
error->all(FLERR,"Could not find fix_modify temperature ID");
|
||||
temperature = modify->compute[icompute];
|
||||
|
||||
if (temperature->tempflag == 0)
|
||||
error->all(FLERR,"Fix_modify temperature ID does not compute temperature");
|
||||
error->all(FLERR,"Fix_modify temperature ID does not "
|
||||
"compute temperature");
|
||||
if (temperature->igroup != 0 && comm->me == 0)
|
||||
error->warning(FLERR,"Temperature for MSST is not for group all");
|
||||
|
||||
@ -806,6 +948,10 @@ double FixMSST::compute_scalar()
|
||||
(1.0 - volume/ v0) * mvv2e;
|
||||
energy -= p0 * ( v0 - volume ) / nktv2p;
|
||||
|
||||
// subtract off precomputed TS_int integral value
|
||||
|
||||
energy -= TS_int;
|
||||
|
||||
return energy;
|
||||
}
|
||||
|
||||
@ -920,25 +1066,7 @@ double FixMSST::compute_vol()
|
||||
return domain->xprd * domain->yprd;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Checks to see if the allocated size of old_velocity is >= n
|
||||
The number of local atoms can change during a parallel run.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixMSST::check_alloc(int n)
|
||||
{
|
||||
if ( atoms_allocated < n ) {
|
||||
for ( int j = 0; j < atoms_allocated; j++ ) {
|
||||
delete [] old_velocity[j];
|
||||
}
|
||||
delete [] old_velocity;
|
||||
|
||||
old_velocity = new double* [n];
|
||||
for ( int j = 0; j < n; j++ )
|
||||
old_velocity[j] = new double [3];
|
||||
atoms_allocated = n;
|
||||
}
|
||||
}
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
double FixMSST::compute_vsum()
|
||||
{
|
||||
@ -959,3 +1087,14 @@ double FixMSST::compute_vsum()
|
||||
MPI_Allreduce(&t,&vsum,1,MPI_DOUBLE,MPI_SUM,world);
|
||||
return vsum;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
memory usage of local atom-based array
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
double FixMSST::memory_usage()
|
||||
{
|
||||
double bytes = 3*atom->nmax * sizeof(double);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
@ -10,10 +10,6 @@
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
/* Implementation of the Multi-Scale Shock Method.
|
||||
See Reed, Fried, Joannopoulos, Phys. Rev. Lett., 90, 235503(2003).
|
||||
Implementation by Laurence Fried, LLNL, 4/2007.
|
||||
*/
|
||||
|
||||
#ifdef FIX_CLASS
|
||||
|
||||
@ -42,55 +38,67 @@ class FixMSST : public Fix {
|
||||
void write_restart(FILE *);
|
||||
void restart(char *);
|
||||
int modify_param(int, char **);
|
||||
double memory_usage();
|
||||
|
||||
private:
|
||||
double dtv,dtf,dthalf; // Full and half step sizes.
|
||||
double boltz,nktv2p, mvv2e; // Boltzmann factor and unit conversions.
|
||||
double total_mass; // Mass of the computational cell.
|
||||
double dtv,dtf,dthalf; // Full and half step sizes
|
||||
double boltz,nktv2p, mvv2e; // Boltzmann factor and unit conversions
|
||||
double total_mass; // Mass of the computational cell
|
||||
|
||||
double omega[3]; // Time derivative of the volume.
|
||||
double omega[3]; // Time derivative of the volume
|
||||
double p_current[3],dilation[3];
|
||||
double qmass; // Effective cell mass.
|
||||
double mu; // Effective cell viscosity.
|
||||
double qmass; // Effective cell mass
|
||||
double mu; // Effective cell viscosity
|
||||
double tscale; // Converts thermal energy to compressive
|
||||
// strain ke at simulation start
|
||||
int dftb; // flag for use with DFTB+
|
||||
|
||||
double velocity_sum; // Sum of the velocities squared.
|
||||
double velocity_sum; // Sum of the velocities squared
|
||||
double damping; // Damping function for TS force term at
|
||||
// small volume difference (v0 - vol)
|
||||
double T0S0; // Initial TS term for DFTB+ simulations
|
||||
double S_elec,S_elec_1,S_elec_2; // time history of electron entropy
|
||||
// for DFTB+ simulaitons
|
||||
double TS_dot; // time derivative of TS term for
|
||||
// DFTB+ simulations
|
||||
|
||||
double **old_velocity; // Saved velocities.
|
||||
double **old_velocity; // Saved velocities
|
||||
|
||||
int kspace_flag; // 1 if KSpace invoked, 0 if not
|
||||
int nrigid; // number of rigid fixes
|
||||
int *rfix; // indices of rigid fixes
|
||||
|
||||
char *id_temp,*id_press; // Strings with identifiers of
|
||||
char *id_pe; // created computes.
|
||||
char *id_pe; // created computes
|
||||
|
||||
class Compute *temperature; // Computes created to evaluate
|
||||
class Compute *pressure; // thermodynamic quantities.
|
||||
class Compute *pressure; // thermodynamic quantities
|
||||
class Compute *pe;
|
||||
int tflag,pflag,vsflag,peflag; // Flags to keep track of computes that
|
||||
// were created.
|
||||
// were created
|
||||
|
||||
// shock initial conditions.
|
||||
// shock initial conditions
|
||||
|
||||
double e0; // Initial energy
|
||||
double v0; // Initial volume
|
||||
double p0; // Initial pressure
|
||||
double velocity; // Velocity of the shock.
|
||||
double velocity; // Velocity of the shock
|
||||
double lagrangian_position; // Lagrangian location of computational cell
|
||||
int direction; // Direction of shock
|
||||
int p0_set; // Is pressure set.
|
||||
int v0_set; // Is volume set.
|
||||
int e0_set; // Is energy set.
|
||||
int p0_set; // Is pressure set
|
||||
int v0_set; // Is volume set
|
||||
int e0_set; // Is energy set
|
||||
double TS_int; // Needed for conserved quantity
|
||||
// with thermal electronic excitations
|
||||
double beta; // Energy conservation scaling factor
|
||||
|
||||
int atoms_allocated; // The number of allocated atoms in old_velocity.
|
||||
int maxold; // allocated size of old_velocity
|
||||
class FixExternal *fix_external; // ptr to fix external
|
||||
|
||||
// functions
|
||||
|
||||
void couple();
|
||||
void remap(int);
|
||||
void check_alloc(int n);
|
||||
double compute_etotal();
|
||||
double compute_vol();
|
||||
double compute_hugoniot();
|
||||
|
||||
@ -748,7 +748,8 @@ void FixIntel::add_oresults(const ft * _noalias const f_in,
|
||||
if (eatom) {
|
||||
double * _noalias const lmp_eatom = force->pair->eatom + out_offset;
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma novector
|
||||
#pragma vector aligned
|
||||
#pragma ivdep
|
||||
#endif
|
||||
for (int i = ifrom; i < ito; i++) {
|
||||
f[i].x += f_in[ii].x;
|
||||
@ -762,7 +763,8 @@ void FixIntel::add_oresults(const ft * _noalias const f_in,
|
||||
}
|
||||
} else {
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma novector
|
||||
#pragma vector aligned
|
||||
#pragma ivdep
|
||||
#endif
|
||||
for (int i = ifrom; i < ito; i++) {
|
||||
f[i].x += f_in[ii].x;
|
||||
@ -778,7 +780,8 @@ void FixIntel::add_oresults(const ft * _noalias const f_in,
|
||||
if (eatom) {
|
||||
double * _noalias const lmp_eatom = force->pair->eatom + out_offset;
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma novector
|
||||
#pragma vector aligned
|
||||
#pragma ivdep
|
||||
#endif
|
||||
for (int i = ifrom; i < ito; i++) {
|
||||
f[i].x += f_in[i].x;
|
||||
@ -788,7 +791,8 @@ void FixIntel::add_oresults(const ft * _noalias const f_in,
|
||||
}
|
||||
} else {
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma novector
|
||||
#pragma vector aligned
|
||||
#pragma ivdep
|
||||
#endif
|
||||
for (int i = ifrom; i < ito; i++) {
|
||||
f[i].x += f_in[i].x;
|
||||
|
||||
@ -172,6 +172,10 @@ class IntelBuffers {
|
||||
|
||||
inline void thr_pack(const int ifrom, const int ito, const int ago) {
|
||||
if (ago == 0) {
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma vector aligned
|
||||
#pragma ivdep
|
||||
#endif
|
||||
for (int i = ifrom; i < ito; i++) {
|
||||
_x[i].x = lmp->atom->x[i][0];
|
||||
_x[i].y = lmp->atom->x[i][1];
|
||||
@ -179,9 +183,17 @@ class IntelBuffers {
|
||||
_x[i].w = lmp->atom->type[i];
|
||||
}
|
||||
if (lmp->atom->q != NULL)
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma vector aligned
|
||||
#pragma ivdep
|
||||
#endif
|
||||
for (int i = ifrom; i < ito; i++)
|
||||
_q[i] = lmp->atom->q[i];
|
||||
} else {
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma vector aligned
|
||||
#pragma ivdep
|
||||
#endif
|
||||
for (int i = ifrom; i < ito; i++) {
|
||||
_x[i].x = lmp->atom->x[i][0];
|
||||
_x[i].y = lmp->atom->x[i][1];
|
||||
@ -204,7 +216,10 @@ class IntelBuffers {
|
||||
const int offset, const bool dotype = false) {
|
||||
double ** x = lmp->atom->x + offset;
|
||||
if (dotype == false) {
|
||||
#pragma vector nontemporal
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma vector aligned
|
||||
#pragma ivdep
|
||||
#endif
|
||||
for (int i = ifrom; i < ito; i++) {
|
||||
_x[i].x = x[i][0];
|
||||
_x[i].y = x[i][1];
|
||||
@ -212,7 +227,10 @@ class IntelBuffers {
|
||||
}
|
||||
} else {
|
||||
int *type = lmp->atom->type + offset;
|
||||
#pragma vector nontemporal
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma vector aligned
|
||||
#pragma ivdep
|
||||
#endif
|
||||
for (int i = ifrom; i < ito; i++) {
|
||||
_x[i].x = x[i][0];
|
||||
_x[i].y = x[i][1];
|
||||
@ -225,6 +243,10 @@ class IntelBuffers {
|
||||
inline void thr_pack_host(const int ifrom, const int ito,
|
||||
const int offset) {
|
||||
double ** x = lmp->atom->x + offset;
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma vector aligned
|
||||
#pragma ivdep
|
||||
#endif
|
||||
for (int i = ifrom; i < ito; i++) {
|
||||
_host_x[i].x = x[i][0];
|
||||
_host_x[i].y = x[i][1];
|
||||
|
||||
@ -68,7 +68,7 @@ enum {TIME_PACK, TIME_HOST_NEIGHBOR, TIME_HOST_PAIR, TIME_OFFLOAD_NEIGHBOR,
|
||||
#define INTEL_MAX_STENCIL 256
|
||||
// INTEL_MAX_STENCIL * sqrt(INTEL_MAX_STENCIL)
|
||||
#define INTEL_MAX_STENCIL_CHECK 4096
|
||||
#define INTEL_P3M_MAXORDER 7
|
||||
#define INTEL_P3M_MAXORDER 8
|
||||
#define INTEL_P3M_ALIGNED_MAXORDER 8
|
||||
// PRECOMPUTE VALUES IN TABLE (DOESN'T AFFECT ACCURACY)
|
||||
#define INTEL_P3M_TABLE 1
|
||||
@ -248,12 +248,6 @@ enum {TIME_PACK, TIME_HOST_NEIGHBOR, TIME_HOST_PAIR, TIME_OFFLOAD_NEIGHBOR,
|
||||
|
||||
#else
|
||||
|
||||
#define IP_PRE_omp_range(ifrom, ito, tid, inum, nthreads) \
|
||||
{ \
|
||||
ifrom = 0; \
|
||||
ito = inum; \
|
||||
}
|
||||
|
||||
#define IP_PRE_omp_range_id(ifrom, ito, tid, inum, nthreads) \
|
||||
{ \
|
||||
tid = 0; \
|
||||
@ -299,15 +293,6 @@ enum {TIME_PACK, TIME_HOST_NEIGHBOR, TIME_HOST_PAIR, TIME_OFFLOAD_NEIGHBOR,
|
||||
ito = inum; \
|
||||
}
|
||||
|
||||
#define IP_PRE_omp_range_id_vec(ifrom, ip, ito, tid, inum, \
|
||||
nthreads, vecsize) \
|
||||
{ \
|
||||
tid = 0; \
|
||||
ifrom = 0; \
|
||||
ito = inum; \
|
||||
ip = vecsize; \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define IP_PRE_fdotr_acc_force_l5(lf, lt, minlocal, nthreads, f_start, \
|
||||
|
||||
@ -885,21 +885,22 @@ void PPPMDispIntel::make_rho_c(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
FFT_SCALAR z0 = fdelvolinv * q[i];
|
||||
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int n = 0; n < order; n++) {
|
||||
int mz = n*nix*niy + nzsum;
|
||||
FFT_SCALAR y0 = z0*rho[2][n];
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int m = 0; m < order; m++) {
|
||||
int mzy = m*nix + mz;
|
||||
FFT_SCALAR x0 = y0*rho[1][m];
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#pragma simd
|
||||
#endif
|
||||
for (int l = 0; l < INTEL_P3M_ALIGNED_MAXORDER; l++) {
|
||||
for (int l = 0; l < order; l++) {
|
||||
int mzyx = l + mzy;
|
||||
my_density[mzyx] += x0*rho[0][l];
|
||||
}
|
||||
@ -1034,21 +1035,22 @@ void PPPMDispIntel::make_rho_g(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
FFT_SCALAR z0 = fdelvolinv * B[type];
|
||||
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int n = 0; n < order_6; n++) {
|
||||
int mz = n*nix*niy + nzsum;
|
||||
FFT_SCALAR y0 = z0*rho[2][n];
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int m = 0; m < order_6; m++) {
|
||||
int mzy = m*nix + mz;
|
||||
FFT_SCALAR x0 = y0*rho[1][m];
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#pragma simd
|
||||
#endif
|
||||
for (int l = 0; l < INTEL_P3M_ALIGNED_MAXORDER; l++) {
|
||||
for (int l = 0; l < order; l++) {
|
||||
int mzyx = l + mzy;
|
||||
my_density[mzyx] += x0*rho[0][l];
|
||||
}
|
||||
@ -1181,21 +1183,22 @@ void PPPMDispIntel::make_rho_a(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
FFT_SCALAR z0 = fdelvolinv;
|
||||
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int n = 0; n < order_6; n++) {
|
||||
int mz = n + nzsum;
|
||||
FFT_SCALAR y0 = z0*rho[2][n];
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int m = 0; m < order_6; m++) {
|
||||
int my = m + nysum;
|
||||
FFT_SCALAR x0 = y0*rho[1][m];
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#pragma simd
|
||||
#endif
|
||||
for (int l = 0; l < INTEL_P3M_ALIGNED_MAXORDER; l++) {
|
||||
for (int l = 0; l < order; l++) {
|
||||
int mx = l + nxsum;
|
||||
FFT_SCALAR w = x0*rho[0][l];
|
||||
density_brick_a0[mz][my][mx] += w*B[7*type];
|
||||
@ -1314,21 +1317,22 @@ void PPPMDispIntel::make_rho_none(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
FFT_SCALAR z0 = fdelvolinv;
|
||||
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int n = 0; n < order_6; n++) {
|
||||
int mz = n*nix*niy + nzsum;
|
||||
FFT_SCALAR y0 = z0*rho[2][n];
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int m = 0; m < order_6; m++) {
|
||||
int mzy = m*nix + mz;
|
||||
FFT_SCALAR x0 = y0*rho[1][m];
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#pragma simd
|
||||
#endif
|
||||
for (int l = 0; l < INTEL_P3M_ALIGNED_MAXORDER; l++) {
|
||||
for (int l = 0; l < order; l++) {
|
||||
int mzyx = l + mzy;
|
||||
FFT_SCALAR w0 = x0*rho[0][l];
|
||||
for(int k = 0; k < nsplit; k++)
|
||||
@ -1462,21 +1466,22 @@ void PPPMDispIntel::fieldforce_c_ik(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
_alignvar(FFT_SCALAR ekz_arr[INTEL_P3M_ALIGNED_MAXORDER], 64) = {0};
|
||||
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int n = 0; n < order; n++) {
|
||||
int mz = n+nzsum;
|
||||
FFT_SCALAR z0 = rho2[n];
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int m = 0; m < order; m++) {
|
||||
int my = m+nysum;
|
||||
FFT_SCALAR y0 = z0*rho1[m];
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#pragma simd
|
||||
#endif
|
||||
for (int l = 0; l < INTEL_P3M_ALIGNED_MAXORDER; l++) {
|
||||
for (int l = 0; l < order; l++) {
|
||||
int mx = l+nxsum;
|
||||
FFT_SCALAR x0 = y0*rho0[l];
|
||||
ekx_arr[l] -= x0*vdx_brick[mz][my][mx];
|
||||
@ -1490,12 +1495,11 @@ void PPPMDispIntel::fieldforce_c_ik(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
FFT_SCALAR ekx, eky, ekz;
|
||||
ekx = eky = ekz = ZEROF;
|
||||
|
||||
|
||||
for (int l = 0; l < INTEL_P3M_ALIGNED_MAXORDER; l++) {
|
||||
ekx += ekx_arr[l];
|
||||
eky += eky_arr[l];
|
||||
ekz += ekz_arr[l];
|
||||
}
|
||||
for (int l = 0; l < order; l++) {
|
||||
ekx += ekx_arr[l];
|
||||
eky += eky_arr[l];
|
||||
ekz += ekz_arr[l];
|
||||
}
|
||||
|
||||
// convert E-field to force
|
||||
|
||||
@ -1643,12 +1647,12 @@ void PPPMDispIntel::fieldforce_c_ad(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
|
||||
particle_ekx[i] = particle_eky[i] = particle_ekz[i] = ZEROF;
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int n = 0; n < order; n++) {
|
||||
int mz = n + nzsum;
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int m = 0; m < order; m++) {
|
||||
int my = m + nysum;
|
||||
@ -1656,9 +1660,10 @@ void PPPMDispIntel::fieldforce_c_ad(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
FFT_SCALAR eky_p = drho[1][m] * rho[2][n];
|
||||
FFT_SCALAR ekz_p = rho[1][m] * drho[2][n];
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#pragma simd
|
||||
#endif
|
||||
for (int l = 0; l < INTEL_P3M_ALIGNED_MAXORDER; l++) {
|
||||
for (int l = 0; l < order; l++) {
|
||||
int mx = l + nxsum;
|
||||
ekx[l] += drho[0][l] * ekx_p * u_brick[mz][my][mx];
|
||||
eky[l] += rho[0][l] * eky_p * u_brick[mz][my][mx];
|
||||
@ -1668,9 +1673,9 @@ void PPPMDispIntel::fieldforce_c_ad(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
}
|
||||
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma simd
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int l = 0; l < INTEL_P3M_ALIGNED_MAXORDER; l++){
|
||||
for (int l = 0; l < order; l++){
|
||||
particle_ekx[i] += ekx[l];
|
||||
particle_eky[i] += eky[l];
|
||||
particle_ekz[i] += ekz[l];
|
||||
@ -1809,21 +1814,22 @@ void PPPMDispIntel::fieldforce_g_ik(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
_alignvar(FFT_SCALAR ekz_arr[INTEL_P3M_ALIGNED_MAXORDER], 64) = {0};
|
||||
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int n = 0; n < order_6; n++) {
|
||||
int mz = n+nzsum;
|
||||
FFT_SCALAR z0 = rho2[n];
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int m = 0; m < order_6; m++) {
|
||||
int my = m+nysum;
|
||||
FFT_SCALAR y0 = z0*rho1[m];
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#pragma simd
|
||||
#endif
|
||||
for (int l = 0; l < INTEL_P3M_ALIGNED_MAXORDER; l++) {
|
||||
for (int l = 0; l < order; l++) {
|
||||
int mx = l+nxsum;
|
||||
FFT_SCALAR x0 = y0*rho0[l];
|
||||
ekx_arr[l] -= x0*vdx_brick_g[mz][my][mx];
|
||||
@ -1837,12 +1843,11 @@ void PPPMDispIntel::fieldforce_g_ik(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
FFT_SCALAR ekx, eky, ekz;
|
||||
ekx = eky = ekz = ZEROF;
|
||||
|
||||
|
||||
for (int l = 0; l < INTEL_P3M_ALIGNED_MAXORDER; l++) {
|
||||
ekx += ekx_arr[l];
|
||||
eky += eky_arr[l];
|
||||
ekz += ekz_arr[l];
|
||||
}
|
||||
for (int l = 0; l < order; l++) {
|
||||
ekx += ekx_arr[l];
|
||||
eky += eky_arr[l];
|
||||
ekz += ekz_arr[l];
|
||||
}
|
||||
|
||||
// convert E-field to force
|
||||
|
||||
@ -1985,12 +1990,12 @@ void PPPMDispIntel::fieldforce_g_ad(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
|
||||
particle_ekx[i] = particle_eky[i] = particle_ekz[i] = ZEROF;
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int n = 0; n < order_6; n++) {
|
||||
int mz = n + nzsum;
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int m = 0; m < order_6; m++) {
|
||||
int my = m + nysum;
|
||||
@ -1998,9 +2003,10 @@ void PPPMDispIntel::fieldforce_g_ad(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
FFT_SCALAR eky_p = drho[1][m] * rho[2][n];
|
||||
FFT_SCALAR ekz_p = rho[1][m] * drho[2][n];
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#pragma simd
|
||||
#endif
|
||||
for (int l = 0; l < INTEL_P3M_ALIGNED_MAXORDER; l++) {
|
||||
for (int l = 0; l < order; l++) {
|
||||
int mx = l + nxsum;
|
||||
ekx[l] += drho[0][l] * ekx_p * u_brick_g[mz][my][mx];
|
||||
eky[l] += rho[0][l] * eky_p * u_brick_g[mz][my][mx];
|
||||
@ -2010,9 +2016,9 @@ void PPPMDispIntel::fieldforce_g_ad(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
}
|
||||
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma simd
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int l = 0; l < INTEL_P3M_ALIGNED_MAXORDER; l++){
|
||||
for (int l = 0; l < order; l++){
|
||||
particle_ekx[i] += ekx[l];
|
||||
particle_eky[i] += eky[l];
|
||||
particle_ekz[i] += ekz[l];
|
||||
@ -2168,21 +2174,22 @@ void PPPMDispIntel::fieldforce_a_ik(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
|
||||
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int n = 0; n < order_6; n++) {
|
||||
int mz = n+nzsum;
|
||||
FFT_SCALAR z0 = rho2[n];
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int m = 0; m < order_6; m++) {
|
||||
int my = m+nysum;
|
||||
FFT_SCALAR y0 = z0*rho1[m];
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#pragma simd
|
||||
#endif
|
||||
for (int l = 0; l < INTEL_P3M_ALIGNED_MAXORDER; l++) {
|
||||
for (int l = 0; l < order; l++) {
|
||||
int mx = l+nxsum;
|
||||
FFT_SCALAR x0 = y0*rho0[l];
|
||||
ekx0_arr[l] -= x0*vdx_brick_a0[mz][my][mx];
|
||||
@ -2221,29 +2228,29 @@ void PPPMDispIntel::fieldforce_a_ik(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
ekx5 = eky5 = ekz5 = ZEROF;
|
||||
ekx6 = eky6 = ekz6 = ZEROF;
|
||||
|
||||
for (int l = 0; l < INTEL_P3M_ALIGNED_MAXORDER; l++) {
|
||||
ekx0 += ekx0_arr[l];
|
||||
eky0 += eky0_arr[l];
|
||||
ekz0 += ekz0_arr[l];
|
||||
ekx1 += ekx1_arr[l];
|
||||
eky1 += eky1_arr[l];
|
||||
ekz1 += ekz1_arr[l];
|
||||
ekx2 += ekx2_arr[l];
|
||||
eky2 += eky2_arr[l];
|
||||
ekz2 += ekz2_arr[l];
|
||||
ekx3 += ekx3_arr[l];
|
||||
eky3 += eky3_arr[l];
|
||||
ekz3 += ekz3_arr[l];
|
||||
ekx4 += ekx4_arr[l];
|
||||
eky4 += eky4_arr[l];
|
||||
ekz4 += ekz4_arr[l];
|
||||
ekx5 += ekx5_arr[l];
|
||||
eky5 += eky5_arr[l];
|
||||
ekz5 += ekz5_arr[l];
|
||||
ekx6 += ekx6_arr[l];
|
||||
eky6 += eky6_arr[l];
|
||||
ekz6 += ekz6_arr[l];
|
||||
}
|
||||
for (int l = 0; l < order; l++) {
|
||||
ekx0 += ekx0_arr[l];
|
||||
eky0 += eky0_arr[l];
|
||||
ekz0 += ekz0_arr[l];
|
||||
ekx1 += ekx1_arr[l];
|
||||
eky1 += eky1_arr[l];
|
||||
ekz1 += ekz1_arr[l];
|
||||
ekx2 += ekx2_arr[l];
|
||||
eky2 += eky2_arr[l];
|
||||
ekz2 += ekz2_arr[l];
|
||||
ekx3 += ekx3_arr[l];
|
||||
eky3 += eky3_arr[l];
|
||||
ekz3 += ekz3_arr[l];
|
||||
ekx4 += ekx4_arr[l];
|
||||
eky4 += eky4_arr[l];
|
||||
ekz4 += ekz4_arr[l];
|
||||
ekx5 += ekx5_arr[l];
|
||||
eky5 += eky5_arr[l];
|
||||
ekz5 += ekz5_arr[l];
|
||||
ekx6 += ekx6_arr[l];
|
||||
eky6 += eky6_arr[l];
|
||||
ekz6 += ekz6_arr[l];
|
||||
}
|
||||
|
||||
// convert D-field to force
|
||||
|
||||
@ -2439,12 +2446,12 @@ void PPPMDispIntel::fieldforce_a_ad(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
particle_ekx6[i] = particle_eky6[i] = particle_ekz6[i] = ZEROF;
|
||||
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int n = 0; n < order_6; n++) {
|
||||
int mz = n + nzsum;
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int m = 0; m < order_6; m++) {
|
||||
int my = m + nysum;
|
||||
@ -2452,9 +2459,10 @@ void PPPMDispIntel::fieldforce_a_ad(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
FFT_SCALAR eky_p = drho[1][m] * rho[2][n];
|
||||
FFT_SCALAR ekz_p = rho[1][m] * drho[2][n];
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#pragma simd
|
||||
#endif
|
||||
for (int l = 0; l < INTEL_P3M_ALIGNED_MAXORDER; l++) {
|
||||
for (int l = 0; l < order; l++) {
|
||||
int mx = l + nxsum;
|
||||
FFT_SCALAR x0 = drho[0][l] * ekx_p;
|
||||
FFT_SCALAR y0 = rho[0][l] * eky_p;
|
||||
@ -2486,9 +2494,9 @@ void PPPMDispIntel::fieldforce_a_ad(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
}
|
||||
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma simd
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int l = 0; l < INTEL_P3M_ALIGNED_MAXORDER; l++){
|
||||
for (int l = 0; l < order; l++){
|
||||
particle_ekx0[i] += ekx0[l];
|
||||
particle_eky0[i] += eky0[l];
|
||||
particle_ekz0[i] += ekz0[l];
|
||||
@ -2681,21 +2689,22 @@ void PPPMDispIntel::fieldforce_none_ik(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
|
||||
for (int k = 0; k < nsplit; k++) {
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int n = 0; n < order_6; n++) {
|
||||
int mz = n+nzsum;
|
||||
FFT_SCALAR z0 = rho2[n];
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int m = 0; m < order_6; m++) {
|
||||
int my = m+nysum;
|
||||
FFT_SCALAR y0 = z0*rho1[m];
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#pragma simd
|
||||
#endif
|
||||
for (int l = 0; l < INTEL_P3M_ALIGNED_MAXORDER; l++) {
|
||||
for (int l = 0; l < order; l++) {
|
||||
int mx = l+nxsum;
|
||||
FFT_SCALAR x0 = y0*rho0[l];
|
||||
ekx_arr[k*INTEL_P3M_ALIGNED_MAXORDER + l] -=
|
||||
@ -2716,13 +2725,13 @@ void PPPMDispIntel::fieldforce_none_ik(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
ekx[k] = eky[k] = ekz[k] = ZEROF;
|
||||
}
|
||||
|
||||
for (int l = 0; l < INTEL_P3M_ALIGNED_MAXORDER; l++) {
|
||||
for (int k = 0; k < nsplit; k++) {
|
||||
ekx[k] += ekx_arr[k*INTEL_P3M_ALIGNED_MAXORDER + l];
|
||||
eky[k] += eky_arr[k*INTEL_P3M_ALIGNED_MAXORDER + l];
|
||||
ekz[k] += ekz_arr[k*INTEL_P3M_ALIGNED_MAXORDER + l];
|
||||
}
|
||||
}
|
||||
for (int l = 0; l < order; l++) {
|
||||
for (int k = 0; k < nsplit; k++) {
|
||||
ekx[k] += ekx_arr[k*INTEL_P3M_ALIGNED_MAXORDER + l];
|
||||
eky[k] += eky_arr[k*INTEL_P3M_ALIGNED_MAXORDER + l];
|
||||
ekz[k] += ekz_arr[k*INTEL_P3M_ALIGNED_MAXORDER + l];
|
||||
}
|
||||
}
|
||||
|
||||
// convert E-field to force
|
||||
|
||||
@ -2867,12 +2876,12 @@ void PPPMDispIntel::fieldforce_none_ad(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
for (int k = 0; k < nsplit; k++) {
|
||||
particle_ekx[i] = particle_eky[i] = particle_ekz[i] = ZEROF;
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int n = 0; n < order_6; n++) {
|
||||
int mz = n + nzsum;
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int m = 0; m < order_6; m++) {
|
||||
int my = m + nysum;
|
||||
@ -2880,9 +2889,10 @@ void PPPMDispIntel::fieldforce_none_ad(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
FFT_SCALAR eky_p = drho[1][m] * rho[2][n];
|
||||
FFT_SCALAR ekz_p = rho[1][m] * drho[2][n];
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#pragma simd
|
||||
#endif
|
||||
for (int l = 0; l < INTEL_P3M_ALIGNED_MAXORDER; l++) {
|
||||
for (int l = 0; l < order; l++) {
|
||||
int mx = l + nxsum;
|
||||
ekx[k*INTEL_P3M_ALIGNED_MAXORDER+l] += drho[0][l] * ekx_p *
|
||||
u_brick_none[k][mz][my][mx];
|
||||
@ -2903,9 +2913,9 @@ void PPPMDispIntel::fieldforce_none_ad(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
}
|
||||
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma simd
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int l = 0; l < INTEL_P3M_ALIGNED_MAXORDER; l++){
|
||||
for (int l = 0; l < order; l++){
|
||||
for (int k = 0; k < nsplit; k++) {
|
||||
ekx_tot[k] += ekx[k*INTEL_P3M_ALIGNED_MAXORDER+l];
|
||||
eky_tot[k] += eky[k*INTEL_P3M_ALIGNED_MAXORDER+l];
|
||||
|
||||
@ -149,13 +149,13 @@ void PPPMIntel::init()
|
||||
memory->destroy3d_offset(vdy_brick,nzlo_out,nylo_out,nxlo_out);
|
||||
memory->destroy3d_offset(vdz_brick,nzlo_out,nylo_out,nxlo_out);
|
||||
memory->destroy3d_offset(vdxy_brick, nzlo_out, nylo_out, 2*nxlo_out);
|
||||
memory->create3d_offset(vdxy_brick, nzlo_out, nzhi_out+2,
|
||||
nylo_out, nyhi_out, 2*nxlo_out, 2*nxhi_out+1,
|
||||
"pppmintel:vdxy_brick");
|
||||
create3d_offset(vdxy_brick, nzlo_out, nzhi_out+2,
|
||||
nylo_out, nyhi_out, 2*nxlo_out, 2*nxhi_out+1,
|
||||
"pppmintel:vdxy_brick");
|
||||
memory->destroy3d_offset(vdz0_brick, nzlo_out, nylo_out, 2*nxlo_out);
|
||||
memory->create3d_offset(vdz0_brick, nzlo_out, nzhi_out+2,
|
||||
nylo_out, nyhi_out, 2*nxlo_out, 2*nxhi_out+1,
|
||||
"pppmintel:vdz0_brick");
|
||||
create3d_offset(vdz0_brick, nzlo_out, nzhi_out+2,
|
||||
nylo_out, nyhi_out, 2*nxlo_out, 2*nxhi_out+1,
|
||||
"pppmintel:vdz0_brick");
|
||||
memory->destroy(work3);
|
||||
memory->create(work3, 2*nfft_both, "pppmintel:work3");
|
||||
|
||||
@ -555,13 +555,13 @@ void PPPMIntel::make_rho(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
FFT_SCALAR z0 = fdelvolinv * q[i];
|
||||
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int n = 0; n < order; n++) {
|
||||
int mz = n*nix*niy + nzsum;
|
||||
FFT_SCALAR y0 = z0*rho[2][n];
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int m = 0; m < order; m++) {
|
||||
int mzy = m*nix + mz;
|
||||
@ -708,13 +708,13 @@ void PPPMIntel::fieldforce_ik(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
_alignvar(FFT_SCALAR ekz0_arr[2 * INTEL_P3M_ALIGNED_MAXORDER], 64) = {0};
|
||||
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int n = 0; n < order; n++) {
|
||||
int mz = n+nzsum;
|
||||
FFT_SCALAR z0 = rho2[n];
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int m = 0; m < order; m++) {
|
||||
int my = m+nysum;
|
||||
@ -742,13 +742,13 @@ void PPPMIntel::fieldforce_ik(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
ekx = eky = ekz = ZEROF;
|
||||
|
||||
if (use_packing) {
|
||||
for (int l = 0; l < 2*INTEL_P3M_ALIGNED_MAXORDER; l += 2) {
|
||||
for (int l = 0; l < 2*order; l += 2) {
|
||||
ekx += ekxy_arr[l];
|
||||
eky += ekxy_arr[l+1];
|
||||
ekz += ekz0_arr[l];
|
||||
}
|
||||
} else {
|
||||
for (int l = 0; l < INTEL_P3M_ALIGNED_MAXORDER; l++) {
|
||||
for (int l = 0; l < order; l++) {
|
||||
ekx += ekx_arr[l];
|
||||
eky += eky_arr[l];
|
||||
ekz += ekz_arr[l];
|
||||
@ -896,12 +896,12 @@ void PPPMIntel::fieldforce_ad(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
particle_ekx[i] = particle_eky[i] = particle_ekz[i] = ZEROF;
|
||||
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int n = 0; n < order; n++) {
|
||||
int mz = n + nzsum;
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma loop_count=7
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int m = 0; m < order; m++) {
|
||||
int my = m + nysum;
|
||||
@ -921,9 +921,9 @@ void PPPMIntel::fieldforce_ad(IntelBuffers<flt_t,acc_t> *buffers)
|
||||
}
|
||||
|
||||
#if defined(LMP_SIMD_COMPILER)
|
||||
#pragma simd
|
||||
#pragma loop_count min(2), max(INTEL_P3M_ALIGNED_MAXORDER), avg(7)
|
||||
#endif
|
||||
for (int l = 0; l < INTEL_P3M_ALIGNED_MAXORDER; l++){
|
||||
for (int l = 0; l < order; l++){
|
||||
particle_ekx[i] += ekx[l];
|
||||
particle_eky[i] += eky[l];
|
||||
particle_ekz[i] += ekz[l];
|
||||
@ -1240,6 +1240,73 @@ void PPPMIntel::pack_buffers()
|
||||
fix->stop_watch(TIME_PACK);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Allocate density_brick with extra padding for vector writes
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PPPMIntel::allocate()
|
||||
{
|
||||
PPPM::allocate();
|
||||
memory->destroy3d_offset(density_brick,nzlo_out,nylo_out,nxlo_out);
|
||||
create3d_offset(density_brick,nzlo_out,nzhi_out,nylo_out,nyhi_out,
|
||||
nxlo_out,nxhi_out,"pppm:density_brick");
|
||||
|
||||
if (differentiation_flag == 1) {
|
||||
memory->destroy3d_offset(u_brick,nzlo_out,nylo_out,nxlo_out);
|
||||
create3d_offset(u_brick,nzlo_out,nzhi_out,nylo_out,nyhi_out,
|
||||
nxlo_out,nxhi_out,"pppm:u_brick");
|
||||
} else {
|
||||
memory->destroy3d_offset(vdx_brick,nzlo_out,nylo_out,nxlo_out);
|
||||
memory->destroy3d_offset(vdy_brick,nzlo_out,nylo_out,nxlo_out);
|
||||
memory->destroy3d_offset(vdz_brick,nzlo_out,nylo_out,nxlo_out);
|
||||
create3d_offset(vdx_brick,nzlo_out,nzhi_out,nylo_out,nyhi_out,
|
||||
nxlo_out,nxhi_out,"pppm:vdx_brick");
|
||||
create3d_offset(vdy_brick,nzlo_out,nzhi_out,nylo_out,nyhi_out,
|
||||
nxlo_out,nxhi_out,"pppm:vdy_brick");
|
||||
create3d_offset(vdz_brick,nzlo_out,nzhi_out,nylo_out,nyhi_out,
|
||||
nxlo_out,nxhi_out,"pppm:vdz_brick");
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Create 3D-offset allocation with extra padding for vector writes
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
FFT_SCALAR *** PPPMIntel::create3d_offset(FFT_SCALAR ***&array, int n1lo,
|
||||
int n1hi, int n2lo, int n2hi,
|
||||
int n3lo, int n3hi,
|
||||
const char *name)
|
||||
{
|
||||
int n1 = n1hi - n1lo + 1;
|
||||
int n2 = n2hi - n2lo + 1;
|
||||
int n3 = n3hi - n3lo + 1;
|
||||
|
||||
bigint nbytes = ((bigint) sizeof(FFT_SCALAR)) * n1*n2*n3 +
|
||||
INTEL_P3M_ALIGNED_MAXORDER*2;
|
||||
FFT_SCALAR *data = (FFT_SCALAR *) memory->smalloc(nbytes,name);
|
||||
nbytes = ((bigint) sizeof(FFT_SCALAR *)) * n1*n2;
|
||||
FFT_SCALAR **plane = (FFT_SCALAR **) memory->smalloc(nbytes,name);
|
||||
nbytes = ((bigint) sizeof(FFT_SCALAR **)) * n1;
|
||||
array = (FFT_SCALAR ***) memory->smalloc(nbytes,name);
|
||||
|
||||
bigint m;
|
||||
bigint n = 0;
|
||||
for (int i = 0; i < n1; i++) {
|
||||
m = ((bigint) i) * n2;
|
||||
array[i] = &plane[m];
|
||||
for (int j = 0; j < n2; j++) {
|
||||
plane[m+j] = &data[n];
|
||||
n += n3;
|
||||
}
|
||||
}
|
||||
|
||||
m = ((bigint) n1) * n2;
|
||||
for (bigint i = 0; i < m; i++) array[0][i] -= n3lo;
|
||||
for (int i = 0; i < n1; i++) array[i] -= n2lo;
|
||||
array -= n1lo;
|
||||
return array;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Returns 0 if Intel optimizations for PPPM ignored due to offload
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
@ -74,9 +74,10 @@ class PPPMIntel : public PPPM {
|
||||
int _use_base;
|
||||
#endif
|
||||
|
||||
template<class flt_t, class acc_t>
|
||||
void test_function(IntelBuffers<flt_t,acc_t> *buffers);
|
||||
virtual void allocate();
|
||||
|
||||
template<class flt_t, class acc_t>
|
||||
void test_function(IntelBuffers<flt_t,acc_t> *buffers);
|
||||
|
||||
void precompute_rho();
|
||||
template<class flt_t, class acc_t>
|
||||
@ -120,6 +121,8 @@ class PPPMIntel : public PPPM {
|
||||
fieldforce_ad<flt_t,acc_t,0>(buffers);
|
||||
}
|
||||
}
|
||||
FFT_SCALAR ***create3d_offset(FFT_SCALAR ***&, int, int, int,
|
||||
int, int, int, const char *name);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -1,138 +1,374 @@
|
||||
#include "manifold_gaussian_bump.h"
|
||||
|
||||
#include "comm.h"
|
||||
#include "error.h"
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
using namespace user_manifold;
|
||||
|
||||
// This manifold comes with some baggage;
|
||||
// it needs a taper function that is sufficiently smooth
|
||||
// so we use a cubic Hermite interpolation and then for
|
||||
// efficiency we construct a lookup table for that....
|
||||
|
||||
class cubic_hermite
|
||||
{
|
||||
public:
|
||||
// Represent x-polynomial as a * t^3 + b * t^2 + c*t + d.
|
||||
double a, b, c, d;
|
||||
// And y-polynomial as s * t^3 + u * t^2 + v * t + w.
|
||||
double s, u, v, w;
|
||||
|
||||
double x0, x1, y0, y1, yp0, yp1;
|
||||
|
||||
LAMMPS_NS::Error *err;
|
||||
|
||||
cubic_hermite( double x0, double x1, double y0, double y1,
|
||||
double yp0, double yp1, LAMMPS_NS::Error *err ) :
|
||||
x0(x0), x1(x1), y0(y0), y1(y1), yp0(yp0), yp1(yp1),
|
||||
a( 2*x0 + 2 - 2*x1 ),
|
||||
b( -3*x0 - 3 + 3*x1 ),
|
||||
c( 1.0 ),
|
||||
d( x0 ),
|
||||
s( 2*y0 - 2*y1 + yp0 + yp1 ),
|
||||
u( -3*y0 + 3*y1 - 2*yp0 - yp1 ),
|
||||
v( yp0 ),
|
||||
w( y0 ),
|
||||
err(err)
|
||||
{
|
||||
test();
|
||||
}
|
||||
|
||||
|
||||
void test()
|
||||
{
|
||||
if( fabs( x(0) - x0 ) > 1e-8 ) err->one(FLERR, "x0 wrong");
|
||||
if( fabs( x(1) - x1 ) > 1e-8 ) err->one(FLERR, "x1 wrong");
|
||||
if( fabs( y(0) - y0 ) > 1e-8 ) err->one(FLERR, "y0 wrong");
|
||||
if( fabs( y(1) - y1 ) > 1e-8 ) err->one(FLERR, "y1 wrong");
|
||||
}
|
||||
|
||||
double get_t_from_x( double xx ) const
|
||||
{
|
||||
if( xx < x0 || xx > x1 ){
|
||||
char msg[2048];
|
||||
sprintf(msg, "x ( %g ) out of bounds [%g, %g]", xx, x0, x1 );
|
||||
err->one(FLERR, msg);
|
||||
}
|
||||
|
||||
// Newton iterate to get right t.
|
||||
double t = xx - x0;
|
||||
double dx = x1 - x0;
|
||||
// Reasonable initial guess I hope:
|
||||
t /= dx;
|
||||
|
||||
double tol = 1e-8;
|
||||
int maxit = 500;
|
||||
double ff = x(t) - xx;
|
||||
double ffp = xp(t);
|
||||
// double l = 1.0 / ( 1 + res*res );
|
||||
for( int i = 0; i < maxit; ++i ){
|
||||
t -= ff / ffp;
|
||||
ff = x(t) - xx;
|
||||
ffp = xp(t);
|
||||
double res = ff;
|
||||
if( fabs( res ) < tol ){
|
||||
return t;
|
||||
}
|
||||
}
|
||||
err->warning(FLERR, "Convergence failed");
|
||||
return t;
|
||||
}
|
||||
|
||||
double x( double t ) const
|
||||
{
|
||||
double t2 = t*t;
|
||||
double t3 = t2*t;
|
||||
return a*t3 + b*t2 + c*t + d;
|
||||
}
|
||||
|
||||
double y_from_x( double x ) const
|
||||
{
|
||||
double t = get_t_from_x( x );
|
||||
return y(t);
|
||||
}
|
||||
|
||||
double yp_from_x( double x ) const
|
||||
{
|
||||
double t = get_t_from_x( x );
|
||||
return yp(t);
|
||||
}
|
||||
|
||||
double y( double t ) const
|
||||
{
|
||||
double t2 = t*t;
|
||||
double t3 = t2*t;
|
||||
return s*t3 + u*t2 + v*t + w;
|
||||
}
|
||||
|
||||
void xy( double t, double &xx, double &yy ) const
|
||||
{
|
||||
xx = x(t);
|
||||
yy = y(t);
|
||||
}
|
||||
|
||||
double xp( double t ) const
|
||||
{
|
||||
double t2 = t*t;
|
||||
return 3*a*t2 + 2*b*t + c;
|
||||
}
|
||||
|
||||
double yp( double t ) const
|
||||
{
|
||||
double t2 = t*t;
|
||||
return 3*t2*s + 2*u*t + v;
|
||||
}
|
||||
|
||||
double xpp( double t ) const
|
||||
{
|
||||
return 6*a*t + 2*b;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Manifold itself:
|
||||
manifold_gaussian_bump::manifold_gaussian_bump(class LAMMPS* lmp,
|
||||
int narg, char **arg)
|
||||
: manifold(lmp), lut_z(NULL), lut_zp(NULL) {}
|
||||
|
||||
|
||||
manifold_gaussian_bump::~manifold_gaussian_bump()
|
||||
{
|
||||
if( lut_z ) delete lut_z;
|
||||
if( lut_zp ) delete lut_zp;
|
||||
}
|
||||
|
||||
|
||||
// The constraint is z = f(r = sqrt( x^2 + y^2) )
|
||||
// f(x) = A*exp( -x^2 / 2 l^2 ) if x < rc1
|
||||
// = a + b*x + c*x**2 + d*x**3 if rc1 <= x < rc2
|
||||
// = Some interpolation if rc1 <= rc2
|
||||
// = 0 if x >= rc2
|
||||
//
|
||||
double manifold_gaussian_bump::g( const double *x )
|
||||
{
|
||||
double xf[3];
|
||||
xf[0] = x[0];
|
||||
xf[1] = x[1];
|
||||
xf[2] = 0.0;
|
||||
|
||||
double x2 = dot(xf,xf);
|
||||
if( x2 < rc12 ){
|
||||
return x[2] - gaussian_bump_x2( x2 );
|
||||
}else if( x2 < rc22 ){
|
||||
double rr = sqrt(x2);
|
||||
double xi = rr - rc1;
|
||||
xi *= inv_dr;
|
||||
double xi2 = x2 * inv_dr*inv_dr;
|
||||
double xi3 = xi*xi2;
|
||||
return x[2] - ( aa + bb*xi + cc*xi2 + dd*xi3 );
|
||||
|
||||
}else{
|
||||
return x[2];
|
||||
}
|
||||
double xf[3];
|
||||
xf[0] = x[0];
|
||||
xf[1] = x[1];
|
||||
xf[2] = 0.0;
|
||||
|
||||
double x2 = dot(xf,xf);
|
||||
if( x2 < rc12 ){
|
||||
return x[2] - gaussian_bump_x2( x2 );
|
||||
}else if( x2 < rc22 ){
|
||||
double rr = sqrt( x2 );
|
||||
double z_taper_func = lut_get_z( rr );
|
||||
return x[2] - z_taper_func;
|
||||
}else{
|
||||
return x[2];
|
||||
}
|
||||
}
|
||||
|
||||
void manifold_gaussian_bump::n( const double *x, double *nn )
|
||||
{
|
||||
double xf[3];
|
||||
xf[0] = x[0];
|
||||
xf[1] = x[1];
|
||||
xf[2] = 0.0;
|
||||
nn[2] = 1.0;
|
||||
|
||||
double x2 = dot(xf,xf);
|
||||
|
||||
if( x2 < rc12 ){
|
||||
double factor = gaussian_bump_x2(x2);
|
||||
factor /= (ll*ll);
|
||||
nn[0] = factor * x[0];
|
||||
nn[1] = factor * x[1];
|
||||
}else if( x2 < rc22 ){
|
||||
double rr = sqrt(x2);
|
||||
double xi = rr - rc1;
|
||||
xi *= inv_dr;
|
||||
double xi2 = x2 * inv_dr*inv_dr;
|
||||
double der = bb + 2*cc*xi + 3*dd*xi2;
|
||||
|
||||
nn[0] = -der * x[0] / rr;
|
||||
nn[1] = -der * x[1] / rr;
|
||||
}else{
|
||||
nn[0] = nn[1] = 0.0;
|
||||
}
|
||||
double xf[3];
|
||||
xf[0] = x[0];
|
||||
xf[1] = x[1];
|
||||
xf[2] = 0.0;
|
||||
nn[2] = 1.0;
|
||||
|
||||
double x2 = dot(xf,xf);
|
||||
|
||||
if( x2 < rc12 ){
|
||||
double factor = gaussian_bump_x2(x2);
|
||||
factor /= (ll*ll);
|
||||
nn[0] = factor * x[0];
|
||||
nn[1] = factor * x[1];
|
||||
}else if( x2 < rc22 ){
|
||||
double rr = sqrt( x2 );
|
||||
double zp_taper_func = lut_get_zp( rr );
|
||||
|
||||
double inv_r = 1.0 / rr;
|
||||
double der_part = zp_taper_func * inv_r;
|
||||
|
||||
nn[0] = der_part * x[0];
|
||||
nn[1] = der_part * x[1];
|
||||
|
||||
}else{
|
||||
nn[0] = nn[1] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
double manifold_gaussian_bump::g_and_n( const double *x, double *nn )
|
||||
{
|
||||
double xf[3];
|
||||
xf[0] = x[0];
|
||||
xf[1] = x[1];
|
||||
xf[2] = 0.0;
|
||||
nn[2] = 1.0;
|
||||
|
||||
double x2 = dot(xf,xf);
|
||||
if( x2 < rc12 ){
|
||||
double gb = gaussian_bump_x2(x2);
|
||||
double factor = gb / (ll*ll);
|
||||
nn[0] = factor * x[0];
|
||||
nn[1] = factor * x[1];
|
||||
|
||||
return x[2] - gb;
|
||||
}else if( x2 < rc22 ){
|
||||
|
||||
double rr = sqrt(x2);
|
||||
double xi = rr - rc1;
|
||||
xi *= inv_dr;
|
||||
double xi2 = x2 * inv_dr*inv_dr;
|
||||
double xi3 = xi*xi2;
|
||||
double xf[3];
|
||||
xf[0] = x[0];
|
||||
xf[1] = x[1];
|
||||
xf[2] = 0.0;
|
||||
nn[2] = 1.0;
|
||||
|
||||
double der = bb + 2*cc*xi + 3*dd*xi2;
|
||||
|
||||
nn[0] = -der * x[0] / rr;
|
||||
nn[1] = -der * x[1] / rr;
|
||||
double x2 = dot(xf,xf);
|
||||
if( x2 < rc12 ){
|
||||
double gb = gaussian_bump_x2(x2);
|
||||
double factor = gb / (ll*ll);
|
||||
nn[0] = factor * x[0];
|
||||
nn[1] = factor * x[1];
|
||||
|
||||
return x[2] - gb;
|
||||
}else if( x2 < rc22 ){
|
||||
double z_taper_func, zp_taper_func;
|
||||
double rr = sqrt( x2 );
|
||||
lut_get_z_and_zp( rr, z_taper_func, zp_taper_func );
|
||||
|
||||
double inv_r = 1.0 / rr;
|
||||
double der_part = zp_taper_func * inv_r;
|
||||
|
||||
nn[0] = der_part * x[0];
|
||||
nn[1] = der_part * x[1];
|
||||
|
||||
return x[2] - z_taper_func;
|
||||
}else{
|
||||
nn[0] = nn[1] = 0.0;
|
||||
return x[2];
|
||||
}
|
||||
|
||||
|
||||
return x[2] - ( aa + bb*xi + cc*xi2 + dd*xi3 );
|
||||
|
||||
}else{
|
||||
nn[0] = nn[1] = 0.0;
|
||||
return x[2];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void manifold_gaussian_bump::post_param_init()
|
||||
{
|
||||
// Read in the params:
|
||||
AA = params[0];
|
||||
ll = params[1];
|
||||
rc1 = params[2];
|
||||
rc2 = params[3];
|
||||
// Read in the params:
|
||||
AA = params[0];
|
||||
ll = params[1];
|
||||
rc1 = params[2];
|
||||
rc2 = params[3];
|
||||
|
||||
ll2 = 2.0*ll*ll;
|
||||
ll2 = 2.0*ll*ll;
|
||||
|
||||
f_at_rc = gaussian_bump_x2 ( rc12 );
|
||||
fp_at_rc = gaussian_bump_der( rc12 );
|
||||
rc12 = rc1*rc1;
|
||||
rc22 = rc2*rc2;
|
||||
dr = rc2 - rc1;
|
||||
inv_dr = 1.0 / dr;
|
||||
|
||||
rc12 = rc1*rc1;
|
||||
rc22 = rc2*rc2;
|
||||
dr = rc2 - rc1;
|
||||
inv_dr = 1.0 / dr;
|
||||
f_at_rc = gaussian_bump_x2 ( rc12 );
|
||||
fp_at_rc = gaussian_bump_der( rc1 );
|
||||
|
||||
|
||||
|
||||
make_lut();
|
||||
|
||||
// test_lut();
|
||||
}
|
||||
|
||||
|
||||
double manifold_gaussian_bump::gaussian_bump( double x )
|
||||
double manifold_gaussian_bump::gaussian_bump( double x ) const
|
||||
{
|
||||
double x2 = x*x;
|
||||
return gaussian_bump_x2( x2 );
|
||||
double x2 = x*x;
|
||||
return gaussian_bump_x2( x2 );
|
||||
}
|
||||
|
||||
double manifold_gaussian_bump::gaussian_bump_x2( double x2 )
|
||||
double manifold_gaussian_bump::gaussian_bump_x2( double x2 ) const
|
||||
{
|
||||
return AA*exp( -x2 / ll2 );
|
||||
return AA*exp( -x2 / ll2 );
|
||||
}
|
||||
|
||||
double manifold_gaussian_bump::gaussian_bump_der( double x )
|
||||
double manifold_gaussian_bump::gaussian_bump_der( double x ) const
|
||||
{
|
||||
double x2 = x*x;
|
||||
return gaussian_bump_x2( x2 )*( -x/(ll*ll) );
|
||||
double x2 = x*x;
|
||||
return gaussian_bump_x2( x2 )*( -x/(ll*ll) );
|
||||
}
|
||||
|
||||
|
||||
void manifold_gaussian_bump::make_lut()
|
||||
{
|
||||
|
||||
lut_x0 = rc1;
|
||||
lut_x1 = rc2;
|
||||
lut_Nbins = 1024; // Don't make it too big, it should fit in cache.
|
||||
lut_z = new double[lut_Nbins+1];
|
||||
lut_zp = new double[lut_Nbins+1];
|
||||
|
||||
lut_dx = (lut_x1 - lut_x0) / lut_Nbins;
|
||||
|
||||
cubic_hermite pchip( lut_x0, lut_x1, f_at_rc, 0.0, fp_at_rc, 0.0, error );
|
||||
|
||||
double xx = lut_x0;
|
||||
for( int i = 0; i <= lut_Nbins; ++i ){
|
||||
lut_z[i] = pchip.y_from_x( xx );
|
||||
lut_zp[i] = pchip.yp_from_x( xx );
|
||||
xx += lut_dx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double manifold_gaussian_bump::lut_get_z ( double rr ) const
|
||||
{
|
||||
double xs = rr - lut_x0;
|
||||
double xss = xs / lut_dx;
|
||||
int bin = static_cast<int>(xss);
|
||||
double frac = xss - bin;
|
||||
|
||||
double zleft = lut_z[bin];
|
||||
double zright = lut_z[bin+1];
|
||||
|
||||
return zleft * ( 1 - frac ) + frac * zright;
|
||||
}
|
||||
|
||||
double manifold_gaussian_bump::lut_get_zp( double rr ) const
|
||||
{
|
||||
double xs = rr - lut_x0;
|
||||
double xss = xs / lut_dx;
|
||||
int bin = static_cast<int>(xss);
|
||||
double frac = xss - bin;
|
||||
|
||||
double zleft = lut_zp[bin];
|
||||
double zright = lut_zp[bin+1];
|
||||
|
||||
return zleft * ( 1 - frac) + frac * zright;
|
||||
}
|
||||
|
||||
|
||||
void manifold_gaussian_bump::lut_get_z_and_zp( double rr, double &zz,
|
||||
double &zzp ) const
|
||||
{
|
||||
double xs = rr - lut_x0;
|
||||
double xss = xs / lut_dx;
|
||||
int bin = static_cast<int>(xss);
|
||||
double frac = xss - bin;
|
||||
double fmin = 1 - frac;
|
||||
|
||||
double zleft = lut_z[bin];
|
||||
double zright = lut_z[bin+1];
|
||||
double zpleft = lut_zp[bin];
|
||||
double zpright = lut_zp[bin+1];
|
||||
|
||||
zz = zleft * fmin + zright * frac;
|
||||
zzp = zpleft * fmin + zpright * frac;
|
||||
}
|
||||
|
||||
|
||||
void manifold_gaussian_bump::test_lut()
|
||||
{
|
||||
double x[3], nn[3];
|
||||
if( comm->me != 0 ) return;
|
||||
|
||||
FILE *fp = fopen( "test_lut_gaussian.dat", "w" );
|
||||
double dx = 0.1;
|
||||
for( double xx = 0; xx < 20; xx += dx ){
|
||||
x[0] = xx;
|
||||
x[1] = 0.0;
|
||||
x[2] = 0.0;
|
||||
double gg = g( x );
|
||||
n( x, nn );
|
||||
double taper_z;
|
||||
if( xx <= rc1 ){
|
||||
taper_z = gaussian_bump(xx);
|
||||
}else if( xx < rc2 ){
|
||||
taper_z = lut_get_z( xx );
|
||||
}else{
|
||||
taper_z = 0.0;
|
||||
}
|
||||
fprintf( fp, "%g %g %g %g %g\n", xx, gaussian_bump(xx), taper_z,
|
||||
gg, nn[0], nn[1], nn[2] );
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/* -*- c++ -*- ----------------------------------------------------------
|
||||
/* ----------------------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
http://lammps.sandia.gov, Sandia National Laboratories
|
||||
Steve Plimpton, sjplimp@sandia.gov
|
||||
@ -50,8 +50,8 @@ namespace user_manifold {
|
||||
class manifold_gaussian_bump : public manifold {
|
||||
public:
|
||||
enum { NPARAMS = 4 };
|
||||
manifold_gaussian_bump(class LAMMPS*, int, char **) : manifold(lmp) {}
|
||||
virtual ~manifold_gaussian_bump(){}
|
||||
manifold_gaussian_bump(class LAMMPS*, int, char **);
|
||||
virtual ~manifold_gaussian_bump();
|
||||
|
||||
virtual double g( const double * );
|
||||
virtual void n( const double *, double * );
|
||||
@ -66,12 +66,29 @@ namespace user_manifold {
|
||||
virtual void post_param_init();
|
||||
private:
|
||||
// Some private constants:
|
||||
double aa, bb, cc, dd, AA, ll, ll2, f_at_rc, fp_at_rc;
|
||||
double AA, ll, ll2, f_at_rc, fp_at_rc;
|
||||
double rc1, rc2, rc12, rc22, dr, inv_dr;
|
||||
|
||||
double gaussian_bump ( double );
|
||||
double gaussian_bump_x2 ( double );
|
||||
double gaussian_bump_der( double );
|
||||
// Stuff for the look-up table:
|
||||
double lut_x0, lut_x1;
|
||||
int lut_Nbins;
|
||||
double lut_dx;
|
||||
double *lut_z;
|
||||
double *lut_zp;
|
||||
|
||||
double gaussian_bump ( double ) const;
|
||||
double gaussian_bump_x2 ( double ) const;
|
||||
double gaussian_bump_der( double ) const;
|
||||
|
||||
void make_lut();
|
||||
double lut_get_z ( double rr ) const;
|
||||
double lut_get_zp( double rr ) const;
|
||||
void lut_get_z_and_zp( double rr, double &zz, double &zzp ) const;
|
||||
|
||||
void test_lut();
|
||||
|
||||
double taper( double );
|
||||
double taper_der( double );
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
26
src/USER-MEAMC/README
Normal file
26
src/USER-MEAMC/README
Normal file
@ -0,0 +1,26 @@
|
||||
This package implements the MEAM/C potential as a LAMMPS pair style.
|
||||
|
||||
==============================================================================
|
||||
|
||||
This package is a translation of the MEAM package to native C++. See
|
||||
that package as well as the Fortran code distributed in lib/meam for
|
||||
the original sources and information.
|
||||
|
||||
|
||||
Translation by
|
||||
Sebastian Hütter, sebastian.huetter@ovgu.de
|
||||
Institute of Materials and Joining Technology
|
||||
Otto-von-Guericke University Magdeburg, Germany
|
||||
|
||||
The original Fortran implementation was created by
|
||||
Greg Wagner (while at Sandia, now at Northwestern U).
|
||||
|
||||
==============================================================================
|
||||
|
||||
Use "make yes-user-meamc" to enable this package when building LAMMPS.
|
||||
|
||||
In your LAMMPS input script, specifiy
|
||||
pair_style meam/c
|
||||
to enable the use of this implementation. All parameters, input files and
|
||||
outputs are exactly identical to these used with pair_style meam.
|
||||
|
||||
252
src/USER-MEAMC/meam.h
Normal file
252
src/USER-MEAMC/meam.h
Normal file
@ -0,0 +1,252 @@
|
||||
#ifndef LMP_MEAM_H
|
||||
#define LMP_MEAM_H
|
||||
|
||||
#include "memory.h"
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define maxelt 5
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
|
||||
typedef enum { FCC, BCC, HCP, DIM, DIA, B1, C11, L12, B2 } lattice_t;
|
||||
|
||||
class MEAM
|
||||
{
|
||||
public:
|
||||
MEAM(Memory* mem);
|
||||
~MEAM();
|
||||
|
||||
private:
|
||||
Memory* memory;
|
||||
|
||||
// cutforce = force cutoff
|
||||
// cutforcesq = force cutoff squared
|
||||
|
||||
double cutforce, cutforcesq;
|
||||
|
||||
// Ec_meam = cohesive energy
|
||||
// re_meam = nearest-neighbor distance
|
||||
// Omega_meam = atomic volume
|
||||
// B_meam = bulk modulus
|
||||
// Z_meam = number of first neighbors for reference structure
|
||||
// ielt_meam = atomic number of element
|
||||
// A_meam = adjustable parameter
|
||||
// alpha_meam = sqrt(9*Omega*B/Ec)
|
||||
// rho0_meam = density scaling parameter
|
||||
// delta_meam = heat of formation for alloys
|
||||
// beta[0-3]_meam = electron density constants
|
||||
// t[0-3]_meam = coefficients on densities in Gamma computation
|
||||
// rho_ref_meam = background density for reference structure
|
||||
// ibar_meam(i) = selection parameter for Gamma function for elt i,
|
||||
// lattce_meam(i,j) = lattce configuration for elt i or alloy (i,j)
|
||||
// neltypes = maximum number of element type defined
|
||||
// eltind = index number of pair (similar to Voigt notation; ij = ji)
|
||||
// phir = pair potential function array
|
||||
// phirar[1-6] = spline coeffs
|
||||
// attrac_meam = attraction parameter in Rose energy
|
||||
// repuls_meam = repulsion parameter in Rose energy
|
||||
// nn2_meam = 1 if second nearest neighbors are to be computed, else 0
|
||||
// zbl_meam = 1 if zbl potential for small r to be use, else 0
|
||||
// emb_lin_neg = 1 if linear embedding function for rhob to be used, else 0
|
||||
// bkgd_dyn = 1 if reference densities follows Dynamo, else 0
|
||||
// Cmin_meam, Cmax_meam = min and max values in screening cutoff
|
||||
// rc_meam = cutoff distance for meam
|
||||
// delr_meam = cutoff region for meam
|
||||
// ebound_meam = factor giving maximum boundary of sceen fcn ellipse
|
||||
// augt1 = flag for whether t1 coefficient should be augmented
|
||||
// ialloy = flag for newer alloy formulation (as in dynamo code)
|
||||
// mix_ref_t = flag to recover "old" way of computing t in reference config
|
||||
// erose_form = selection parameter for form of E_rose function
|
||||
// gsmooth_factor = factor determining length of G smoothing region
|
||||
// vind[23]D = Voight notation index maps for 2 and 3D
|
||||
// v2D,v3D = array of factors to apply for Voight notation
|
||||
|
||||
// nr,dr = pair function discretization parameters
|
||||
// nrar,rdrar = spline coeff array parameters
|
||||
|
||||
double Ec_meam[maxelt][maxelt], re_meam[maxelt][maxelt];
|
||||
double Omega_meam[maxelt], Z_meam[maxelt];
|
||||
double A_meam[maxelt], alpha_meam[maxelt][maxelt], rho0_meam[maxelt];
|
||||
double delta_meam[maxelt][maxelt];
|
||||
double beta0_meam[maxelt], beta1_meam[maxelt];
|
||||
double beta2_meam[maxelt], beta3_meam[maxelt];
|
||||
double t0_meam[maxelt], t1_meam[maxelt];
|
||||
double t2_meam[maxelt], t3_meam[maxelt];
|
||||
double rho_ref_meam[maxelt];
|
||||
int ibar_meam[maxelt], ielt_meam[maxelt];
|
||||
lattice_t lattce_meam[maxelt][maxelt];
|
||||
int nn2_meam[maxelt][maxelt];
|
||||
int zbl_meam[maxelt][maxelt];
|
||||
int eltind[maxelt][maxelt];
|
||||
int neltypes;
|
||||
|
||||
double** phir;
|
||||
|
||||
double **phirar, **phirar1, **phirar2, **phirar3, **phirar4, **phirar5, **phirar6;
|
||||
|
||||
double attrac_meam[maxelt][maxelt], repuls_meam[maxelt][maxelt];
|
||||
|
||||
double Cmin_meam[maxelt][maxelt][maxelt];
|
||||
double Cmax_meam[maxelt][maxelt][maxelt];
|
||||
double rc_meam, delr_meam, ebound_meam[maxelt][maxelt];
|
||||
int augt1, ialloy, mix_ref_t, erose_form;
|
||||
int emb_lin_neg, bkgd_dyn;
|
||||
double gsmooth_factor;
|
||||
int vind2D[3][3], vind3D[3][3][3];
|
||||
int v2D[6], v3D[10];
|
||||
|
||||
int nr, nrar;
|
||||
double dr, rdrar;
|
||||
|
||||
public:
|
||||
int nmax;
|
||||
double *rho, *rho0, *rho1, *rho2, *rho3, *frhop;
|
||||
double *gamma, *dgamma1, *dgamma2, *dgamma3, *arho2b;
|
||||
double **arho1, **arho2, **arho3, **arho3b, **t_ave, **tsq_ave;
|
||||
|
||||
int maxneigh;
|
||||
double *scrfcn, *dscrfcn, *fcpair;
|
||||
|
||||
protected:
|
||||
// meam_funcs.cpp
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Cutoff function
|
||||
//
|
||||
static double fcut(const double xi) {
|
||||
double a;
|
||||
if (xi >= 1.0)
|
||||
return 1.0;
|
||||
else if (xi <= 0.0)
|
||||
return 0.0;
|
||||
else {
|
||||
a = 1.0 - xi;
|
||||
a *= a; a *= a;
|
||||
a = 1.0 - a;
|
||||
return a * a;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Cutoff function and derivative
|
||||
//
|
||||
static double dfcut(const double xi, double& dfc) {
|
||||
double a, a3, a4, a1m4;
|
||||
if (xi >= 1.0) {
|
||||
dfc = 0.0;
|
||||
return 1.0;
|
||||
} else if (xi <= 0.0) {
|
||||
dfc = 0.0;
|
||||
return 0.0;
|
||||
} else {
|
||||
a = 1.0 - xi;
|
||||
a3 = a * a * a;
|
||||
a4 = a * a3;
|
||||
a1m4 = 1.0-a4;
|
||||
|
||||
dfc = 8 * a1m4 * a3;
|
||||
return a1m4*a1m4;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Derivative of Cikj w.r.t. rij
|
||||
// Inputs: rij,rij2,rik2,rjk2
|
||||
//
|
||||
static double dCfunc(const double rij2, const double rik2, const double rjk2) {
|
||||
double rij4, a, asq, b,denom;
|
||||
|
||||
rij4 = rij2 * rij2;
|
||||
a = rik2 - rjk2;
|
||||
b = rik2 + rjk2;
|
||||
asq = a*a;
|
||||
denom = rij4 - asq;
|
||||
denom = denom * denom;
|
||||
return -4 * (-2 * rij2 * asq + rij4 * b + asq * b) / denom;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Derivative of Cikj w.r.t. rik and rjk
|
||||
// Inputs: rij,rij2,rik2,rjk2
|
||||
//
|
||||
static void dCfunc2(const double rij2, const double rik2, const double rjk2,
|
||||
double& dCikj1, double& dCikj2) {
|
||||
double rij4, rik4, rjk4, a, denom;
|
||||
|
||||
rij4 = rij2 * rij2;
|
||||
rik4 = rik2 * rik2;
|
||||
rjk4 = rjk2 * rjk2;
|
||||
a = rik2 - rjk2;
|
||||
denom = rij4 - a * a;
|
||||
denom = denom * denom;
|
||||
dCikj1 = 4 * rij2 * (rij4 + rik4 + 2 * rik2 * rjk2 - 3 * rjk4 - 2 * rij2 * a) / denom;
|
||||
dCikj2 = 4 * rij2 * (rij4 - 3 * rik4 + 2 * rik2 * rjk2 + rjk4 + 2 * rij2 * a) / denom;
|
||||
}
|
||||
|
||||
double G_gam(const double gamma, const int ibar, int &errorflag) const;
|
||||
double dG_gam(const double gamma, const int ibar, double &dG) const;
|
||||
static double zbl(const double r, const int z1, const int z2);
|
||||
static double erose(const double r, const double re, const double alpha, const double Ec, const double repuls, const double attrac, const int form);
|
||||
|
||||
static void get_shpfcn(const lattice_t latt, double (&s)[3]);
|
||||
static int get_Zij(const lattice_t latt);
|
||||
static int get_Zij2(const lattice_t latt, const double cmin, const double cmax, double &a, double &S);
|
||||
protected:
|
||||
void meam_checkindex(int, int, int, int*, int*);
|
||||
void getscreen(int i, double* scrfcn, double* dscrfcn, double* fcpair, double** x, int numneigh,
|
||||
int* firstneigh, int numneigh_full, int* firstneigh_full, int ntype, int* type, int* fmap);
|
||||
void calc_rho1(int i, int ntype, int* type, int* fmap, double** x, int numneigh, int* firstneigh,
|
||||
double* scrfcn, double* fcpair);
|
||||
|
||||
void alloyparams();
|
||||
void compute_pair_meam();
|
||||
double phi_meam(double, int, int);
|
||||
void compute_reference_density();
|
||||
void get_tavref(double*, double*, double*, double*, double*, double*, double, double, double, double,
|
||||
double, double, double, int, int, lattice_t);
|
||||
void get_sijk(double, int, int, int, double*);
|
||||
void get_densref(double, int, int, double*, double*, double*, double*, double*, double*, double*, double*);
|
||||
void interpolate_meam(int);
|
||||
double compute_phi(double, int, int);
|
||||
|
||||
public:
|
||||
void meam_setup_global(int nelt, lattice_t* lat, double* z, int* ielement, double* atwt, double* alpha,
|
||||
double* b0, double* b1, double* b2, double* b3, double* alat, double* esub,
|
||||
double* asub, double* t0, double* t1, double* t2, double* t3, double* rozero,
|
||||
int* ibar);
|
||||
void meam_setup_param(int which, double value, int nindex, int* index /*index(3)*/, int* errorflag);
|
||||
void meam_setup_done(double* cutmax);
|
||||
void meam_dens_setup(int atom_nmax, int nall, int n_neigh);
|
||||
void meam_dens_init(int i, int ntype, int* type, int* fmap, double** x, int numneigh, int* firstneigh,
|
||||
int numneigh_full, int* firstneigh_full, int fnoffset);
|
||||
void meam_dens_final(int nlocal, int eflag_either, int eflag_global, int eflag_atom, double* eng_vdwl,
|
||||
double* eatom, int ntype, int* type, int* fmap, int& errorflag);
|
||||
void meam_force(int i, int eflag_either, int eflag_global, int eflag_atom, int vflag_atom, double* eng_vdwl,
|
||||
double* eatom, int ntype, int* type, int* fmap, double** x, int numneigh, int* firstneigh,
|
||||
int numneigh_full, int* firstneigh_full, int fnoffset, double** f, double** vatom);
|
||||
};
|
||||
|
||||
// Functions we need for compat
|
||||
|
||||
static inline bool iszero(const double f) {
|
||||
return fabs(f) < 1e-20;
|
||||
}
|
||||
|
||||
template <typename TYPE, size_t maxi, size_t maxj>
|
||||
static inline void setall2d(TYPE (&arr)[maxi][maxj], const TYPE v) {
|
||||
for (size_t i = 0; i < maxi; i++)
|
||||
for (size_t j = 0; j < maxj; j++)
|
||||
arr[i][j] = v;
|
||||
}
|
||||
|
||||
template <typename TYPE, size_t maxi, size_t maxj, size_t maxk>
|
||||
static inline void setall3d(TYPE (&arr)[maxi][maxj][maxk], const TYPE v) {
|
||||
for (size_t i = 0; i < maxi; i++)
|
||||
for (size_t j = 0; j < maxj; j++)
|
||||
for (size_t k = 0; k < maxk; k++)
|
||||
arr[i][j][k] = v;
|
||||
}
|
||||
|
||||
};
|
||||
#endif
|
||||
148
src/USER-MEAMC/meam_dens_final.cpp
Normal file
148
src/USER-MEAMC/meam_dens_final.cpp
Normal file
@ -0,0 +1,148 @@
|
||||
#include "meam.h"
|
||||
#include "math_special.h"
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
void
|
||||
MEAM::meam_dens_final(int nlocal, int eflag_either, int eflag_global, int eflag_atom, double* eng_vdwl,
|
||||
double* eatom, int ntype, int* type, int* fmap, int& errorflag)
|
||||
{
|
||||
int i, elti;
|
||||
int m;
|
||||
double rhob, G, dG, Gbar, dGbar, gam, shp[3], Z;
|
||||
double B, denom, rho_bkgd;
|
||||
|
||||
// Complete the calculation of density
|
||||
|
||||
for (i = 0; i < nlocal; i++) {
|
||||
elti = fmap[type[i]];
|
||||
if (elti >= 0) {
|
||||
rho1[i] = 0.0;
|
||||
rho2[i] = -1.0 / 3.0 * arho2b[i] * arho2b[i];
|
||||
rho3[i] = 0.0;
|
||||
for (m = 0; m < 3; m++) {
|
||||
rho1[i] = rho1[i] + arho1[i][m] * arho1[i][m];
|
||||
rho3[i] = rho3[i] - 3.0 / 5.0 * arho3b[i][m] * arho3b[i][m];
|
||||
}
|
||||
for (m = 0; m < 6; m++) {
|
||||
rho2[i] = rho2[i] + this->v2D[m] * arho2[i][m] * arho2[i][m];
|
||||
}
|
||||
for (m = 0; m < 10; m++) {
|
||||
rho3[i] = rho3[i] + this->v3D[m] * arho3[i][m] * arho3[i][m];
|
||||
}
|
||||
|
||||
if (rho0[i] > 0.0) {
|
||||
if (this->ialloy == 1) {
|
||||
t_ave[i][0] = t_ave[i][0] / tsq_ave[i][0];
|
||||
t_ave[i][1] = t_ave[i][1] / tsq_ave[i][1];
|
||||
t_ave[i][2] = t_ave[i][2] / tsq_ave[i][2];
|
||||
} else if (this->ialloy == 2) {
|
||||
t_ave[i][0] = this->t1_meam[elti];
|
||||
t_ave[i][1] = this->t2_meam[elti];
|
||||
t_ave[i][2] = this->t3_meam[elti];
|
||||
} else {
|
||||
t_ave[i][0] = t_ave[i][0] / rho0[i];
|
||||
t_ave[i][1] = t_ave[i][1] / rho0[i];
|
||||
t_ave[i][2] = t_ave[i][2] / rho0[i];
|
||||
}
|
||||
}
|
||||
|
||||
gamma[i] = t_ave[i][0] * rho1[i] + t_ave[i][1] * rho2[i] + t_ave[i][2] * rho3[i];
|
||||
|
||||
if (rho0[i] > 0.0) {
|
||||
gamma[i] = gamma[i] / (rho0[i] * rho0[i]);
|
||||
}
|
||||
|
||||
Z = this->Z_meam[elti];
|
||||
|
||||
G = G_gam(gamma[i], this->ibar_meam[elti], errorflag);
|
||||
if (errorflag != 0)
|
||||
return;
|
||||
get_shpfcn(this->lattce_meam[elti][elti], shp);
|
||||
if (this->ibar_meam[elti] <= 0) {
|
||||
Gbar = 1.0;
|
||||
dGbar = 0.0;
|
||||
} else {
|
||||
if (this->mix_ref_t == 1) {
|
||||
gam = (t_ave[i][0] * shp[0] + t_ave[i][1] * shp[1] + t_ave[i][2] * shp[2]) / (Z * Z);
|
||||
} else {
|
||||
gam = (this->t1_meam[elti] * shp[0] + this->t2_meam[elti] * shp[1] + this->t3_meam[elti] * shp[2]) /
|
||||
(Z * Z);
|
||||
}
|
||||
Gbar = G_gam(gam, this->ibar_meam[elti], errorflag);
|
||||
}
|
||||
rho[i] = rho0[i] * G;
|
||||
|
||||
if (this->mix_ref_t == 1) {
|
||||
if (this->ibar_meam[elti] <= 0) {
|
||||
Gbar = 1.0;
|
||||
dGbar = 0.0;
|
||||
} else {
|
||||
gam = (t_ave[i][0] * shp[0] + t_ave[i][1] * shp[1] + t_ave[i][2] * shp[2]) / (Z * Z);
|
||||
Gbar = dG_gam(gam, this->ibar_meam[elti], dGbar);
|
||||
}
|
||||
rho_bkgd = this->rho0_meam[elti] * Z * Gbar;
|
||||
} else {
|
||||
if (this->bkgd_dyn == 1) {
|
||||
rho_bkgd = this->rho0_meam[elti] * Z;
|
||||
} else {
|
||||
rho_bkgd = this->rho_ref_meam[elti];
|
||||
}
|
||||
}
|
||||
rhob = rho[i] / rho_bkgd;
|
||||
denom = 1.0 / rho_bkgd;
|
||||
|
||||
G = dG_gam(gamma[i], this->ibar_meam[elti], dG);
|
||||
|
||||
dgamma1[i] = (G - 2 * dG * gamma[i]) * denom;
|
||||
|
||||
if (!iszero(rho0[i])) {
|
||||
dgamma2[i] = (dG / rho0[i]) * denom;
|
||||
} else {
|
||||
dgamma2[i] = 0.0;
|
||||
}
|
||||
|
||||
// dgamma3 is nonzero only if we are using the "mixed" rule for
|
||||
// computing t in the reference system (which is not correct, but
|
||||
// included for backward compatibility
|
||||
if (this->mix_ref_t == 1) {
|
||||
dgamma3[i] = rho0[i] * G * dGbar / (Gbar * Z * Z) * denom;
|
||||
} else {
|
||||
dgamma3[i] = 0.0;
|
||||
}
|
||||
|
||||
B = this->A_meam[elti] * this->Ec_meam[elti][elti];
|
||||
|
||||
if (!iszero(rhob)) {
|
||||
if (this->emb_lin_neg == 1 && rhob <= 0) {
|
||||
frhop[i] = -B;
|
||||
} else {
|
||||
frhop[i] = B * (log(rhob) + 1.0);
|
||||
}
|
||||
if (eflag_either != 0) {
|
||||
if (eflag_global != 0) {
|
||||
if (this->emb_lin_neg == 1 && rhob <= 0) {
|
||||
*eng_vdwl = *eng_vdwl - B * rhob;
|
||||
} else {
|
||||
*eng_vdwl = *eng_vdwl + B * rhob * log(rhob);
|
||||
}
|
||||
}
|
||||
if (eflag_atom != 0) {
|
||||
if (this->emb_lin_neg == 1 && rhob <= 0) {
|
||||
eatom[i] = eatom[i] - B * rhob;
|
||||
} else {
|
||||
eatom[i] = eatom[i] + B * rhob * log(rhob);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (this->emb_lin_neg == 1) {
|
||||
frhop[i] = -B;
|
||||
} else {
|
||||
frhop[i] = B;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
355
src/USER-MEAMC/meam_dens_init.cpp
Normal file
355
src/USER-MEAMC/meam_dens_init.cpp
Normal file
@ -0,0 +1,355 @@
|
||||
#include "meam.h"
|
||||
#include "math_special.h"
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
void
|
||||
MEAM::meam_dens_setup(int atom_nmax, int nall, int n_neigh)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
// grow local arrays if necessary
|
||||
|
||||
if (atom_nmax > nmax) {
|
||||
memory->destroy(rho);
|
||||
memory->destroy(rho0);
|
||||
memory->destroy(rho1);
|
||||
memory->destroy(rho2);
|
||||
memory->destroy(rho3);
|
||||
memory->destroy(frhop);
|
||||
memory->destroy(gamma);
|
||||
memory->destroy(dgamma1);
|
||||
memory->destroy(dgamma2);
|
||||
memory->destroy(dgamma3);
|
||||
memory->destroy(arho2b);
|
||||
memory->destroy(arho1);
|
||||
memory->destroy(arho2);
|
||||
memory->destroy(arho3);
|
||||
memory->destroy(arho3b);
|
||||
memory->destroy(t_ave);
|
||||
memory->destroy(tsq_ave);
|
||||
|
||||
nmax = atom_nmax;
|
||||
|
||||
memory->create(rho, nmax, "pair:rho");
|
||||
memory->create(rho0, nmax, "pair:rho0");
|
||||
memory->create(rho1, nmax, "pair:rho1");
|
||||
memory->create(rho2, nmax, "pair:rho2");
|
||||
memory->create(rho3, nmax, "pair:rho3");
|
||||
memory->create(frhop, nmax, "pair:frhop");
|
||||
memory->create(gamma, nmax, "pair:gamma");
|
||||
memory->create(dgamma1, nmax, "pair:dgamma1");
|
||||
memory->create(dgamma2, nmax, "pair:dgamma2");
|
||||
memory->create(dgamma3, nmax, "pair:dgamma3");
|
||||
memory->create(arho2b, nmax, "pair:arho2b");
|
||||
memory->create(arho1, nmax, 3, "pair:arho1");
|
||||
memory->create(arho2, nmax, 6, "pair:arho2");
|
||||
memory->create(arho3, nmax, 10, "pair:arho3");
|
||||
memory->create(arho3b, nmax, 3, "pair:arho3b");
|
||||
memory->create(t_ave, nmax, 3, "pair:t_ave");
|
||||
memory->create(tsq_ave, nmax, 3, "pair:tsq_ave");
|
||||
}
|
||||
|
||||
if (n_neigh > maxneigh) {
|
||||
memory->destroy(scrfcn);
|
||||
memory->destroy(dscrfcn);
|
||||
memory->destroy(fcpair);
|
||||
maxneigh = n_neigh;
|
||||
memory->create(scrfcn, maxneigh, "pair:scrfcn");
|
||||
memory->create(dscrfcn, maxneigh, "pair:dscrfcn");
|
||||
memory->create(fcpair, maxneigh, "pair:fcpair");
|
||||
}
|
||||
|
||||
// zero out local arrays
|
||||
|
||||
for (i = 0; i < nall; i++) {
|
||||
rho0[i] = 0.0;
|
||||
arho2b[i] = 0.0;
|
||||
arho1[i][0] = arho1[i][1] = arho1[i][2] = 0.0;
|
||||
for (j = 0; j < 6; j++)
|
||||
arho2[i][j] = 0.0;
|
||||
for (j = 0; j < 10; j++)
|
||||
arho3[i][j] = 0.0;
|
||||
arho3b[i][0] = arho3b[i][1] = arho3b[i][2] = 0.0;
|
||||
t_ave[i][0] = t_ave[i][1] = t_ave[i][2] = 0.0;
|
||||
tsq_ave[i][0] = tsq_ave[i][1] = tsq_ave[i][2] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MEAM::meam_dens_init(int i, int ntype, int* type, int* fmap, double** x,
|
||||
int numneigh, int* firstneigh,
|
||||
int numneigh_full, int* firstneigh_full, int fnoffset)
|
||||
{
|
||||
// Compute screening function and derivatives
|
||||
getscreen(i, &scrfcn[fnoffset], &dscrfcn[fnoffset], &fcpair[fnoffset], x, numneigh, firstneigh,
|
||||
numneigh_full, firstneigh_full, ntype, type, fmap);
|
||||
|
||||
// Calculate intermediate density terms to be communicated
|
||||
calc_rho1(i, ntype, type, fmap, x, numneigh, firstneigh, &scrfcn[fnoffset], &fcpair[fnoffset]);
|
||||
}
|
||||
|
||||
// ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
|
||||
|
||||
void
|
||||
MEAM::getscreen(int i, double* scrfcn, double* dscrfcn, double* fcpair, double** x, int numneigh,
|
||||
int* firstneigh, int numneigh_full, int* firstneigh_full, int ntype, int* type, int* fmap)
|
||||
{
|
||||
int jn, j, kn, k;
|
||||
int elti, eltj, eltk;
|
||||
double xitmp, yitmp, zitmp, delxij, delyij, delzij, rij2, rij;
|
||||
double xjtmp, yjtmp, zjtmp, delxik, delyik, delzik, rik2 /*,rik*/;
|
||||
double xktmp, yktmp, zktmp, delxjk, delyjk, delzjk, rjk2 /*,rjk*/;
|
||||
double xik, xjk, sij, fcij, sfcij, dfcij, sikj, dfikj, cikj;
|
||||
double Cmin, Cmax, delc, /*ebound,*/ rbound, a, coef1, coef2;
|
||||
double dCikj;
|
||||
double rnorm, fc, dfc, drinv;
|
||||
|
||||
drinv = 1.0 / this->delr_meam;
|
||||
elti = fmap[type[i]];
|
||||
if (elti < 0) return;
|
||||
|
||||
xitmp = x[i][0];
|
||||
yitmp = x[i][1];
|
||||
zitmp = x[i][2];
|
||||
|
||||
for (jn = 0; jn < numneigh; jn++) {
|
||||
j = firstneigh[jn];
|
||||
|
||||
eltj = fmap[type[j]];
|
||||
if (eltj < 0) continue;
|
||||
|
||||
// First compute screening function itself, sij
|
||||
xjtmp = x[j][0];
|
||||
yjtmp = x[j][1];
|
||||
zjtmp = x[j][2];
|
||||
delxij = xjtmp - xitmp;
|
||||
delyij = yjtmp - yitmp;
|
||||
delzij = zjtmp - zitmp;
|
||||
rij2 = delxij * delxij + delyij * delyij + delzij * delzij;
|
||||
rij = sqrt(rij2);
|
||||
|
||||
if (rij > this->rc_meam) {
|
||||
fcij = 0.0;
|
||||
dfcij = 0.0;
|
||||
sij = 0.0;
|
||||
} else {
|
||||
rnorm = (this->rc_meam - rij) * drinv;
|
||||
sij = 1.0;
|
||||
|
||||
// if rjk2 > ebound*rijsq, atom k is definitely outside the ellipse
|
||||
const double rbound = this->ebound_meam[elti][eltj] * rij2;
|
||||
for (kn = 0; kn < numneigh_full; kn++) {
|
||||
k = firstneigh_full[kn];
|
||||
eltk = fmap[type[k]];
|
||||
if (eltk < 0) continue;
|
||||
if (k == j) continue;
|
||||
|
||||
delxjk = x[k][0] - xjtmp;
|
||||
delyjk = x[k][1] - yjtmp;
|
||||
delzjk = x[k][2] - zjtmp;
|
||||
rjk2 = delxjk * delxjk + delyjk * delyjk + delzjk * delzjk;
|
||||
if (rjk2 > rbound) continue;
|
||||
|
||||
delxik = x[k][0] - xitmp;
|
||||
delyik = x[k][1] - yitmp;
|
||||
delzik = x[k][2] - zitmp;
|
||||
rik2 = delxik * delxik + delyik * delyik + delzik * delzik;
|
||||
if (rik2 > rbound) continue;
|
||||
|
||||
xik = rik2 / rij2;
|
||||
xjk = rjk2 / rij2;
|
||||
a = 1 - (xik - xjk) * (xik - xjk);
|
||||
// if a < 0, then ellipse equation doesn't describe this case and
|
||||
// atom k can't possibly screen i-j
|
||||
if (a <= 0.0) continue;
|
||||
|
||||
cikj = (2.0 * (xik + xjk) + a - 2.0) / a;
|
||||
Cmax = this->Cmax_meam[elti][eltj][eltk];
|
||||
Cmin = this->Cmin_meam[elti][eltj][eltk];
|
||||
if (cikj >= Cmax) continue;
|
||||
// note that cikj may be slightly negative (within numerical
|
||||
// tolerance) if atoms are colinear, so don't reject that case here
|
||||
// (other negative cikj cases were handled by the test on "a" above)
|
||||
else if (cikj <= Cmin) {
|
||||
sij = 0.0;
|
||||
break;
|
||||
} else {
|
||||
delc = Cmax - Cmin;
|
||||
cikj = (cikj - Cmin) / delc;
|
||||
sikj = fcut(cikj);
|
||||
}
|
||||
sij *= sikj;
|
||||
}
|
||||
|
||||
fc = dfcut(rnorm, dfc);
|
||||
fcij = fc;
|
||||
dfcij = dfc * drinv;
|
||||
}
|
||||
|
||||
// Now compute derivatives
|
||||
dscrfcn[jn] = 0.0;
|
||||
sfcij = sij * fcij;
|
||||
if (iszero(sfcij) || iszero(sfcij - 1.0))
|
||||
goto LABEL_100;
|
||||
|
||||
rbound = this->ebound_meam[elti][eltj] * rij2;
|
||||
for (kn = 0; kn < numneigh_full; kn++) {
|
||||
k = firstneigh_full[kn];
|
||||
if (k == j) continue;
|
||||
eltk = fmap[type[k]];
|
||||
if (eltk < 0) continue;
|
||||
|
||||
xktmp = x[k][0];
|
||||
yktmp = x[k][1];
|
||||
zktmp = x[k][2];
|
||||
delxjk = xktmp - xjtmp;
|
||||
delyjk = yktmp - yjtmp;
|
||||
delzjk = zktmp - zjtmp;
|
||||
rjk2 = delxjk * delxjk + delyjk * delyjk + delzjk * delzjk;
|
||||
if (rjk2 > rbound) continue;
|
||||
|
||||
delxik = xktmp - xitmp;
|
||||
delyik = yktmp - yitmp;
|
||||
delzik = zktmp - zitmp;
|
||||
rik2 = delxik * delxik + delyik * delyik + delzik * delzik;
|
||||
if (rik2 > rbound) continue;
|
||||
|
||||
xik = rik2 / rij2;
|
||||
xjk = rjk2 / rij2;
|
||||
a = 1 - (xik - xjk) * (xik - xjk);
|
||||
// if a < 0, then ellipse equation doesn't describe this case and
|
||||
// atom k can't possibly screen i-j
|
||||
if (a <= 0.0) continue;
|
||||
|
||||
cikj = (2.0 * (xik + xjk) + a - 2.0) / a;
|
||||
Cmax = this->Cmax_meam[elti][eltj][eltk];
|
||||
Cmin = this->Cmin_meam[elti][eltj][eltk];
|
||||
if (cikj >= Cmax) {
|
||||
continue;
|
||||
// Note that cikj may be slightly negative (within numerical
|
||||
// tolerance) if atoms are colinear, so don't reject that case
|
||||
// here
|
||||
// (other negative cikj cases were handled by the test on "a"
|
||||
// above)
|
||||
// Note that we never have 0<cikj<Cmin here, else sij=0
|
||||
// (rejected above)
|
||||
} else {
|
||||
delc = Cmax - Cmin;
|
||||
cikj = (cikj - Cmin) / delc;
|
||||
sikj = dfcut(cikj, dfikj);
|
||||
coef1 = dfikj / (delc * sikj);
|
||||
dCikj = dCfunc(rij2, rik2, rjk2);
|
||||
dscrfcn[jn] = dscrfcn[jn] + coef1 * dCikj;
|
||||
}
|
||||
}
|
||||
coef1 = sfcij;
|
||||
coef2 = sij * dfcij / rij;
|
||||
dscrfcn[jn] = dscrfcn[jn] * coef1 - coef2;
|
||||
|
||||
LABEL_100:
|
||||
scrfcn[jn] = sij;
|
||||
fcpair[jn] = fcij;
|
||||
}
|
||||
}
|
||||
|
||||
// ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
|
||||
|
||||
void
|
||||
MEAM::calc_rho1(int i, int ntype, int* type, int* fmap, double** x, int numneigh, int* firstneigh,
|
||||
double* scrfcn, double* fcpair)
|
||||
{
|
||||
int jn, j, m, n, p, elti, eltj;
|
||||
int nv2, nv3;
|
||||
double xtmp, ytmp, ztmp, delij[3], rij2, rij, sij;
|
||||
double ai, aj, rhoa0j, rhoa1j, rhoa2j, rhoa3j, A1j, A2j, A3j;
|
||||
// double G,Gbar,gam,shp[3+1];
|
||||
double ro0i, ro0j;
|
||||
double rhoa0i, rhoa1i, rhoa2i, rhoa3i, A1i, A2i, A3i;
|
||||
|
||||
elti = fmap[type[i]];
|
||||
xtmp = x[i][0];
|
||||
ytmp = x[i][1];
|
||||
ztmp = x[i][2];
|
||||
for (jn = 0; jn < numneigh; jn++) {
|
||||
if (!iszero(scrfcn[jn])) {
|
||||
j = firstneigh[jn];
|
||||
sij = scrfcn[jn] * fcpair[jn];
|
||||
delij[0] = x[j][0] - xtmp;
|
||||
delij[1] = x[j][1] - ytmp;
|
||||
delij[2] = x[j][2] - ztmp;
|
||||
rij2 = delij[0] * delij[0] + delij[1] * delij[1] + delij[2] * delij[2];
|
||||
if (rij2 < this->cutforcesq) {
|
||||
eltj = fmap[type[j]];
|
||||
rij = sqrt(rij2);
|
||||
ai = rij / this->re_meam[elti][elti] - 1.0;
|
||||
aj = rij / this->re_meam[eltj][eltj] - 1.0;
|
||||
ro0i = this->rho0_meam[elti];
|
||||
ro0j = this->rho0_meam[eltj];
|
||||
rhoa0j = ro0j * MathSpecial::fm_exp(-this->beta0_meam[eltj] * aj) * sij;
|
||||
rhoa1j = ro0j * MathSpecial::fm_exp(-this->beta1_meam[eltj] * aj) * sij;
|
||||
rhoa2j = ro0j * MathSpecial::fm_exp(-this->beta2_meam[eltj] * aj) * sij;
|
||||
rhoa3j = ro0j * MathSpecial::fm_exp(-this->beta3_meam[eltj] * aj) * sij;
|
||||
rhoa0i = ro0i * MathSpecial::fm_exp(-this->beta0_meam[elti] * ai) * sij;
|
||||
rhoa1i = ro0i * MathSpecial::fm_exp(-this->beta1_meam[elti] * ai) * sij;
|
||||
rhoa2i = ro0i * MathSpecial::fm_exp(-this->beta2_meam[elti] * ai) * sij;
|
||||
rhoa3i = ro0i * MathSpecial::fm_exp(-this->beta3_meam[elti] * ai) * sij;
|
||||
if (this->ialloy == 1) {
|
||||
rhoa1j = rhoa1j * this->t1_meam[eltj];
|
||||
rhoa2j = rhoa2j * this->t2_meam[eltj];
|
||||
rhoa3j = rhoa3j * this->t3_meam[eltj];
|
||||
rhoa1i = rhoa1i * this->t1_meam[elti];
|
||||
rhoa2i = rhoa2i * this->t2_meam[elti];
|
||||
rhoa3i = rhoa3i * this->t3_meam[elti];
|
||||
}
|
||||
rho0[i] = rho0[i] + rhoa0j;
|
||||
rho0[j] = rho0[j] + rhoa0i;
|
||||
// For ialloy = 2, use single-element value (not average)
|
||||
if (this->ialloy != 2) {
|
||||
t_ave[i][0] = t_ave[i][0] + this->t1_meam[eltj] * rhoa0j;
|
||||
t_ave[i][1] = t_ave[i][1] + this->t2_meam[eltj] * rhoa0j;
|
||||
t_ave[i][2] = t_ave[i][2] + this->t3_meam[eltj] * rhoa0j;
|
||||
t_ave[j][0] = t_ave[j][0] + this->t1_meam[elti] * rhoa0i;
|
||||
t_ave[j][1] = t_ave[j][1] + this->t2_meam[elti] * rhoa0i;
|
||||
t_ave[j][2] = t_ave[j][2] + this->t3_meam[elti] * rhoa0i;
|
||||
}
|
||||
if (this->ialloy == 1) {
|
||||
tsq_ave[i][0] = tsq_ave[i][0] + this->t1_meam[eltj] * this->t1_meam[eltj] * rhoa0j;
|
||||
tsq_ave[i][1] = tsq_ave[i][1] + this->t2_meam[eltj] * this->t2_meam[eltj] * rhoa0j;
|
||||
tsq_ave[i][2] = tsq_ave[i][2] + this->t3_meam[eltj] * this->t3_meam[eltj] * rhoa0j;
|
||||
tsq_ave[j][0] = tsq_ave[j][0] + this->t1_meam[elti] * this->t1_meam[elti] * rhoa0i;
|
||||
tsq_ave[j][1] = tsq_ave[j][1] + this->t2_meam[elti] * this->t2_meam[elti] * rhoa0i;
|
||||
tsq_ave[j][2] = tsq_ave[j][2] + this->t3_meam[elti] * this->t3_meam[elti] * rhoa0i;
|
||||
}
|
||||
arho2b[i] = arho2b[i] + rhoa2j;
|
||||
arho2b[j] = arho2b[j] + rhoa2i;
|
||||
|
||||
A1j = rhoa1j / rij;
|
||||
A2j = rhoa2j / rij2;
|
||||
A3j = rhoa3j / (rij2 * rij);
|
||||
A1i = rhoa1i / rij;
|
||||
A2i = rhoa2i / rij2;
|
||||
A3i = rhoa3i / (rij2 * rij);
|
||||
nv2 = 0;
|
||||
nv3 = 0;
|
||||
for (m = 0; m < 3; m++) {
|
||||
arho1[i][m] = arho1[i][m] + A1j * delij[m];
|
||||
arho1[j][m] = arho1[j][m] - A1i * delij[m];
|
||||
arho3b[i][m] = arho3b[i][m] + rhoa3j * delij[m] / rij;
|
||||
arho3b[j][m] = arho3b[j][m] - rhoa3i * delij[m] / rij;
|
||||
for (n = m; n < 3; n++) {
|
||||
arho2[i][nv2] = arho2[i][nv2] + A2j * delij[m] * delij[n];
|
||||
arho2[j][nv2] = arho2[j][nv2] + A2i * delij[m] * delij[n];
|
||||
nv2 = nv2 + 1;
|
||||
for (p = n; p < 3; p++) {
|
||||
arho3[i][nv3] = arho3[i][nv3] + A3j * delij[m] * delij[n] * delij[p];
|
||||
arho3[j][nv3] = arho3[j][nv3] - A3i * delij[m] * delij[n] * delij[p];
|
||||
nv3 = nv3 + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
531
src/USER-MEAMC/meam_force.cpp
Normal file
531
src/USER-MEAMC/meam_force.cpp
Normal file
@ -0,0 +1,531 @@
|
||||
#include "meam.h"
|
||||
#include "math_special.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
|
||||
void
|
||||
MEAM::meam_force(int i, int eflag_either, int eflag_global, int eflag_atom, int vflag_atom, double* eng_vdwl,
|
||||
double* eatom, int ntype, int* type, int* fmap, double** x, int numneigh, int* firstneigh,
|
||||
int numneigh_full, int* firstneigh_full, int fnoffset, double** f, double** vatom)
|
||||
{
|
||||
int j, jn, k, kn, kk, m, n, p, q;
|
||||
int nv2, nv3, elti, eltj, eltk, ind;
|
||||
double xitmp, yitmp, zitmp, delij[3], rij2, rij, rij3;
|
||||
double v[6], fi[3], fj[3];
|
||||
double third, sixth;
|
||||
double pp, dUdrij, dUdsij, dUdrijm[3], force, forcem;
|
||||
double r, recip, phi, phip;
|
||||
double sij;
|
||||
double a1, a1i, a1j, a2, a2i, a2j;
|
||||
double a3i, a3j;
|
||||
double shpi[3], shpj[3];
|
||||
double ai, aj, ro0i, ro0j, invrei, invrej;
|
||||
double rhoa0j, drhoa0j, rhoa0i, drhoa0i;
|
||||
double rhoa1j, drhoa1j, rhoa1i, drhoa1i;
|
||||
double rhoa2j, drhoa2j, rhoa2i, drhoa2i;
|
||||
double a3, a3a, rhoa3j, drhoa3j, rhoa3i, drhoa3i;
|
||||
double drho0dr1, drho0dr2, drho0ds1, drho0ds2;
|
||||
double drho1dr1, drho1dr2, drho1ds1, drho1ds2;
|
||||
double drho1drm1[3], drho1drm2[3];
|
||||
double drho2dr1, drho2dr2, drho2ds1, drho2ds2;
|
||||
double drho2drm1[3], drho2drm2[3];
|
||||
double drho3dr1, drho3dr2, drho3ds1, drho3ds2;
|
||||
double drho3drm1[3], drho3drm2[3];
|
||||
double dt1dr1, dt1dr2, dt1ds1, dt1ds2;
|
||||
double dt2dr1, dt2dr2, dt2ds1, dt2ds2;
|
||||
double dt3dr1, dt3dr2, dt3ds1, dt3ds2;
|
||||
double drhodr1, drhodr2, drhods1, drhods2, drhodrm1[3], drhodrm2[3];
|
||||
double arg;
|
||||
double arg1i1, arg1j1, arg1i2, arg1j2, arg1i3, arg1j3, arg3i3, arg3j3;
|
||||
double dsij1, dsij2, force1, force2;
|
||||
double t1i, t2i, t3i, t1j, t2j, t3j;
|
||||
|
||||
third = 1.0 / 3.0;
|
||||
sixth = 1.0 / 6.0;
|
||||
|
||||
// Compute forces atom i
|
||||
|
||||
elti = fmap[type[i]];
|
||||
if (elti < 0) return;
|
||||
|
||||
xitmp = x[i][0];
|
||||
yitmp = x[i][1];
|
||||
zitmp = x[i][2];
|
||||
|
||||
// Treat each pair
|
||||
for (jn = 0; jn < numneigh; jn++) {
|
||||
j = firstneigh[jn];
|
||||
eltj = fmap[type[j]];
|
||||
|
||||
if (!iszero(scrfcn[fnoffset + jn]) && eltj >= 0) {
|
||||
|
||||
sij = scrfcn[fnoffset + jn] * fcpair[fnoffset + jn];
|
||||
delij[0] = x[j][0] - xitmp;
|
||||
delij[1] = x[j][1] - yitmp;
|
||||
delij[2] = x[j][2] - zitmp;
|
||||
rij2 = delij[0] * delij[0] + delij[1] * delij[1] + delij[2] * delij[2];
|
||||
if (rij2 < this->cutforcesq) {
|
||||
rij = sqrt(rij2);
|
||||
r = rij;
|
||||
|
||||
// Compute phi and phip
|
||||
ind = this->eltind[elti][eltj];
|
||||
pp = rij * this->rdrar;
|
||||
kk = (int)pp;
|
||||
kk = std::min(kk, this->nrar - 2);
|
||||
pp = pp - kk;
|
||||
pp = std::min(pp, 1.0);
|
||||
phi = ((this->phirar3[ind][kk] * pp + this->phirar2[ind][kk]) * pp + this->phirar1[ind][kk]) * pp +
|
||||
this->phirar[ind][kk];
|
||||
phip = (this->phirar6[ind][kk] * pp + this->phirar5[ind][kk]) * pp + this->phirar4[ind][kk];
|
||||
recip = 1.0 / r;
|
||||
|
||||
if (eflag_either != 0) {
|
||||
if (eflag_global != 0)
|
||||
*eng_vdwl = *eng_vdwl + phi * sij;
|
||||
if (eflag_atom != 0) {
|
||||
eatom[i] = eatom[i] + 0.5 * phi * sij;
|
||||
eatom[j] = eatom[j] + 0.5 * phi * sij;
|
||||
}
|
||||
}
|
||||
|
||||
// write(1,*) "force_meamf: phi: ",phi
|
||||
// write(1,*) "force_meamf: phip: ",phip
|
||||
|
||||
// Compute pair densities and derivatives
|
||||
invrei = 1.0 / this->re_meam[elti][elti];
|
||||
ai = rij * invrei - 1.0;
|
||||
ro0i = this->rho0_meam[elti];
|
||||
rhoa0i = ro0i * MathSpecial::fm_exp(-this->beta0_meam[elti] * ai);
|
||||
drhoa0i = -this->beta0_meam[elti] * invrei * rhoa0i;
|
||||
rhoa1i = ro0i * MathSpecial::fm_exp(-this->beta1_meam[elti] * ai);
|
||||
drhoa1i = -this->beta1_meam[elti] * invrei * rhoa1i;
|
||||
rhoa2i = ro0i * MathSpecial::fm_exp(-this->beta2_meam[elti] * ai);
|
||||
drhoa2i = -this->beta2_meam[elti] * invrei * rhoa2i;
|
||||
rhoa3i = ro0i * MathSpecial::fm_exp(-this->beta3_meam[elti] * ai);
|
||||
drhoa3i = -this->beta3_meam[elti] * invrei * rhoa3i;
|
||||
|
||||
if (elti != eltj) {
|
||||
invrej = 1.0 / this->re_meam[eltj][eltj];
|
||||
aj = rij * invrej - 1.0;
|
||||
ro0j = this->rho0_meam[eltj];
|
||||
rhoa0j = ro0j * MathSpecial::fm_exp(-this->beta0_meam[eltj] * aj);
|
||||
drhoa0j = -this->beta0_meam[eltj] * invrej * rhoa0j;
|
||||
rhoa1j = ro0j * MathSpecial::fm_exp(-this->beta1_meam[eltj] * aj);
|
||||
drhoa1j = -this->beta1_meam[eltj] * invrej * rhoa1j;
|
||||
rhoa2j = ro0j * MathSpecial::fm_exp(-this->beta2_meam[eltj] * aj);
|
||||
drhoa2j = -this->beta2_meam[eltj] * invrej * rhoa2j;
|
||||
rhoa3j = ro0j * MathSpecial::fm_exp(-this->beta3_meam[eltj] * aj);
|
||||
drhoa3j = -this->beta3_meam[eltj] * invrej * rhoa3j;
|
||||
} else {
|
||||
rhoa0j = rhoa0i;
|
||||
drhoa0j = drhoa0i;
|
||||
rhoa1j = rhoa1i;
|
||||
drhoa1j = drhoa1i;
|
||||
rhoa2j = rhoa2i;
|
||||
drhoa2j = drhoa2i;
|
||||
rhoa3j = rhoa3i;
|
||||
drhoa3j = drhoa3i;
|
||||
}
|
||||
|
||||
const double t1mi = this->t1_meam[elti];
|
||||
const double t2mi = this->t2_meam[elti];
|
||||
const double t3mi = this->t3_meam[elti];
|
||||
const double t1mj = this->t1_meam[eltj];
|
||||
const double t2mj = this->t2_meam[eltj];
|
||||
const double t3mj = this->t3_meam[eltj];
|
||||
|
||||
if (this->ialloy == 1) {
|
||||
rhoa1j *= t1mj;
|
||||
rhoa2j *= t2mj;
|
||||
rhoa3j *= t3mj;
|
||||
rhoa1i *= t1mi;
|
||||
rhoa2i *= t2mi;
|
||||
rhoa3i *= t3mi;
|
||||
drhoa1j *= t1mj;
|
||||
drhoa2j *= t2mj;
|
||||
drhoa3j *= t3mj;
|
||||
drhoa1i *= t1mi;
|
||||
drhoa2i *= t2mi;
|
||||
drhoa3i *= t3mi;
|
||||
}
|
||||
|
||||
nv2 = 0;
|
||||
nv3 = 0;
|
||||
arg1i1 = 0.0;
|
||||
arg1j1 = 0.0;
|
||||
arg1i2 = 0.0;
|
||||
arg1j2 = 0.0;
|
||||
arg1i3 = 0.0;
|
||||
arg1j3 = 0.0;
|
||||
arg3i3 = 0.0;
|
||||
arg3j3 = 0.0;
|
||||
for (n = 0; n < 3; n++) {
|
||||
for (p = n; p < 3; p++) {
|
||||
for (q = p; q < 3; q++) {
|
||||
arg = delij[n] * delij[p] * delij[q] * this->v3D[nv3];
|
||||
arg1i3 = arg1i3 + arho3[i][nv3] * arg;
|
||||
arg1j3 = arg1j3 - arho3[j][nv3] * arg;
|
||||
nv3 = nv3 + 1;
|
||||
}
|
||||
arg = delij[n] * delij[p] * this->v2D[nv2];
|
||||
arg1i2 = arg1i2 + arho2[i][nv2] * arg;
|
||||
arg1j2 = arg1j2 + arho2[j][nv2] * arg;
|
||||
nv2 = nv2 + 1;
|
||||
}
|
||||
arg1i1 = arg1i1 + arho1[i][n] * delij[n];
|
||||
arg1j1 = arg1j1 - arho1[j][n] * delij[n];
|
||||
arg3i3 = arg3i3 + arho3b[i][n] * delij[n];
|
||||
arg3j3 = arg3j3 - arho3b[j][n] * delij[n];
|
||||
}
|
||||
|
||||
// rho0 terms
|
||||
drho0dr1 = drhoa0j * sij;
|
||||
drho0dr2 = drhoa0i * sij;
|
||||
|
||||
// rho1 terms
|
||||
a1 = 2 * sij / rij;
|
||||
drho1dr1 = a1 * (drhoa1j - rhoa1j / rij) * arg1i1;
|
||||
drho1dr2 = a1 * (drhoa1i - rhoa1i / rij) * arg1j1;
|
||||
a1 = 2.0 * sij / rij;
|
||||
for (m = 0; m < 3; m++) {
|
||||
drho1drm1[m] = a1 * rhoa1j * arho1[i][m];
|
||||
drho1drm2[m] = -a1 * rhoa1i * arho1[j][m];
|
||||
}
|
||||
|
||||
// rho2 terms
|
||||
a2 = 2 * sij / rij2;
|
||||
drho2dr1 = a2 * (drhoa2j - 2 * rhoa2j / rij) * arg1i2 - 2.0 / 3.0 * arho2b[i] * drhoa2j * sij;
|
||||
drho2dr2 = a2 * (drhoa2i - 2 * rhoa2i / rij) * arg1j2 - 2.0 / 3.0 * arho2b[j] * drhoa2i * sij;
|
||||
a2 = 4 * sij / rij2;
|
||||
for (m = 0; m < 3; m++) {
|
||||
drho2drm1[m] = 0.0;
|
||||
drho2drm2[m] = 0.0;
|
||||
for (n = 0; n < 3; n++) {
|
||||
drho2drm1[m] = drho2drm1[m] + arho2[i][this->vind2D[m][n]] * delij[n];
|
||||
drho2drm2[m] = drho2drm2[m] - arho2[j][this->vind2D[m][n]] * delij[n];
|
||||
}
|
||||
drho2drm1[m] = a2 * rhoa2j * drho2drm1[m];
|
||||
drho2drm2[m] = -a2 * rhoa2i * drho2drm2[m];
|
||||
}
|
||||
|
||||
// rho3 terms
|
||||
rij3 = rij * rij2;
|
||||
a3 = 2 * sij / rij3;
|
||||
a3a = 6.0 / 5.0 * sij / rij;
|
||||
drho3dr1 = a3 * (drhoa3j - 3 * rhoa3j / rij) * arg1i3 - a3a * (drhoa3j - rhoa3j / rij) * arg3i3;
|
||||
drho3dr2 = a3 * (drhoa3i - 3 * rhoa3i / rij) * arg1j3 - a3a * (drhoa3i - rhoa3i / rij) * arg3j3;
|
||||
a3 = 6 * sij / rij3;
|
||||
a3a = 6 * sij / (5 * rij);
|
||||
for (m = 0; m < 3; m++) {
|
||||
drho3drm1[m] = 0.0;
|
||||
drho3drm2[m] = 0.0;
|
||||
nv2 = 0;
|
||||
for (n = 0; n < 3; n++) {
|
||||
for (p = n; p < 3; p++) {
|
||||
arg = delij[n] * delij[p] * this->v2D[nv2];
|
||||
drho3drm1[m] = drho3drm1[m] + arho3[i][this->vind3D[m][n][p]] * arg;
|
||||
drho3drm2[m] = drho3drm2[m] + arho3[j][this->vind3D[m][n][p]] * arg;
|
||||
nv2 = nv2 + 1;
|
||||
}
|
||||
}
|
||||
drho3drm1[m] = (a3 * drho3drm1[m] - a3a * arho3b[i][m]) * rhoa3j;
|
||||
drho3drm2[m] = (-a3 * drho3drm2[m] + a3a * arho3b[j][m]) * rhoa3i;
|
||||
}
|
||||
|
||||
// Compute derivatives of weighting functions t wrt rij
|
||||
t1i = t_ave[i][0];
|
||||
t2i = t_ave[i][1];
|
||||
t3i = t_ave[i][2];
|
||||
t1j = t_ave[j][0];
|
||||
t2j = t_ave[j][1];
|
||||
t3j = t_ave[j][2];
|
||||
|
||||
if (this->ialloy == 1) {
|
||||
|
||||
a1i = 0.0;
|
||||
a1j = 0.0;
|
||||
a2i = 0.0;
|
||||
a2j = 0.0;
|
||||
a3i = 0.0;
|
||||
a3j = 0.0;
|
||||
if (!iszero(tsq_ave[i][0]))
|
||||
a1i = drhoa0j * sij / tsq_ave[i][0];
|
||||
if (!iszero(tsq_ave[j][0]))
|
||||
a1j = drhoa0i * sij / tsq_ave[j][0];
|
||||
if (!iszero(tsq_ave[i][1]))
|
||||
a2i = drhoa0j * sij / tsq_ave[i][1];
|
||||
if (!iszero(tsq_ave[j][1]))
|
||||
a2j = drhoa0i * sij / tsq_ave[j][1];
|
||||
if (!iszero(tsq_ave[i][2]))
|
||||
a3i = drhoa0j * sij / tsq_ave[i][2];
|
||||
if (!iszero(tsq_ave[j][2]))
|
||||
a3j = drhoa0i * sij / tsq_ave[j][2];
|
||||
|
||||
dt1dr1 = a1i * (t1mj - t1i * t1mj*t1mj);
|
||||
dt1dr2 = a1j * (t1mi - t1j * t1mi*t1mi);
|
||||
dt2dr1 = a2i * (t2mj - t2i * t2mj*t2mj);
|
||||
dt2dr2 = a2j * (t2mi - t2j * t2mi*t2mi);
|
||||
dt3dr1 = a3i * (t3mj - t3i * t3mj*t3mj);
|
||||
dt3dr2 = a3j * (t3mi - t3j * t3mi*t3mi);
|
||||
|
||||
} else if (this->ialloy == 2) {
|
||||
|
||||
dt1dr1 = 0.0;
|
||||
dt1dr2 = 0.0;
|
||||
dt2dr1 = 0.0;
|
||||
dt2dr2 = 0.0;
|
||||
dt3dr1 = 0.0;
|
||||
dt3dr2 = 0.0;
|
||||
|
||||
} else {
|
||||
|
||||
ai = 0.0;
|
||||
if (!iszero(rho0[i]))
|
||||
ai = drhoa0j * sij / rho0[i];
|
||||
aj = 0.0;
|
||||
if (!iszero(rho0[j]))
|
||||
aj = drhoa0i * sij / rho0[j];
|
||||
|
||||
dt1dr1 = ai * (t1mj - t1i);
|
||||
dt1dr2 = aj * (t1mi - t1j);
|
||||
dt2dr1 = ai * (t2mj - t2i);
|
||||
dt2dr2 = aj * (t2mi - t2j);
|
||||
dt3dr1 = ai * (t3mj - t3i);
|
||||
dt3dr2 = aj * (t3mi - t3j);
|
||||
}
|
||||
|
||||
// Compute derivatives of total density wrt rij, sij and rij(3)
|
||||
get_shpfcn(this->lattce_meam[elti][elti], shpi);
|
||||
get_shpfcn(this->lattce_meam[eltj][eltj], shpj);
|
||||
drhodr1 = dgamma1[i] * drho0dr1 +
|
||||
dgamma2[i] * (dt1dr1 * rho1[i] + t1i * drho1dr1 + dt2dr1 * rho2[i] + t2i * drho2dr1 +
|
||||
dt3dr1 * rho3[i] + t3i * drho3dr1) -
|
||||
dgamma3[i] * (shpi[0] * dt1dr1 + shpi[1] * dt2dr1 + shpi[2] * dt3dr1);
|
||||
drhodr2 = dgamma1[j] * drho0dr2 +
|
||||
dgamma2[j] * (dt1dr2 * rho1[j] + t1j * drho1dr2 + dt2dr2 * rho2[j] + t2j * drho2dr2 +
|
||||
dt3dr2 * rho3[j] + t3j * drho3dr2) -
|
||||
dgamma3[j] * (shpj[0] * dt1dr2 + shpj[1] * dt2dr2 + shpj[2] * dt3dr2);
|
||||
for (m = 0; m < 3; m++) {
|
||||
drhodrm1[m] = 0.0;
|
||||
drhodrm2[m] = 0.0;
|
||||
drhodrm1[m] = dgamma2[i] * (t1i * drho1drm1[m] + t2i * drho2drm1[m] + t3i * drho3drm1[m]);
|
||||
drhodrm2[m] = dgamma2[j] * (t1j * drho1drm2[m] + t2j * drho2drm2[m] + t3j * drho3drm2[m]);
|
||||
}
|
||||
|
||||
// Compute derivatives wrt sij, but only if necessary
|
||||
if (!iszero(dscrfcn[fnoffset + jn])) {
|
||||
drho0ds1 = rhoa0j;
|
||||
drho0ds2 = rhoa0i;
|
||||
a1 = 2.0 / rij;
|
||||
drho1ds1 = a1 * rhoa1j * arg1i1;
|
||||
drho1ds2 = a1 * rhoa1i * arg1j1;
|
||||
a2 = 2.0 / rij2;
|
||||
drho2ds1 = a2 * rhoa2j * arg1i2 - 2.0 / 3.0 * arho2b[i] * rhoa2j;
|
||||
drho2ds2 = a2 * rhoa2i * arg1j2 - 2.0 / 3.0 * arho2b[j] * rhoa2i;
|
||||
a3 = 2.0 / rij3;
|
||||
a3a = 6.0 / (5.0 * rij);
|
||||
drho3ds1 = a3 * rhoa3j * arg1i3 - a3a * rhoa3j * arg3i3;
|
||||
drho3ds2 = a3 * rhoa3i * arg1j3 - a3a * rhoa3i * arg3j3;
|
||||
|
||||
if (this->ialloy == 1) {
|
||||
|
||||
a1i = 0.0;
|
||||
a1j = 0.0;
|
||||
a2i = 0.0;
|
||||
a2j = 0.0;
|
||||
a3i = 0.0;
|
||||
a3j = 0.0;
|
||||
if (!iszero(tsq_ave[i][0]))
|
||||
a1i = rhoa0j / tsq_ave[i][0];
|
||||
if (!iszero(tsq_ave[j][0]))
|
||||
a1j = rhoa0i / tsq_ave[j][0];
|
||||
if (!iszero(tsq_ave[i][1]))
|
||||
a2i = rhoa0j / tsq_ave[i][1];
|
||||
if (!iszero(tsq_ave[j][1]))
|
||||
a2j = rhoa0i / tsq_ave[j][1];
|
||||
if (!iszero(tsq_ave[i][2]))
|
||||
a3i = rhoa0j / tsq_ave[i][2];
|
||||
if (!iszero(tsq_ave[j][2]))
|
||||
a3j = rhoa0i / tsq_ave[j][2];
|
||||
|
||||
dt1ds1 = a1i * (t1mj - t1i * pow(t1mj, 2));
|
||||
dt1ds2 = a1j * (t1mi - t1j * pow(t1mi, 2));
|
||||
dt2ds1 = a2i * (t2mj - t2i * pow(t2mj, 2));
|
||||
dt2ds2 = a2j * (t2mi - t2j * pow(t2mi, 2));
|
||||
dt3ds1 = a3i * (t3mj - t3i * pow(t3mj, 2));
|
||||
dt3ds2 = a3j * (t3mi - t3j * pow(t3mi, 2));
|
||||
|
||||
} else if (this->ialloy == 2) {
|
||||
|
||||
dt1ds1 = 0.0;
|
||||
dt1ds2 = 0.0;
|
||||
dt2ds1 = 0.0;
|
||||
dt2ds2 = 0.0;
|
||||
dt3ds1 = 0.0;
|
||||
dt3ds2 = 0.0;
|
||||
|
||||
} else {
|
||||
|
||||
ai = 0.0;
|
||||
if (!iszero(rho0[i]))
|
||||
ai = rhoa0j / rho0[i];
|
||||
aj = 0.0;
|
||||
if (!iszero(rho0[j]))
|
||||
aj = rhoa0i / rho0[j];
|
||||
|
||||
dt1ds1 = ai * (t1mj - t1i);
|
||||
dt1ds2 = aj * (t1mi - t1j);
|
||||
dt2ds1 = ai * (t2mj - t2i);
|
||||
dt2ds2 = aj * (t2mi - t2j);
|
||||
dt3ds1 = ai * (t3mj - t3i);
|
||||
dt3ds2 = aj * (t3mi - t3j);
|
||||
}
|
||||
|
||||
drhods1 = dgamma1[i] * drho0ds1 +
|
||||
dgamma2[i] * (dt1ds1 * rho1[i] + t1i * drho1ds1 + dt2ds1 * rho2[i] + t2i * drho2ds1 +
|
||||
dt3ds1 * rho3[i] + t3i * drho3ds1) -
|
||||
dgamma3[i] * (shpi[0] * dt1ds1 + shpi[1] * dt2ds1 + shpi[2] * dt3ds1);
|
||||
drhods2 = dgamma1[j] * drho0ds2 +
|
||||
dgamma2[j] * (dt1ds2 * rho1[j] + t1j * drho1ds2 + dt2ds2 * rho2[j] + t2j * drho2ds2 +
|
||||
dt3ds2 * rho3[j] + t3j * drho3ds2) -
|
||||
dgamma3[j] * (shpj[0] * dt1ds2 + shpj[1] * dt2ds2 + shpj[2] * dt3ds2);
|
||||
}
|
||||
|
||||
// Compute derivatives of energy wrt rij, sij and rij[3]
|
||||
dUdrij = phip * sij + frhop[i] * drhodr1 + frhop[j] * drhodr2;
|
||||
dUdsij = 0.0;
|
||||
if (!iszero(dscrfcn[fnoffset + jn])) {
|
||||
dUdsij = phi + frhop[i] * drhods1 + frhop[j] * drhods2;
|
||||
}
|
||||
for (m = 0; m < 3; m++) {
|
||||
dUdrijm[m] = frhop[i] * drhodrm1[m] + frhop[j] * drhodrm2[m];
|
||||
}
|
||||
|
||||
// Add the part of the force due to dUdrij and dUdsij
|
||||
|
||||
force = dUdrij * recip + dUdsij * dscrfcn[fnoffset + jn];
|
||||
for (m = 0; m < 3; m++) {
|
||||
forcem = delij[m] * force + dUdrijm[m];
|
||||
f[i][m] = f[i][m] + forcem;
|
||||
f[j][m] = f[j][m] - forcem;
|
||||
}
|
||||
|
||||
// Tabulate per-atom virial as symmetrized stress tensor
|
||||
|
||||
if (vflag_atom != 0) {
|
||||
fi[0] = delij[0] * force + dUdrijm[0];
|
||||
fi[1] = delij[1] * force + dUdrijm[1];
|
||||
fi[2] = delij[2] * force + dUdrijm[2];
|
||||
v[0] = -0.5 * (delij[0] * fi[0]);
|
||||
v[1] = -0.5 * (delij[1] * fi[1]);
|
||||
v[2] = -0.5 * (delij[2] * fi[2]);
|
||||
v[3] = -0.25 * (delij[0] * fi[1] + delij[1] * fi[0]);
|
||||
v[4] = -0.25 * (delij[0] * fi[2] + delij[2] * fi[0]);
|
||||
v[5] = -0.25 * (delij[1] * fi[2] + delij[2] * fi[1]);
|
||||
|
||||
for (m = 0; m < 6; m++) {
|
||||
vatom[i][m] = vatom[i][m] + v[m];
|
||||
vatom[j][m] = vatom[j][m] + v[m];
|
||||
}
|
||||
}
|
||||
|
||||
// Now compute forces on other atoms k due to change in sij
|
||||
|
||||
if (iszero(sij) || iszero(sij - 1.0)) continue; //: cont jn loop
|
||||
|
||||
double dxik(0), dyik(0), dzik(0);
|
||||
double dxjk(0), dyjk(0), dzjk(0);
|
||||
|
||||
for (kn = 0; kn < numneigh_full; kn++) {
|
||||
k = firstneigh_full[kn];
|
||||
eltk = fmap[type[k]];
|
||||
if (k != j && eltk >= 0) {
|
||||
double xik, xjk, cikj, sikj, dfc, a;
|
||||
double dCikj1, dCikj2;
|
||||
double delc, rik2, rjk2;
|
||||
|
||||
sij = scrfcn[jn+fnoffset] * fcpair[jn+fnoffset];
|
||||
const double Cmax = this->Cmax_meam[elti][eltj][eltk];
|
||||
const double Cmin = this->Cmin_meam[elti][eltj][eltk];
|
||||
|
||||
dsij1 = 0.0;
|
||||
dsij2 = 0.0;
|
||||
if (!iszero(sij) && !iszero(sij - 1.0)) {
|
||||
const double rbound = rij2 * this->ebound_meam[elti][eltj];
|
||||
delc = Cmax - Cmin;
|
||||
dxjk = x[k][0] - x[j][0];
|
||||
dyjk = x[k][1] - x[j][1];
|
||||
dzjk = x[k][2] - x[j][2];
|
||||
rjk2 = dxjk * dxjk + dyjk * dyjk + dzjk * dzjk;
|
||||
if (rjk2 <= rbound) {
|
||||
dxik = x[k][0] - x[i][0];
|
||||
dyik = x[k][1] - x[i][1];
|
||||
dzik = x[k][2] - x[i][2];
|
||||
rik2 = dxik * dxik + dyik * dyik + dzik * dzik;
|
||||
if (rik2 <= rbound) {
|
||||
xik = rik2 / rij2;
|
||||
xjk = rjk2 / rij2;
|
||||
a = 1 - (xik - xjk) * (xik - xjk);
|
||||
if (!iszero(a)) {
|
||||
cikj = (2.0 * (xik + xjk) + a - 2.0) / a;
|
||||
if (cikj >= Cmin && cikj <= Cmax) {
|
||||
cikj = (cikj - Cmin) / delc;
|
||||
sikj = dfcut(cikj, dfc);
|
||||
dCfunc2(rij2, rik2, rjk2, dCikj1, dCikj2);
|
||||
a = sij / delc * dfc / sikj;
|
||||
dsij1 = a * dCikj1;
|
||||
dsij2 = a * dCikj2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!iszero(dsij1) || !iszero(dsij2)) {
|
||||
force1 = dUdsij * dsij1;
|
||||
force2 = dUdsij * dsij2;
|
||||
|
||||
f[i][0] += force1 * dxik;
|
||||
f[i][1] += force1 * dyik;
|
||||
f[i][2] += force1 * dzik;
|
||||
f[j][0] += force2 * dxjk;
|
||||
f[j][1] += force2 * dyjk;
|
||||
f[j][2] += force2 * dzjk;
|
||||
f[k][0] -= force1 * dxik + force2 * dxjk;
|
||||
f[k][1] -= force1 * dyik + force2 * dyjk;
|
||||
f[k][2] -= force1 * dzik + force2 * dzjk;
|
||||
|
||||
// Tabulate per-atom virial as symmetrized stress tensor
|
||||
|
||||
if (vflag_atom != 0) {
|
||||
fi[0] = force1 * dxik;
|
||||
fi[1] = force1 * dyik;
|
||||
fi[2] = force1 * dzik;
|
||||
fj[0] = force2 * dxjk;
|
||||
fj[1] = force2 * dyjk;
|
||||
fj[2] = force2 * dzjk;
|
||||
v[0] = -third * (dxik * fi[0] + dxjk * fj[0]);
|
||||
v[1] = -third * (dyik * fi[1] + dyjk * fj[1]);
|
||||
v[2] = -third * (dzik * fi[2] + dzjk * fj[2]);
|
||||
v[3] = -sixth * (dxik * fi[1] + dxjk * fj[1] + dyik * fi[0] + dyjk * fj[0]);
|
||||
v[4] = -sixth * (dxik * fi[2] + dxjk * fj[2] + dzik * fi[0] + dzjk * fj[0]);
|
||||
v[5] = -sixth * (dyik * fi[2] + dyjk * fj[2] + dzik * fi[1] + dzjk * fj[1]);
|
||||
|
||||
for (m = 0; m < 6; m++) {
|
||||
vatom[i][m] = vatom[i][m] + v[m];
|
||||
vatom[j][m] = vatom[j][m] + v[m];
|
||||
vatom[k][m] = vatom[k][m] + v[m];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// end of k loop
|
||||
}
|
||||
}
|
||||
}
|
||||
// end of j loop
|
||||
}
|
||||
}
|
||||
321
src/USER-MEAMC/meam_funcs.cpp
Normal file
321
src/USER-MEAMC/meam_funcs.cpp
Normal file
@ -0,0 +1,321 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
http://lammps.sandia.gov, Sandia National Laboratories
|
||||
Steve Plimpton, sjplimp@sandia.gov
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Contributing author: Sebastian Hütter (OvGU)
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#include "meam.h"
|
||||
#include "math_special.h"
|
||||
#include <math.h>
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Compute G(gamma) based on selection flag ibar:
|
||||
// 0 => G = sqrt(1+gamma)
|
||||
// 1 => G = exp(gamma/2)
|
||||
// 2 => not implemented
|
||||
// 3 => G = 2/(1+exp(-gamma))
|
||||
// 4 => G = sqrt(1+gamma)
|
||||
// -5 => G = +-sqrt(abs(1+gamma))
|
||||
//
|
||||
double
|
||||
MEAM::G_gam(const double gamma, const int ibar, int& errorflag) const
|
||||
{
|
||||
double gsmooth_switchpoint;
|
||||
|
||||
switch (ibar) {
|
||||
case 0:
|
||||
case 4:
|
||||
gsmooth_switchpoint = -gsmooth_factor / (gsmooth_factor + 1);
|
||||
if (gamma < gsmooth_switchpoint) {
|
||||
// e.g. gsmooth_factor is 99, {:
|
||||
// gsmooth_switchpoint = -0.99
|
||||
// G = 0.01*(-0.99/gamma)**99
|
||||
double G = 1 / (gsmooth_factor + 1) * pow((gsmooth_switchpoint / gamma), gsmooth_factor);
|
||||
return sqrt(G);
|
||||
} else {
|
||||
return sqrt(1.0 + gamma);
|
||||
}
|
||||
case 1:
|
||||
return MathSpecial::fm_exp(gamma / 2.0);
|
||||
case 3:
|
||||
return 2.0 / (1.0 + exp(-gamma));
|
||||
case -5:
|
||||
if ((1.0 + gamma) >= 0) {
|
||||
return sqrt(1.0 + gamma);
|
||||
} else {
|
||||
return -sqrt(-1.0 - gamma);
|
||||
}
|
||||
}
|
||||
errorflag = 1;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Compute G(gamma and dG(gamma) based on selection flag ibar:
|
||||
// 0 => G = sqrt(1+gamma)
|
||||
// 1 => G = exp(gamma/2)
|
||||
// 2 => not implemented
|
||||
// 3 => G = 2/(1+exp(-gamma))
|
||||
// 4 => G = sqrt(1+gamma)
|
||||
// -5 => G = +-sqrt(abs(1+gamma))
|
||||
//
|
||||
double
|
||||
MEAM::dG_gam(const double gamma, const int ibar, double& dG) const
|
||||
{
|
||||
double gsmooth_switchpoint;
|
||||
double G;
|
||||
|
||||
switch (ibar) {
|
||||
case 0:
|
||||
case 4:
|
||||
gsmooth_switchpoint = -gsmooth_factor / (gsmooth_factor + 1);
|
||||
if (gamma < gsmooth_switchpoint) {
|
||||
// e.g. gsmooth_factor is 99, {:
|
||||
// gsmooth_switchpoint = -0.99
|
||||
// G = 0.01*(-0.99/gamma)**99
|
||||
double G = 1 / (gsmooth_factor + 1) * pow((gsmooth_switchpoint / gamma), gsmooth_factor);
|
||||
G = sqrt(G);
|
||||
dG = -gsmooth_factor * G / (2.0 * gamma);
|
||||
return G;
|
||||
} else {
|
||||
G = sqrt(1.0 + gamma);
|
||||
dG = 1.0 / (2.0 * G);
|
||||
return G;
|
||||
}
|
||||
case 1:
|
||||
G = MathSpecial::fm_exp(gamma / 2.0);
|
||||
dG = G / 2.0;
|
||||
return G;
|
||||
case 3:
|
||||
G = 2.0 / (1.0 + MathSpecial::fm_exp(-gamma));
|
||||
dG = G * (2.0 - G) / 2;
|
||||
return G;
|
||||
case -5:
|
||||
if ((1.0 + gamma) >= 0) {
|
||||
G = sqrt(1.0 + gamma);
|
||||
dG = 1.0 / (2.0 * G);
|
||||
return G;
|
||||
} else {
|
||||
G = -sqrt(-1.0 - gamma);
|
||||
dG = -1.0 / (2.0 * G);
|
||||
return G;
|
||||
}
|
||||
}
|
||||
dG = 1.0;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Compute ZBL potential
|
||||
//
|
||||
double
|
||||
MEAM::zbl(const double r, const int z1, const int z2)
|
||||
{
|
||||
int i;
|
||||
const double c[] = { 0.028171, 0.28022, 0.50986, 0.18175 };
|
||||
const double d[] = { 0.20162, 0.40290, 0.94229, 3.1998 };
|
||||
const double azero = 0.4685;
|
||||
const double cc = 14.3997;
|
||||
double a, x;
|
||||
// azero = (9pi^2/128)^1/3 (0.529) Angstroms
|
||||
a = azero / (pow(z1, 0.23) + pow(z2, 0.23));
|
||||
double result = 0.0;
|
||||
x = r / a;
|
||||
for (i = 0; i <= 3; i++) {
|
||||
result = result + c[i] * MathSpecial::fm_exp(-d[i] * x);
|
||||
}
|
||||
if (r > 0.0)
|
||||
result = result * z1 * z2 / r * cc;
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Compute Rose energy function, I.16
|
||||
//
|
||||
double
|
||||
MEAM::erose(const double r, const double re, const double alpha, const double Ec, const double repuls,
|
||||
const double attrac, const int form)
|
||||
{
|
||||
double astar, a3;
|
||||
double result = 0.0;
|
||||
|
||||
if (r > 0.0) {
|
||||
astar = alpha * (r / re - 1.0);
|
||||
a3 = 0.0;
|
||||
if (astar >= 0)
|
||||
a3 = attrac;
|
||||
else if (astar < 0)
|
||||
a3 = repuls;
|
||||
|
||||
if (form == 1)
|
||||
result = -Ec * (1 + astar + (-attrac + repuls / r) * pow(astar, 3)) * MathSpecial::fm_exp(-astar);
|
||||
else if (form == 2)
|
||||
result = -Ec * (1 + astar + a3 * pow(astar, 3)) * MathSpecial::fm_exp(-astar);
|
||||
else
|
||||
result = -Ec * (1 + astar + a3 * pow(astar, 3) / (r / re)) * MathSpecial::fm_exp(-astar);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Shape factors for various configurations
|
||||
//
|
||||
void
|
||||
MEAM::get_shpfcn(const lattice_t latt, double (&s)[3])
|
||||
{
|
||||
switch (latt) {
|
||||
case FCC:
|
||||
case BCC:
|
||||
case B1:
|
||||
case B2:
|
||||
s[0] = 0.0;
|
||||
s[1] = 0.0;
|
||||
s[2] = 0.0;
|
||||
break;
|
||||
case HCP:
|
||||
s[0] = 0.0;
|
||||
s[1] = 0.0;
|
||||
s[2] = 1.0 / 3.0;
|
||||
break;
|
||||
case DIA:
|
||||
s[0] = 0.0;
|
||||
s[1] = 0.0;
|
||||
s[2] = 32.0 / 9.0;
|
||||
break;
|
||||
case DIM:
|
||||
s[0] = 1.0;
|
||||
s[1] = 2.0 / 3.0;
|
||||
// s(3) = 1.d0
|
||||
s[2] = 0.40;
|
||||
break;
|
||||
default:
|
||||
s[0] = 0.0;
|
||||
// call error('Lattice not defined in get_shpfcn.')
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Number of neighbors for the reference structure
|
||||
//
|
||||
int
|
||||
MEAM::get_Zij(const lattice_t latt)
|
||||
{
|
||||
switch (latt) {
|
||||
case FCC:
|
||||
return 12;
|
||||
case BCC:
|
||||
return 8;
|
||||
case HCP:
|
||||
return 12;
|
||||
case B1:
|
||||
return 6;
|
||||
case DIA:
|
||||
return 4;
|
||||
case DIM:
|
||||
return 1;
|
||||
case C11:
|
||||
return 10;
|
||||
case L12:
|
||||
return 12;
|
||||
case B2:
|
||||
return 8;
|
||||
// call error('Lattice not defined in get_Zij.')
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Number of second neighbors for the reference structure
|
||||
// a = distance ratio R1/R2
|
||||
// S = second neighbor screening function
|
||||
//
|
||||
int
|
||||
MEAM::get_Zij2(const lattice_t latt, const double cmin, const double cmax, double& a, double& S)
|
||||
{
|
||||
|
||||
double C, x, sijk;
|
||||
int Zij2 = 0, numscr = 0;
|
||||
|
||||
switch (latt) {
|
||||
|
||||
case FCC:
|
||||
Zij2 = 6;
|
||||
a = sqrt(2.0);
|
||||
numscr = 4;
|
||||
break;
|
||||
|
||||
case BCC:
|
||||
Zij2 = 6;
|
||||
a = 2.0 / sqrt(3.0);
|
||||
numscr = 4;
|
||||
break;
|
||||
|
||||
case HCP:
|
||||
Zij2 = 6;
|
||||
a = sqrt(2.0);
|
||||
numscr = 4;
|
||||
break;
|
||||
|
||||
case B1:
|
||||
Zij2 = 12;
|
||||
a = sqrt(2.0);
|
||||
numscr = 2;
|
||||
break;
|
||||
|
||||
case DIA:
|
||||
Zij2 = 0;
|
||||
a = sqrt(8.0 / 3.0);
|
||||
numscr = 4;
|
||||
if (cmin < 0.500001) {
|
||||
// call error('can not do 2NN MEAM for dia')
|
||||
}
|
||||
break;
|
||||
|
||||
case DIM:
|
||||
// this really shouldn't be allowed; make sure screening is zero
|
||||
a = 1.0;
|
||||
S = 0.0;
|
||||
return 0;
|
||||
|
||||
case L12:
|
||||
Zij2 = 6;
|
||||
a = sqrt(2.0);
|
||||
numscr = 4;
|
||||
break;
|
||||
|
||||
case B2:
|
||||
Zij2 = 6;
|
||||
a = 2.0 / sqrt(3.0);
|
||||
numscr = 4;
|
||||
break;
|
||||
case C11:
|
||||
// unsupported lattice flag C11 in get_Zij
|
||||
break;
|
||||
default:
|
||||
// unknown lattic flag in get Zij
|
||||
// call error('Lattice not defined in get_Zij.')
|
||||
break;
|
||||
}
|
||||
|
||||
// Compute screening for each first neighbor
|
||||
C = 4.0 / (a * a) - 1.0;
|
||||
x = (C - cmin) / (cmax - cmin);
|
||||
sijk = fcut(x);
|
||||
// There are numscr first neighbors screening the second neighbors
|
||||
S = MathSpecial::powint(sijk, numscr);
|
||||
return Zij2;
|
||||
}
|
||||
72
src/USER-MEAMC/meam_impl.cpp
Normal file
72
src/USER-MEAMC/meam_impl.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
http://lammps.sandia.gov, Sandia National Laboratories
|
||||
Steve Plimpton, sjplimp@sandia.gov
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Contributing author: Sebastian Hütter (OvGU)
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#include "meam.h"
|
||||
#include "memory.h"
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
MEAM::MEAM(Memory* mem)
|
||||
: memory(mem)
|
||||
{
|
||||
phir = phirar = phirar1 = phirar2 = phirar3 = phirar4 = phirar5 = phirar6 = NULL;
|
||||
|
||||
nmax = 0;
|
||||
rho = rho0 = rho1 = rho2 = rho3 = frhop = NULL;
|
||||
gamma = dgamma1 = dgamma2 = dgamma3 = arho2b = NULL;
|
||||
arho1 = arho2 = arho3 = arho3b = t_ave = tsq_ave = NULL;
|
||||
|
||||
maxneigh = 0;
|
||||
scrfcn = dscrfcn = fcpair = NULL;
|
||||
}
|
||||
|
||||
MEAM::~MEAM()
|
||||
{
|
||||
memory->destroy(this->phirar6);
|
||||
memory->destroy(this->phirar5);
|
||||
memory->destroy(this->phirar4);
|
||||
memory->destroy(this->phirar3);
|
||||
memory->destroy(this->phirar2);
|
||||
memory->destroy(this->phirar1);
|
||||
memory->destroy(this->phirar);
|
||||
memory->destroy(this->phir);
|
||||
|
||||
memory->destroy(this->rho);
|
||||
memory->destroy(this->rho0);
|
||||
memory->destroy(this->rho1);
|
||||
memory->destroy(this->rho2);
|
||||
memory->destroy(this->rho3);
|
||||
memory->destroy(this->frhop);
|
||||
memory->destroy(this->gamma);
|
||||
memory->destroy(this->dgamma1);
|
||||
memory->destroy(this->dgamma2);
|
||||
memory->destroy(this->dgamma3);
|
||||
memory->destroy(this->arho2b);
|
||||
|
||||
memory->destroy(this->arho1);
|
||||
memory->destroy(this->arho2);
|
||||
memory->destroy(this->arho3);
|
||||
memory->destroy(this->arho3b);
|
||||
memory->destroy(this->t_ave);
|
||||
memory->destroy(this->tsq_ave);
|
||||
|
||||
memory->destroy(this->scrfcn);
|
||||
memory->destroy(this->dscrfcn);
|
||||
memory->destroy(this->fcpair);
|
||||
}
|
||||
792
src/USER-MEAMC/meam_setup_done.cpp
Normal file
792
src/USER-MEAMC/meam_setup_done.cpp
Normal file
@ -0,0 +1,792 @@
|
||||
#include "meam.h"
|
||||
#include "math_special.h"
|
||||
#include <algorithm>
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
void
|
||||
MEAM::meam_setup_done(double* cutmax)
|
||||
{
|
||||
int nv2, nv3, m, n, p;
|
||||
|
||||
// Force cutoff
|
||||
this->cutforce = this->rc_meam;
|
||||
this->cutforcesq = this->cutforce * this->cutforce;
|
||||
|
||||
// Pass cutoff back to calling program
|
||||
*cutmax = this->cutforce;
|
||||
|
||||
// Augment t1 term
|
||||
for (int i = 0; i < maxelt; i++)
|
||||
this->t1_meam[i] = this->t1_meam[i] + this->augt1 * 3.0 / 5.0 * this->t3_meam[i];
|
||||
|
||||
// Compute off-diagonal alloy parameters
|
||||
alloyparams();
|
||||
|
||||
// indices and factors for Voight notation
|
||||
nv2 = 0;
|
||||
nv3 = 0;
|
||||
for (m = 0; m < 3; m++) {
|
||||
for (n = m; n < 3; n++) {
|
||||
this->vind2D[m][n] = nv2;
|
||||
this->vind2D[n][m] = nv2;
|
||||
nv2 = nv2 + 1;
|
||||
for (p = n; p < 3; p++) {
|
||||
this->vind3D[m][n][p] = nv3;
|
||||
this->vind3D[m][p][n] = nv3;
|
||||
this->vind3D[n][m][p] = nv3;
|
||||
this->vind3D[n][p][m] = nv3;
|
||||
this->vind3D[p][m][n] = nv3;
|
||||
this->vind3D[p][n][m] = nv3;
|
||||
nv3 = nv3 + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this->v2D[0] = 1;
|
||||
this->v2D[1] = 2;
|
||||
this->v2D[2] = 2;
|
||||
this->v2D[3] = 1;
|
||||
this->v2D[4] = 2;
|
||||
this->v2D[5] = 1;
|
||||
|
||||
this->v3D[0] = 1;
|
||||
this->v3D[1] = 3;
|
||||
this->v3D[2] = 3;
|
||||
this->v3D[3] = 3;
|
||||
this->v3D[4] = 6;
|
||||
this->v3D[5] = 3;
|
||||
this->v3D[6] = 1;
|
||||
this->v3D[7] = 3;
|
||||
this->v3D[8] = 3;
|
||||
this->v3D[9] = 1;
|
||||
|
||||
nv2 = 0;
|
||||
for (m = 0; m < this->neltypes; m++) {
|
||||
for (n = m; n < this->neltypes; n++) {
|
||||
this->eltind[m][n] = nv2;
|
||||
this->eltind[n][m] = nv2;
|
||||
nv2 = nv2 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute background densities for reference structure
|
||||
compute_reference_density();
|
||||
|
||||
// Compute pair potentials and setup arrays for interpolation
|
||||
this->nr = 1000;
|
||||
this->dr = 1.1 * this->rc_meam / this->nr;
|
||||
compute_pair_meam();
|
||||
}
|
||||
|
||||
// ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
|
||||
// Fill off-diagonal alloy parameters
|
||||
void
|
||||
MEAM::alloyparams(void)
|
||||
{
|
||||
|
||||
int i, j, k;
|
||||
double eb;
|
||||
|
||||
// Loop over pairs
|
||||
for (i = 0; i < this->neltypes; i++) {
|
||||
for (j = 0; j < this->neltypes; j++) {
|
||||
// Treat off-diagonal pairs
|
||||
// If i>j, set all equal to i<j case (which has aready been set,
|
||||
// here or in the input file)
|
||||
if (i > j) {
|
||||
this->re_meam[i][j] = this->re_meam[j][i];
|
||||
this->Ec_meam[i][j] = this->Ec_meam[j][i];
|
||||
this->alpha_meam[i][j] = this->alpha_meam[j][i];
|
||||
this->lattce_meam[i][j] = this->lattce_meam[j][i];
|
||||
this->nn2_meam[i][j] = this->nn2_meam[j][i];
|
||||
// If i<j and term is unset, use default values (e.g. mean of i-i and
|
||||
// j-j)
|
||||
} else if (j > i) {
|
||||
if (iszero(this->Ec_meam[i][j])) {
|
||||
if (this->lattce_meam[i][j] == L12)
|
||||
this->Ec_meam[i][j] =
|
||||
(3 * this->Ec_meam[i][i] + this->Ec_meam[j][j]) / 4.0 - this->delta_meam[i][j];
|
||||
else if (this->lattce_meam[i][j] == C11) {
|
||||
if (this->lattce_meam[i][i] == DIA)
|
||||
this->Ec_meam[i][j] =
|
||||
(2 * this->Ec_meam[i][i] + this->Ec_meam[j][j]) / 3.0 - this->delta_meam[i][j];
|
||||
else
|
||||
this->Ec_meam[i][j] =
|
||||
(this->Ec_meam[i][i] + 2 * this->Ec_meam[j][j]) / 3.0 - this->delta_meam[i][j];
|
||||
} else
|
||||
this->Ec_meam[i][j] = (this->Ec_meam[i][i] + this->Ec_meam[j][j]) / 2.0 - this->delta_meam[i][j];
|
||||
}
|
||||
if (iszero(this->alpha_meam[i][j]))
|
||||
this->alpha_meam[i][j] = (this->alpha_meam[i][i] + this->alpha_meam[j][j]) / 2.0;
|
||||
if (iszero(this->re_meam[i][j]))
|
||||
this->re_meam[i][j] = (this->re_meam[i][i] + this->re_meam[j][j]) / 2.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cmin[i][k][j] is symmetric in i-j, but not k. For all triplets
|
||||
// where i>j, set equal to the i<j element. Likewise for Cmax.
|
||||
for (i = 1; i < this->neltypes; i++) {
|
||||
for (j = 0; j < i; j++) {
|
||||
for (k = 0; k < this->neltypes; k++) {
|
||||
this->Cmin_meam[i][j][k] = this->Cmin_meam[j][i][k];
|
||||
this->Cmax_meam[i][j][k] = this->Cmax_meam[j][i][k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ebound gives the squared distance such that, for rik2 or rjk2>ebound,
|
||||
// atom k definitely lies outside the screening function ellipse (so
|
||||
// there is no need to calculate its effects). Here, compute it for all
|
||||
// triplets [i][j][k] so that ebound[i][j] is the maximized over k
|
||||
for (i = 0; i < this->neltypes; i++) {
|
||||
for (j = 0; j < this->neltypes; j++) {
|
||||
for (k = 0; k < this->neltypes; k++) {
|
||||
eb = (this->Cmax_meam[i][j][k] * this->Cmax_meam[i][j][k]) / (4.0 * (this->Cmax_meam[i][j][k] - 1.0));
|
||||
this->ebound_meam[i][j] = std::max(this->ebound_meam[i][j], eb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// compute MEAM pair potential for each pair of element types
|
||||
//
|
||||
|
||||
void
|
||||
MEAM::compute_pair_meam(void)
|
||||
{
|
||||
|
||||
double r /*ununsed:, temp*/;
|
||||
int j, a, b, nv2;
|
||||
double astar, frac, phizbl;
|
||||
int n, nmax, Z1, Z2;
|
||||
double arat, rarat, scrn, scrn2;
|
||||
double phiaa, phibb /*unused:,phitmp*/;
|
||||
double C, s111, s112, s221, S11, S22;
|
||||
|
||||
// check for previously allocated arrays and free them
|
||||
if (this->phir != NULL)
|
||||
memory->destroy(this->phir);
|
||||
if (this->phirar != NULL)
|
||||
memory->destroy(this->phirar);
|
||||
if (this->phirar1 != NULL)
|
||||
memory->destroy(this->phirar1);
|
||||
if (this->phirar2 != NULL)
|
||||
memory->destroy(this->phirar2);
|
||||
if (this->phirar3 != NULL)
|
||||
memory->destroy(this->phirar3);
|
||||
if (this->phirar4 != NULL)
|
||||
memory->destroy(this->phirar4);
|
||||
if (this->phirar5 != NULL)
|
||||
memory->destroy(this->phirar5);
|
||||
if (this->phirar6 != NULL)
|
||||
memory->destroy(this->phirar6);
|
||||
|
||||
// allocate memory for array that defines the potential
|
||||
memory->create(this->phir, (this->neltypes * (this->neltypes + 1)) / 2, this->nr, "pair:phir");
|
||||
|
||||
// allocate coeff memory
|
||||
|
||||
memory->create(this->phirar, (this->neltypes * (this->neltypes + 1)) / 2, this->nr, "pair:phirar");
|
||||
memory->create(this->phirar1, (this->neltypes * (this->neltypes + 1)) / 2, this->nr, "pair:phirar1");
|
||||
memory->create(this->phirar2, (this->neltypes * (this->neltypes + 1)) / 2, this->nr, "pair:phirar2");
|
||||
memory->create(this->phirar3, (this->neltypes * (this->neltypes + 1)) / 2, this->nr, "pair:phirar3");
|
||||
memory->create(this->phirar4, (this->neltypes * (this->neltypes + 1)) / 2, this->nr, "pair:phirar4");
|
||||
memory->create(this->phirar5, (this->neltypes * (this->neltypes + 1)) / 2, this->nr, "pair:phirar5");
|
||||
memory->create(this->phirar6, (this->neltypes * (this->neltypes + 1)) / 2, this->nr, "pair:phirar6");
|
||||
|
||||
// loop over pairs of element types
|
||||
nv2 = 0;
|
||||
for (a = 0; a < this->neltypes; a++) {
|
||||
for (b = a; b < this->neltypes; b++) {
|
||||
// loop over r values and compute
|
||||
for (j = 0; j < this->nr; j++) {
|
||||
r = j * this->dr;
|
||||
|
||||
this->phir[nv2][j] = phi_meam(r, a, b);
|
||||
|
||||
// if using second-nearest neighbor, solve recursive problem
|
||||
// (see Lee and Baskes, PRB 62(13):8564 eqn.(21))
|
||||
if (this->nn2_meam[a][b] == 1) {
|
||||
Z1 = get_Zij(this->lattce_meam[a][b]);
|
||||
Z2 = get_Zij2(this->lattce_meam[a][b], this->Cmin_meam[a][a][b],
|
||||
this->Cmax_meam[a][a][b], arat, scrn);
|
||||
|
||||
// The B1, B2, and L12 cases with NN2 have a trick to them; we
|
||||
// need to
|
||||
// compute the contributions from second nearest neighbors, like
|
||||
// a-a
|
||||
// pairs, but need to include NN2 contributions to those pairs as
|
||||
// well.
|
||||
if (this->lattce_meam[a][b] == B1 || this->lattce_meam[a][b] == B2 ||
|
||||
this->lattce_meam[a][b] == L12) {
|
||||
rarat = r * arat;
|
||||
|
||||
// phi_aa
|
||||
phiaa = phi_meam(rarat, a, a);
|
||||
Z1 = get_Zij(this->lattce_meam[a][a]);
|
||||
Z2 = get_Zij2(this->lattce_meam[a][a], this->Cmin_meam[a][a][a],
|
||||
this->Cmax_meam[a][a][a], arat, scrn);
|
||||
nmax = 10;
|
||||
if (scrn > 0.0) {
|
||||
for (n = 1; n <= nmax; n++) {
|
||||
phiaa = phiaa + pow((-Z2 * scrn / Z1), n) * phi_meam(rarat * pow(arat, n), a, a);
|
||||
}
|
||||
}
|
||||
|
||||
// phi_bb
|
||||
phibb = phi_meam(rarat, b, b);
|
||||
Z1 = get_Zij(this->lattce_meam[b][b]);
|
||||
Z2 = get_Zij2(this->lattce_meam[b][b], this->Cmin_meam[b][b][b],
|
||||
this->Cmax_meam[b][b][b], arat, scrn);
|
||||
nmax = 10;
|
||||
if (scrn > 0.0) {
|
||||
for (n = 1; n <= nmax; n++) {
|
||||
phibb = phibb + pow((-Z2 * scrn / Z1), n) * phi_meam(rarat * pow(arat, n), b, b);
|
||||
}
|
||||
}
|
||||
|
||||
if (this->lattce_meam[a][b] == B1 || this->lattce_meam[a][b] == B2) {
|
||||
// Add contributions to the B1 or B2 potential
|
||||
Z1 = get_Zij(this->lattce_meam[a][b]);
|
||||
Z2 = get_Zij2(this->lattce_meam[a][b], this->Cmin_meam[a][a][b],
|
||||
this->Cmax_meam[a][a][b], arat, scrn);
|
||||
this->phir[nv2][j] = this->phir[nv2][j] - Z2 * scrn / (2 * Z1) * phiaa;
|
||||
Z2 = get_Zij2(this->lattce_meam[a][b], this->Cmin_meam[b][b][a],
|
||||
this->Cmax_meam[b][b][a], arat, scrn2);
|
||||
this->phir[nv2][j] = this->phir[nv2][j] - Z2 * scrn2 / (2 * Z1) * phibb;
|
||||
|
||||
} else if (this->lattce_meam[a][b] == L12) {
|
||||
// The L12 case has one last trick; we have to be careful to
|
||||
// compute
|
||||
// the correct screening between 2nd-neighbor pairs. 1-1
|
||||
// second-neighbor pairs are screened by 2 type 1 atoms and
|
||||
// two type
|
||||
// 2 atoms. 2-2 second-neighbor pairs are screened by 4 type
|
||||
// 1
|
||||
// atoms.
|
||||
C = 1.0;
|
||||
get_sijk(C, a, a, a, &s111);
|
||||
get_sijk(C, a, a, b, &s112);
|
||||
get_sijk(C, b, b, a, &s221);
|
||||
S11 = s111 * s111 * s112 * s112;
|
||||
S22 = pow(s221, 4);
|
||||
this->phir[nv2][j] = this->phir[nv2][j] - 0.75 * S11 * phiaa - 0.25 * S22 * phibb;
|
||||
}
|
||||
|
||||
} else {
|
||||
nmax = 10;
|
||||
for (n = 1; n <= nmax; n++) {
|
||||
this->phir[nv2][j] =
|
||||
this->phir[nv2][j] + pow((-Z2 * scrn / Z1), n) * phi_meam(r * pow(arat, n), a, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For Zbl potential:
|
||||
// if astar <= -3
|
||||
// potential is zbl potential
|
||||
// else if -3 < astar < -1
|
||||
// potential is linear combination with zbl potential
|
||||
// endif
|
||||
if (this->zbl_meam[a][b] == 1) {
|
||||
astar = this->alpha_meam[a][b] * (r / this->re_meam[a][b] - 1.0);
|
||||
if (astar <= -3.0)
|
||||
this->phir[nv2][j] = zbl(r, this->ielt_meam[a], this->ielt_meam[b]);
|
||||
else if (astar > -3.0 && astar < -1.0) {
|
||||
frac = fcut(1 - (astar + 1.0) / (-3.0 + 1.0));
|
||||
phizbl = zbl(r, this->ielt_meam[a], this->ielt_meam[b]);
|
||||
this->phir[nv2][j] = frac * this->phir[nv2][j] + (1 - frac) * phizbl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// call interpolation
|
||||
interpolate_meam(nv2);
|
||||
|
||||
nv2 = nv2 + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------c
|
||||
// Compute MEAM pair potential for distance r, element types a and b
|
||||
//
|
||||
double
|
||||
MEAM::phi_meam(double r, int a, int b)
|
||||
{
|
||||
/*unused:double a1,a2,a12;*/
|
||||
double t11av, t21av, t31av, t12av, t22av, t32av;
|
||||
double G1, G2, s1[3], s2[3], rho0_1, rho0_2;
|
||||
double Gam1, Gam2, Z1, Z2;
|
||||
double rhobar1, rhobar2, F1, F2;
|
||||
double rho01, rho11, rho21, rho31;
|
||||
double rho02, rho12, rho22, rho32;
|
||||
double scalfac, phiaa, phibb;
|
||||
double Eu;
|
||||
double arat, scrn /*unused:,scrn2*/;
|
||||
int Z12, errorflag;
|
||||
int n, nmax, Z1nn, Z2nn;
|
||||
lattice_t latta /*unused:,lattb*/;
|
||||
double rho_bkgd1, rho_bkgd2;
|
||||
|
||||
double phi_m = 0.0;
|
||||
|
||||
// Equation numbers below refer to:
|
||||
// I. Huang et.al., Modelling simul. Mater. Sci. Eng. 3:615
|
||||
|
||||
// get number of neighbors in the reference structure
|
||||
// Nref[i][j] = # of i's neighbors of type j
|
||||
Z12 = get_Zij(this->lattce_meam[a][b]);
|
||||
|
||||
get_densref(r, a, b, &rho01, &rho11, &rho21, &rho31, &rho02, &rho12, &rho22, &rho32);
|
||||
|
||||
// if densities are too small, numerical problems may result; just return zero
|
||||
if (rho01 <= 1e-14 && rho02 <= 1e-14)
|
||||
return 0.0;
|
||||
|
||||
// calculate average weighting factors for the reference structure
|
||||
if (this->lattce_meam[a][b] == C11) {
|
||||
if (this->ialloy == 2) {
|
||||
t11av = this->t1_meam[a];
|
||||
t12av = this->t1_meam[b];
|
||||
t21av = this->t2_meam[a];
|
||||
t22av = this->t2_meam[b];
|
||||
t31av = this->t3_meam[a];
|
||||
t32av = this->t3_meam[b];
|
||||
} else {
|
||||
scalfac = 1.0 / (rho01 + rho02);
|
||||
t11av = scalfac * (this->t1_meam[a] * rho01 + this->t1_meam[b] * rho02);
|
||||
t12av = t11av;
|
||||
t21av = scalfac * (this->t2_meam[a] * rho01 + this->t2_meam[b] * rho02);
|
||||
t22av = t21av;
|
||||
t31av = scalfac * (this->t3_meam[a] * rho01 + this->t3_meam[b] * rho02);
|
||||
t32av = t31av;
|
||||
}
|
||||
} else {
|
||||
// average weighting factors for the reference structure, eqn. I.8
|
||||
get_tavref(&t11av, &t21av, &t31av, &t12av, &t22av, &t32av, this->t1_meam[a], this->t2_meam[a],
|
||||
this->t3_meam[a], this->t1_meam[b], this->t2_meam[b], this->t3_meam[b], r, a, b,
|
||||
this->lattce_meam[a][b]);
|
||||
}
|
||||
|
||||
// for c11b structure, calculate background electron densities
|
||||
if (this->lattce_meam[a][b] == C11) {
|
||||
latta = this->lattce_meam[a][a];
|
||||
if (latta == DIA) {
|
||||
rhobar1 = pow(((Z12 / 2) * (rho02 + rho01)), 2) + t11av * pow((rho12 - rho11), 2) +
|
||||
t21av / 6.0 * pow(rho22 + rho21, 2) + 121.0 / 40.0 * t31av * pow((rho32 - rho31), 2);
|
||||
rhobar1 = sqrt(rhobar1);
|
||||
rhobar2 = pow(Z12 * rho01, 2) + 2.0 / 3.0 * t21av * pow(rho21, 2);
|
||||
rhobar2 = sqrt(rhobar2);
|
||||
} else {
|
||||
rhobar2 = pow(((Z12 / 2) * (rho01 + rho02)), 2) + t12av * pow((rho11 - rho12), 2) +
|
||||
t22av / 6.0 * pow(rho21 + rho22, 2) + 121.0 / 40.0 * t32av * pow((rho31 - rho32), 2);
|
||||
rhobar2 = sqrt(rhobar2);
|
||||
rhobar1 = pow(Z12 * rho02, 2) + 2.0 / 3.0 * t22av * pow(rho22, 2);
|
||||
rhobar1 = sqrt(rhobar1);
|
||||
}
|
||||
} else {
|
||||
// for other structures, use formalism developed in Huang's paper
|
||||
//
|
||||
// composition-dependent scaling, equation I.7
|
||||
// If using mixing rule for t, apply to reference structure; else
|
||||
// use precomputed values
|
||||
if (this->mix_ref_t == 1) {
|
||||
Z1 = this->Z_meam[a];
|
||||
Z2 = this->Z_meam[b];
|
||||
if (this->ibar_meam[a] <= 0)
|
||||
G1 = 1.0;
|
||||
else {
|
||||
get_shpfcn(this->lattce_meam[a][a], s1);
|
||||
Gam1 = (s1[0] * t11av + s1[1] * t21av + s1[2] * t31av) / (Z1 * Z1);
|
||||
G1 = G_gam(Gam1, this->ibar_meam[a], errorflag);
|
||||
}
|
||||
if (this->ibar_meam[b] <= 0)
|
||||
G2 = 1.0;
|
||||
else {
|
||||
get_shpfcn(this->lattce_meam[b][b], s2);
|
||||
Gam2 = (s2[0] * t12av + s2[1] * t22av + s2[2] * t32av) / (Z2 * Z2);
|
||||
G2 = G_gam(Gam2, this->ibar_meam[b], errorflag);
|
||||
}
|
||||
rho0_1 = this->rho0_meam[a] * Z1 * G1;
|
||||
rho0_2 = this->rho0_meam[b] * Z2 * G2;
|
||||
}
|
||||
Gam1 = (t11av * rho11 + t21av * rho21 + t31av * rho31);
|
||||
if (rho01 < 1.0e-14)
|
||||
Gam1 = 0.0;
|
||||
else
|
||||
Gam1 = Gam1 / (rho01 * rho01);
|
||||
|
||||
Gam2 = (t12av * rho12 + t22av * rho22 + t32av * rho32);
|
||||
if (rho02 < 1.0e-14)
|
||||
Gam2 = 0.0;
|
||||
else
|
||||
Gam2 = Gam2 / (rho02 * rho02);
|
||||
|
||||
G1 = G_gam(Gam1, this->ibar_meam[a], errorflag);
|
||||
G2 = G_gam(Gam2, this->ibar_meam[b], errorflag);
|
||||
if (this->mix_ref_t == 1) {
|
||||
rho_bkgd1 = rho0_1;
|
||||
rho_bkgd2 = rho0_2;
|
||||
} else {
|
||||
if (this->bkgd_dyn == 1) {
|
||||
rho_bkgd1 = this->rho0_meam[a] * this->Z_meam[a];
|
||||
rho_bkgd2 = this->rho0_meam[b] * this->Z_meam[b];
|
||||
} else {
|
||||
rho_bkgd1 = this->rho_ref_meam[a];
|
||||
rho_bkgd2 = this->rho_ref_meam[b];
|
||||
}
|
||||
}
|
||||
rhobar1 = rho01 / rho_bkgd1 * G1;
|
||||
rhobar2 = rho02 / rho_bkgd2 * G2;
|
||||
}
|
||||
|
||||
// compute embedding functions, eqn I.5
|
||||
if (iszero(rhobar1))
|
||||
F1 = 0.0;
|
||||
else {
|
||||
if (this->emb_lin_neg == 1 && rhobar1 <= 0)
|
||||
F1 = -this->A_meam[a] * this->Ec_meam[a][a] * rhobar1;
|
||||
else
|
||||
F1 = this->A_meam[a] * this->Ec_meam[a][a] * rhobar1 * log(rhobar1);
|
||||
}
|
||||
if (iszero(rhobar2))
|
||||
F2 = 0.0;
|
||||
else {
|
||||
if (this->emb_lin_neg == 1 && rhobar2 <= 0)
|
||||
F2 = -this->A_meam[b] * this->Ec_meam[b][b] * rhobar2;
|
||||
else
|
||||
F2 = this->A_meam[b] * this->Ec_meam[b][b] * rhobar2 * log(rhobar2);
|
||||
}
|
||||
|
||||
// compute Rose function, I.16
|
||||
Eu = erose(r, this->re_meam[a][b], this->alpha_meam[a][b], this->Ec_meam[a][b], this->repuls_meam[a][b],
|
||||
this->attrac_meam[a][b], this->erose_form);
|
||||
|
||||
// calculate the pair energy
|
||||
if (this->lattce_meam[a][b] == C11) {
|
||||
latta = this->lattce_meam[a][a];
|
||||
if (latta == DIA) {
|
||||
phiaa = phi_meam(r, a, a);
|
||||
phi_m = (3 * Eu - F2 - 2 * F1 - 5 * phiaa) / Z12;
|
||||
} else {
|
||||
phibb = phi_meam(r, b, b);
|
||||
phi_m = (3 * Eu - F1 - 2 * F2 - 5 * phibb) / Z12;
|
||||
}
|
||||
} else if (this->lattce_meam[a][b] == L12) {
|
||||
phiaa = phi_meam(r, a, a);
|
||||
// account for second neighbor a-a potential here...
|
||||
Z1nn = get_Zij(this->lattce_meam[a][a]);
|
||||
Z2nn = get_Zij2(this->lattce_meam[a][a], this->Cmin_meam[a][a][a],
|
||||
this->Cmax_meam[a][a][a], arat, scrn);
|
||||
nmax = 10;
|
||||
if (scrn > 0.0) {
|
||||
for (n = 1; n <= nmax; n++) {
|
||||
phiaa = phiaa + pow((-Z2nn * scrn / Z1nn), n) * phi_meam(r * pow(arat, n), a, a);
|
||||
}
|
||||
}
|
||||
phi_m = Eu / 3.0 - F1 / 4.0 - F2 / 12.0 - phiaa;
|
||||
|
||||
} else {
|
||||
//
|
||||
// potential is computed from Rose function and embedding energy
|
||||
phi_m = (2 * Eu - F1 - F2) / Z12;
|
||||
//
|
||||
}
|
||||
|
||||
// if r = 0, just return 0
|
||||
if (iszero(r)) {
|
||||
phi_m = 0.0;
|
||||
}
|
||||
|
||||
return phi_m;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------c
|
||||
// Compute background density for reference structure of each element
|
||||
void
|
||||
MEAM::compute_reference_density(void)
|
||||
{
|
||||
int a, Z, Z2, errorflag;
|
||||
double gam, Gbar, shp[3];
|
||||
double rho0, rho0_2nn, arat, scrn;
|
||||
|
||||
// loop over element types
|
||||
for (a = 0; a < this->neltypes; a++) {
|
||||
Z = (int)this->Z_meam[a];
|
||||
if (this->ibar_meam[a] <= 0)
|
||||
Gbar = 1.0;
|
||||
else {
|
||||
get_shpfcn(this->lattce_meam[a][a], shp);
|
||||
gam = (this->t1_meam[a] * shp[0] + this->t2_meam[a] * shp[1] + this->t3_meam[a] * shp[2]) / (Z * Z);
|
||||
Gbar = G_gam(gam, this->ibar_meam[a], errorflag);
|
||||
}
|
||||
|
||||
// The zeroth order density in the reference structure, with
|
||||
// equilibrium spacing, is just the number of first neighbors times
|
||||
// the rho0_meam coefficient...
|
||||
rho0 = this->rho0_meam[a] * Z;
|
||||
|
||||
// ...unless we have unscreened second neighbors, in which case we
|
||||
// add on the contribution from those (accounting for partial
|
||||
// screening)
|
||||
if (this->nn2_meam[a][a] == 1) {
|
||||
Z2 = get_Zij2(this->lattce_meam[a][a], this->Cmin_meam[a][a][a],
|
||||
this->Cmax_meam[a][a][a], arat, scrn);
|
||||
rho0_2nn = this->rho0_meam[a] * MathSpecial::fm_exp(-this->beta0_meam[a] * (arat - 1));
|
||||
rho0 = rho0 + Z2 * rho0_2nn * scrn;
|
||||
}
|
||||
|
||||
this->rho_ref_meam[a] = rho0 * Gbar;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------c
|
||||
// Average weighting factors for the reference structure
|
||||
void
|
||||
MEAM::get_tavref(double* t11av, double* t21av, double* t31av, double* t12av, double* t22av, double* t32av,
|
||||
double t11, double t21, double t31, double t12, double t22, double t32, double r, int a,
|
||||
int b, lattice_t latt)
|
||||
{
|
||||
double rhoa01, rhoa02, a1, a2, rho01 /*,rho02*/;
|
||||
|
||||
// For ialloy = 2, no averaging is done
|
||||
if (this->ialloy == 2) {
|
||||
*t11av = t11;
|
||||
*t21av = t21;
|
||||
*t31av = t31;
|
||||
*t12av = t12;
|
||||
*t22av = t22;
|
||||
*t32av = t32;
|
||||
} else {
|
||||
if (latt == FCC || latt == BCC || latt == DIA || latt == HCP || latt == B1 || latt == DIM || latt == B2) {
|
||||
// all neighbors are of the opposite type
|
||||
*t11av = t12;
|
||||
*t21av = t22;
|
||||
*t31av = t32;
|
||||
*t12av = t11;
|
||||
*t22av = t21;
|
||||
*t32av = t31;
|
||||
} else {
|
||||
a1 = r / this->re_meam[a][a] - 1.0;
|
||||
a2 = r / this->re_meam[b][b] - 1.0;
|
||||
rhoa01 = this->rho0_meam[a] * MathSpecial::fm_exp(-this->beta0_meam[a] * a1);
|
||||
rhoa02 = this->rho0_meam[b] * MathSpecial::fm_exp(-this->beta0_meam[b] * a2);
|
||||
if (latt == L12) {
|
||||
rho01 = 8 * rhoa01 + 4 * rhoa02;
|
||||
*t11av = (8 * t11 * rhoa01 + 4 * t12 * rhoa02) / rho01;
|
||||
*t12av = t11;
|
||||
*t21av = (8 * t21 * rhoa01 + 4 * t22 * rhoa02) / rho01;
|
||||
*t22av = t21;
|
||||
*t31av = (8 * t31 * rhoa01 + 4 * t32 * rhoa02) / rho01;
|
||||
*t32av = t31;
|
||||
} else {
|
||||
// call error('Lattice not defined in get_tavref.')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------c
|
||||
void
|
||||
MEAM::get_sijk(double C, int i, int j, int k, double* sijk)
|
||||
{
|
||||
double x;
|
||||
x = (C - this->Cmin_meam[i][j][k]) / (this->Cmax_meam[i][j][k] - this->Cmin_meam[i][j][k]);
|
||||
*sijk = fcut(x);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------c
|
||||
// Calculate density functions, assuming reference configuration
|
||||
void
|
||||
MEAM::get_densref(double r, int a, int b, double* rho01, double* rho11, double* rho21, double* rho31,
|
||||
double* rho02, double* rho12, double* rho22, double* rho32)
|
||||
{
|
||||
double a1, a2;
|
||||
double s[3];
|
||||
lattice_t lat;
|
||||
int Zij2nn;
|
||||
double rhoa01nn, rhoa02nn;
|
||||
double rhoa01, rhoa11, rhoa21, rhoa31;
|
||||
double rhoa02, rhoa12, rhoa22, rhoa32;
|
||||
double arat, scrn, denom;
|
||||
double C, s111, s112, s221, S11, S22;
|
||||
|
||||
a1 = r / this->re_meam[a][a] - 1.0;
|
||||
a2 = r / this->re_meam[b][b] - 1.0;
|
||||
|
||||
rhoa01 = this->rho0_meam[a] * MathSpecial::fm_exp(-this->beta0_meam[a] * a1);
|
||||
rhoa11 = this->rho0_meam[a] * MathSpecial::fm_exp(-this->beta1_meam[a] * a1);
|
||||
rhoa21 = this->rho0_meam[a] * MathSpecial::fm_exp(-this->beta2_meam[a] * a1);
|
||||
rhoa31 = this->rho0_meam[a] * MathSpecial::fm_exp(-this->beta3_meam[a] * a1);
|
||||
rhoa02 = this->rho0_meam[b] * MathSpecial::fm_exp(-this->beta0_meam[b] * a2);
|
||||
rhoa12 = this->rho0_meam[b] * MathSpecial::fm_exp(-this->beta1_meam[b] * a2);
|
||||
rhoa22 = this->rho0_meam[b] * MathSpecial::fm_exp(-this->beta2_meam[b] * a2);
|
||||
rhoa32 = this->rho0_meam[b] * MathSpecial::fm_exp(-this->beta3_meam[b] * a2);
|
||||
|
||||
lat = this->lattce_meam[a][b];
|
||||
|
||||
*rho11 = 0.0;
|
||||
*rho21 = 0.0;
|
||||
*rho31 = 0.0;
|
||||
*rho12 = 0.0;
|
||||
*rho22 = 0.0;
|
||||
*rho32 = 0.0;
|
||||
|
||||
if (lat == FCC) {
|
||||
*rho01 = 12.0 * rhoa02;
|
||||
*rho02 = 12.0 * rhoa01;
|
||||
} else if (lat == BCC) {
|
||||
*rho01 = 8.0 * rhoa02;
|
||||
*rho02 = 8.0 * rhoa01;
|
||||
} else if (lat == B1) {
|
||||
*rho01 = 6.0 * rhoa02;
|
||||
*rho02 = 6.0 * rhoa01;
|
||||
} else if (lat == DIA) {
|
||||
*rho01 = 4.0 * rhoa02;
|
||||
*rho02 = 4.0 * rhoa01;
|
||||
*rho31 = 32.0 / 9.0 * rhoa32 * rhoa32;
|
||||
*rho32 = 32.0 / 9.0 * rhoa31 * rhoa31;
|
||||
} else if (lat == HCP) {
|
||||
*rho01 = 12 * rhoa02;
|
||||
*rho02 = 12 * rhoa01;
|
||||
*rho31 = 1.0 / 3.0 * rhoa32 * rhoa32;
|
||||
*rho32 = 1.0 / 3.0 * rhoa31 * rhoa31;
|
||||
} else if (lat == DIM) {
|
||||
get_shpfcn(DIM, s);
|
||||
*rho01 = rhoa02;
|
||||
*rho02 = rhoa01;
|
||||
*rho11 = s[0] * rhoa12 * rhoa12;
|
||||
*rho12 = s[0] * rhoa11 * rhoa11;
|
||||
*rho21 = s[1] * rhoa22 * rhoa22;
|
||||
*rho22 = s[1] * rhoa21 * rhoa21;
|
||||
*rho31 = s[2] * rhoa32 * rhoa32;
|
||||
*rho32 = s[2] * rhoa31 * rhoa31;
|
||||
} else if (lat == C11) {
|
||||
*rho01 = rhoa01;
|
||||
*rho02 = rhoa02;
|
||||
*rho11 = rhoa11;
|
||||
*rho12 = rhoa12;
|
||||
*rho21 = rhoa21;
|
||||
*rho22 = rhoa22;
|
||||
*rho31 = rhoa31;
|
||||
*rho32 = rhoa32;
|
||||
} else if (lat == L12) {
|
||||
*rho01 = 8 * rhoa01 + 4 * rhoa02;
|
||||
*rho02 = 12 * rhoa01;
|
||||
if (this->ialloy == 1) {
|
||||
*rho21 = 8. / 3. * pow(rhoa21 * this->t2_meam[a] - rhoa22 * this->t2_meam[b], 2);
|
||||
denom = 8 * rhoa01 * pow(this->t2_meam[a], 2) + 4 * rhoa02 * pow(this->t2_meam[b], 2);
|
||||
if (denom > 0.)
|
||||
*rho21 = *rho21 / denom * *rho01;
|
||||
} else
|
||||
*rho21 = 8. / 3. * (rhoa21 - rhoa22) * (rhoa21 - rhoa22);
|
||||
} else if (lat == B2) {
|
||||
*rho01 = 8.0 * rhoa02;
|
||||
*rho02 = 8.0 * rhoa01;
|
||||
} else {
|
||||
// call error('Lattice not defined in get_densref.')
|
||||
}
|
||||
|
||||
if (this->nn2_meam[a][b] == 1) {
|
||||
|
||||
Zij2nn = get_Zij2(lat, this->Cmin_meam[a][a][b], this->Cmax_meam[a][a][b], arat, scrn);
|
||||
|
||||
a1 = arat * r / this->re_meam[a][a] - 1.0;
|
||||
a2 = arat * r / this->re_meam[b][b] - 1.0;
|
||||
|
||||
rhoa01nn = this->rho0_meam[a] * MathSpecial::fm_exp(-this->beta0_meam[a] * a1);
|
||||
rhoa02nn = this->rho0_meam[b] * MathSpecial::fm_exp(-this->beta0_meam[b] * a2);
|
||||
|
||||
if (lat == L12) {
|
||||
// As usual, L12 thinks it's special; we need to be careful computing
|
||||
// the screening functions
|
||||
C = 1.0;
|
||||
get_sijk(C, a, a, a, &s111);
|
||||
get_sijk(C, a, a, b, &s112);
|
||||
get_sijk(C, b, b, a, &s221);
|
||||
S11 = s111 * s111 * s112 * s112;
|
||||
S22 = pow(s221, 4);
|
||||
*rho01 = *rho01 + 6 * S11 * rhoa01nn;
|
||||
*rho02 = *rho02 + 6 * S22 * rhoa02nn;
|
||||
|
||||
} else {
|
||||
// For other cases, assume that second neighbor is of same type,
|
||||
// first neighbor may be of different type
|
||||
|
||||
*rho01 = *rho01 + Zij2nn * scrn * rhoa01nn;
|
||||
|
||||
// Assume Zij2nn and arat don't depend on order, but scrn might
|
||||
Zij2nn = get_Zij2(lat, this->Cmin_meam[b][b][a], this->Cmax_meam[b][b][a], arat, scrn);
|
||||
*rho02 = *rho02 + Zij2nn * scrn * rhoa02nn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MEAM::interpolate_meam(int ind)
|
||||
{
|
||||
int j;
|
||||
double drar;
|
||||
|
||||
// map to coefficient space
|
||||
|
||||
this->nrar = this->nr;
|
||||
drar = this->dr;
|
||||
this->rdrar = 1.0 / drar;
|
||||
|
||||
// phir interp
|
||||
for (j = 0; j < this->nrar; j++) {
|
||||
this->phirar[ind][j] = this->phir[ind][j];
|
||||
}
|
||||
this->phirar1[ind][0] = this->phirar[ind][1] - this->phirar[ind][0];
|
||||
this->phirar1[ind][1] = 0.5 * (this->phirar[ind][2] - this->phirar[ind][0]);
|
||||
this->phirar1[ind][this->nrar - 2] =
|
||||
0.5 * (this->phirar[ind][this->nrar - 1] - this->phirar[ind][this->nrar - 3]);
|
||||
this->phirar1[ind][this->nrar - 1] = 0.0;
|
||||
for (j = 2; j < this->nrar - 2; j++) {
|
||||
this->phirar1[ind][j] = ((this->phirar[ind][j - 2] - this->phirar[ind][j + 2]) +
|
||||
8.0 * (this->phirar[ind][j + 1] - this->phirar[ind][j - 1])) /
|
||||
12.;
|
||||
}
|
||||
|
||||
for (j = 0; j < this->nrar - 1; j++) {
|
||||
this->phirar2[ind][j] = 3.0 * (this->phirar[ind][j + 1] - this->phirar[ind][j]) -
|
||||
2.0 * this->phirar1[ind][j] - this->phirar1[ind][j + 1];
|
||||
this->phirar3[ind][j] = this->phirar1[ind][j] + this->phirar1[ind][j + 1] -
|
||||
2.0 * (this->phirar[ind][j + 1] - this->phirar[ind][j]);
|
||||
}
|
||||
this->phirar2[ind][this->nrar - 1] = 0.0;
|
||||
this->phirar3[ind][this->nrar - 1] = 0.0;
|
||||
|
||||
for (j = 0; j < this->nrar; j++) {
|
||||
this->phirar4[ind][j] = this->phirar1[ind][j] / drar;
|
||||
this->phirar5[ind][j] = 2.0 * this->phirar2[ind][j] / drar;
|
||||
this->phirar6[ind][j] = 3.0 * this->phirar3[ind][j] / drar;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Compute Rose energy function, I.16
|
||||
//
|
||||
double
|
||||
MEAM::compute_phi(double rij, int elti, int eltj)
|
||||
{
|
||||
double pp;
|
||||
int ind, kk;
|
||||
|
||||
ind = this->eltind[elti][eltj];
|
||||
pp = rij * this->rdrar;
|
||||
kk = (int)pp;
|
||||
kk = std::min(kk, this->nrar - 2);
|
||||
pp = pp - kk;
|
||||
pp = std::min(pp, 1.0);
|
||||
double result =
|
||||
((this->phirar3[ind][kk] * pp + this->phirar2[ind][kk]) * pp + this->phirar1[ind][kk]) * pp +
|
||||
this->phirar[ind][kk];
|
||||
|
||||
return result;
|
||||
}
|
||||
70
src/USER-MEAMC/meam_setup_global.cpp
Normal file
70
src/USER-MEAMC/meam_setup_global.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
#include "meam.h"
|
||||
#include <math.h>
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
void
|
||||
MEAM::meam_setup_global(int nelt, lattice_t* lat, double* z, int* ielement, double* atwt, double* alpha,
|
||||
double* b0, double* b1, double* b2, double* b3, double* alat, double* esub,
|
||||
double* asub, double* t0, double* t1, double* t2, double* t3, double* rozero,
|
||||
int* ibar)
|
||||
{
|
||||
|
||||
int i;
|
||||
double tmplat[maxelt];
|
||||
|
||||
this->neltypes = nelt;
|
||||
|
||||
for (i = 0; i < nelt; i++) {
|
||||
this->lattce_meam[i][i] = lat[i];
|
||||
|
||||
this->Z_meam[i] = z[i];
|
||||
this->ielt_meam[i] = ielement[i];
|
||||
this->alpha_meam[i][i] = alpha[i];
|
||||
this->beta0_meam[i] = b0[i];
|
||||
this->beta1_meam[i] = b1[i];
|
||||
this->beta2_meam[i] = b2[i];
|
||||
this->beta3_meam[i] = b3[i];
|
||||
tmplat[i] = alat[i];
|
||||
this->Ec_meam[i][i] = esub[i];
|
||||
this->A_meam[i] = asub[i];
|
||||
this->t0_meam[i] = t0[i];
|
||||
this->t1_meam[i] = t1[i];
|
||||
this->t2_meam[i] = t2[i];
|
||||
this->t3_meam[i] = t3[i];
|
||||
this->rho0_meam[i] = rozero[i];
|
||||
this->ibar_meam[i] = ibar[i];
|
||||
|
||||
if (this->lattce_meam[i][i] == FCC)
|
||||
this->re_meam[i][i] = tmplat[i] / sqrt(2.0);
|
||||
else if (this->lattce_meam[i][i] == BCC)
|
||||
this->re_meam[i][i] = tmplat[i] * sqrt(3.0) / 2.0;
|
||||
else if (this->lattce_meam[i][i] == HCP)
|
||||
this->re_meam[i][i] = tmplat[i];
|
||||
else if (this->lattce_meam[i][i] == DIM)
|
||||
this->re_meam[i][i] = tmplat[i];
|
||||
else if (this->lattce_meam[i][i] == DIA)
|
||||
this->re_meam[i][i] = tmplat[i] * sqrt(3.0) / 4.0;
|
||||
else {
|
||||
// error
|
||||
}
|
||||
}
|
||||
|
||||
// Set some defaults
|
||||
this->rc_meam = 4.0;
|
||||
this->delr_meam = 0.1;
|
||||
setall2d(this->attrac_meam, 0.0);
|
||||
setall2d(this->repuls_meam, 0.0);
|
||||
setall3d(this->Cmax_meam, 2.8);
|
||||
setall3d(this->Cmin_meam, 2.0);
|
||||
setall2d(this->ebound_meam, pow(2.8, 2) / (4.0 * (2.8 - 1.0)));
|
||||
setall2d(this->delta_meam, 0.0);
|
||||
setall2d(this->nn2_meam, 0);
|
||||
setall2d(this->zbl_meam, 1);
|
||||
this->gsmooth_factor = 99.0;
|
||||
this->augt1 = 1;
|
||||
this->ialloy = 0;
|
||||
this->mix_ref_t = 0;
|
||||
this->emb_lin_neg = 0;
|
||||
this->bkgd_dyn = 0;
|
||||
this->erose_form = 0;
|
||||
}
|
||||
209
src/USER-MEAMC/meam_setup_param.cpp
Normal file
209
src/USER-MEAMC/meam_setup_param.cpp
Normal file
@ -0,0 +1,209 @@
|
||||
#include "meam.h"
|
||||
#include <algorithm>
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
//
|
||||
// do a sanity check on index parameters
|
||||
void
|
||||
MEAM::meam_checkindex(int num, int lim, int nidx, int* idx /*idx(3)*/, int* ierr)
|
||||
{
|
||||
//: idx[0..2]
|
||||
*ierr = 0;
|
||||
if (nidx < num) {
|
||||
*ierr = 2;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < num; i++) {
|
||||
if ((idx[i] < 0) || (idx[i] >= lim)) {
|
||||
*ierr = 3;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The "which" argument corresponds to the index of the "keyword" array
|
||||
// in pair_meam.cpp:
|
||||
//
|
||||
// 0 = Ec_meam
|
||||
// 1 = alpha_meam
|
||||
// 2 = rho0_meam
|
||||
// 3 = delta_meam
|
||||
// 4 = lattce_meam
|
||||
// 5 = attrac_meam
|
||||
// 6 = repuls_meam
|
||||
// 7 = nn2_meam
|
||||
// 8 = Cmin_meam
|
||||
// 9 = Cmax_meam
|
||||
// 10 = rc_meam
|
||||
// 11 = delr_meam
|
||||
// 12 = augt1
|
||||
// 13 = gsmooth_factor
|
||||
// 14 = re_meam
|
||||
// 15 = ialloy
|
||||
// 16 = mixture_ref_t
|
||||
// 17 = erose_form
|
||||
// 18 = zbl_meam
|
||||
// 19 = emb_lin_neg
|
||||
// 20 = bkgd_dyn
|
||||
|
||||
void
|
||||
MEAM::meam_setup_param(int which, double value, int nindex, int* index /*index(3)*/, int* errorflag)
|
||||
{
|
||||
//: index[0..2]
|
||||
int i1, i2;
|
||||
lattice_t vlat;
|
||||
*errorflag = 0;
|
||||
|
||||
switch (which) {
|
||||
// 0 = Ec_meam
|
||||
case 0:
|
||||
meam_checkindex(2, neltypes, nindex, index, errorflag);
|
||||
if (*errorflag != 0)
|
||||
return;
|
||||
this->Ec_meam[index[0]][index[1]] = value;
|
||||
break;
|
||||
|
||||
// 1 = alpha_meam
|
||||
case 1:
|
||||
meam_checkindex(2, neltypes, nindex, index, errorflag);
|
||||
if (*errorflag != 0)
|
||||
return;
|
||||
this->alpha_meam[index[0]][index[1]] = value;
|
||||
break;
|
||||
|
||||
// 2 = rho0_meam
|
||||
case 2:
|
||||
meam_checkindex(1, neltypes, nindex, index, errorflag);
|
||||
if (*errorflag != 0)
|
||||
return;
|
||||
this->rho0_meam[index[0]] = value;
|
||||
break;
|
||||
|
||||
// 3 = delta_meam
|
||||
case 3:
|
||||
meam_checkindex(2, neltypes, nindex, index, errorflag);
|
||||
if (*errorflag != 0)
|
||||
return;
|
||||
this->delta_meam[index[0]][index[1]] = value;
|
||||
break;
|
||||
|
||||
// 4 = lattce_meam
|
||||
case 4:
|
||||
meam_checkindex(2, neltypes, nindex, index, errorflag);
|
||||
if (*errorflag != 0)
|
||||
return;
|
||||
vlat = (lattice_t)value;
|
||||
|
||||
this->lattce_meam[index[0]][index[1]] = vlat;
|
||||
break;
|
||||
|
||||
// 5 = attrac_meam
|
||||
case 5:
|
||||
meam_checkindex(2, neltypes, nindex, index, errorflag);
|
||||
if (*errorflag != 0)
|
||||
return;
|
||||
this->attrac_meam[index[0]][index[1]] = value;
|
||||
break;
|
||||
|
||||
// 6 = repuls_meam
|
||||
case 6:
|
||||
meam_checkindex(2, neltypes, nindex, index, errorflag);
|
||||
if (*errorflag != 0)
|
||||
return;
|
||||
this->repuls_meam[index[0]][index[1]] = value;
|
||||
break;
|
||||
|
||||
// 7 = nn2_meam
|
||||
case 7:
|
||||
meam_checkindex(2, neltypes, nindex, index, errorflag);
|
||||
if (*errorflag != 0)
|
||||
return;
|
||||
i1 = std::min(index[0], index[1]);
|
||||
i2 = std::max(index[0], index[1]);
|
||||
this->nn2_meam[i1][i2] = (int)value;
|
||||
break;
|
||||
|
||||
// 8 = Cmin_meam
|
||||
case 8:
|
||||
meam_checkindex(3, neltypes, nindex, index, errorflag);
|
||||
if (*errorflag != 0)
|
||||
return;
|
||||
this->Cmin_meam[index[0]][index[1]][index[2]] = value;
|
||||
break;
|
||||
|
||||
// 9 = Cmax_meam
|
||||
case 9:
|
||||
meam_checkindex(3, neltypes, nindex, index, errorflag);
|
||||
if (*errorflag != 0)
|
||||
return;
|
||||
this->Cmax_meam[index[0]][index[1]][index[2]] = value;
|
||||
break;
|
||||
|
||||
// 10 = rc_meam
|
||||
case 10:
|
||||
this->rc_meam = value;
|
||||
break;
|
||||
|
||||
// 11 = delr_meam
|
||||
case 11:
|
||||
this->delr_meam = value;
|
||||
break;
|
||||
|
||||
// 12 = augt1
|
||||
case 12:
|
||||
this->augt1 = (int)value;
|
||||
break;
|
||||
|
||||
// 13 = gsmooth
|
||||
case 13:
|
||||
this->gsmooth_factor = value;
|
||||
break;
|
||||
|
||||
// 14 = re_meam
|
||||
case 14:
|
||||
meam_checkindex(2, neltypes, nindex, index, errorflag);
|
||||
if (*errorflag != 0)
|
||||
return;
|
||||
this->re_meam[index[0]][index[1]] = value;
|
||||
break;
|
||||
|
||||
// 15 = ialloy
|
||||
case 15:
|
||||
this->ialloy = (int)value;
|
||||
break;
|
||||
|
||||
// 16 = mixture_ref_t
|
||||
case 16:
|
||||
this->mix_ref_t = (int)value;
|
||||
break;
|
||||
|
||||
// 17 = erose_form
|
||||
case 17:
|
||||
this->erose_form = (int)value;
|
||||
break;
|
||||
|
||||
// 18 = zbl_meam
|
||||
case 18:
|
||||
meam_checkindex(2, neltypes, nindex, index, errorflag);
|
||||
if (*errorflag != 0)
|
||||
return;
|
||||
i1 = std::min(index[0], index[1]);
|
||||
i2 = std::max(index[0], index[1]);
|
||||
this->zbl_meam[i1][i2] = (int)value;
|
||||
break;
|
||||
|
||||
// 19 = emb_lin_neg
|
||||
case 19:
|
||||
this->emb_lin_neg = (int)value;
|
||||
break;
|
||||
|
||||
// 20 = bkgd_dyn
|
||||
case 20:
|
||||
this->bkgd_dyn = (int)value;
|
||||
break;
|
||||
|
||||
default:
|
||||
*errorflag = 1;
|
||||
}
|
||||
}
|
||||
782
src/USER-MEAMC/pair_meamc.cpp
Normal file
782
src/USER-MEAMC/pair_meamc.cpp
Normal file
@ -0,0 +1,782 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
http://lammps.sandia.gov, Sandia National Laboratories
|
||||
Steve Plimpton, sjplimp@sandia.gov
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Contributing author: Greg Wagner (SNL)
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "meam.h"
|
||||
#include "pair_meamc.h"
|
||||
#include "atom.h"
|
||||
#include "force.h"
|
||||
#include "comm.h"
|
||||
#include "memory.h"
|
||||
#include "neighbor.h"
|
||||
#include "neigh_list.h"
|
||||
#include "neigh_request.h"
|
||||
#include "memory.h"
|
||||
#include "error.h"
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
#define MAXLINE 1024
|
||||
|
||||
static const int nkeywords = 21;
|
||||
static const char *keywords[] = {
|
||||
"Ec","alpha","rho0","delta","lattce",
|
||||
"attrac","repuls","nn2","Cmin","Cmax","rc","delr",
|
||||
"augt1","gsmooth_factor","re","ialloy",
|
||||
"mixture_ref_t","erose_form","zbl",
|
||||
"emb_lin_neg","bkgd_dyn"};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
PairMEAMC::PairMEAMC(LAMMPS *lmp) : Pair(lmp)
|
||||
{
|
||||
single_enable = 0;
|
||||
restartinfo = 0;
|
||||
one_coeff = 1;
|
||||
manybody_flag = 1;
|
||||
|
||||
allocated = 0;
|
||||
|
||||
nelements = 0;
|
||||
elements = NULL;
|
||||
mass = NULL;
|
||||
meam_inst = new MEAM(memory);
|
||||
|
||||
// set comm size needed by this Pair
|
||||
|
||||
comm_forward = 38;
|
||||
comm_reverse = 30;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
free all arrays
|
||||
check if allocated, since class can be destructed when incomplete
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
PairMEAMC::~PairMEAMC()
|
||||
{
|
||||
delete meam_inst;
|
||||
|
||||
for (int i = 0; i < nelements; i++) delete [] elements[i];
|
||||
delete [] elements;
|
||||
delete [] mass;
|
||||
|
||||
if (allocated) {
|
||||
memory->destroy(setflag);
|
||||
memory->destroy(cutsq);
|
||||
delete [] map;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void PairMEAMC::compute(int eflag, int vflag)
|
||||
{
|
||||
int i,ii,n,inum_half,errorflag;
|
||||
int *ilist_half,*numneigh_half,**firstneigh_half;
|
||||
int *numneigh_full,**firstneigh_full;
|
||||
|
||||
if (eflag || vflag) ev_setup(eflag,vflag);
|
||||
else evflag = vflag_fdotr = eflag_global = vflag_global =
|
||||
eflag_atom = vflag_atom = 0;
|
||||
|
||||
// neighbor list info
|
||||
|
||||
inum_half = listhalf->inum;
|
||||
ilist_half = listhalf->ilist;
|
||||
numneigh_half = listhalf->numneigh;
|
||||
firstneigh_half = listhalf->firstneigh;
|
||||
numneigh_full = listfull->numneigh;
|
||||
firstneigh_full = listfull->firstneigh;
|
||||
|
||||
// strip neighbor lists of any special bond flags before using with MEAM
|
||||
// necessary before doing neigh_f2c and neigh_c2f conversions each step
|
||||
|
||||
if (neighbor->ago == 0) {
|
||||
neigh_strip(inum_half,ilist_half,numneigh_half,firstneigh_half);
|
||||
neigh_strip(inum_half,ilist_half,numneigh_full,firstneigh_full);
|
||||
}
|
||||
|
||||
// check size of scrfcn based on half neighbor list
|
||||
|
||||
int nlocal = atom->nlocal;
|
||||
int nall = nlocal + atom->nghost;
|
||||
|
||||
n = 0;
|
||||
for (ii = 0; ii < inum_half; ii++) n += numneigh_half[ilist_half[ii]];
|
||||
|
||||
meam_inst->meam_dens_setup(atom->nmax, nall, n);
|
||||
|
||||
double **x = atom->x;
|
||||
double **f = atom->f;
|
||||
int *type = atom->type;
|
||||
int ntype = atom->ntypes;
|
||||
|
||||
// 3 stages of MEAM calculation
|
||||
// loop over my atoms followed by communication
|
||||
|
||||
int offset = 0;
|
||||
errorflag = 0;
|
||||
|
||||
for (ii = 0; ii < inum_half; ii++) {
|
||||
i = ilist_half[ii];
|
||||
meam_inst->meam_dens_init(i,ntype,type,map,x,
|
||||
numneigh_half[i],firstneigh_half[i],
|
||||
numneigh_full[i],firstneigh_full[i],
|
||||
offset);
|
||||
offset += numneigh_half[i];
|
||||
}
|
||||
|
||||
comm->reverse_comm_pair(this);
|
||||
|
||||
meam_inst->meam_dens_final(nlocal,eflag_either,eflag_global,eflag_atom,
|
||||
&eng_vdwl,eatom,ntype,type,map,errorflag);
|
||||
if (errorflag) {
|
||||
char str[128];
|
||||
sprintf(str,"MEAM library error %d",errorflag);
|
||||
error->one(FLERR,str);
|
||||
}
|
||||
|
||||
comm->forward_comm_pair(this);
|
||||
|
||||
offset = 0;
|
||||
|
||||
// vptr is first value in vatom if it will be used by meam_force()
|
||||
// else vatom may not exist, so pass dummy ptr
|
||||
|
||||
double **vptr;
|
||||
if (vflag_atom) vptr = vatom;
|
||||
else vptr = NULL;
|
||||
|
||||
for (ii = 0; ii < inum_half; ii++) {
|
||||
i = ilist_half[ii];
|
||||
meam_inst->meam_force(i,eflag_either,eflag_global,eflag_atom,
|
||||
vflag_atom,&eng_vdwl,eatom,ntype,type,map,x,
|
||||
numneigh_half[i],firstneigh_half[i],
|
||||
numneigh_full[i],firstneigh_full[i],
|
||||
offset,f,vptr);
|
||||
offset += numneigh_half[i];
|
||||
}
|
||||
|
||||
if (vflag_fdotr) virial_fdotr_compute();
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void PairMEAMC::allocate()
|
||||
{
|
||||
allocated = 1;
|
||||
int n = atom->ntypes;
|
||||
|
||||
memory->create(setflag,n+1,n+1,"pair:setflag");
|
||||
memory->create(cutsq,n+1,n+1,"pair:cutsq");
|
||||
|
||||
map = new int[n+1];
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
global settings
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PairMEAMC::settings(int narg, char **arg)
|
||||
{
|
||||
if (narg != 0) error->all(FLERR,"Illegal pair_style command");
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
set coeffs for one or more type pairs
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PairMEAMC::coeff(int narg, char **arg)
|
||||
{
|
||||
int i,j,m,n;
|
||||
|
||||
if (!allocated) allocate();
|
||||
|
||||
if (narg < 6) error->all(FLERR,"Incorrect args for pair coefficients");
|
||||
|
||||
// insure I,J args are * *
|
||||
|
||||
if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0)
|
||||
error->all(FLERR,"Incorrect args for pair coefficients");
|
||||
|
||||
// read MEAM element names between 2 filenames
|
||||
// nelements = # of MEAM elements
|
||||
// elements = list of unique element names
|
||||
|
||||
if (nelements) {
|
||||
for (i = 0; i < nelements; i++) delete [] elements[i];
|
||||
delete [] elements;
|
||||
delete [] mass;
|
||||
}
|
||||
nelements = narg - 4 - atom->ntypes;
|
||||
if (nelements < 1) error->all(FLERR,"Incorrect args for pair coefficients");
|
||||
elements = new char*[nelements];
|
||||
mass = new double[nelements];
|
||||
|
||||
for (i = 0; i < nelements; i++) {
|
||||
n = strlen(arg[i+3]) + 1;
|
||||
elements[i] = new char[n];
|
||||
strcpy(elements[i],arg[i+3]);
|
||||
}
|
||||
|
||||
// read MEAM library and parameter files
|
||||
// pass all parameters to MEAM package
|
||||
// tell MEAM package that setup is done
|
||||
|
||||
read_files(arg[2],arg[2+nelements+1]);
|
||||
meam_inst->meam_setup_done(&cutmax);
|
||||
|
||||
// read args that map atom types to MEAM elements
|
||||
// map[i] = which element the Ith atom type is, -1 if not mapped
|
||||
|
||||
for (i = 4 + nelements; i < narg; i++) {
|
||||
m = i - (4+nelements) + 1;
|
||||
for (j = 0; j < nelements; j++)
|
||||
if (strcmp(arg[i],elements[j]) == 0) break;
|
||||
if (j < nelements) map[m] = j;
|
||||
else if (strcmp(arg[i],"NULL") == 0) map[m] = -1;
|
||||
else error->all(FLERR,"Incorrect args for pair coefficients");
|
||||
}
|
||||
|
||||
// clear setflag since coeff() called once with I,J = * *
|
||||
|
||||
n = atom->ntypes;
|
||||
for (int i = 1; i <= n; i++)
|
||||
for (int j = i; j <= n; j++)
|
||||
setflag[i][j] = 0;
|
||||
|
||||
// set setflag i,j for type pairs where both are mapped to elements
|
||||
// set mass for i,i in atom class
|
||||
|
||||
int count = 0;
|
||||
for (int i = 1; i <= n; i++)
|
||||
for (int j = i; j <= n; j++)
|
||||
if (map[i] >= 0 && map[j] >= 0) {
|
||||
setflag[i][j] = 1;
|
||||
if (i == j) atom->set_mass(FLERR,i,mass[map[i]]);
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
init specific to this pair style
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PairMEAMC::init_style()
|
||||
{
|
||||
if (force->newton_pair == 0)
|
||||
error->all(FLERR,"Pair style MEAM requires newton pair on");
|
||||
|
||||
// need full and half neighbor list
|
||||
|
||||
int irequest_full = neighbor->request(this,instance_me);
|
||||
neighbor->requests[irequest_full]->id = 1;
|
||||
neighbor->requests[irequest_full]->half = 0;
|
||||
neighbor->requests[irequest_full]->full = 1;
|
||||
int irequest_half = neighbor->request(this,instance_me);
|
||||
neighbor->requests[irequest_half]->id = 2;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
neighbor callback to inform pair style of neighbor list to use
|
||||
half or full
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PairMEAMC::init_list(int id, NeighList *ptr)
|
||||
{
|
||||
if (id == 1) listfull = ptr;
|
||||
else if (id == 2) listhalf = ptr;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
init for one type pair i,j and corresponding j,i
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
double PairMEAMC::init_one(int i, int j)
|
||||
{
|
||||
return cutmax;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void PairMEAMC::read_files(char *globalfile, char *userfile)
|
||||
{
|
||||
// open global meamf file on proc 0
|
||||
|
||||
FILE *fp;
|
||||
if (comm->me == 0) {
|
||||
fp = force->open_potential(globalfile);
|
||||
if (fp == NULL) {
|
||||
char str[128];
|
||||
sprintf(str,"Cannot open MEAM potential file %s",globalfile);
|
||||
error->one(FLERR,str);
|
||||
}
|
||||
}
|
||||
|
||||
// allocate parameter arrays
|
||||
|
||||
int params_per_line = 19;
|
||||
|
||||
lattice_t *lat = new lattice_t[nelements];
|
||||
int *ielement = new int[nelements];
|
||||
int *ibar = new int[nelements];
|
||||
double *z = new double[nelements];
|
||||
double *atwt = new double[nelements];
|
||||
double *alpha = new double[nelements];
|
||||
double *b0 = new double[nelements];
|
||||
double *b1 = new double[nelements];
|
||||
double *b2 = new double[nelements];
|
||||
double *b3 = new double[nelements];
|
||||
double *alat = new double[nelements];
|
||||
double *esub = new double[nelements];
|
||||
double *asub = new double[nelements];
|
||||
double *t0 = new double[nelements];
|
||||
double *t1 = new double[nelements];
|
||||
double *t2 = new double[nelements];
|
||||
double *t3 = new double[nelements];
|
||||
double *rozero = new double[nelements];
|
||||
|
||||
bool *found = new bool[nelements];
|
||||
for (int i = 0; i < nelements; i++) found[i] = false;
|
||||
|
||||
// read each set of params from global MEAM file
|
||||
// one set of params can span multiple lines
|
||||
// store params if element name is in element list
|
||||
// if element name appears multiple times, only store 1st entry
|
||||
|
||||
int i,n,nwords;
|
||||
char **words = new char*[params_per_line+1];
|
||||
char line[MAXLINE],*ptr;
|
||||
int eof = 0;
|
||||
|
||||
int nset = 0;
|
||||
while (1) {
|
||||
if (comm->me == 0) {
|
||||
ptr = fgets(line,MAXLINE,fp);
|
||||
if (ptr == NULL) {
|
||||
eof = 1;
|
||||
fclose(fp);
|
||||
} else n = strlen(line) + 1;
|
||||
}
|
||||
MPI_Bcast(&eof,1,MPI_INT,0,world);
|
||||
if (eof) break;
|
||||
MPI_Bcast(&n,1,MPI_INT,0,world);
|
||||
MPI_Bcast(line,n,MPI_CHAR,0,world);
|
||||
|
||||
// strip comment, skip line if blank
|
||||
|
||||
if ((ptr = strchr(line,'#'))) *ptr = '\0';
|
||||
nwords = atom->count_words(line);
|
||||
if (nwords == 0) continue;
|
||||
|
||||
// concatenate additional lines until have params_per_line words
|
||||
|
||||
while (nwords < params_per_line) {
|
||||
n = strlen(line);
|
||||
if (comm->me == 0) {
|
||||
ptr = fgets(&line[n],MAXLINE-n,fp);
|
||||
if (ptr == NULL) {
|
||||
eof = 1;
|
||||
fclose(fp);
|
||||
} else n = strlen(line) + 1;
|
||||
}
|
||||
MPI_Bcast(&eof,1,MPI_INT,0,world);
|
||||
if (eof) break;
|
||||
MPI_Bcast(&n,1,MPI_INT,0,world);
|
||||
MPI_Bcast(line,n,MPI_CHAR,0,world);
|
||||
if ((ptr = strchr(line,'#'))) *ptr = '\0';
|
||||
nwords = atom->count_words(line);
|
||||
}
|
||||
|
||||
if (nwords != params_per_line)
|
||||
error->all(FLERR,"Incorrect format in MEAM potential file");
|
||||
|
||||
// words = ptrs to all words in line
|
||||
// strip single and double quotes from words
|
||||
|
||||
nwords = 0;
|
||||
words[nwords++] = strtok(line,"' \t\n\r\f");
|
||||
while ((words[nwords++] = strtok(NULL,"' \t\n\r\f"))) continue;
|
||||
|
||||
// skip if element name isn't in element list
|
||||
|
||||
for (i = 0; i < nelements; i++)
|
||||
if (strcmp(words[0],elements[i]) == 0) break;
|
||||
if (i >= nelements) continue;
|
||||
|
||||
// skip if element already appeared
|
||||
|
||||
if (found[i] == true) continue;
|
||||
found[i] = true;
|
||||
|
||||
// map lat string to an integer
|
||||
|
||||
if (strcmp(words[1],"fcc") == 0) lat[i] = FCC;
|
||||
else if (strcmp(words[1],"bcc") == 0) lat[i] = BCC;
|
||||
else if (strcmp(words[1],"hcp") == 0) lat[i] = HCP;
|
||||
else if (strcmp(words[1],"dim") == 0) lat[i] = DIM;
|
||||
else if (strcmp(words[1],"dia") == 0) lat[i] = DIA;
|
||||
else error->all(FLERR,"Unrecognized lattice type in MEAM file 1");
|
||||
|
||||
// store parameters
|
||||
|
||||
z[i] = atof(words[2]);
|
||||
ielement[i] = atoi(words[3]);
|
||||
atwt[i] = atof(words[4]);
|
||||
alpha[i] = atof(words[5]);
|
||||
b0[i] = atof(words[6]);
|
||||
b1[i] = atof(words[7]);
|
||||
b2[i] = atof(words[8]);
|
||||
b3[i] = atof(words[9]);
|
||||
alat[i] = atof(words[10]);
|
||||
esub[i] = atof(words[11]);
|
||||
asub[i] = atof(words[12]);
|
||||
t0[i] = atof(words[13]);
|
||||
t1[i] = atof(words[14]);
|
||||
t2[i] = atof(words[15]);
|
||||
t3[i] = atof(words[16]);
|
||||
rozero[i] = atof(words[17]);
|
||||
ibar[i] = atoi(words[18]);
|
||||
|
||||
nset++;
|
||||
}
|
||||
|
||||
// error if didn't find all elements in file
|
||||
|
||||
if (nset != nelements)
|
||||
error->all(FLERR,"Did not find all elements in MEAM library file");
|
||||
|
||||
// pass element parameters to MEAM package
|
||||
|
||||
meam_inst->meam_setup_global(nelements,lat,z,ielement,atwt,alpha,b0,b1,b2,b3,
|
||||
alat,esub,asub,t0,t1,t2,t3,rozero,ibar);
|
||||
|
||||
// set element masses
|
||||
|
||||
for (i = 0; i < nelements; i++) mass[i] = atwt[i];
|
||||
|
||||
// clean-up memory
|
||||
|
||||
delete [] words;
|
||||
|
||||
delete [] lat;
|
||||
delete [] ielement;
|
||||
delete [] ibar;
|
||||
delete [] z;
|
||||
delete [] atwt;
|
||||
delete [] alpha;
|
||||
delete [] b0;
|
||||
delete [] b1;
|
||||
delete [] b2;
|
||||
delete [] b3;
|
||||
delete [] alat;
|
||||
delete [] esub;
|
||||
delete [] asub;
|
||||
delete [] t0;
|
||||
delete [] t1;
|
||||
delete [] t2;
|
||||
delete [] t3;
|
||||
delete [] rozero;
|
||||
delete [] found;
|
||||
|
||||
// done if user param file is NULL
|
||||
|
||||
if (strcmp(userfile,"NULL") == 0) return;
|
||||
|
||||
// open user param file on proc 0
|
||||
|
||||
if (comm->me == 0) {
|
||||
fp = force->open_potential(userfile);
|
||||
if (fp == NULL) {
|
||||
char str[128];
|
||||
sprintf(str,"Cannot open MEAM potential file %s",userfile);
|
||||
error->one(FLERR,str);
|
||||
}
|
||||
}
|
||||
|
||||
// read settings
|
||||
// pass them one at a time to MEAM package
|
||||
// match strings to list of corresponding ints
|
||||
|
||||
int which;
|
||||
double value;
|
||||
int nindex,index[3];
|
||||
int maxparams = 6;
|
||||
char **params = new char*[maxparams];
|
||||
int nparams;
|
||||
|
||||
eof = 0;
|
||||
while (1) {
|
||||
if (comm->me == 0) {
|
||||
ptr = fgets(line,MAXLINE,fp);
|
||||
if (ptr == NULL) {
|
||||
eof = 1;
|
||||
fclose(fp);
|
||||
} else n = strlen(line) + 1;
|
||||
}
|
||||
MPI_Bcast(&eof,1,MPI_INT,0,world);
|
||||
if (eof) break;
|
||||
MPI_Bcast(&n,1,MPI_INT,0,world);
|
||||
MPI_Bcast(line,n,MPI_CHAR,0,world);
|
||||
|
||||
// strip comment, skip line if blank
|
||||
|
||||
if ((ptr = strchr(line,'#'))) *ptr = '\0';
|
||||
nparams = atom->count_words(line);
|
||||
if (nparams == 0) continue;
|
||||
|
||||
// words = ptrs to all words in line
|
||||
|
||||
nparams = 0;
|
||||
params[nparams++] = strtok(line,"=(), '\t\n\r\f");
|
||||
while (nparams < maxparams &&
|
||||
(params[nparams++] = strtok(NULL,"=(), '\t\n\r\f")))
|
||||
continue;
|
||||
nparams--;
|
||||
|
||||
for (which = 0; which < nkeywords; which++)
|
||||
if (strcmp(params[0],keywords[which]) == 0) break;
|
||||
if (which == nkeywords) {
|
||||
char str[128];
|
||||
sprintf(str,"Keyword %s in MEAM parameter file not recognized",
|
||||
params[0]);
|
||||
error->all(FLERR,str);
|
||||
}
|
||||
nindex = nparams - 2;
|
||||
for (i = 0; i < nindex; i++) index[i] = atoi(params[i+1]) - 1;
|
||||
|
||||
// map lattce_meam value to an integer
|
||||
|
||||
if (which == 4) {
|
||||
if (strcmp(params[nparams-1],"fcc") == 0) value = FCC;
|
||||
else if (strcmp(params[nparams-1],"bcc") == 0) value = BCC;
|
||||
else if (strcmp(params[nparams-1],"hcp") == 0) value = HCP;
|
||||
else if (strcmp(params[nparams-1],"dim") == 0) value = DIM;
|
||||
else if (strcmp(params[nparams-1],"dia") == 0) value = DIA;
|
||||
else if (strcmp(params[nparams-1],"b1") == 0) value = B1;
|
||||
else if (strcmp(params[nparams-1],"c11") == 0) value = C11;
|
||||
else if (strcmp(params[nparams-1],"l12") == 0) value = L12;
|
||||
else if (strcmp(params[nparams-1],"b2") == 0) value = B2;
|
||||
else error->all(FLERR,"Unrecognized lattice type in MEAM file 2");
|
||||
}
|
||||
else value = atof(params[nparams-1]);
|
||||
|
||||
// pass single setting to MEAM package
|
||||
|
||||
int errorflag = 0;
|
||||
meam_inst->meam_setup_param(which,value,nindex,index,&errorflag);
|
||||
if (errorflag) {
|
||||
char str[128];
|
||||
sprintf(str,"MEAM library error %d",errorflag);
|
||||
error->all(FLERR,str);
|
||||
}
|
||||
}
|
||||
|
||||
delete [] params;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
int PairMEAMC::pack_forward_comm(int n, int *list, double *buf,
|
||||
int pbc_flag, int *pbc)
|
||||
{
|
||||
int i,j,k,m;
|
||||
|
||||
m = 0;
|
||||
for (i = 0; i < n; i++) {
|
||||
j = list[i];
|
||||
buf[m++] = meam_inst->rho0[j];
|
||||
buf[m++] = meam_inst->rho1[j];
|
||||
buf[m++] = meam_inst->rho2[j];
|
||||
buf[m++] = meam_inst->rho3[j];
|
||||
buf[m++] = meam_inst->frhop[j];
|
||||
buf[m++] = meam_inst->gamma[j];
|
||||
buf[m++] = meam_inst->dgamma1[j];
|
||||
buf[m++] = meam_inst->dgamma2[j];
|
||||
buf[m++] = meam_inst->dgamma3[j];
|
||||
buf[m++] = meam_inst->arho2b[j];
|
||||
buf[m++] = meam_inst->arho1[j][0];
|
||||
buf[m++] = meam_inst->arho1[j][1];
|
||||
buf[m++] = meam_inst->arho1[j][2];
|
||||
buf[m++] = meam_inst->arho2[j][0];
|
||||
buf[m++] = meam_inst->arho2[j][1];
|
||||
buf[m++] = meam_inst->arho2[j][2];
|
||||
buf[m++] = meam_inst->arho2[j][3];
|
||||
buf[m++] = meam_inst->arho2[j][4];
|
||||
buf[m++] = meam_inst->arho2[j][5];
|
||||
for (k = 0; k < 10; k++) buf[m++] = meam_inst->arho3[j][k];
|
||||
buf[m++] = meam_inst->arho3b[j][0];
|
||||
buf[m++] = meam_inst->arho3b[j][1];
|
||||
buf[m++] = meam_inst->arho3b[j][2];
|
||||
buf[m++] = meam_inst->t_ave[j][0];
|
||||
buf[m++] = meam_inst->t_ave[j][1];
|
||||
buf[m++] = meam_inst->t_ave[j][2];
|
||||
buf[m++] = meam_inst->tsq_ave[j][0];
|
||||
buf[m++] = meam_inst->tsq_ave[j][1];
|
||||
buf[m++] = meam_inst->tsq_ave[j][2];
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void PairMEAMC::unpack_forward_comm(int n, int first, double *buf)
|
||||
{
|
||||
int i,k,m,last;
|
||||
|
||||
m = 0;
|
||||
last = first + n;
|
||||
for (i = first; i < last; i++) {
|
||||
meam_inst->rho0[i] = buf[m++];
|
||||
meam_inst->rho1[i] = buf[m++];
|
||||
meam_inst->rho2[i] = buf[m++];
|
||||
meam_inst->rho3[i] = buf[m++];
|
||||
meam_inst->frhop[i] = buf[m++];
|
||||
meam_inst->gamma[i] = buf[m++];
|
||||
meam_inst->dgamma1[i] = buf[m++];
|
||||
meam_inst->dgamma2[i] = buf[m++];
|
||||
meam_inst->dgamma3[i] = buf[m++];
|
||||
meam_inst->arho2b[i] = buf[m++];
|
||||
meam_inst->arho1[i][0] = buf[m++];
|
||||
meam_inst->arho1[i][1] = buf[m++];
|
||||
meam_inst->arho1[i][2] = buf[m++];
|
||||
meam_inst->arho2[i][0] = buf[m++];
|
||||
meam_inst->arho2[i][1] = buf[m++];
|
||||
meam_inst->arho2[i][2] = buf[m++];
|
||||
meam_inst->arho2[i][3] = buf[m++];
|
||||
meam_inst->arho2[i][4] = buf[m++];
|
||||
meam_inst->arho2[i][5] = buf[m++];
|
||||
for (k = 0; k < 10; k++) meam_inst->arho3[i][k] = buf[m++];
|
||||
meam_inst->arho3b[i][0] = buf[m++];
|
||||
meam_inst->arho3b[i][1] = buf[m++];
|
||||
meam_inst->arho3b[i][2] = buf[m++];
|
||||
meam_inst->t_ave[i][0] = buf[m++];
|
||||
meam_inst->t_ave[i][1] = buf[m++];
|
||||
meam_inst->t_ave[i][2] = buf[m++];
|
||||
meam_inst->tsq_ave[i][0] = buf[m++];
|
||||
meam_inst->tsq_ave[i][1] = buf[m++];
|
||||
meam_inst->tsq_ave[i][2] = buf[m++];
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
int PairMEAMC::pack_reverse_comm(int n, int first, double *buf)
|
||||
{
|
||||
int i,k,m,last;
|
||||
|
||||
m = 0;
|
||||
last = first + n;
|
||||
for (i = first; i < last; i++) {
|
||||
buf[m++] = meam_inst->rho0[i];
|
||||
buf[m++] = meam_inst->arho2b[i];
|
||||
buf[m++] = meam_inst->arho1[i][0];
|
||||
buf[m++] = meam_inst->arho1[i][1];
|
||||
buf[m++] = meam_inst->arho1[i][2];
|
||||
buf[m++] = meam_inst->arho2[i][0];
|
||||
buf[m++] = meam_inst->arho2[i][1];
|
||||
buf[m++] = meam_inst->arho2[i][2];
|
||||
buf[m++] = meam_inst->arho2[i][3];
|
||||
buf[m++] = meam_inst->arho2[i][4];
|
||||
buf[m++] = meam_inst->arho2[i][5];
|
||||
for (k = 0; k < 10; k++) buf[m++] = meam_inst->arho3[i][k];
|
||||
buf[m++] = meam_inst->arho3b[i][0];
|
||||
buf[m++] = meam_inst->arho3b[i][1];
|
||||
buf[m++] = meam_inst->arho3b[i][2];
|
||||
buf[m++] = meam_inst->t_ave[i][0];
|
||||
buf[m++] = meam_inst->t_ave[i][1];
|
||||
buf[m++] = meam_inst->t_ave[i][2];
|
||||
buf[m++] = meam_inst->tsq_ave[i][0];
|
||||
buf[m++] = meam_inst->tsq_ave[i][1];
|
||||
buf[m++] = meam_inst->tsq_ave[i][2];
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void PairMEAMC::unpack_reverse_comm(int n, int *list, double *buf)
|
||||
{
|
||||
int i,j,k,m;
|
||||
|
||||
m = 0;
|
||||
for (i = 0; i < n; i++) {
|
||||
j = list[i];
|
||||
meam_inst->rho0[j] += buf[m++];
|
||||
meam_inst->arho2b[j] += buf[m++];
|
||||
meam_inst->arho1[j][0] += buf[m++];
|
||||
meam_inst->arho1[j][1] += buf[m++];
|
||||
meam_inst->arho1[j][2] += buf[m++];
|
||||
meam_inst->arho2[j][0] += buf[m++];
|
||||
meam_inst->arho2[j][1] += buf[m++];
|
||||
meam_inst->arho2[j][2] += buf[m++];
|
||||
meam_inst->arho2[j][3] += buf[m++];
|
||||
meam_inst->arho2[j][4] += buf[m++];
|
||||
meam_inst->arho2[j][5] += buf[m++];
|
||||
for (k = 0; k < 10; k++) meam_inst->arho3[j][k] += buf[m++];
|
||||
meam_inst->arho3b[j][0] += buf[m++];
|
||||
meam_inst->arho3b[j][1] += buf[m++];
|
||||
meam_inst->arho3b[j][2] += buf[m++];
|
||||
meam_inst->t_ave[j][0] += buf[m++];
|
||||
meam_inst->t_ave[j][1] += buf[m++];
|
||||
meam_inst->t_ave[j][2] += buf[m++];
|
||||
meam_inst->tsq_ave[j][0] += buf[m++];
|
||||
meam_inst->tsq_ave[j][1] += buf[m++];
|
||||
meam_inst->tsq_ave[j][2] += buf[m++];
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
memory usage of local atom-based arrays
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
double PairMEAMC::memory_usage()
|
||||
{
|
||||
double bytes = 11 * meam_inst->nmax * sizeof(double);
|
||||
bytes += (3 + 6 + 10 + 3 + 3 + 3) * meam_inst->nmax * sizeof(double);
|
||||
bytes += 3 * meam_inst->maxneigh * sizeof(double);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
strip special bond flags from neighbor list entries
|
||||
are not used with MEAM
|
||||
need to do here so Fortran lib doesn't see them
|
||||
done once per reneighbor so that neigh_f2c and neigh_c2f don't see them
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PairMEAMC::neigh_strip(int inum, int *ilist,
|
||||
int *numneigh, int **firstneigh)
|
||||
{
|
||||
int i,j,ii,jnum;
|
||||
int *jlist;
|
||||
|
||||
for (ii = 0; ii < inum; ii++) {
|
||||
i = ilist[ii];
|
||||
jlist = firstneigh[i];
|
||||
jnum = numneigh[i];
|
||||
for (j = 0; j < jnum; j++) jlist[j] &= NEIGHMASK;
|
||||
}
|
||||
}
|
||||
112
src/USER-MEAMC/pair_meamc.h
Normal file
112
src/USER-MEAMC/pair_meamc.h
Normal file
@ -0,0 +1,112 @@
|
||||
/* -*- c++ -*- ----------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
http://lammps.sandia.gov, Sandia National Laboratories
|
||||
Steve Plimpton, sjplimp@sandia.gov
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef PAIR_CLASS
|
||||
|
||||
PairStyle(meam/c,PairMEAMC)
|
||||
|
||||
#else
|
||||
|
||||
#ifndef LMP_PAIR_MEAMC_H
|
||||
#define LMP_PAIR_MEAMC_H
|
||||
|
||||
#include "pair.h"
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
class MEAM;
|
||||
|
||||
class PairMEAMC : public Pair {
|
||||
public:
|
||||
PairMEAMC(class LAMMPS *);
|
||||
~PairMEAMC();
|
||||
void compute(int, int);
|
||||
void settings(int, char **);
|
||||
void coeff(int, char **);
|
||||
void init_style();
|
||||
void init_list(int, class NeighList *);
|
||||
double init_one(int, int);
|
||||
|
||||
int pack_forward_comm(int, int *, double *, int, int *);
|
||||
void unpack_forward_comm(int, int, double *);
|
||||
int pack_reverse_comm(int, int, double *);
|
||||
void unpack_reverse_comm(int, int *, double *);
|
||||
double memory_usage();
|
||||
|
||||
private:
|
||||
class MEAM *meam_inst;
|
||||
double cutmax; // max cutoff for all elements
|
||||
int nelements; // # of unique elements
|
||||
char **elements; // names of unique elements
|
||||
double *mass; // mass of each element
|
||||
|
||||
int *map; // mapping from atom types (1-indexed) to elements (1-indexed)
|
||||
|
||||
void allocate();
|
||||
void read_files(char *, char *);
|
||||
void neigh_strip(int, int *, int *, int **);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* ERROR/WARNING messages:
|
||||
|
||||
E: MEAM library error %d
|
||||
|
||||
A call to the MEAM Fortran library returned an error.
|
||||
|
||||
E: Illegal ... command
|
||||
|
||||
Self-explanatory. Check the input script syntax and compare to the
|
||||
documentation for the command. You can use -echo screen as a
|
||||
command-line option when running LAMMPS to see the offending line.
|
||||
|
||||
E: Incorrect args for pair coefficients
|
||||
|
||||
Self-explanatory. Check the input script or data file.
|
||||
|
||||
E: Pair style MEAM requires newton pair on
|
||||
|
||||
See the newton command. This is a restriction to use the MEAM
|
||||
potential.
|
||||
|
||||
E: Cannot open MEAM potential file %s
|
||||
|
||||
The specified MEAM potential file cannot be opened. Check that the
|
||||
path and name are correct.
|
||||
|
||||
E: Incorrect format in MEAM potential file
|
||||
|
||||
Incorrect number of words per line in the potential file.
|
||||
|
||||
E: Unrecognized lattice type in MEAM file 1
|
||||
|
||||
The lattice type in an entry of the MEAM library file is not
|
||||
valid.
|
||||
|
||||
E: Did not find all elements in MEAM library file
|
||||
|
||||
The requested elements were not found in the MEAM file.
|
||||
|
||||
E: Keyword %s in MEAM parameter file not recognized
|
||||
|
||||
Self-explanatory.
|
||||
|
||||
E: Unrecognized lattice type in MEAM file 2
|
||||
|
||||
The lattice type in an entry of the MEAM parameter file is not
|
||||
valid.
|
||||
|
||||
*/
|
||||
@ -172,6 +172,7 @@ void FixQEqReaxOMP::compute_H()
|
||||
H.firstnbr[ai] = num_nbrs;
|
||||
num_nbrs += numneigh[ai];
|
||||
}
|
||||
m_fill = num_nbrs;
|
||||
|
||||
// fill in the H matrix
|
||||
|
||||
|
||||
@ -29,127 +29,6 @@
|
||||
using namespace LAMMPS_NS;
|
||||
using namespace MathSpecial;
|
||||
|
||||
/*
|
||||
Copyright (c) 2012,2013 Axel Kohlmeyer <akohlmey@gmail.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* faster versions of 2**x, e**x, and 10**x in single and double precision.
|
||||
*
|
||||
* Based on the Cephes math library 2.8
|
||||
*/
|
||||
|
||||
/* internal definitions for the fastermath library */
|
||||
|
||||
/* IEEE 754 double precision floating point data manipulation */
|
||||
typedef union
|
||||
{
|
||||
double f;
|
||||
uint64_t u;
|
||||
struct {int32_t i0,i1;};
|
||||
} udi_t;
|
||||
#define FM_DOUBLE_BIAS 1023
|
||||
#define FM_DOUBLE_EMASK 2146435072
|
||||
#define FM_DOUBLE_MBITS 20
|
||||
#define FM_DOUBLE_MMASK 1048575
|
||||
#define FM_DOUBLE_EZERO 1072693248
|
||||
|
||||
/* generate 2**num in floating point by bitshifting */
|
||||
#define FM_DOUBLE_INIT_EXP(var,num) \
|
||||
var.i0 = 0; \
|
||||
var.i1 = (((int) num) + FM_DOUBLE_BIAS) << 20
|
||||
|
||||
/* double precision constants */
|
||||
#define FM_DOUBLE_LOG2OFE 1.4426950408889634074
|
||||
#define FM_DOUBLE_LOGEOF2 6.9314718055994530942e-1
|
||||
#define FM_DOUBLE_LOG2OF10 3.32192809488736234789
|
||||
#define FM_DOUBLE_LOG10OF2 3.0102999566398119521e-1
|
||||
#define FM_DOUBLE_LOG10OFE 4.3429448190325182765e-1
|
||||
#define FM_DOUBLE_SQRT2 1.41421356237309504880
|
||||
#define FM_DOUBLE_SQRTH 0.70710678118654752440
|
||||
|
||||
/* optimizer friendly implementation of exp2(x).
|
||||
*
|
||||
* strategy:
|
||||
*
|
||||
* split argument into an integer part and a fraction:
|
||||
* ipart = floor(x+0.5);
|
||||
* fpart = x - ipart;
|
||||
*
|
||||
* compute exp2(ipart) from setting the ieee754 exponent
|
||||
* compute exp2(fpart) using a pade' approximation for x in [-0.5;0.5[
|
||||
*
|
||||
* the result becomes: exp2(x) = exp2(ipart) * exp2(fpart)
|
||||
*/
|
||||
|
||||
static const double fm_exp2_q[] = {
|
||||
/* 1.00000000000000000000e0, */
|
||||
2.33184211722314911771e2,
|
||||
4.36821166879210612817e3
|
||||
};
|
||||
static const double fm_exp2_p[] = {
|
||||
2.30933477057345225087e-2,
|
||||
2.02020656693165307700e1,
|
||||
1.51390680115615096133e3
|
||||
};
|
||||
|
||||
static double fm_exp2(double x)
|
||||
{
|
||||
double ipart, fpart, px, qx;
|
||||
udi_t epart;
|
||||
|
||||
ipart = floor(x+0.5);
|
||||
fpart = x - ipart;
|
||||
FM_DOUBLE_INIT_EXP(epart,ipart);
|
||||
|
||||
x = fpart*fpart;
|
||||
|
||||
px = fm_exp2_p[0];
|
||||
px = px*x + fm_exp2_p[1];
|
||||
qx = x + fm_exp2_q[0];
|
||||
px = px*x + fm_exp2_p[2];
|
||||
qx = qx*x + fm_exp2_q[1];
|
||||
|
||||
px = px * fpart;
|
||||
|
||||
x = 1.0 + 2.0*(px/(qx-px));
|
||||
return epart.f*x;
|
||||
}
|
||||
|
||||
static double fm_exp(double x)
|
||||
{
|
||||
#if defined(__BYTE_ORDER__)
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
return fm_exp2(FM_DOUBLE_LOG2OFE * (x));
|
||||
#endif
|
||||
#endif
|
||||
return exp(x);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
PairAGNIOMP::PairAGNIOMP(LAMMPS *lmp) :
|
||||
|
||||
@ -84,10 +84,11 @@ PairReaxCOMP::PairReaxCOMP(LAMMPS *lmp) : PairReaxC(lmp), ThrOMP(lmp, THR_PAIR)
|
||||
|
||||
PairReaxCOMP::~PairReaxCOMP()
|
||||
{
|
||||
reax_list * bonds = lists+BONDS;
|
||||
for (int i=0; i<bonds->num_intrs; ++i)
|
||||
sfree(bonds->select.bond_list[i].bo_data.CdboReduction, "CdboReduction");
|
||||
|
||||
if (setup_flag) {
|
||||
reax_list * bonds = lists+BONDS;
|
||||
for (int i=0; i<bonds->num_intrs; ++i)
|
||||
sfree(bonds->select.bond_list[i].bo_data.CdboReduction, "CdboReduction");
|
||||
}
|
||||
memory->destroy(num_nbrs_offset);
|
||||
|
||||
#ifdef OMP_TIMING
|
||||
|
||||
@ -48,7 +48,7 @@ using namespace MathSpecial;
|
||||
PPPMTIP4POMP::PPPMTIP4POMP(LAMMPS *lmp, int narg, char **arg) :
|
||||
PPPMTIP4P(lmp, narg, arg), ThrOMP(lmp, THR_KSPACE)
|
||||
{
|
||||
triclinic_support = 0;
|
||||
triclinic_support = 1;
|
||||
suffix_flag |= Suffix::OMP;
|
||||
}
|
||||
|
||||
@ -735,6 +735,8 @@ void PPPMTIP4POMP::fieldforce_ad()
|
||||
|
||||
void PPPMTIP4POMP::find_M_thr(int i, int &iH1, int &iH2, dbl3_t &xM)
|
||||
{
|
||||
double **x = atom->x;
|
||||
|
||||
iH1 = atom->map(atom->tag[i] + 1);
|
||||
iH2 = atom->map(atom->tag[i] + 2);
|
||||
|
||||
@ -742,24 +744,102 @@ void PPPMTIP4POMP::find_M_thr(int i, int &iH1, int &iH2, dbl3_t &xM)
|
||||
if (atom->type[iH1] != typeH || atom->type[iH2] != typeH)
|
||||
error->one(FLERR,"TIP4P hydrogen has incorrect atom type");
|
||||
|
||||
// set iH1,iH2 to index of closest image to O
|
||||
if (triclinic) {
|
||||
|
||||
iH1 = domain->closest_image(i,iH1);
|
||||
iH2 = domain->closest_image(i,iH2);
|
||||
// need to use custom code to find the closest image for triclinic,
|
||||
// since local atoms are in lambda coordinates, but ghosts are not.
|
||||
|
||||
const dbl3_t * _noalias const x = (dbl3_t *) atom->x[0];
|
||||
int *sametag = atom->sametag;
|
||||
double xo[3],xh1[3],xh2[3];
|
||||
|
||||
double delx1 = x[iH1].x - x[i].x;
|
||||
double dely1 = x[iH1].y - x[i].y;
|
||||
double delz1 = x[iH1].z - x[i].z;
|
||||
domain->lamda2x(x[i],xo);
|
||||
domain->lamda2x(x[iH1],xh1);
|
||||
domain->lamda2x(x[iH2],xh2);
|
||||
|
||||
double delx2 = x[iH2].x - x[i].x;
|
||||
double dely2 = x[iH2].y - x[i].y;
|
||||
double delz2 = x[iH2].z - x[i].z;
|
||||
double delx = xo[0] - xh1[0];
|
||||
double dely = xo[1] - xh1[1];
|
||||
double delz = xo[2] - xh1[2];
|
||||
double rsqmin = delx*delx + dely*dely + delz*delz;
|
||||
double rsq;
|
||||
int closest = iH1;
|
||||
|
||||
xM.x = x[i].x + alpha * 0.5 * (delx1 + delx2);
|
||||
xM.y = x[i].y + alpha * 0.5 * (dely1 + dely2);
|
||||
xM.z = x[i].z + alpha * 0.5 * (delz1 + delz2);
|
||||
while (sametag[iH1] >= 0) {
|
||||
iH1 = sametag[iH1];
|
||||
delx = xo[0] - x[iH1][0];
|
||||
dely = xo[1] - x[iH1][1];
|
||||
delz = xo[2] - x[iH1][2];
|
||||
rsq = delx*delx + dely*dely + delz*delz;
|
||||
if (rsq < rsqmin) {
|
||||
rsqmin = rsq;
|
||||
closest = iH1;
|
||||
xh1[0] = x[iH1][0];
|
||||
xh1[1] = x[iH1][1];
|
||||
xh1[2] = x[iH1][2];
|
||||
}
|
||||
}
|
||||
iH1 = closest;
|
||||
|
||||
closest = iH2;
|
||||
delx = xo[0] - xh2[0];
|
||||
dely = xo[1] - xh2[1];
|
||||
delz = xo[2] - xh2[2];
|
||||
rsqmin = delx*delx + dely*dely + delz*delz;
|
||||
|
||||
while (sametag[iH2] >= 0) {
|
||||
iH2 = sametag[iH2];
|
||||
delx = xo[0] - x[iH2][0];
|
||||
dely = xo[1] - x[iH2][1];
|
||||
delz = xo[2] - x[iH2][2];
|
||||
rsq = delx*delx + dely*dely + delz*delz;
|
||||
if (rsq < rsqmin) {
|
||||
rsqmin = rsq;
|
||||
closest = iH2;
|
||||
xh2[0] = x[iH2][0];
|
||||
xh2[1] = x[iH2][1];
|
||||
xh2[2] = x[iH2][2];
|
||||
}
|
||||
}
|
||||
iH2 = closest;
|
||||
|
||||
// finally compute M in real coordinates ...
|
||||
|
||||
double delx1 = xh1[0] - xo[0];
|
||||
double dely1 = xh1[1] - xo[1];
|
||||
double delz1 = xh1[2] - xo[2];
|
||||
|
||||
double delx2 = xh2[0] - xo[0];
|
||||
double dely2 = xh2[1] - xo[1];
|
||||
double delz2 = xh2[2] - xo[2];
|
||||
|
||||
xM.x = xo[0] + alpha * 0.5 * (delx1 + delx2);
|
||||
xM.y = xo[1] + alpha * 0.5 * (dely1 + dely2);
|
||||
xM.z = xo[2] + alpha * 0.5 * (delz1 + delz2);
|
||||
|
||||
// ... and convert M to lamda space for PPPM
|
||||
|
||||
domain->x2lamda((double *)&xM,(double *)&xM);
|
||||
|
||||
} else {
|
||||
|
||||
// set iH1,iH2 to index of closest image to O
|
||||
|
||||
iH1 = domain->closest_image(i,iH1);
|
||||
iH2 = domain->closest_image(i,iH2);
|
||||
|
||||
const dbl3_t * _noalias const x = (dbl3_t *) atom->x[0];
|
||||
|
||||
double delx1 = x[iH1].x - x[i].x;
|
||||
double dely1 = x[iH1].y - x[i].y;
|
||||
double delz1 = x[iH1].z - x[i].z;
|
||||
|
||||
double delx2 = x[iH2].x - x[i].x;
|
||||
double dely2 = x[iH2].y - x[i].y;
|
||||
double delz2 = x[iH2].z - x[i].z;
|
||||
|
||||
xM.x = x[i].x + alpha * 0.5 * (delx1 + delx2);
|
||||
xM.y = x[i].y + alpha * 0.5 * (dely1 + dely2);
|
||||
xM.z = x[i].z + alpha * 0.5 * (delz1 + delz2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1514,12 +1514,13 @@ void Atom::set_mass(double *values)
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
check that all masses have been set
|
||||
check that all per-atom-type masses have been set
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void Atom::check_mass(const char *file, int line)
|
||||
{
|
||||
if (mass == NULL) return;
|
||||
if (rmass_flag) return;
|
||||
for (int itype = 1; itype <= ntypes; itype++)
|
||||
if (mass_setflag[itype] == 0)
|
||||
error->all(file,line,"Not all per-type masses are set");
|
||||
|
||||
@ -11,6 +11,10 @@
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Contributing authors: Mike Salerno (NRL) added single methods
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "create_bonds.h"
|
||||
@ -27,6 +31,8 @@
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
enum{MANY,SBOND,SANGLE,SDIHEDRAL};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
CreateBonds::CreateBonds(LAMMPS *lmp) : Pointers(lmp) {}
|
||||
@ -42,25 +48,104 @@ void CreateBonds::command(int narg, char **arg)
|
||||
if (atom->molecular != 1)
|
||||
error->all(FLERR,"Cannot use create_bonds with non-molecular system");
|
||||
|
||||
if (narg != 5) error->all(FLERR,"Illegal create_bonds command");
|
||||
if (narg < 4) error->all(FLERR,"Illegal create_bonds command");
|
||||
|
||||
// parse args
|
||||
|
||||
int igroup = group->find(arg[0]);
|
||||
if (igroup == -1) error->all(FLERR,"Cannot find create_bonds group ID");
|
||||
int group1bit = group->bitmask[igroup];
|
||||
igroup = group->find(arg[1]);
|
||||
if (igroup == -1) error->all(FLERR,"Cannot find create_bonds group ID");
|
||||
int group2bit = group->bitmask[igroup];
|
||||
int style;
|
||||
|
||||
int btype = force->inumeric(FLERR,arg[2]);
|
||||
double rmin = force->numeric(FLERR,arg[3]);
|
||||
double rmax = force->numeric(FLERR,arg[4]);
|
||||
int iarg;
|
||||
if (strcmp(arg[0],"many") == 0) {
|
||||
style = MANY;
|
||||
if (narg != 6) error->all(FLERR,"Illegal create_bonds command");
|
||||
igroup = group->find(arg[1]);
|
||||
if (igroup == -1) error->all(FLERR,"Cannot find create_bonds group ID");
|
||||
group1bit = group->bitmask[igroup];
|
||||
igroup = group->find(arg[2]);
|
||||
if (igroup == -1) error->all(FLERR,"Cannot find create_bonds group ID");
|
||||
group2bit = group->bitmask[igroup];
|
||||
btype = force->inumeric(FLERR,arg[3]);
|
||||
rmin = force->numeric(FLERR,arg[4]);
|
||||
rmax = force->numeric(FLERR,arg[5]);
|
||||
if (rmin > rmax) error->all(FLERR,"Illegal create_bonds command");
|
||||
iarg = 6;
|
||||
} else if (strcmp(arg[0],"single/bond") == 0) {
|
||||
style = SBOND;
|
||||
if (narg < 4) error->all(FLERR,"Illegal create_bonds command");
|
||||
btype = force->inumeric(FLERR,arg[1]);
|
||||
batom1 = force->tnumeric(FLERR,arg[2]);
|
||||
batom2 = force->tnumeric(FLERR,arg[3]);
|
||||
iarg = 4;
|
||||
} else if (strcmp(arg[0],"single/angle") == 0) {
|
||||
style = SANGLE;
|
||||
if (narg < 5) error->all(FLERR,"Illegal create_bonds command");
|
||||
atype = force->inumeric(FLERR,arg[1]);
|
||||
aatom1 = force->tnumeric(FLERR,arg[2]);
|
||||
aatom2 = force->tnumeric(FLERR,arg[3]);
|
||||
aatom3 = force->tnumeric(FLERR,arg[4]);
|
||||
iarg = 5;
|
||||
} else if (strcmp(arg[0],"single/dihedral") == 0) {
|
||||
style = SDIHEDRAL;
|
||||
if (narg < 6) error->all(FLERR,"Illegal create_bonds command");
|
||||
dtype = force->inumeric(FLERR,arg[1]);
|
||||
datom1 = force->tnumeric(FLERR,arg[2]);
|
||||
datom2 = force->tnumeric(FLERR,arg[3]);
|
||||
datom3 = force->tnumeric(FLERR,arg[4]);
|
||||
datom4 = force->tnumeric(FLERR,arg[5]);
|
||||
iarg = 6;
|
||||
} else error->all(FLERR,"Illegal create_bonds command");
|
||||
|
||||
if (btype <= 0 || btype > atom->nbondtypes)
|
||||
error->all(FLERR,"Invalid bond type in create_bonds command");
|
||||
if (rmin > rmax) error->all(FLERR,"Illegal create_bonds command");
|
||||
// optional args
|
||||
|
||||
int specialflag = 1;
|
||||
|
||||
while (iarg < narg) {
|
||||
if (strcmp(arg[iarg],"special") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal create_bonds command");
|
||||
if (strcmp(arg[iarg+1],"yes") == 0) specialflag = 1;
|
||||
else if (strcmp(arg[iarg+1],"no") == 0) specialflag = 0;
|
||||
else error->all(FLERR,"Illegal create_bonds command");
|
||||
iarg += 2;
|
||||
} else error->all(FLERR,"Illegal create_bonds command");
|
||||
}
|
||||
|
||||
// error checks
|
||||
|
||||
if (style == MANY) {
|
||||
if (btype <= 0 || btype > atom->nbondtypes)
|
||||
error->all(FLERR,"Invalid bond type in create_bonds command");
|
||||
if (specialflag == 0)
|
||||
error->all(FLERR,"Cannot use special no with create_bonds many");
|
||||
} else if (style == SBOND) {
|
||||
if (btype <= 0 || btype > atom->nbondtypes)
|
||||
error->all(FLERR,"Invalid bond type in create_bonds command");
|
||||
} else if (style == SANGLE) {
|
||||
if (atype <= 0 || atype > atom->nangletypes)
|
||||
error->all(FLERR,"Invalid angle type in create_bonds command");
|
||||
} else if (style == SDIHEDRAL) {
|
||||
if (dtype <= 0 || dtype > atom->ndihedraltypes)
|
||||
error->all(FLERR,"Invalid dihedral type in create_bonds command");
|
||||
}
|
||||
|
||||
// invoke creation method
|
||||
|
||||
if (style == MANY) many();
|
||||
else if (style == SBOND) single_bond();
|
||||
else if (style == SANGLE) single_angle();
|
||||
else if (style == SDIHEDRAL) single_dihedral();
|
||||
|
||||
// trigger special list build
|
||||
|
||||
if (specialflag) {
|
||||
Special special(lmp);
|
||||
special.build();
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void CreateBonds::many()
|
||||
{
|
||||
double rminsq = rmin*rmin;
|
||||
double rmaxsq = rmax*rmax;
|
||||
|
||||
@ -221,9 +306,184 @@ void CreateBonds::command(int narg, char **arg)
|
||||
nadd_bonds,atom->nbonds);
|
||||
}
|
||||
}
|
||||
|
||||
// re-trigger special list build
|
||||
|
||||
Special special(lmp);
|
||||
special.build();
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void CreateBonds::single_bond()
|
||||
{
|
||||
int m;
|
||||
|
||||
// check that 2 atoms exist
|
||||
|
||||
int count = 0;
|
||||
if (atom->map(batom1) >= 0) count++;
|
||||
if (atom->map(batom2) >= 0) count++;
|
||||
|
||||
int allcount;
|
||||
MPI_Allreduce(&count,&allcount,1,MPI_INT,MPI_SUM,world);
|
||||
if (allcount != 2)
|
||||
error->all(FLERR,"Create_bonds single/bond atoms do not exist");
|
||||
|
||||
// create bond once or 2x if newton_bond set
|
||||
|
||||
int *num_bond = atom->num_bond;
|
||||
int **bond_type = atom->bond_type;
|
||||
tagint **bond_atom = atom->bond_atom;
|
||||
|
||||
if ((m = atom->map(batom1)) >= 0) {
|
||||
if (num_bond[m] == atom->bond_per_atom)
|
||||
error->one(FLERR,"New bond exceeded bonds per atom in create_bonds");
|
||||
bond_type[m][num_bond[m]] = btype;
|
||||
bond_atom[m][num_bond[m]] = batom2;
|
||||
num_bond[m]++;
|
||||
}
|
||||
|
||||
if (force->newton_bond) return;
|
||||
|
||||
if ((m = atom->map(batom2)) >= 0) {
|
||||
if (num_bond[m] == atom->bond_per_atom)
|
||||
error->one(FLERR,"New bond exceeded bonds per atom in create_bonds");
|
||||
bond_type[m][num_bond[m]] = btype;
|
||||
bond_atom[m][num_bond[m]] = batom1;
|
||||
num_bond[m]++;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void CreateBonds::single_angle()
|
||||
{
|
||||
int m;
|
||||
|
||||
// check that 3 atoms exist
|
||||
|
||||
int count = 0;
|
||||
if (atom->map(aatom1) >= 0) count++;
|
||||
if (atom->map(aatom2) >= 0) count++;
|
||||
if (atom->map(aatom3) >= 0) count++;
|
||||
|
||||
int allcount;
|
||||
MPI_Allreduce(&count,&allcount,1,MPI_INT,MPI_SUM,world);
|
||||
if (allcount != 3)
|
||||
error->all(FLERR,"Create_bonds single/angle atoms do not exist");
|
||||
|
||||
// create angle once or 3x if newton_bond set
|
||||
|
||||
int *num_angle = atom->num_angle;
|
||||
int **angle_type = atom->angle_type;
|
||||
tagint **angle_atom1 = atom->angle_atom1;
|
||||
tagint **angle_atom2 = atom->angle_atom2;
|
||||
tagint **angle_atom3 = atom->angle_atom3;
|
||||
|
||||
if ((m = atom->map(aatom2)) >= 0) {
|
||||
if (num_angle[m] == atom->angle_per_atom)
|
||||
error->one(FLERR,"New angle exceeded angles per atom in create_bonds");
|
||||
angle_type[m][num_angle[m]] = atype;
|
||||
angle_atom1[m][num_angle[m]] = aatom1;
|
||||
angle_atom2[m][num_angle[m]] = aatom2;
|
||||
angle_atom3[m][num_angle[m]] = aatom3;
|
||||
num_angle[m]++;
|
||||
}
|
||||
|
||||
if (force->newton_bond) return;
|
||||
|
||||
if ((m = atom->map(aatom1)) >= 0) {
|
||||
if (num_angle[m] == atom->angle_per_atom)
|
||||
error->one(FLERR,"New angle exceeded angles per atom in create_bonds");
|
||||
angle_type[m][num_angle[m]] = atype;
|
||||
angle_atom1[m][num_angle[m]] = aatom1;
|
||||
angle_atom2[m][num_angle[m]] = aatom2;
|
||||
angle_atom3[m][num_angle[m]] = aatom3;
|
||||
num_angle[m]++;
|
||||
}
|
||||
|
||||
if ((m = atom->map(aatom3)) >= 0) {
|
||||
if (num_angle[m] == atom->angle_per_atom)
|
||||
error->one(FLERR,"New angle exceeded angles per atom in create_bonds");
|
||||
angle_type[m][num_angle[m]] = atype;
|
||||
angle_atom1[m][num_angle[m]] = aatom1;
|
||||
angle_atom2[m][num_angle[m]] = aatom2;
|
||||
angle_atom3[m][num_angle[m]] = aatom3;
|
||||
num_angle[m]++;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void CreateBonds::single_dihedral()
|
||||
{
|
||||
int m;
|
||||
|
||||
// check that 4 atoms exist
|
||||
|
||||
int count = 0;
|
||||
if (atom->map(datom1) >= 0) count++;
|
||||
if (atom->map(datom2) >= 0) count++;
|
||||
if (atom->map(datom3) >= 0) count++;
|
||||
if (atom->map(datom4) >= 0) count++;
|
||||
|
||||
int allcount;
|
||||
MPI_Allreduce(&count,&allcount,1,MPI_INT,MPI_SUM,world);
|
||||
if (allcount != 4)
|
||||
error->all(FLERR,"Create_bonds single/dihedral atoms do not exist");
|
||||
|
||||
// create bond once or 4x if newton_bond set
|
||||
|
||||
int *num_dihedral = atom->num_dihedral;
|
||||
int **dihedral_type = atom->dihedral_type;
|
||||
tagint **dihedral_atom1 = atom->dihedral_atom1;
|
||||
tagint **dihedral_atom2 = atom->dihedral_atom2;
|
||||
tagint **dihedral_atom3 = atom->dihedral_atom3;
|
||||
tagint **dihedral_atom4 = atom->dihedral_atom4;
|
||||
|
||||
if ((m = atom->map(datom2)) >= 0) {
|
||||
if (num_dihedral[m] == atom->dihedral_per_atom)
|
||||
error->one(FLERR,
|
||||
"New dihedral exceeded dihedrals per atom in create_bonds");
|
||||
dihedral_type[m][num_dihedral[m]] = dtype;
|
||||
dihedral_atom1[m][num_dihedral[m]] = datom1;
|
||||
dihedral_atom2[m][num_dihedral[m]] = datom2;
|
||||
dihedral_atom3[m][num_dihedral[m]] = datom3;
|
||||
dihedral_atom4[m][num_dihedral[m]] = datom4;
|
||||
num_dihedral[m]++;
|
||||
}
|
||||
|
||||
if (force->newton_bond) return;
|
||||
|
||||
if ((m = atom->map(datom1)) >= 0) {
|
||||
if (num_dihedral[m] == atom->dihedral_per_atom)
|
||||
error->one(FLERR,
|
||||
"New dihedral exceeded dihedrals per atom in create_bonds");
|
||||
dihedral_type[m][num_dihedral[m]] = dtype;
|
||||
dihedral_atom1[m][num_dihedral[m]] = datom1;
|
||||
dihedral_atom2[m][num_dihedral[m]] = datom2;
|
||||
dihedral_atom3[m][num_dihedral[m]] = datom3;
|
||||
dihedral_atom4[m][num_dihedral[m]] = datom4;
|
||||
num_dihedral[m]++;
|
||||
}
|
||||
|
||||
if ((m = atom->map(datom3)) >= 0) {
|
||||
if (num_dihedral[m] == atom->dihedral_per_atom)
|
||||
error->one(FLERR,
|
||||
"New dihedral exceeded dihedrals per atom in create_bonds");
|
||||
dihedral_type[m][num_dihedral[m]] = dtype;
|
||||
dihedral_atom1[m][num_dihedral[m]] = datom1;
|
||||
dihedral_atom2[m][num_dihedral[m]] = datom2;
|
||||
dihedral_atom3[m][num_dihedral[m]] = datom3;
|
||||
dihedral_atom4[m][num_dihedral[m]] = datom4;
|
||||
num_dihedral[m]++;
|
||||
}
|
||||
|
||||
if ((m = atom->map(datom4)) >= 0) {
|
||||
if (num_dihedral[m] == atom->dihedral_per_atom)
|
||||
error->one(FLERR,
|
||||
"New dihedral exceeded dihedrals per atom in create_bonds");
|
||||
dihedral_type[m][num_dihedral[m]] = dtype;
|
||||
dihedral_atom1[m][num_dihedral[m]] = datom1;
|
||||
dihedral_atom2[m][num_dihedral[m]] = datom2;
|
||||
dihedral_atom3[m][num_dihedral[m]] = datom3;
|
||||
dihedral_atom4[m][num_dihedral[m]] = datom4;
|
||||
num_dihedral[m]++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,9 +30,15 @@ class CreateBonds : protected Pointers {
|
||||
void command(int, char **);
|
||||
|
||||
private:
|
||||
inline int sbmask(int j) const {
|
||||
return j >> SBBITS & 3;
|
||||
}
|
||||
int igroup,group1bit,group2bit;
|
||||
int btype,atype,dtype;
|
||||
tagint batom1,batom2,aatom1,aatom2,aatom3,datom1,datom2,datom3,datom4;
|
||||
double rmin,rmax;
|
||||
|
||||
void many();
|
||||
void single_bond();
|
||||
void single_angle();
|
||||
void single_dihedral();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -161,7 +161,7 @@ void Fix::modify_params(int narg, char **arg)
|
||||
/* ----------------------------------------------------------------------
|
||||
setup for energy, virial computation
|
||||
see integrate::ev_set() for values of eflag (0-3) and vflag (0-6)
|
||||
fixes call this if use ev_tally()
|
||||
fixes call this if they use ev_tally()
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void Fix::ev_setup(int eflag, int vflag)
|
||||
|
||||
@ -30,7 +30,7 @@ enum{PF_CALLBACK,PF_ARRAY};
|
||||
|
||||
FixExternal::FixExternal(LAMMPS *lmp, int narg, char **arg) :
|
||||
Fix(lmp, narg, arg),
|
||||
fexternal(NULL)
|
||||
fexternal(NULL), caller_vector(NULL)
|
||||
{
|
||||
if (narg < 4) error->all(FLERR,"Illegal fix external command");
|
||||
|
||||
@ -62,6 +62,11 @@ FixExternal::FixExternal(LAMMPS *lmp, int narg, char **arg) :
|
||||
atom->add_callback(0);
|
||||
|
||||
user_energy = 0.0;
|
||||
|
||||
// optional vector of values provided by caller
|
||||
// vector_flag and size_vector are setup via set_vector_length()
|
||||
|
||||
caller_vector = NULL;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -73,6 +78,7 @@ FixExternal::~FixExternal()
|
||||
atom->delete_callback(id,0);
|
||||
|
||||
memory->destroy(fexternal);
|
||||
delete [] caller_vector;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -167,10 +173,15 @@ void FixExternal::min_post_force(int vflag)
|
||||
post_force(vflag);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// "set" methods caller can invoke directly
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
caller invokes this method to set its contribution to global energy
|
||||
do not just return if eflag_global is not set
|
||||
input script could access this quantity via compute_scalar()
|
||||
unlike other energy/virial set methods:
|
||||
do not just return if eflag_global is not set
|
||||
b/c input script could access this quantity via compute_scalar()
|
||||
even if eflag is not set on a particular timestep
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
@ -220,6 +231,34 @@ void FixExternal::set_virial_peratom(double **caller_virial)
|
||||
vatom[i][j] = caller_virial[i][j];
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
caller invokes this method to set length of vector of values
|
||||
assume all vector values are extensive, could make this an option
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixExternal::set_vector_length(int n)
|
||||
{
|
||||
delete [] caller_vector;
|
||||
|
||||
vector_flag = 1;
|
||||
size_vector = n;
|
||||
extvector = 1;
|
||||
|
||||
caller_vector = new double[n];
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
caller invokes this method to set Index value in vector
|
||||
index ranges from 1 to N inclusive
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixExternal::set_vector(int index, double value)
|
||||
{
|
||||
if (index >= size_vector)
|
||||
error->all(FLERR,"Invalid set_vector index in fix external");
|
||||
caller_vector[index-1] = value;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
potential energy of added force
|
||||
up to user to set it via set_energy()
|
||||
@ -230,6 +269,16 @@ double FixExternal::compute_scalar()
|
||||
return user_energy;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
arbitrary value computed by caller
|
||||
up to user to set it via set_vector()
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
double FixExternal::compute_vector(int n)
|
||||
{
|
||||
return caller_vector[n];
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
memory usage of local atom-based array
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
@ -39,11 +39,14 @@ class FixExternal : public Fix {
|
||||
void post_force(int);
|
||||
void min_post_force(int);
|
||||
double compute_scalar();
|
||||
double compute_vector(int);
|
||||
|
||||
void set_energy_global(double);
|
||||
void set_virial_global(double *);
|
||||
void set_energy_peratom(double *);
|
||||
void set_virial_peratom(double **);
|
||||
void set_vector_length(int);
|
||||
void set_vector(int,double);
|
||||
|
||||
double memory_usage();
|
||||
void grow_arrays(int);
|
||||
@ -59,6 +62,7 @@ class FixExternal : public Fix {
|
||||
FnPtr callback;
|
||||
void *ptr_caller;
|
||||
double user_energy;
|
||||
double *caller_vector;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
fputs
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
http://lammps.sandia.gov, Sandia National Laboratories
|
||||
Steve Plimpton, sjplimp@sandia.gov
|
||||
|
||||
@ -508,6 +508,9 @@ static const double fm_exp2_p[] = {
|
||||
1.51390680115615096133e3
|
||||
};
|
||||
|
||||
/* double precision constants */
|
||||
#define FM_DOUBLE_LOG2OFE 1.4426950408889634074
|
||||
|
||||
double MathSpecial::exp2_x86(double x)
|
||||
{
|
||||
double ipart, fpart, px, qx;
|
||||
@ -531,3 +534,14 @@ double MathSpecial::exp2_x86(double x)
|
||||
x = 1.0 + 2.0*(px/(qx-px));
|
||||
return epart.f*x;
|
||||
}
|
||||
|
||||
double MathSpecial::fm_exp(double x)
|
||||
{
|
||||
#if defined(__BYTE_ORDER__)
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
return exp2_x86(FM_DOUBLE_LOG2OFE * x);
|
||||
#endif
|
||||
#endif
|
||||
return ::exp(x);
|
||||
}
|
||||
|
||||
|
||||
@ -27,6 +27,9 @@ namespace MathSpecial {
|
||||
// fast 2**x function without argument checks for little endian CPUs
|
||||
extern double exp2_x86(double x);
|
||||
|
||||
// fast e**x function for little endian CPUs, falls back to libc on other platforms
|
||||
extern double fm_exp(double x);
|
||||
|
||||
// scaled error function complement exp(x*x)*erfc(x) for coul/long styles
|
||||
|
||||
static inline double my_erfcx(const double x)
|
||||
|
||||
@ -996,7 +996,6 @@ int Modify::check_package(const char *package_fix_name)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
check if the group indicated by groupbit overlaps with any
|
||||
currently existing rigid fixes. return 1 in this case otherwise 0
|
||||
@ -1067,7 +1066,6 @@ int Modify::check_rigid_region_overlap(int groupbit, Region *reg)
|
||||
|
||||
int Modify::check_rigid_list_overlap(int *select)
|
||||
{
|
||||
const int * const mask = atom->mask;
|
||||
const int nlocal = atom->nlocal;
|
||||
int dim;
|
||||
|
||||
|
||||
@ -219,7 +219,7 @@ void Molecule::compute_mass()
|
||||
if (massflag) return;
|
||||
massflag = 1;
|
||||
|
||||
if (!rmassflag) atom->check_mass(FLERR);
|
||||
atom->check_mass(FLERR);
|
||||
|
||||
masstotal = 0.0;
|
||||
for (int i = 0; i < natoms; i++) {
|
||||
@ -243,7 +243,7 @@ void Molecule::compute_com()
|
||||
if (!comflag) {
|
||||
comflag = 1;
|
||||
|
||||
if (!rmassflag) atom->check_mass(FLERR);
|
||||
atom->check_mass(FLERR);
|
||||
|
||||
double onemass;
|
||||
com[0] = com[1] = com[2] = 0.0;
|
||||
@ -308,7 +308,7 @@ void Molecule::compute_inertia()
|
||||
if (!inertiaflag) {
|
||||
inertiaflag = 1;
|
||||
|
||||
if (!rmassflag) atom->check_mass(FLERR);
|
||||
atom->check_mass(FLERR);
|
||||
|
||||
double onemass,dx,dy,dz;
|
||||
for (int i = 0; i < 6; i++) itensor[i] = 0.0;
|
||||
|
||||
@ -48,6 +48,7 @@ NeighList::NeighList(LAMMPS *lmp) : Pointers(lmp)
|
||||
ghost = 0;
|
||||
ssa = 0;
|
||||
copy = 0;
|
||||
copymode = 0;
|
||||
dnum = 0;
|
||||
|
||||
// ptrs
|
||||
@ -85,6 +86,7 @@ NeighList::NeighList(LAMMPS *lmp) : Pointers(lmp)
|
||||
|
||||
NeighList::~NeighList()
|
||||
{
|
||||
if (copymode) return;
|
||||
if (!copy) {
|
||||
memory->destroy(ilist);
|
||||
memory->destroy(numneigh);
|
||||
|
||||
@ -34,7 +34,8 @@ class NeighList : protected Pointers {
|
||||
int occasional; // 0 if build every reneighbor, 1 if not
|
||||
int ghost; // 1 if list stores neighbors of ghosts
|
||||
int ssa; // 1 if list stores Shardlow data
|
||||
int copy; // 1 if this list copied from another list
|
||||
int copy; // 1 if this list is (host) copied from another list
|
||||
int copymode; // 1 if this is a Kokkos on-device copy
|
||||
int dnum; // # of doubles per neighbor, 0 if none
|
||||
|
||||
// data structs to store neighbor pairs I,J and associated values
|
||||
|
||||
@ -211,13 +211,51 @@ void ReadData::command(int narg, char **arg)
|
||||
if (extra_improper_types < 0)
|
||||
error->all(FLERR,"Illegal read_data command");
|
||||
iarg += 2;
|
||||
|
||||
} else if (strcmp(arg[iarg],"extra/bond/per/atom") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal read_data command");
|
||||
if (! atom->molecular)
|
||||
error->all(FLERR,"No bonds allowed with this atom style");
|
||||
atom->extra_bond_per_atom = force->inumeric(FLERR,arg[iarg+1]);
|
||||
if (atom->extra_bond_per_atom < 0)
|
||||
error->all(FLERR,"Illegal read_data command");
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"extra/angle/per/atom") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal read_data command");
|
||||
if (! atom->molecular)
|
||||
error->all(FLERR,"No angles allowed with this atom style");
|
||||
atom->extra_angle_per_atom = force->inumeric(FLERR,arg[iarg+1]);
|
||||
if (atom->extra_angle_per_atom < 0)
|
||||
error->all(FLERR,"Illegal read_data command");
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"extra/dihedral/per/atom") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal read_data command");
|
||||
if (! atom->molecular)
|
||||
error->all(FLERR,"No dihedrals allowed with this atom style");
|
||||
atom->extra_dihedral_per_atom = force->inumeric(FLERR,arg[iarg+1]);
|
||||
if (atom->extra_dihedral_per_atom < 0)
|
||||
error->all(FLERR,"Illegal read_data command");
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"extra/improper/per/atom") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal read_data command");
|
||||
if (! atom->molecular)
|
||||
error->all(FLERR,"No impropers allowed with this atom style");
|
||||
atom->extra_improper_per_atom = force->inumeric(FLERR,arg[iarg+1]);
|
||||
if (atom->extra_improper_per_atom < 0)
|
||||
error->all(FLERR,"Illegal read_data command");
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"extra/special/per/atom") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal read_data command");
|
||||
if (! atom->molecular)
|
||||
error->all(FLERR,"No bonded interactions allowed with this atom style");
|
||||
force->special_extra = force->inumeric(FLERR,arg[iarg+1]);
|
||||
if (force->special_extra < 0)
|
||||
error->all(FLERR,"Illegal read_data command");
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg],"group") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal read_data command");
|
||||
int igroup = group->find_or_create(arg[iarg+1]);
|
||||
groupbit = group->bitmask[igroup];
|
||||
iarg += 2;
|
||||
|
||||
} else if (strcmp(arg[iarg],"fix") == 0) {
|
||||
if (iarg+4 > narg)
|
||||
error->all(FLERR,"Illegal read_data command");
|
||||
@ -930,6 +968,7 @@ void ReadData::header(int firstpass)
|
||||
// search line for header keyword and set corresponding variable
|
||||
// customize for new header lines
|
||||
// check for triangles before angles so "triangles" not matched as "angles"
|
||||
int extra_flag_value = 0;
|
||||
|
||||
if (strstr(line,"atoms")) {
|
||||
sscanf(line,BIGINT_FORMAT,&natoms);
|
||||
@ -991,17 +1030,26 @@ void ReadData::header(int firstpass)
|
||||
atom->nimpropertypes = nimpropertypes + extra_improper_types;
|
||||
|
||||
// these settings only used by first data file
|
||||
// also, these are obsolescent. we parse them to maintain backward
|
||||
// compatibility, but the recommended way is to set them via keywords
|
||||
// in the LAMMPS input file. In case these flags are set in both,
|
||||
// the input and the data file, we use the larger of the two.
|
||||
|
||||
} else if (strstr(line,"extra bond per atom")) {
|
||||
if (addflag == NONE) sscanf(line,"%d",&atom->extra_bond_per_atom);
|
||||
if (addflag == NONE) sscanf(line,"%d",&extra_flag_value);
|
||||
atom->extra_bond_per_atom = MAX(atom->extra_bond_per_atom,extra_flag_value);
|
||||
} else if (strstr(line,"extra angle per atom")) {
|
||||
if (addflag == NONE) sscanf(line,"%d",&atom->extra_angle_per_atom);
|
||||
if (addflag == NONE) sscanf(line,"%d",&extra_flag_value);
|
||||
atom->extra_angle_per_atom = MAX(atom->extra_angle_per_atom,extra_flag_value);
|
||||
} else if (strstr(line,"extra dihedral per atom")) {
|
||||
if (addflag == NONE) sscanf(line,"%d",&atom->extra_dihedral_per_atom);
|
||||
if (addflag == NONE) sscanf(line,"%d",&extra_flag_value);
|
||||
atom->extra_dihedral_per_atom = MAX(atom->extra_dihedral_per_atom,extra_flag_value);
|
||||
} else if (strstr(line,"extra improper per atom")) {
|
||||
if (addflag == NONE) sscanf(line,"%d",&atom->extra_improper_per_atom);
|
||||
if (addflag == NONE) sscanf(line,"%d",&extra_flag_value);
|
||||
atom->extra_improper_per_atom = MAX(atom->extra_improper_per_atom,extra_flag_value);
|
||||
} else if (strstr(line,"extra special per atom")) {
|
||||
if (addflag == NONE) sscanf(line,"%d",&force->special_extra);
|
||||
if (addflag == NONE) sscanf(line,"%d",&extra_flag_value);
|
||||
force->special_extra = MAX(force->special_extra,extra_flag_value);
|
||||
|
||||
// local copy of box info
|
||||
// so can treat differently for first vs subsequent data files
|
||||
|
||||
@ -472,8 +472,8 @@ outside a non-periodic simulation box.
|
||||
|
||||
E: Subsequent read data induced too many bonds per atom
|
||||
|
||||
See the create_box extra/bond/per/atom or read_data "extra bond per
|
||||
atom" header value to set this limit larger.
|
||||
See the extra/bond/per/atom keyword for the create_box
|
||||
or the read_data command to set this limit larger.
|
||||
|
||||
E: Bonds assigned incorrectly
|
||||
|
||||
@ -482,8 +482,8 @@ This means there is something invalid about the topology definitions.
|
||||
|
||||
E: Subsequent read data induced too many angles per atom
|
||||
|
||||
See the create_box extra/angle/per/atom or read_data "extra angle per
|
||||
atom" header value to set this limit larger.
|
||||
See the extra/angle/per/atom keyword for the create_box
|
||||
or the read_data command to set this limit larger.
|
||||
|
||||
E: Angles assigned incorrectly
|
||||
|
||||
@ -493,8 +493,8 @@ definitions.
|
||||
|
||||
E: Subsequent read data induced too many dihedrals per atom
|
||||
|
||||
See the create_box extra/dihedral/per/atom or read_data "extra
|
||||
dihedral per atom" header value to set this limit larger.
|
||||
See the extra/dihedral/per/atom keyword for the create_box
|
||||
or the read_data command to set this limit larger.
|
||||
|
||||
E: Dihedrals assigned incorrectly
|
||||
|
||||
@ -504,8 +504,8 @@ definitions.
|
||||
|
||||
E: Subsequent read data induced too many impropers per atom
|
||||
|
||||
See the create_box extra/improper/per/atom or read_data "extra
|
||||
improper per atom" header value to set this limit larger.
|
||||
See the extra/improper/per/atom keyword for the create_box
|
||||
or the read_data command to set this limit larger.
|
||||
|
||||
E: Impropers assigned incorrectly
|
||||
|
||||
|
||||
@ -1 +1 @@
|
||||
#define LAMMPS_VERSION "23 Jun 2017"
|
||||
#define LAMMPS_VERSION "6 Jul 2017"
|
||||
|
||||
Reference in New Issue
Block a user